@mastra/pg 1.0.0-beta.4 → 1.0.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
- import { createVectorErrorId, MastraStorage, createStorageErrorId, StoreOperations, TABLE_SCHEMAS, TABLE_WORKFLOW_SNAPSHOT, TABLE_SPANS, TABLE_THREADS, TABLE_MESSAGES, TABLE_TRACES, TABLE_SCORERS, ScoresStorage, normalizePerPage, calculatePagination, WorkflowsStorage, MemoryStorage, TABLE_RESOURCES, ObservabilityStorage, transformScoreRow as transformScoreRow$1 } from '@mastra/core/storage';
2
+ import { createVectorErrorId, MastraStorage, createStorageErrorId, StoreOperations, TABLE_SCHEMAS, TABLE_WORKFLOW_SNAPSHOT, TABLE_SPANS, TABLE_THREADS, TABLE_MESSAGES, TABLE_TRACES, TABLE_SCORERS, ScoresStorage, normalizePerPage, calculatePagination, WorkflowsStorage, MemoryStorage, TABLE_RESOURCES, ObservabilityStorage, AgentsStorage, transformScoreRow as transformScoreRow$1, TABLE_AGENTS } 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';
@@ -1637,7 +1637,302 @@ function transformFromSqlRow({
1637
1637
  return result;
1638
1638
  }
1639
1639
 
1640
- // src/storage/domains/memory/index.ts
1640
+ // src/storage/domains/agents/index.ts
1641
+ var AgentsPG = class extends AgentsStorage {
1642
+ client;
1643
+ schema;
1644
+ constructor({ client, schema }) {
1645
+ super();
1646
+ this.client = client;
1647
+ this.schema = schema;
1648
+ }
1649
+ parseJson(value, fieldName) {
1650
+ if (!value) return void 0;
1651
+ if (typeof value !== "string") return value;
1652
+ try {
1653
+ return JSON.parse(value);
1654
+ } catch (error) {
1655
+ const details = {
1656
+ value: value.length > 100 ? value.substring(0, 100) + "..." : value
1657
+ };
1658
+ if (fieldName) {
1659
+ details.field = fieldName;
1660
+ }
1661
+ throw new MastraError(
1662
+ {
1663
+ id: createStorageErrorId("PG", "PARSE_JSON", "INVALID_JSON"),
1664
+ domain: ErrorDomain.STORAGE,
1665
+ category: ErrorCategory.SYSTEM,
1666
+ text: `Failed to parse JSON${fieldName ? ` for field "${fieldName}"` : ""}: ${error instanceof Error ? error.message : "Unknown error"}`,
1667
+ details
1668
+ },
1669
+ error
1670
+ );
1671
+ }
1672
+ }
1673
+ parseRow(row) {
1674
+ return {
1675
+ id: row.id,
1676
+ name: row.name,
1677
+ description: row.description,
1678
+ instructions: row.instructions,
1679
+ model: this.parseJson(row.model, "model"),
1680
+ tools: this.parseJson(row.tools, "tools"),
1681
+ defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
1682
+ workflows: this.parseJson(row.workflows, "workflows"),
1683
+ agents: this.parseJson(row.agents, "agents"),
1684
+ inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
1685
+ outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
1686
+ memory: this.parseJson(row.memory, "memory"),
1687
+ scorers: this.parseJson(row.scorers, "scorers"),
1688
+ metadata: this.parseJson(row.metadata, "metadata"),
1689
+ createdAt: row.createdAtZ || row.createdAt,
1690
+ updatedAt: row.updatedAtZ || row.updatedAt
1691
+ };
1692
+ }
1693
+ async getAgentById({ id }) {
1694
+ try {
1695
+ const tableName = getTableName({ indexName: TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1696
+ const result = await this.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
1697
+ if (!result) {
1698
+ return null;
1699
+ }
1700
+ return this.parseRow(result);
1701
+ } catch (error) {
1702
+ throw new MastraError(
1703
+ {
1704
+ id: createStorageErrorId("PG", "GET_AGENT_BY_ID", "FAILED"),
1705
+ domain: ErrorDomain.STORAGE,
1706
+ category: ErrorCategory.THIRD_PARTY,
1707
+ details: { agentId: id }
1708
+ },
1709
+ error
1710
+ );
1711
+ }
1712
+ }
1713
+ async createAgent({ agent }) {
1714
+ try {
1715
+ const tableName = getTableName({ indexName: TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1716
+ const now = /* @__PURE__ */ new Date();
1717
+ const nowIso = now.toISOString();
1718
+ await this.client.none(
1719
+ `INSERT INTO ${tableName} (
1720
+ id, name, description, instructions, model, tools,
1721
+ "defaultOptions", workflows, agents, "inputProcessors", "outputProcessors", memory, scorers, metadata,
1722
+ "createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
1723
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)`,
1724
+ [
1725
+ agent.id,
1726
+ agent.name,
1727
+ agent.description ?? null,
1728
+ agent.instructions,
1729
+ JSON.stringify(agent.model),
1730
+ agent.tools ? JSON.stringify(agent.tools) : null,
1731
+ agent.defaultOptions ? JSON.stringify(agent.defaultOptions) : null,
1732
+ agent.workflows ? JSON.stringify(agent.workflows) : null,
1733
+ agent.agents ? JSON.stringify(agent.agents) : null,
1734
+ agent.inputProcessors ? JSON.stringify(agent.inputProcessors) : null,
1735
+ agent.outputProcessors ? JSON.stringify(agent.outputProcessors) : null,
1736
+ agent.memory ? JSON.stringify(agent.memory) : null,
1737
+ agent.scorers ? JSON.stringify(agent.scorers) : null,
1738
+ agent.metadata ? JSON.stringify(agent.metadata) : null,
1739
+ nowIso,
1740
+ nowIso,
1741
+ nowIso,
1742
+ nowIso
1743
+ ]
1744
+ );
1745
+ return {
1746
+ ...agent,
1747
+ createdAt: now,
1748
+ updatedAt: now
1749
+ };
1750
+ } catch (error) {
1751
+ throw new MastraError(
1752
+ {
1753
+ id: createStorageErrorId("PG", "CREATE_AGENT", "FAILED"),
1754
+ domain: ErrorDomain.STORAGE,
1755
+ category: ErrorCategory.THIRD_PARTY,
1756
+ details: { agentId: agent.id }
1757
+ },
1758
+ error
1759
+ );
1760
+ }
1761
+ }
1762
+ async updateAgent({ id, ...updates }) {
1763
+ try {
1764
+ const tableName = getTableName({ indexName: TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1765
+ const existingAgent = await this.getAgentById({ id });
1766
+ if (!existingAgent) {
1767
+ throw new MastraError({
1768
+ id: createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND"),
1769
+ domain: ErrorDomain.STORAGE,
1770
+ category: ErrorCategory.USER,
1771
+ text: `Agent ${id} not found`,
1772
+ details: { agentId: id }
1773
+ });
1774
+ }
1775
+ const setClauses = [];
1776
+ const values = [];
1777
+ let paramIndex = 1;
1778
+ if (updates.name !== void 0) {
1779
+ setClauses.push(`name = $${paramIndex++}`);
1780
+ values.push(updates.name);
1781
+ }
1782
+ if (updates.description !== void 0) {
1783
+ setClauses.push(`description = $${paramIndex++}`);
1784
+ values.push(updates.description);
1785
+ }
1786
+ if (updates.instructions !== void 0) {
1787
+ setClauses.push(`instructions = $${paramIndex++}`);
1788
+ values.push(updates.instructions);
1789
+ }
1790
+ if (updates.model !== void 0) {
1791
+ setClauses.push(`model = $${paramIndex++}`);
1792
+ values.push(JSON.stringify(updates.model));
1793
+ }
1794
+ if (updates.tools !== void 0) {
1795
+ setClauses.push(`tools = $${paramIndex++}`);
1796
+ values.push(JSON.stringify(updates.tools));
1797
+ }
1798
+ if (updates.defaultOptions !== void 0) {
1799
+ setClauses.push(`"defaultOptions" = $${paramIndex++}`);
1800
+ values.push(JSON.stringify(updates.defaultOptions));
1801
+ }
1802
+ if (updates.workflows !== void 0) {
1803
+ setClauses.push(`workflows = $${paramIndex++}`);
1804
+ values.push(JSON.stringify(updates.workflows));
1805
+ }
1806
+ if (updates.agents !== void 0) {
1807
+ setClauses.push(`agents = $${paramIndex++}`);
1808
+ values.push(JSON.stringify(updates.agents));
1809
+ }
1810
+ if (updates.inputProcessors !== void 0) {
1811
+ setClauses.push(`"inputProcessors" = $${paramIndex++}`);
1812
+ values.push(JSON.stringify(updates.inputProcessors));
1813
+ }
1814
+ if (updates.outputProcessors !== void 0) {
1815
+ setClauses.push(`"outputProcessors" = $${paramIndex++}`);
1816
+ values.push(JSON.stringify(updates.outputProcessors));
1817
+ }
1818
+ if (updates.memory !== void 0) {
1819
+ setClauses.push(`memory = $${paramIndex++}`);
1820
+ values.push(JSON.stringify(updates.memory));
1821
+ }
1822
+ if (updates.scorers !== void 0) {
1823
+ setClauses.push(`scorers = $${paramIndex++}`);
1824
+ values.push(JSON.stringify(updates.scorers));
1825
+ }
1826
+ if (updates.metadata !== void 0) {
1827
+ const mergedMetadata = { ...existingAgent.metadata, ...updates.metadata };
1828
+ setClauses.push(`metadata = $${paramIndex++}`);
1829
+ values.push(JSON.stringify(mergedMetadata));
1830
+ }
1831
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1832
+ setClauses.push(`"updatedAt" = $${paramIndex++}`);
1833
+ values.push(now);
1834
+ setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
1835
+ values.push(now);
1836
+ values.push(id);
1837
+ if (setClauses.length > 2) {
1838
+ await this.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
1839
+ }
1840
+ const updatedAgent = await this.getAgentById({ id });
1841
+ if (!updatedAgent) {
1842
+ throw new MastraError({
1843
+ id: createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND_AFTER_UPDATE"),
1844
+ domain: ErrorDomain.STORAGE,
1845
+ category: ErrorCategory.SYSTEM,
1846
+ text: `Agent ${id} not found after update`,
1847
+ details: { agentId: id }
1848
+ });
1849
+ }
1850
+ return updatedAgent;
1851
+ } catch (error) {
1852
+ if (error instanceof MastraError) {
1853
+ throw error;
1854
+ }
1855
+ throw new MastraError(
1856
+ {
1857
+ id: createStorageErrorId("PG", "UPDATE_AGENT", "FAILED"),
1858
+ domain: ErrorDomain.STORAGE,
1859
+ category: ErrorCategory.THIRD_PARTY,
1860
+ details: { agentId: id }
1861
+ },
1862
+ error
1863
+ );
1864
+ }
1865
+ }
1866
+ async deleteAgent({ id }) {
1867
+ try {
1868
+ const tableName = getTableName({ indexName: TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1869
+ await this.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
1870
+ } catch (error) {
1871
+ throw new MastraError(
1872
+ {
1873
+ id: createStorageErrorId("PG", "DELETE_AGENT", "FAILED"),
1874
+ domain: ErrorDomain.STORAGE,
1875
+ category: ErrorCategory.THIRD_PARTY,
1876
+ details: { agentId: id }
1877
+ },
1878
+ error
1879
+ );
1880
+ }
1881
+ }
1882
+ async listAgents(args) {
1883
+ const { page = 0, perPage: perPageInput, orderBy } = args || {};
1884
+ const { field, direction } = this.parseOrderBy(orderBy);
1885
+ if (page < 0) {
1886
+ throw new MastraError(
1887
+ {
1888
+ id: createStorageErrorId("PG", "LIST_AGENTS", "INVALID_PAGE"),
1889
+ domain: ErrorDomain.STORAGE,
1890
+ category: ErrorCategory.USER,
1891
+ details: { page }
1892
+ },
1893
+ new Error("page must be >= 0")
1894
+ );
1895
+ }
1896
+ const perPage = normalizePerPage(perPageInput, 100);
1897
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1898
+ try {
1899
+ const tableName = getTableName({ indexName: TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1900
+ const countResult = await this.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
1901
+ const total = parseInt(countResult.count, 10);
1902
+ if (total === 0) {
1903
+ return {
1904
+ agents: [],
1905
+ total: 0,
1906
+ page,
1907
+ perPage: perPageForResponse,
1908
+ hasMore: false
1909
+ };
1910
+ }
1911
+ const limitValue = perPageInput === false ? total : perPage;
1912
+ const dataResult = await this.client.manyOrNone(
1913
+ `SELECT * FROM ${tableName} ORDER BY "${field}" ${direction} LIMIT $1 OFFSET $2`,
1914
+ [limitValue, offset]
1915
+ );
1916
+ const agents = (dataResult || []).map((row) => this.parseRow(row));
1917
+ return {
1918
+ agents,
1919
+ total,
1920
+ page,
1921
+ perPage: perPageForResponse,
1922
+ hasMore: perPageInput === false ? false : offset + perPage < total
1923
+ };
1924
+ } catch (error) {
1925
+ throw new MastraError(
1926
+ {
1927
+ id: createStorageErrorId("PG", "LIST_AGENTS", "FAILED"),
1928
+ domain: ErrorDomain.STORAGE,
1929
+ category: ErrorCategory.THIRD_PARTY
1930
+ },
1931
+ error
1932
+ );
1933
+ }
1934
+ }
1935
+ };
1641
1936
  var MemoryPG = class extends MemoryStorage {
1642
1937
  client;
1643
1938
  schema;
@@ -3711,15 +4006,15 @@ var ScoresPG = class extends ScoresStorage {
3711
4006
  } catch (error) {
3712
4007
  throw new MastraError(
3713
4008
  {
3714
- id: createStorageErrorId("PG", "SAVE_SCORE", "INVALID_PAYLOAD"),
4009
+ id: createStorageErrorId("PG", "SAVE_SCORE", "VALIDATION_FAILED"),
3715
4010
  domain: ErrorDomain.STORAGE,
3716
4011
  category: ErrorCategory.USER,
3717
4012
  details: {
3718
- scorer: score.scorer.id,
3719
- entityId: score.entityId,
3720
- entityType: score.entityType,
3721
- traceId: score.traceId || "",
3722
- spanId: score.spanId || ""
4013
+ scorer: score.scorer?.id ?? "unknown",
4014
+ entityId: score.entityId ?? "unknown",
4015
+ entityType: score.entityType ?? "unknown",
4016
+ traceId: score.traceId ?? "",
4017
+ spanId: score.spanId ?? ""
3723
4018
  }
3724
4019
  },
3725
4020
  error
@@ -3727,6 +4022,7 @@ var ScoresPG = class extends ScoresStorage {
3727
4022
  }
3728
4023
  try {
3729
4024
  const id = crypto.randomUUID();
4025
+ const now = /* @__PURE__ */ new Date();
3730
4026
  const {
3731
4027
  scorer,
3732
4028
  preprocessStepResult,
@@ -3749,14 +4045,15 @@ var ScoresPG = class extends ScoresStorage {
3749
4045
  scorer: scorer ? JSON.stringify(scorer) : null,
3750
4046
  preprocessStepResult: preprocessStepResult ? JSON.stringify(preprocessStepResult) : null,
3751
4047
  analyzeStepResult: analyzeStepResult ? JSON.stringify(analyzeStepResult) : null,
4048
+ metadata: metadata ? JSON.stringify(metadata) : null,
4049
+ additionalContext: additionalContext ? JSON.stringify(additionalContext) : null,
3752
4050
  requestContext: requestContext ? JSON.stringify(requestContext) : null,
3753
4051
  entity: entity ? JSON.stringify(entity) : null,
3754
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3755
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
4052
+ createdAt: now.toISOString(),
4053
+ updatedAt: now.toISOString()
3756
4054
  }
3757
4055
  });
3758
- const scoreFromDb = await this.getScoreById({ id });
3759
- return { score: scoreFromDb };
4056
+ return { score: { ...parsedScore, id, createdAt: now, updatedAt: now } };
3760
4057
  } catch (error) {
3761
4058
  throw new MastraError(
3762
4059
  {
@@ -4138,17 +4435,17 @@ var WorkflowsPG = class extends WorkflowsStorage {
4138
4435
  var PostgresStore = class extends MastraStorage {
4139
4436
  #db;
4140
4437
  #pgp;
4141
- #config;
4142
4438
  schema;
4143
- isConnected = false;
4439
+ isInitialized = false;
4144
4440
  stores;
4145
4441
  constructor(config) {
4146
4442
  try {
4147
4443
  validateConfig("PostgresStore", config);
4148
4444
  super({ id: config.id, name: "PostgresStore", disableInit: config.disableInit });
4149
4445
  this.schema = config.schemaName || "public";
4446
+ let pgConfig;
4150
4447
  if (isConnectionStringConfig(config)) {
4151
- this.#config = {
4448
+ pgConfig = {
4152
4449
  id: config.id,
4153
4450
  connectionString: config.connectionString,
4154
4451
  max: config.max,
@@ -4156,14 +4453,14 @@ var PostgresStore = class extends MastraStorage {
4156
4453
  ssl: config.ssl
4157
4454
  };
4158
4455
  } else if (isCloudSqlConfig(config)) {
4159
- this.#config = {
4456
+ pgConfig = {
4160
4457
  ...config,
4161
4458
  id: config.id,
4162
4459
  max: config.max,
4163
4460
  idleTimeoutMillis: config.idleTimeoutMillis
4164
4461
  };
4165
4462
  } else if (isHostConfig(config)) {
4166
- this.#config = {
4463
+ pgConfig = {
4167
4464
  id: config.id,
4168
4465
  host: config.host,
4169
4466
  port: config.port,
@@ -4179,7 +4476,22 @@ var PostgresStore = class extends MastraStorage {
4179
4476
  "PostgresStore: invalid config. Provide either {connectionString}, {host,port,database,user,password}, or a pg ClientConfig (e.g., Cloud SQL connector with `stream`)."
4180
4477
  );
4181
4478
  }
4182
- this.stores = {};
4479
+ this.#pgp = pgPromise();
4480
+ this.#db = this.#pgp(pgConfig);
4481
+ const operations = new StoreOperationsPG({ client: this.#db, schemaName: this.schema });
4482
+ const scores = new ScoresPG({ client: this.#db, operations, schema: this.schema });
4483
+ const workflows = new WorkflowsPG({ client: this.#db, operations, schema: this.schema });
4484
+ const memory = new MemoryPG({ client: this.#db, schema: this.schema, operations });
4485
+ const observability = new ObservabilityPG({ client: this.#db, operations, schema: this.schema });
4486
+ const agents = new AgentsPG({ client: this.#db, schema: this.schema });
4487
+ this.stores = {
4488
+ operations,
4489
+ scores,
4490
+ workflows,
4491
+ memory,
4492
+ observability,
4493
+ agents
4494
+ };
4183
4495
  } catch (e) {
4184
4496
  throw new MastraError(
4185
4497
  {
@@ -4192,33 +4504,19 @@ var PostgresStore = class extends MastraStorage {
4192
4504
  }
4193
4505
  }
4194
4506
  async init() {
4195
- if (this.isConnected) {
4507
+ if (this.isInitialized) {
4196
4508
  return;
4197
4509
  }
4198
4510
  try {
4199
- this.isConnected = true;
4200
- this.#pgp = pgPromise();
4201
- this.#db = this.#pgp(this.#config);
4202
- const operations = new StoreOperationsPG({ client: this.#db, schemaName: this.schema });
4203
- const scores = new ScoresPG({ client: this.#db, operations, schema: this.schema });
4204
- const workflows = new WorkflowsPG({ client: this.#db, operations, schema: this.schema });
4205
- const memory = new MemoryPG({ client: this.#db, schema: this.schema, operations });
4206
- const observability = new ObservabilityPG({ client: this.#db, operations, schema: this.schema });
4207
- this.stores = {
4208
- operations,
4209
- scores,
4210
- workflows,
4211
- memory,
4212
- observability
4213
- };
4511
+ this.isInitialized = true;
4214
4512
  await super.init();
4215
4513
  try {
4216
- await operations.createAutomaticIndexes();
4514
+ await this.stores.operations.createAutomaticIndexes();
4217
4515
  } catch (indexError) {
4218
4516
  console.warn("Failed to create indexes:", indexError);
4219
4517
  }
4220
4518
  } catch (error) {
4221
- this.isConnected = false;
4519
+ this.isInitialized = false;
4222
4520
  throw new MastraError(
4223
4521
  {
4224
4522
  id: createStorageErrorId("PG", "INIT", "FAILED"),
@@ -4230,15 +4528,9 @@ var PostgresStore = class extends MastraStorage {
4230
4528
  }
4231
4529
  }
4232
4530
  get db() {
4233
- if (!this.#db) {
4234
- throw new Error(`PostgresStore: Store is not initialized, please call "init()" first.`);
4235
- }
4236
4531
  return this.#db;
4237
4532
  }
4238
4533
  get pgp() {
4239
- if (!this.#pgp) {
4240
- throw new Error(`PostgresStore: Store is not initialized, please call "init()" first.`);
4241
- }
4242
4534
  return this.#pgp;
4243
4535
  }
4244
4536
  get supports() {
@@ -4250,7 +4542,8 @@ var PostgresStore = class extends MastraStorage {
4250
4542
  deleteMessages: true,
4251
4543
  observabilityInstance: true,
4252
4544
  indexManagement: true,
4253
- listScoresBySpan: true
4545
+ listScoresBySpan: true,
4546
+ agents: true
4254
4547
  };
4255
4548
  }
4256
4549
  async createTable({