@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.cjs
CHANGED
|
@@ -8,7 +8,6 @@ var asyncMutex = require('async-mutex');
|
|
|
8
8
|
var pg = require('pg');
|
|
9
9
|
var xxhash = require('xxhash-wasm');
|
|
10
10
|
var filter = require('@mastra/core/vector/filter');
|
|
11
|
-
var pgPromise = require('pg-promise');
|
|
12
11
|
var base = require('@mastra/core/base');
|
|
13
12
|
var agent = require('@mastra/core/agent');
|
|
14
13
|
var evals = require('@mastra/core/evals');
|
|
@@ -35,13 +34,15 @@ function _interopNamespace(e) {
|
|
|
35
34
|
|
|
36
35
|
var pg__namespace = /*#__PURE__*/_interopNamespace(pg);
|
|
37
36
|
var xxhash__default = /*#__PURE__*/_interopDefault(xxhash);
|
|
38
|
-
var pgPromise__default = /*#__PURE__*/_interopDefault(pgPromise);
|
|
39
37
|
|
|
40
38
|
// src/vector/index.ts
|
|
41
39
|
|
|
42
40
|
// src/shared/config.ts
|
|
41
|
+
var isPoolConfig = (cfg) => {
|
|
42
|
+
return "pool" in cfg;
|
|
43
|
+
};
|
|
43
44
|
var isConnectionStringConfig = (cfg) => {
|
|
44
|
-
return "connectionString" in cfg;
|
|
45
|
+
return "connectionString" in cfg && typeof cfg.connectionString === "string";
|
|
45
46
|
};
|
|
46
47
|
var isHostConfig = (cfg) => {
|
|
47
48
|
return "host" in cfg && "database" in cfg && "user" in cfg && "password" in cfg;
|
|
@@ -49,16 +50,13 @@ var isHostConfig = (cfg) => {
|
|
|
49
50
|
var isCloudSqlConfig = (cfg) => {
|
|
50
51
|
return "stream" in cfg || "password" in cfg && typeof cfg.password === "function";
|
|
51
52
|
};
|
|
52
|
-
var isClientConfig = (cfg) => {
|
|
53
|
-
return "client" in cfg;
|
|
54
|
-
};
|
|
55
53
|
var validateConfig = (name, config) => {
|
|
56
54
|
if (!config.id || typeof config.id !== "string" || config.id.trim() === "") {
|
|
57
55
|
throw new Error(`${name}: id must be provided and cannot be empty.`);
|
|
58
56
|
}
|
|
59
|
-
if (
|
|
60
|
-
if (!config.
|
|
61
|
-
throw new Error(`${name}:
|
|
57
|
+
if (isPoolConfig(config)) {
|
|
58
|
+
if (!config.pool) {
|
|
59
|
+
throw new Error(`${name}: pool must be provided when using pool config.`);
|
|
62
60
|
}
|
|
63
61
|
return;
|
|
64
62
|
}
|
|
@@ -79,7 +77,7 @@ var validateConfig = (name, config) => {
|
|
|
79
77
|
}
|
|
80
78
|
} else {
|
|
81
79
|
throw new Error(
|
|
82
|
-
`${name}: invalid config. Provide either {
|
|
80
|
+
`${name}: invalid config. Provide either {pool}, {connectionString}, {host,port,database,user,password}, or a pg ClientConfig (e.g., Cloud SQL connector with \`stream\`).`
|
|
83
81
|
);
|
|
84
82
|
}
|
|
85
83
|
};
|
|
@@ -544,8 +542,8 @@ var PgVector = class extends vector.MastraVector {
|
|
|
544
542
|
} else if (isCloudSqlConfig(config)) {
|
|
545
543
|
poolConfig = {
|
|
546
544
|
...config,
|
|
547
|
-
max: config.max ?? 20,
|
|
548
|
-
idleTimeoutMillis: config.idleTimeoutMillis ?? 3e4,
|
|
545
|
+
max: config.pgPoolOptions?.max ?? 20,
|
|
546
|
+
idleTimeoutMillis: config.pgPoolOptions?.idleTimeoutMillis ?? 3e4,
|
|
549
547
|
connectionTimeoutMillis: 2e3,
|
|
550
548
|
...config.pgPoolOptions
|
|
551
549
|
};
|
|
@@ -1687,6 +1685,132 @@ var PgVector = class extends vector.MastraVector {
|
|
|
1687
1685
|
}
|
|
1688
1686
|
}
|
|
1689
1687
|
};
|
|
1688
|
+
|
|
1689
|
+
// src/storage/client.ts
|
|
1690
|
+
function truncateQuery(query, maxLength = 100) {
|
|
1691
|
+
const normalized = query.replace(/\s+/g, " ").trim();
|
|
1692
|
+
if (normalized.length <= maxLength) {
|
|
1693
|
+
return normalized;
|
|
1694
|
+
}
|
|
1695
|
+
return normalized.slice(0, maxLength) + "...";
|
|
1696
|
+
}
|
|
1697
|
+
var PoolAdapter = class {
|
|
1698
|
+
constructor($pool) {
|
|
1699
|
+
this.$pool = $pool;
|
|
1700
|
+
}
|
|
1701
|
+
connect() {
|
|
1702
|
+
return this.$pool.connect();
|
|
1703
|
+
}
|
|
1704
|
+
async none(query, values) {
|
|
1705
|
+
await this.$pool.query(query, values);
|
|
1706
|
+
return null;
|
|
1707
|
+
}
|
|
1708
|
+
async one(query, values) {
|
|
1709
|
+
const result = await this.$pool.query(query, values);
|
|
1710
|
+
if (result.rows.length === 0) {
|
|
1711
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1712
|
+
}
|
|
1713
|
+
if (result.rows.length > 1) {
|
|
1714
|
+
throw new Error(`Multiple rows returned when one was expected: ${truncateQuery(query)}`);
|
|
1715
|
+
}
|
|
1716
|
+
return result.rows[0];
|
|
1717
|
+
}
|
|
1718
|
+
async oneOrNone(query, values) {
|
|
1719
|
+
const result = await this.$pool.query(query, values);
|
|
1720
|
+
if (result.rows.length === 0) {
|
|
1721
|
+
return null;
|
|
1722
|
+
}
|
|
1723
|
+
if (result.rows.length > 1) {
|
|
1724
|
+
throw new Error(`Multiple rows returned when one or none was expected: ${truncateQuery(query)}`);
|
|
1725
|
+
}
|
|
1726
|
+
return result.rows[0];
|
|
1727
|
+
}
|
|
1728
|
+
async any(query, values) {
|
|
1729
|
+
const result = await this.$pool.query(query, values);
|
|
1730
|
+
return result.rows;
|
|
1731
|
+
}
|
|
1732
|
+
async manyOrNone(query, values) {
|
|
1733
|
+
return this.any(query, values);
|
|
1734
|
+
}
|
|
1735
|
+
async many(query, values) {
|
|
1736
|
+
const result = await this.$pool.query(query, values);
|
|
1737
|
+
if (result.rows.length === 0) {
|
|
1738
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1739
|
+
}
|
|
1740
|
+
return result.rows;
|
|
1741
|
+
}
|
|
1742
|
+
async query(query, values) {
|
|
1743
|
+
return this.$pool.query(query, values);
|
|
1744
|
+
}
|
|
1745
|
+
async tx(callback) {
|
|
1746
|
+
const client = await this.$pool.connect();
|
|
1747
|
+
try {
|
|
1748
|
+
await client.query("BEGIN");
|
|
1749
|
+
const txClient = new TransactionClient(client);
|
|
1750
|
+
const result = await callback(txClient);
|
|
1751
|
+
await client.query("COMMIT");
|
|
1752
|
+
return result;
|
|
1753
|
+
} catch (error) {
|
|
1754
|
+
try {
|
|
1755
|
+
await client.query("ROLLBACK");
|
|
1756
|
+
} catch (rollbackError) {
|
|
1757
|
+
console.error("Transaction rollback failed:", rollbackError);
|
|
1758
|
+
}
|
|
1759
|
+
throw error;
|
|
1760
|
+
} finally {
|
|
1761
|
+
client.release();
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
};
|
|
1765
|
+
var TransactionClient = class {
|
|
1766
|
+
constructor(client) {
|
|
1767
|
+
this.client = client;
|
|
1768
|
+
}
|
|
1769
|
+
async none(query, values) {
|
|
1770
|
+
await this.client.query(query, values);
|
|
1771
|
+
return null;
|
|
1772
|
+
}
|
|
1773
|
+
async one(query, values) {
|
|
1774
|
+
const result = await this.client.query(query, values);
|
|
1775
|
+
if (result.rows.length === 0) {
|
|
1776
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1777
|
+
}
|
|
1778
|
+
if (result.rows.length > 1) {
|
|
1779
|
+
throw new Error(`Multiple rows returned when one was expected: ${truncateQuery(query)}`);
|
|
1780
|
+
}
|
|
1781
|
+
return result.rows[0];
|
|
1782
|
+
}
|
|
1783
|
+
async oneOrNone(query, values) {
|
|
1784
|
+
const result = await this.client.query(query, values);
|
|
1785
|
+
if (result.rows.length === 0) {
|
|
1786
|
+
return null;
|
|
1787
|
+
}
|
|
1788
|
+
if (result.rows.length > 1) {
|
|
1789
|
+
throw new Error(`Multiple rows returned when one or none was expected: ${truncateQuery(query)}`);
|
|
1790
|
+
}
|
|
1791
|
+
return result.rows[0];
|
|
1792
|
+
}
|
|
1793
|
+
async any(query, values) {
|
|
1794
|
+
const result = await this.client.query(query, values);
|
|
1795
|
+
return result.rows;
|
|
1796
|
+
}
|
|
1797
|
+
async manyOrNone(query, values) {
|
|
1798
|
+
return this.any(query, values);
|
|
1799
|
+
}
|
|
1800
|
+
async many(query, values) {
|
|
1801
|
+
const result = await this.client.query(query, values);
|
|
1802
|
+
if (result.rows.length === 0) {
|
|
1803
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1804
|
+
}
|
|
1805
|
+
return result.rows;
|
|
1806
|
+
}
|
|
1807
|
+
async query(query, values) {
|
|
1808
|
+
return this.client.query(query, values);
|
|
1809
|
+
}
|
|
1810
|
+
async batch(promises) {
|
|
1811
|
+
return Promise.all(promises);
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1690
1814
|
function resolvePgConfig(config) {
|
|
1691
1815
|
if ("client" in config) {
|
|
1692
1816
|
return {
|
|
@@ -1696,10 +1820,32 @@ function resolvePgConfig(config) {
|
|
|
1696
1820
|
indexes: config.indexes
|
|
1697
1821
|
};
|
|
1698
1822
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1823
|
+
if ("pool" in config) {
|
|
1824
|
+
return {
|
|
1825
|
+
client: new PoolAdapter(config.pool),
|
|
1826
|
+
schemaName: config.schemaName,
|
|
1827
|
+
skipDefaultIndexes: config.skipDefaultIndexes,
|
|
1828
|
+
indexes: config.indexes
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
let pool;
|
|
1832
|
+
if ("connectionString" in config) {
|
|
1833
|
+
pool = new pg.Pool({
|
|
1834
|
+
connectionString: config.connectionString,
|
|
1835
|
+
ssl: config.ssl
|
|
1836
|
+
});
|
|
1837
|
+
} else {
|
|
1838
|
+
pool = new pg.Pool({
|
|
1839
|
+
host: config.host,
|
|
1840
|
+
port: config.port,
|
|
1841
|
+
database: config.database,
|
|
1842
|
+
user: config.user,
|
|
1843
|
+
password: config.password,
|
|
1844
|
+
ssl: config.ssl
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1701
1847
|
return {
|
|
1702
|
-
client,
|
|
1848
|
+
client: new PoolAdapter(pool),
|
|
1703
1849
|
schemaName: config.schemaName,
|
|
1704
1850
|
skipDefaultIndexes: config.skipDefaultIndexes,
|
|
1705
1851
|
indexes: config.indexes
|
|
@@ -1714,6 +1860,87 @@ function getTableName({ indexName, schemaName }) {
|
|
|
1714
1860
|
const quotedSchemaName = schemaName;
|
|
1715
1861
|
return quotedSchemaName ? `${quotedSchemaName}.${quotedIndexName}` : quotedIndexName;
|
|
1716
1862
|
}
|
|
1863
|
+
function mapToSqlType(type) {
|
|
1864
|
+
switch (type) {
|
|
1865
|
+
case "uuid":
|
|
1866
|
+
return "UUID";
|
|
1867
|
+
case "boolean":
|
|
1868
|
+
return "BOOLEAN";
|
|
1869
|
+
default:
|
|
1870
|
+
return storage.getSqlType(type);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
function generateTableSQL({
|
|
1874
|
+
tableName,
|
|
1875
|
+
schema,
|
|
1876
|
+
schemaName
|
|
1877
|
+
}) {
|
|
1878
|
+
const timeZColumns = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => {
|
|
1879
|
+
const parsedName = utils.parseSqlIdentifier(name, "column name");
|
|
1880
|
+
return `"${parsedName}Z" TIMESTAMPTZ DEFAULT NOW()`;
|
|
1881
|
+
});
|
|
1882
|
+
const columns = Object.entries(schema).map(([name, def]) => {
|
|
1883
|
+
const parsedName = utils.parseSqlIdentifier(name, "column name");
|
|
1884
|
+
const constraints = [];
|
|
1885
|
+
if (def.primaryKey) constraints.push("PRIMARY KEY");
|
|
1886
|
+
if (!def.nullable) constraints.push("NOT NULL");
|
|
1887
|
+
return `"${parsedName}" ${mapToSqlType(def.type)} ${constraints.join(" ")}`;
|
|
1888
|
+
});
|
|
1889
|
+
const finalColumns = [...columns, ...timeZColumns].join(",\n");
|
|
1890
|
+
const parsedSchemaName = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
|
|
1891
|
+
const constraintPrefix = parsedSchemaName ? `${parsedSchemaName}_` : "";
|
|
1892
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
1893
|
+
const sql = `
|
|
1894
|
+
CREATE TABLE IF NOT EXISTS ${getTableName({ indexName: tableName, schemaName: quotedSchemaName })} (
|
|
1895
|
+
${finalColumns}
|
|
1896
|
+
);
|
|
1897
|
+
${tableName === storage.TABLE_WORKFLOW_SNAPSHOT ? `
|
|
1898
|
+
DO $$ BEGIN
|
|
1899
|
+
IF NOT EXISTS (
|
|
1900
|
+
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1901
|
+
) AND NOT EXISTS (
|
|
1902
|
+
SELECT 1 FROM pg_indexes WHERE indexname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1903
|
+
) THEN
|
|
1904
|
+
ALTER TABLE ${getTableName({ indexName: tableName, schemaName: quotedSchemaName })}
|
|
1905
|
+
ADD CONSTRAINT ${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key
|
|
1906
|
+
UNIQUE (workflow_name, run_id);
|
|
1907
|
+
END IF;
|
|
1908
|
+
END $$;
|
|
1909
|
+
` : ""}
|
|
1910
|
+
${tableName === storage.TABLE_SPANS ? `
|
|
1911
|
+
DO $$ BEGIN
|
|
1912
|
+
IF NOT EXISTS (
|
|
1913
|
+
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_ai_spans_traceid_spanid_pk'
|
|
1914
|
+
) THEN
|
|
1915
|
+
ALTER TABLE ${getTableName({ indexName: tableName, schemaName: quotedSchemaName })}
|
|
1916
|
+
ADD CONSTRAINT ${constraintPrefix}mastra_ai_spans_traceid_spanid_pk
|
|
1917
|
+
PRIMARY KEY ("traceId", "spanId");
|
|
1918
|
+
END IF;
|
|
1919
|
+
END $$;
|
|
1920
|
+
` : ""}
|
|
1921
|
+
`;
|
|
1922
|
+
return sql;
|
|
1923
|
+
}
|
|
1924
|
+
function exportSchemas(schemaName) {
|
|
1925
|
+
const statements = [];
|
|
1926
|
+
if (schemaName) {
|
|
1927
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
1928
|
+
statements.push(`-- Create schema if it doesn't exist`);
|
|
1929
|
+
statements.push(`CREATE SCHEMA IF NOT EXISTS ${quotedSchemaName};`);
|
|
1930
|
+
statements.push("");
|
|
1931
|
+
}
|
|
1932
|
+
for (const [tableName, schema] of Object.entries(storage.TABLE_SCHEMAS)) {
|
|
1933
|
+
statements.push(`-- Table: ${tableName}`);
|
|
1934
|
+
const sql = generateTableSQL({
|
|
1935
|
+
tableName,
|
|
1936
|
+
schema,
|
|
1937
|
+
schemaName
|
|
1938
|
+
});
|
|
1939
|
+
statements.push(sql.trim());
|
|
1940
|
+
statements.push("");
|
|
1941
|
+
}
|
|
1942
|
+
return statements.join("\n");
|
|
1943
|
+
}
|
|
1717
1944
|
var schemaSetupRegistry = /* @__PURE__ */ new Map();
|
|
1718
1945
|
var PgDB = class extends base.MastraBase {
|
|
1719
1946
|
client;
|
|
@@ -1831,16 +2058,6 @@ var PgDB = class extends base.MastraBase {
|
|
|
1831
2058
|
}
|
|
1832
2059
|
await registryEntry.promise;
|
|
1833
2060
|
}
|
|
1834
|
-
getSqlType(type) {
|
|
1835
|
-
switch (type) {
|
|
1836
|
-
case "uuid":
|
|
1837
|
-
return "UUID";
|
|
1838
|
-
case "boolean":
|
|
1839
|
-
return "BOOLEAN";
|
|
1840
|
-
default:
|
|
1841
|
-
return storage.getSqlType(type);
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
2061
|
getDefaultValue(type) {
|
|
1845
2062
|
switch (type) {
|
|
1846
2063
|
case "timestamp":
|
|
@@ -1910,52 +2127,10 @@ var PgDB = class extends base.MastraBase {
|
|
|
1910
2127
|
}) {
|
|
1911
2128
|
try {
|
|
1912
2129
|
const timeZColumnNames = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => name);
|
|
1913
|
-
const timeZColumns = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => {
|
|
1914
|
-
const parsedName = utils.parseSqlIdentifier(name, "column name");
|
|
1915
|
-
return `"${parsedName}Z" TIMESTAMPTZ DEFAULT NOW()`;
|
|
1916
|
-
});
|
|
1917
|
-
const columns = Object.entries(schema).map(([name, def]) => {
|
|
1918
|
-
const parsedName = utils.parseSqlIdentifier(name, "column name");
|
|
1919
|
-
const constraints = [];
|
|
1920
|
-
if (def.primaryKey) constraints.push("PRIMARY KEY");
|
|
1921
|
-
if (!def.nullable) constraints.push("NOT NULL");
|
|
1922
|
-
return `"${parsedName}" ${this.getSqlType(def.type)} ${constraints.join(" ")}`;
|
|
1923
|
-
});
|
|
1924
2130
|
if (this.schemaName) {
|
|
1925
2131
|
await this.setupSchema();
|
|
1926
2132
|
}
|
|
1927
|
-
const
|
|
1928
|
-
const constraintPrefix = this.schemaName ? `${this.schemaName}_` : "";
|
|
1929
|
-
const schemaName = getSchemaName(this.schemaName);
|
|
1930
|
-
const sql = `
|
|
1931
|
-
CREATE TABLE IF NOT EXISTS ${getTableName({ indexName: tableName, schemaName })} (
|
|
1932
|
-
${finalColumns}
|
|
1933
|
-
);
|
|
1934
|
-
${tableName === storage.TABLE_WORKFLOW_SNAPSHOT ? `
|
|
1935
|
-
DO $$ BEGIN
|
|
1936
|
-
IF NOT EXISTS (
|
|
1937
|
-
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1938
|
-
) AND NOT EXISTS (
|
|
1939
|
-
SELECT 1 FROM pg_indexes WHERE indexname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1940
|
-
) THEN
|
|
1941
|
-
ALTER TABLE ${getTableName({ indexName: tableName, schemaName })}
|
|
1942
|
-
ADD CONSTRAINT ${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key
|
|
1943
|
-
UNIQUE (workflow_name, run_id);
|
|
1944
|
-
END IF;
|
|
1945
|
-
END $$;
|
|
1946
|
-
` : ""}
|
|
1947
|
-
${tableName === storage.TABLE_SPANS ? `
|
|
1948
|
-
DO $$ BEGIN
|
|
1949
|
-
IF NOT EXISTS (
|
|
1950
|
-
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_ai_spans_traceid_spanid_pk'
|
|
1951
|
-
) THEN
|
|
1952
|
-
ALTER TABLE ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })}
|
|
1953
|
-
ADD CONSTRAINT ${constraintPrefix}mastra_ai_spans_traceid_spanid_pk
|
|
1954
|
-
PRIMARY KEY ("traceId", "spanId");
|
|
1955
|
-
END IF;
|
|
1956
|
-
END $$;
|
|
1957
|
-
` : ""}
|
|
1958
|
-
`;
|
|
2133
|
+
const sql = generateTableSQL({ tableName, schema, schemaName: this.schemaName });
|
|
1959
2134
|
await this.client.none(sql);
|
|
1960
2135
|
await this.alterTable({
|
|
1961
2136
|
tableName,
|
|
@@ -2029,7 +2204,7 @@ var PgDB = class extends base.MastraBase {
|
|
|
2029
2204
|
const columnExists = await this.hasColumn(storage.TABLE_SPANS, columnName);
|
|
2030
2205
|
if (!columnExists) {
|
|
2031
2206
|
const parsedColumnName = utils.parseSqlIdentifier(columnName, "column name");
|
|
2032
|
-
const sqlType =
|
|
2207
|
+
const sqlType = mapToSqlType(columnDef.type);
|
|
2033
2208
|
const nullable = columnDef.nullable ? "" : "NOT NULL";
|
|
2034
2209
|
const defaultValue = !columnDef.nullable ? this.getDefaultValue(columnDef.type) : "";
|
|
2035
2210
|
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN IF NOT EXISTS "${parsedColumnName}" ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
@@ -2076,7 +2251,7 @@ var PgDB = class extends base.MastraBase {
|
|
|
2076
2251
|
if (schema[columnName]) {
|
|
2077
2252
|
const columnDef = schema[columnName];
|
|
2078
2253
|
const parsedColumnName = utils.parseSqlIdentifier(columnName, "column name");
|
|
2079
|
-
const sqlType =
|
|
2254
|
+
const sqlType = mapToSqlType(columnDef.type);
|
|
2080
2255
|
const nullable = columnDef.nullable ? "" : "NOT NULL";
|
|
2081
2256
|
const defaultValue = !columnDef.nullable ? this.getDefaultValue(columnDef.type) : "";
|
|
2082
2257
|
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN IF NOT EXISTS "${parsedColumnName}" ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
@@ -2396,9 +2571,9 @@ var PgDB = class extends base.MastraBase {
|
|
|
2396
2571
|
size: result.size || "0",
|
|
2397
2572
|
definition: result.definition || "",
|
|
2398
2573
|
method: result.method || "btree",
|
|
2399
|
-
scans: parseInt(result.scans) || 0,
|
|
2400
|
-
tuples_read: parseInt(result.tuples_read) || 0,
|
|
2401
|
-
tuples_fetched: parseInt(result.tuples_fetched) || 0
|
|
2574
|
+
scans: parseInt(String(result.scans)) || 0,
|
|
2575
|
+
tuples_read: parseInt(String(result.tuples_read)) || 0,
|
|
2576
|
+
tuples_fetched: parseInt(String(result.tuples_fetched)) || 0
|
|
2402
2577
|
};
|
|
2403
2578
|
} catch (error$1) {
|
|
2404
2579
|
throw new error.MastraError(
|
|
@@ -2915,6 +3090,9 @@ function getTableName3({ indexName, schemaName }) {
|
|
|
2915
3090
|
const quotedIndexName = `"${indexName}"`;
|
|
2916
3091
|
return schemaName ? `${schemaName}.${quotedIndexName}` : quotedIndexName;
|
|
2917
3092
|
}
|
|
3093
|
+
function inPlaceholders(count, startIndex = 1) {
|
|
3094
|
+
return Array.from({ length: count }, (_, i) => `$${i + startIndex}`).join(", ");
|
|
3095
|
+
}
|
|
2918
3096
|
var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
2919
3097
|
#db;
|
|
2920
3098
|
#schema;
|
|
@@ -3075,13 +3253,19 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3075
3253
|
};
|
|
3076
3254
|
}
|
|
3077
3255
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3078
|
-
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`;
|
|
3079
|
-
const rows = await this.#db.client.manyOrNone(
|
|
3256
|
+
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "createdAtZ", "updatedAt", "updatedAtZ" ${baseQuery} ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`;
|
|
3257
|
+
const rows = await this.#db.client.manyOrNone(
|
|
3258
|
+
dataQuery,
|
|
3259
|
+
[...queryParams, limitValue, offset]
|
|
3260
|
+
);
|
|
3080
3261
|
const threads = (rows || []).map((thread) => ({
|
|
3081
|
-
|
|
3262
|
+
id: thread.id,
|
|
3263
|
+
resourceId: thread.resourceId,
|
|
3264
|
+
title: thread.title,
|
|
3082
3265
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
3083
|
-
|
|
3084
|
-
|
|
3266
|
+
// Use timezone-aware columns (*Z) for correct UTC timestamps, with fallback for legacy data
|
|
3267
|
+
createdAt: thread.createdAtZ || thread.createdAt,
|
|
3268
|
+
updatedAt: thread.updatedAtZ || thread.updatedAt
|
|
3085
3269
|
}));
|
|
3086
3270
|
return {
|
|
3087
3271
|
threads,
|
|
@@ -3186,17 +3370,18 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3186
3370
|
...metadata
|
|
3187
3371
|
};
|
|
3188
3372
|
try {
|
|
3373
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3189
3374
|
const thread = await this.#db.client.one(
|
|
3190
3375
|
`UPDATE ${threadTableName}
|
|
3191
3376
|
SET
|
|
3192
3377
|
title = $1,
|
|
3193
3378
|
metadata = $2,
|
|
3194
3379
|
"updatedAt" = $3,
|
|
3195
|
-
"updatedAtZ" = $
|
|
3196
|
-
WHERE id = $
|
|
3380
|
+
"updatedAtZ" = $4
|
|
3381
|
+
WHERE id = $5
|
|
3197
3382
|
RETURNING *
|
|
3198
3383
|
`,
|
|
3199
|
-
[title, mergedMetadata,
|
|
3384
|
+
[title, mergedMetadata, now, now, id]
|
|
3200
3385
|
);
|
|
3201
3386
|
return {
|
|
3202
3387
|
id: thread.id,
|
|
@@ -3339,7 +3524,7 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3339
3524
|
const tableName = getTableName3({ indexName: storage.TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) });
|
|
3340
3525
|
const query = `
|
|
3341
3526
|
${selectStatement} FROM ${tableName}
|
|
3342
|
-
WHERE id IN (${messageIds.
|
|
3527
|
+
WHERE id IN (${inPlaceholders(messageIds.length)})
|
|
3343
3528
|
ORDER BY "createdAt" DESC
|
|
3344
3529
|
`;
|
|
3345
3530
|
const resultRows = await this.#db.client.manyOrNone(query, messageIds);
|
|
@@ -3400,8 +3585,7 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3400
3585
|
const orderByStatement = `ORDER BY "${field}" ${direction}`;
|
|
3401
3586
|
const selectStatement = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"`;
|
|
3402
3587
|
const tableName = getTableName3({ indexName: storage.TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) });
|
|
3403
|
-
const
|
|
3404
|
-
const conditions = [`thread_id IN (${threadPlaceholders})`];
|
|
3588
|
+
const conditions = [`thread_id IN (${inPlaceholders(threadIds.length)})`];
|
|
3405
3589
|
const queryParams = [...threadIds];
|
|
3406
3590
|
let paramIndex = threadIds.length + 1;
|
|
3407
3591
|
if (resourceId) {
|
|
@@ -3409,11 +3593,13 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3409
3593
|
queryParams.push(resourceId);
|
|
3410
3594
|
}
|
|
3411
3595
|
if (filter?.dateRange?.start) {
|
|
3412
|
-
|
|
3596
|
+
const startOp = filter.dateRange.startExclusive ? ">" : ">=";
|
|
3597
|
+
conditions.push(`"createdAt" ${startOp} $${paramIndex++}`);
|
|
3413
3598
|
queryParams.push(filter.dateRange.start);
|
|
3414
3599
|
}
|
|
3415
3600
|
if (filter?.dateRange?.end) {
|
|
3416
|
-
|
|
3601
|
+
const endOp = filter.dateRange.endExclusive ? "<" : "<=";
|
|
3602
|
+
conditions.push(`"createdAt" ${endOp} $${paramIndex++}`);
|
|
3417
3603
|
queryParams.push(filter.dateRange.end);
|
|
3418
3604
|
}
|
|
3419
3605
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
@@ -3558,14 +3744,15 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3558
3744
|
);
|
|
3559
3745
|
});
|
|
3560
3746
|
const threadTableName = getTableName3({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName3(this.#schema) });
|
|
3747
|
+
const nowStr = (/* @__PURE__ */ new Date()).toISOString();
|
|
3561
3748
|
const threadUpdate = t.none(
|
|
3562
3749
|
`UPDATE ${threadTableName}
|
|
3563
3750
|
SET
|
|
3564
3751
|
"updatedAt" = $1,
|
|
3565
|
-
"updatedAtZ" = $
|
|
3566
|
-
WHERE id = $
|
|
3752
|
+
"updatedAtZ" = $2
|
|
3753
|
+
WHERE id = $3
|
|
3567
3754
|
`,
|
|
3568
|
-
[
|
|
3755
|
+
[nowStr, nowStr, threadId]
|
|
3569
3756
|
);
|
|
3570
3757
|
await Promise.all([...messageInserts, threadUpdate]);
|
|
3571
3758
|
});
|
|
@@ -3602,8 +3789,8 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3602
3789
|
return [];
|
|
3603
3790
|
}
|
|
3604
3791
|
const messageIds = messages.map((m) => m.id);
|
|
3605
|
-
const selectQuery = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId" FROM ${getTableName3({ indexName: storage.TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) })} WHERE id IN ($
|
|
3606
|
-
const existingMessagesDb = await this.#db.client.manyOrNone(selectQuery,
|
|
3792
|
+
const selectQuery = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId" FROM ${getTableName3({ indexName: storage.TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) })} WHERE id IN (${inPlaceholders(messageIds.length)})`;
|
|
3793
|
+
const existingMessagesDb = await this.#db.client.manyOrNone(selectQuery, messageIds);
|
|
3607
3794
|
if (existingMessagesDb.length === 0) {
|
|
3608
3795
|
return [];
|
|
3609
3796
|
}
|
|
@@ -3664,10 +3851,11 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3664
3851
|
}
|
|
3665
3852
|
}
|
|
3666
3853
|
if (threadIdsToUpdate.size > 0) {
|
|
3854
|
+
const threadIds = Array.from(threadIdsToUpdate);
|
|
3667
3855
|
queries.push(
|
|
3668
3856
|
t.none(
|
|
3669
|
-
`UPDATE ${getTableName3({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName3(this.#schema) })} SET "updatedAt" = NOW(), "updatedAtZ" = NOW() WHERE id IN ($
|
|
3670
|
-
|
|
3857
|
+
`UPDATE ${getTableName3({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName3(this.#schema) })} SET "updatedAt" = NOW(), "updatedAtZ" = NOW() WHERE id IN (${inPlaceholders(threadIds.length)})`,
|
|
3858
|
+
threadIds
|
|
3671
3859
|
)
|
|
3672
3860
|
);
|
|
3673
3861
|
}
|
|
@@ -3675,7 +3863,7 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3675
3863
|
await t.batch(queries);
|
|
3676
3864
|
}
|
|
3677
3865
|
});
|
|
3678
|
-
const updatedMessages = await this.#db.client.manyOrNone(selectQuery,
|
|
3866
|
+
const updatedMessages = await this.#db.client.manyOrNone(selectQuery, messageIds);
|
|
3679
3867
|
return (updatedMessages || []).map((row) => {
|
|
3680
3868
|
const message = this.normalizeMessageRow(row);
|
|
3681
3869
|
if (typeof message.content === "string") {
|
|
@@ -3787,15 +3975,159 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
3787
3975
|
values.push(JSON.stringify(updatedResource.metadata));
|
|
3788
3976
|
paramIndex++;
|
|
3789
3977
|
}
|
|
3790
|
-
|
|
3791
|
-
|
|
3978
|
+
const updatedAtStr = updatedResource.updatedAt.toISOString();
|
|
3979
|
+
updates.push(`"updatedAt" = $${paramIndex++}`);
|
|
3980
|
+
values.push(updatedAtStr);
|
|
3792
3981
|
updates.push(`"updatedAtZ" = $${paramIndex++}`);
|
|
3793
|
-
values.push(
|
|
3794
|
-
paramIndex++;
|
|
3982
|
+
values.push(updatedAtStr);
|
|
3795
3983
|
values.push(resourceId);
|
|
3796
3984
|
await this.#db.client.none(`UPDATE ${tableName} SET ${updates.join(", ")} WHERE id = $${paramIndex}`, values);
|
|
3797
3985
|
return updatedResource;
|
|
3798
3986
|
}
|
|
3987
|
+
async cloneThread(args) {
|
|
3988
|
+
const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;
|
|
3989
|
+
const sourceThread = await this.getThreadById({ threadId: sourceThreadId });
|
|
3990
|
+
if (!sourceThread) {
|
|
3991
|
+
throw new error.MastraError({
|
|
3992
|
+
id: storage.createStorageErrorId("PG", "CLONE_THREAD", "SOURCE_NOT_FOUND"),
|
|
3993
|
+
domain: error.ErrorDomain.STORAGE,
|
|
3994
|
+
category: error.ErrorCategory.USER,
|
|
3995
|
+
text: `Source thread with id ${sourceThreadId} not found`,
|
|
3996
|
+
details: { sourceThreadId }
|
|
3997
|
+
});
|
|
3998
|
+
}
|
|
3999
|
+
const newThreadId = providedThreadId || crypto.randomUUID();
|
|
4000
|
+
const existingThread = await this.getThreadById({ threadId: newThreadId });
|
|
4001
|
+
if (existingThread) {
|
|
4002
|
+
throw new error.MastraError({
|
|
4003
|
+
id: storage.createStorageErrorId("PG", "CLONE_THREAD", "THREAD_EXISTS"),
|
|
4004
|
+
domain: error.ErrorDomain.STORAGE,
|
|
4005
|
+
category: error.ErrorCategory.USER,
|
|
4006
|
+
text: `Thread with id ${newThreadId} already exists`,
|
|
4007
|
+
details: { newThreadId }
|
|
4008
|
+
});
|
|
4009
|
+
}
|
|
4010
|
+
const threadTableName = getTableName3({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName3(this.#schema) });
|
|
4011
|
+
const messageTableName = getTableName3({ indexName: storage.TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) });
|
|
4012
|
+
try {
|
|
4013
|
+
return await this.#db.client.tx(async (t) => {
|
|
4014
|
+
let messageQuery = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"
|
|
4015
|
+
FROM ${messageTableName} WHERE thread_id = $1`;
|
|
4016
|
+
const messageParams = [sourceThreadId];
|
|
4017
|
+
let paramIndex = 2;
|
|
4018
|
+
if (options?.messageFilter?.startDate) {
|
|
4019
|
+
messageQuery += ` AND "createdAt" >= $${paramIndex++}`;
|
|
4020
|
+
messageParams.push(options.messageFilter.startDate);
|
|
4021
|
+
}
|
|
4022
|
+
if (options?.messageFilter?.endDate) {
|
|
4023
|
+
messageQuery += ` AND "createdAt" <= $${paramIndex++}`;
|
|
4024
|
+
messageParams.push(options.messageFilter.endDate);
|
|
4025
|
+
}
|
|
4026
|
+
if (options?.messageFilter?.messageIds && options.messageFilter.messageIds.length > 0) {
|
|
4027
|
+
messageQuery += ` AND id IN (${options.messageFilter.messageIds.map(() => `$${paramIndex++}`).join(", ")})`;
|
|
4028
|
+
messageParams.push(...options.messageFilter.messageIds);
|
|
4029
|
+
}
|
|
4030
|
+
messageQuery += ` ORDER BY "createdAt" ASC`;
|
|
4031
|
+
if (options?.messageLimit && options.messageLimit > 0) {
|
|
4032
|
+
const limitQuery = `SELECT * FROM (${messageQuery.replace('ORDER BY "createdAt" ASC', 'ORDER BY "createdAt" DESC')} LIMIT $${paramIndex}) AS limited ORDER BY "createdAt" ASC`;
|
|
4033
|
+
messageParams.push(options.messageLimit);
|
|
4034
|
+
messageQuery = limitQuery;
|
|
4035
|
+
}
|
|
4036
|
+
const sourceMessages = await t.manyOrNone(messageQuery, messageParams);
|
|
4037
|
+
const now = /* @__PURE__ */ new Date();
|
|
4038
|
+
const lastMessageId = sourceMessages.length > 0 ? sourceMessages[sourceMessages.length - 1].id : void 0;
|
|
4039
|
+
const cloneMetadata = {
|
|
4040
|
+
sourceThreadId,
|
|
4041
|
+
clonedAt: now,
|
|
4042
|
+
...lastMessageId && { lastMessageId }
|
|
4043
|
+
};
|
|
4044
|
+
const newThread = {
|
|
4045
|
+
id: newThreadId,
|
|
4046
|
+
resourceId: resourceId || sourceThread.resourceId,
|
|
4047
|
+
title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : void 0),
|
|
4048
|
+
metadata: {
|
|
4049
|
+
...metadata,
|
|
4050
|
+
clone: cloneMetadata
|
|
4051
|
+
},
|
|
4052
|
+
createdAt: now,
|
|
4053
|
+
updatedAt: now
|
|
4054
|
+
};
|
|
4055
|
+
await t.none(
|
|
4056
|
+
`INSERT INTO ${threadTableName} (
|
|
4057
|
+
id,
|
|
4058
|
+
"resourceId",
|
|
4059
|
+
title,
|
|
4060
|
+
metadata,
|
|
4061
|
+
"createdAt",
|
|
4062
|
+
"createdAtZ",
|
|
4063
|
+
"updatedAt",
|
|
4064
|
+
"updatedAtZ"
|
|
4065
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
|
4066
|
+
[
|
|
4067
|
+
newThread.id,
|
|
4068
|
+
newThread.resourceId,
|
|
4069
|
+
newThread.title,
|
|
4070
|
+
newThread.metadata ? JSON.stringify(newThread.metadata) : null,
|
|
4071
|
+
now,
|
|
4072
|
+
now,
|
|
4073
|
+
now,
|
|
4074
|
+
now
|
|
4075
|
+
]
|
|
4076
|
+
);
|
|
4077
|
+
const clonedMessages = [];
|
|
4078
|
+
const targetResourceId = resourceId || sourceThread.resourceId;
|
|
4079
|
+
for (const sourceMsg of sourceMessages) {
|
|
4080
|
+
const newMessageId = crypto.randomUUID();
|
|
4081
|
+
const normalizedMsg = this.normalizeMessageRow(sourceMsg);
|
|
4082
|
+
let parsedContent = normalizedMsg.content;
|
|
4083
|
+
try {
|
|
4084
|
+
parsedContent = JSON.parse(normalizedMsg.content);
|
|
4085
|
+
} catch {
|
|
4086
|
+
}
|
|
4087
|
+
await t.none(
|
|
4088
|
+
`INSERT INTO ${messageTableName} (id, thread_id, content, "createdAt", "createdAtZ", role, type, "resourceId")
|
|
4089
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
|
4090
|
+
[
|
|
4091
|
+
newMessageId,
|
|
4092
|
+
newThreadId,
|
|
4093
|
+
typeof normalizedMsg.content === "string" ? normalizedMsg.content : JSON.stringify(normalizedMsg.content),
|
|
4094
|
+
normalizedMsg.createdAt,
|
|
4095
|
+
normalizedMsg.createdAt,
|
|
4096
|
+
normalizedMsg.role,
|
|
4097
|
+
normalizedMsg.type || "v2",
|
|
4098
|
+
targetResourceId
|
|
4099
|
+
]
|
|
4100
|
+
);
|
|
4101
|
+
clonedMessages.push({
|
|
4102
|
+
id: newMessageId,
|
|
4103
|
+
threadId: newThreadId,
|
|
4104
|
+
content: parsedContent,
|
|
4105
|
+
role: normalizedMsg.role,
|
|
4106
|
+
type: normalizedMsg.type,
|
|
4107
|
+
createdAt: new Date(normalizedMsg.createdAt),
|
|
4108
|
+
resourceId: targetResourceId
|
|
4109
|
+
});
|
|
4110
|
+
}
|
|
4111
|
+
return {
|
|
4112
|
+
thread: newThread,
|
|
4113
|
+
clonedMessages
|
|
4114
|
+
};
|
|
4115
|
+
});
|
|
4116
|
+
} catch (error$1) {
|
|
4117
|
+
if (error$1 instanceof error.MastraError) {
|
|
4118
|
+
throw error$1;
|
|
4119
|
+
}
|
|
4120
|
+
throw new error.MastraError(
|
|
4121
|
+
{
|
|
4122
|
+
id: storage.createStorageErrorId("PG", "CLONE_THREAD", "FAILED"),
|
|
4123
|
+
domain: error.ErrorDomain.STORAGE,
|
|
4124
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
4125
|
+
details: { sourceThreadId, newThreadId }
|
|
4126
|
+
},
|
|
4127
|
+
error$1
|
|
4128
|
+
);
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
3799
4131
|
};
|
|
3800
4132
|
var ObservabilityPG = class _ObservabilityPG extends storage.ObservabilityStorage {
|
|
3801
4133
|
#db;
|
|
@@ -5070,9 +5402,12 @@ var WorkflowsPG = class _WorkflowsPG extends storage.WorkflowsStorage {
|
|
|
5070
5402
|
};
|
|
5071
5403
|
|
|
5072
5404
|
// src/storage/index.ts
|
|
5405
|
+
var DEFAULT_MAX_CONNECTIONS = 20;
|
|
5406
|
+
var DEFAULT_IDLE_TIMEOUT_MS = 3e4;
|
|
5073
5407
|
var PostgresStore = class extends storage.MastraStorage {
|
|
5408
|
+
#pool;
|
|
5074
5409
|
#db;
|
|
5075
|
-
#
|
|
5410
|
+
#ownsPool;
|
|
5076
5411
|
schema;
|
|
5077
5412
|
isInitialized = false;
|
|
5078
5413
|
stores;
|
|
@@ -5081,59 +5416,26 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
5081
5416
|
validateConfig("PostgresStore", config);
|
|
5082
5417
|
super({ id: config.id, name: "PostgresStore", disableInit: config.disableInit });
|
|
5083
5418
|
this.schema = config.schemaName || "public";
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
this.#
|
|
5419
|
+
if (isPoolConfig(config)) {
|
|
5420
|
+
this.#pool = config.pool;
|
|
5421
|
+
this.#ownsPool = false;
|
|
5087
5422
|
} else {
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
pgConfig = {
|
|
5099
|
-
...config,
|
|
5100
|
-
id: config.id,
|
|
5101
|
-
max: config.max,
|
|
5102
|
-
idleTimeoutMillis: config.idleTimeoutMillis
|
|
5103
|
-
};
|
|
5104
|
-
} else if (isHostConfig(config)) {
|
|
5105
|
-
pgConfig = {
|
|
5106
|
-
id: config.id,
|
|
5107
|
-
host: config.host,
|
|
5108
|
-
port: config.port,
|
|
5109
|
-
database: config.database,
|
|
5110
|
-
user: config.user,
|
|
5111
|
-
password: config.password,
|
|
5112
|
-
ssl: config.ssl,
|
|
5113
|
-
max: config.max,
|
|
5114
|
-
idleTimeoutMillis: config.idleTimeoutMillis
|
|
5115
|
-
};
|
|
5116
|
-
} else {
|
|
5117
|
-
throw new Error(
|
|
5118
|
-
"PostgresStore: invalid config. Provide either {client}, {connectionString}, {host,port,database,user,password}, or a pg ClientConfig (e.g., Cloud SQL connector with `stream`)."
|
|
5119
|
-
);
|
|
5120
|
-
}
|
|
5121
|
-
this.#db = this.#pgp(pgConfig);
|
|
5122
|
-
}
|
|
5123
|
-
const skipDefaultIndexes = config.skipDefaultIndexes;
|
|
5124
|
-
const indexes = config.indexes;
|
|
5125
|
-
const domainConfig = { client: this.#db, schemaName: this.schema, skipDefaultIndexes, indexes };
|
|
5126
|
-
const scores = new ScoresPG(domainConfig);
|
|
5127
|
-
const workflows = new WorkflowsPG(domainConfig);
|
|
5128
|
-
const memory = new MemoryPG(domainConfig);
|
|
5129
|
-
const observability = new ObservabilityPG(domainConfig);
|
|
5130
|
-
const agents = new AgentsPG(domainConfig);
|
|
5423
|
+
this.#pool = this.createPool(config);
|
|
5424
|
+
this.#ownsPool = true;
|
|
5425
|
+
}
|
|
5426
|
+
this.#db = new PoolAdapter(this.#pool);
|
|
5427
|
+
const domainConfig = {
|
|
5428
|
+
client: this.#db,
|
|
5429
|
+
schemaName: this.schema,
|
|
5430
|
+
skipDefaultIndexes: config.skipDefaultIndexes,
|
|
5431
|
+
indexes: config.indexes
|
|
5432
|
+
};
|
|
5131
5433
|
this.stores = {
|
|
5132
|
-
scores,
|
|
5133
|
-
workflows,
|
|
5134
|
-
memory,
|
|
5135
|
-
observability,
|
|
5136
|
-
agents
|
|
5434
|
+
scores: new ScoresPG(domainConfig),
|
|
5435
|
+
workflows: new WorkflowsPG(domainConfig),
|
|
5436
|
+
memory: new MemoryPG(domainConfig),
|
|
5437
|
+
observability: new ObservabilityPG(domainConfig),
|
|
5438
|
+
agents: new AgentsPG(domainConfig)
|
|
5137
5439
|
};
|
|
5138
5440
|
} catch (e) {
|
|
5139
5441
|
throw new error.MastraError(
|
|
@@ -5146,6 +5448,32 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
5146
5448
|
);
|
|
5147
5449
|
}
|
|
5148
5450
|
}
|
|
5451
|
+
createPool(config) {
|
|
5452
|
+
if (isConnectionStringConfig(config)) {
|
|
5453
|
+
return new pg.Pool({
|
|
5454
|
+
connectionString: config.connectionString,
|
|
5455
|
+
ssl: config.ssl,
|
|
5456
|
+
max: config.max ?? DEFAULT_MAX_CONNECTIONS,
|
|
5457
|
+
idleTimeoutMillis: config.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MS
|
|
5458
|
+
});
|
|
5459
|
+
}
|
|
5460
|
+
if (isHostConfig(config)) {
|
|
5461
|
+
return new pg.Pool({
|
|
5462
|
+
host: config.host,
|
|
5463
|
+
port: config.port,
|
|
5464
|
+
database: config.database,
|
|
5465
|
+
user: config.user,
|
|
5466
|
+
password: config.password,
|
|
5467
|
+
ssl: config.ssl,
|
|
5468
|
+
max: config.max ?? DEFAULT_MAX_CONNECTIONS,
|
|
5469
|
+
idleTimeoutMillis: config.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MS
|
|
5470
|
+
});
|
|
5471
|
+
}
|
|
5472
|
+
if (isCloudSqlConfig(config)) {
|
|
5473
|
+
return new pg.Pool(config);
|
|
5474
|
+
}
|
|
5475
|
+
throw new Error("PostgresStore: invalid config");
|
|
5476
|
+
}
|
|
5149
5477
|
async init() {
|
|
5150
5478
|
if (this.isInitialized) {
|
|
5151
5479
|
return;
|
|
@@ -5165,19 +5493,32 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
5165
5493
|
);
|
|
5166
5494
|
}
|
|
5167
5495
|
}
|
|
5496
|
+
/**
|
|
5497
|
+
* Database client for executing queries.
|
|
5498
|
+
*
|
|
5499
|
+
* @example
|
|
5500
|
+
* ```typescript
|
|
5501
|
+
* const rows = await store.db.any('SELECT * FROM users WHERE active = $1', [true]);
|
|
5502
|
+
* const user = await store.db.one('SELECT * FROM users WHERE id = $1', [userId]);
|
|
5503
|
+
* ```
|
|
5504
|
+
*/
|
|
5168
5505
|
get db() {
|
|
5169
5506
|
return this.#db;
|
|
5170
5507
|
}
|
|
5171
|
-
|
|
5172
|
-
|
|
5508
|
+
/**
|
|
5509
|
+
* The underlying pg.Pool for direct database access or ORM integration.
|
|
5510
|
+
*/
|
|
5511
|
+
get pool() {
|
|
5512
|
+
return this.#pool;
|
|
5173
5513
|
}
|
|
5174
5514
|
/**
|
|
5175
|
-
* Closes the
|
|
5176
|
-
*
|
|
5177
|
-
* This will close ALL connections in the pool, including pre-configured clients.
|
|
5515
|
+
* Closes the connection pool if it was created by this store.
|
|
5516
|
+
* If a pool was passed in via config, it will not be closed.
|
|
5178
5517
|
*/
|
|
5179
5518
|
async close() {
|
|
5180
|
-
this
|
|
5519
|
+
if (this.#ownsPool) {
|
|
5520
|
+
await this.#pool.end();
|
|
5521
|
+
}
|
|
5181
5522
|
}
|
|
5182
5523
|
};
|
|
5183
5524
|
|
|
@@ -5285,8 +5626,10 @@ exports.MemoryPG = MemoryPG;
|
|
|
5285
5626
|
exports.ObservabilityPG = ObservabilityPG;
|
|
5286
5627
|
exports.PGVECTOR_PROMPT = PGVECTOR_PROMPT;
|
|
5287
5628
|
exports.PgVector = PgVector;
|
|
5629
|
+
exports.PoolAdapter = PoolAdapter;
|
|
5288
5630
|
exports.PostgresStore = PostgresStore;
|
|
5289
5631
|
exports.ScoresPG = ScoresPG;
|
|
5290
5632
|
exports.WorkflowsPG = WorkflowsPG;
|
|
5633
|
+
exports.exportSchemas = exportSchemas;
|
|
5291
5634
|
//# sourceMappingURL=index.cjs.map
|
|
5292
5635
|
//# sourceMappingURL=index.cjs.map
|