@mastra/pg 1.0.0-beta.5 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # @mastra/pg
2
2
 
3
+ ## 1.0.0-beta.6
4
+
5
+ ### Minor Changes
6
+
7
+ - Add stored agents support ([#10953](https://github.com/mastra-ai/mastra/pull/10953))
8
+
9
+ Agents can now be stored in the database and loaded at runtime. This lets you persist agent configurations and dynamically create executable Agent instances from storage.
10
+
11
+ ```typescript
12
+ import { Mastra } from '@mastra/core';
13
+ import { LibSQLStore } from '@mastra/libsql';
14
+
15
+ const mastra = new Mastra({
16
+ storage: new LibSQLStore({ url: ':memory:' }),
17
+ tools: { myTool },
18
+ scorers: { myScorer },
19
+ });
20
+
21
+ // Create agent in storage via API or directly
22
+ await mastra.getStorage().createAgent({
23
+ agent: {
24
+ id: 'my-agent',
25
+ name: 'My Agent',
26
+ instructions: 'You are helpful',
27
+ model: { provider: 'openai', name: 'gpt-4' },
28
+ tools: { myTool: {} },
29
+ scorers: { myScorer: { sampling: { type: 'ratio', rate: 0.5 } } },
30
+ },
31
+ });
32
+
33
+ // Load and use the agent
34
+ const agent = await mastra.getStoredAgentById('my-agent');
35
+ const response = await agent.generate({ messages: 'Hello!' });
36
+
37
+ // List all stored agents with pagination
38
+ const { agents, total, hasMore } = await mastra.listStoredAgents({
39
+ page: 0,
40
+ perPage: 10,
41
+ });
42
+ ```
43
+
44
+ Also adds a memory registry to Mastra so stored agents can reference memory instances by key.
45
+
46
+ ### Patch Changes
47
+
48
+ - Updated dependencies [[`72df8ae`](https://github.com/mastra-ai/mastra/commit/72df8ae595584cdd7747d5c39ffaca45e4507227), [`9198899`](https://github.com/mastra-ai/mastra/commit/91988995c427b185c33714b7f3be955367911324), [`653e65a`](https://github.com/mastra-ai/mastra/commit/653e65ae1f9502c2958a32f47a5a2df11e612a92), [`c6fd6fe`](https://github.com/mastra-ai/mastra/commit/c6fd6fedd09e9cf8004b03a80925f5e94826ad7e), [`0bed332`](https://github.com/mastra-ai/mastra/commit/0bed332843f627202c6520eaf671771313cd20f3)]:
49
+ - @mastra/core@1.0.0-beta.9
50
+
3
51
  ## 1.0.0-beta.5
4
52
 
5
53
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1663,7 +1663,302 @@ function transformFromSqlRow({
1663
1663
  return result;
1664
1664
  }
1665
1665
 
1666
- // src/storage/domains/memory/index.ts
1666
+ // src/storage/domains/agents/index.ts
1667
+ var AgentsPG = class extends storage.AgentsStorage {
1668
+ client;
1669
+ schema;
1670
+ constructor({ client, schema }) {
1671
+ super();
1672
+ this.client = client;
1673
+ this.schema = schema;
1674
+ }
1675
+ parseJson(value, fieldName) {
1676
+ if (!value) return void 0;
1677
+ if (typeof value !== "string") return value;
1678
+ try {
1679
+ return JSON.parse(value);
1680
+ } catch (error$1) {
1681
+ const details = {
1682
+ value: value.length > 100 ? value.substring(0, 100) + "..." : value
1683
+ };
1684
+ if (fieldName) {
1685
+ details.field = fieldName;
1686
+ }
1687
+ throw new error.MastraError(
1688
+ {
1689
+ id: storage.createStorageErrorId("PG", "PARSE_JSON", "INVALID_JSON"),
1690
+ domain: error.ErrorDomain.STORAGE,
1691
+ category: error.ErrorCategory.SYSTEM,
1692
+ text: `Failed to parse JSON${fieldName ? ` for field "${fieldName}"` : ""}: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`,
1693
+ details
1694
+ },
1695
+ error$1
1696
+ );
1697
+ }
1698
+ }
1699
+ parseRow(row) {
1700
+ return {
1701
+ id: row.id,
1702
+ name: row.name,
1703
+ description: row.description,
1704
+ instructions: row.instructions,
1705
+ model: this.parseJson(row.model, "model"),
1706
+ tools: this.parseJson(row.tools, "tools"),
1707
+ defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
1708
+ workflows: this.parseJson(row.workflows, "workflows"),
1709
+ agents: this.parseJson(row.agents, "agents"),
1710
+ inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
1711
+ outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
1712
+ memory: this.parseJson(row.memory, "memory"),
1713
+ scorers: this.parseJson(row.scorers, "scorers"),
1714
+ metadata: this.parseJson(row.metadata, "metadata"),
1715
+ createdAt: row.createdAtZ || row.createdAt,
1716
+ updatedAt: row.updatedAtZ || row.updatedAt
1717
+ };
1718
+ }
1719
+ async getAgentById({ id }) {
1720
+ try {
1721
+ const tableName = getTableName({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1722
+ const result = await this.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
1723
+ if (!result) {
1724
+ return null;
1725
+ }
1726
+ return this.parseRow(result);
1727
+ } catch (error$1) {
1728
+ throw new error.MastraError(
1729
+ {
1730
+ id: storage.createStorageErrorId("PG", "GET_AGENT_BY_ID", "FAILED"),
1731
+ domain: error.ErrorDomain.STORAGE,
1732
+ category: error.ErrorCategory.THIRD_PARTY,
1733
+ details: { agentId: id }
1734
+ },
1735
+ error$1
1736
+ );
1737
+ }
1738
+ }
1739
+ async createAgent({ agent }) {
1740
+ try {
1741
+ const tableName = getTableName({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1742
+ const now = /* @__PURE__ */ new Date();
1743
+ const nowIso = now.toISOString();
1744
+ await this.client.none(
1745
+ `INSERT INTO ${tableName} (
1746
+ id, name, description, instructions, model, tools,
1747
+ "defaultOptions", workflows, agents, "inputProcessors", "outputProcessors", memory, scorers, metadata,
1748
+ "createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
1749
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)`,
1750
+ [
1751
+ agent.id,
1752
+ agent.name,
1753
+ agent.description ?? null,
1754
+ agent.instructions,
1755
+ JSON.stringify(agent.model),
1756
+ agent.tools ? JSON.stringify(agent.tools) : null,
1757
+ agent.defaultOptions ? JSON.stringify(agent.defaultOptions) : null,
1758
+ agent.workflows ? JSON.stringify(agent.workflows) : null,
1759
+ agent.agents ? JSON.stringify(agent.agents) : null,
1760
+ agent.inputProcessors ? JSON.stringify(agent.inputProcessors) : null,
1761
+ agent.outputProcessors ? JSON.stringify(agent.outputProcessors) : null,
1762
+ agent.memory ? JSON.stringify(agent.memory) : null,
1763
+ agent.scorers ? JSON.stringify(agent.scorers) : null,
1764
+ agent.metadata ? JSON.stringify(agent.metadata) : null,
1765
+ nowIso,
1766
+ nowIso,
1767
+ nowIso,
1768
+ nowIso
1769
+ ]
1770
+ );
1771
+ return {
1772
+ ...agent,
1773
+ createdAt: now,
1774
+ updatedAt: now
1775
+ };
1776
+ } catch (error$1) {
1777
+ throw new error.MastraError(
1778
+ {
1779
+ id: storage.createStorageErrorId("PG", "CREATE_AGENT", "FAILED"),
1780
+ domain: error.ErrorDomain.STORAGE,
1781
+ category: error.ErrorCategory.THIRD_PARTY,
1782
+ details: { agentId: agent.id }
1783
+ },
1784
+ error$1
1785
+ );
1786
+ }
1787
+ }
1788
+ async updateAgent({ id, ...updates }) {
1789
+ try {
1790
+ const tableName = getTableName({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1791
+ const existingAgent = await this.getAgentById({ id });
1792
+ if (!existingAgent) {
1793
+ throw new error.MastraError({
1794
+ id: storage.createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND"),
1795
+ domain: error.ErrorDomain.STORAGE,
1796
+ category: error.ErrorCategory.USER,
1797
+ text: `Agent ${id} not found`,
1798
+ details: { agentId: id }
1799
+ });
1800
+ }
1801
+ const setClauses = [];
1802
+ const values = [];
1803
+ let paramIndex = 1;
1804
+ if (updates.name !== void 0) {
1805
+ setClauses.push(`name = $${paramIndex++}`);
1806
+ values.push(updates.name);
1807
+ }
1808
+ if (updates.description !== void 0) {
1809
+ setClauses.push(`description = $${paramIndex++}`);
1810
+ values.push(updates.description);
1811
+ }
1812
+ if (updates.instructions !== void 0) {
1813
+ setClauses.push(`instructions = $${paramIndex++}`);
1814
+ values.push(updates.instructions);
1815
+ }
1816
+ if (updates.model !== void 0) {
1817
+ setClauses.push(`model = $${paramIndex++}`);
1818
+ values.push(JSON.stringify(updates.model));
1819
+ }
1820
+ if (updates.tools !== void 0) {
1821
+ setClauses.push(`tools = $${paramIndex++}`);
1822
+ values.push(JSON.stringify(updates.tools));
1823
+ }
1824
+ if (updates.defaultOptions !== void 0) {
1825
+ setClauses.push(`"defaultOptions" = $${paramIndex++}`);
1826
+ values.push(JSON.stringify(updates.defaultOptions));
1827
+ }
1828
+ if (updates.workflows !== void 0) {
1829
+ setClauses.push(`workflows = $${paramIndex++}`);
1830
+ values.push(JSON.stringify(updates.workflows));
1831
+ }
1832
+ if (updates.agents !== void 0) {
1833
+ setClauses.push(`agents = $${paramIndex++}`);
1834
+ values.push(JSON.stringify(updates.agents));
1835
+ }
1836
+ if (updates.inputProcessors !== void 0) {
1837
+ setClauses.push(`"inputProcessors" = $${paramIndex++}`);
1838
+ values.push(JSON.stringify(updates.inputProcessors));
1839
+ }
1840
+ if (updates.outputProcessors !== void 0) {
1841
+ setClauses.push(`"outputProcessors" = $${paramIndex++}`);
1842
+ values.push(JSON.stringify(updates.outputProcessors));
1843
+ }
1844
+ if (updates.memory !== void 0) {
1845
+ setClauses.push(`memory = $${paramIndex++}`);
1846
+ values.push(JSON.stringify(updates.memory));
1847
+ }
1848
+ if (updates.scorers !== void 0) {
1849
+ setClauses.push(`scorers = $${paramIndex++}`);
1850
+ values.push(JSON.stringify(updates.scorers));
1851
+ }
1852
+ if (updates.metadata !== void 0) {
1853
+ const mergedMetadata = { ...existingAgent.metadata, ...updates.metadata };
1854
+ setClauses.push(`metadata = $${paramIndex++}`);
1855
+ values.push(JSON.stringify(mergedMetadata));
1856
+ }
1857
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1858
+ setClauses.push(`"updatedAt" = $${paramIndex++}`);
1859
+ values.push(now);
1860
+ setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
1861
+ values.push(now);
1862
+ values.push(id);
1863
+ if (setClauses.length > 2) {
1864
+ await this.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
1865
+ }
1866
+ const updatedAgent = await this.getAgentById({ id });
1867
+ if (!updatedAgent) {
1868
+ throw new error.MastraError({
1869
+ id: storage.createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND_AFTER_UPDATE"),
1870
+ domain: error.ErrorDomain.STORAGE,
1871
+ category: error.ErrorCategory.SYSTEM,
1872
+ text: `Agent ${id} not found after update`,
1873
+ details: { agentId: id }
1874
+ });
1875
+ }
1876
+ return updatedAgent;
1877
+ } catch (error$1) {
1878
+ if (error$1 instanceof error.MastraError) {
1879
+ throw error$1;
1880
+ }
1881
+ throw new error.MastraError(
1882
+ {
1883
+ id: storage.createStorageErrorId("PG", "UPDATE_AGENT", "FAILED"),
1884
+ domain: error.ErrorDomain.STORAGE,
1885
+ category: error.ErrorCategory.THIRD_PARTY,
1886
+ details: { agentId: id }
1887
+ },
1888
+ error$1
1889
+ );
1890
+ }
1891
+ }
1892
+ async deleteAgent({ id }) {
1893
+ try {
1894
+ const tableName = getTableName({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1895
+ await this.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
1896
+ } catch (error$1) {
1897
+ throw new error.MastraError(
1898
+ {
1899
+ id: storage.createStorageErrorId("PG", "DELETE_AGENT", "FAILED"),
1900
+ domain: error.ErrorDomain.STORAGE,
1901
+ category: error.ErrorCategory.THIRD_PARTY,
1902
+ details: { agentId: id }
1903
+ },
1904
+ error$1
1905
+ );
1906
+ }
1907
+ }
1908
+ async listAgents(args) {
1909
+ const { page = 0, perPage: perPageInput, orderBy } = args || {};
1910
+ const { field, direction } = this.parseOrderBy(orderBy);
1911
+ if (page < 0) {
1912
+ throw new error.MastraError(
1913
+ {
1914
+ id: storage.createStorageErrorId("PG", "LIST_AGENTS", "INVALID_PAGE"),
1915
+ domain: error.ErrorDomain.STORAGE,
1916
+ category: error.ErrorCategory.USER,
1917
+ details: { page }
1918
+ },
1919
+ new Error("page must be >= 0")
1920
+ );
1921
+ }
1922
+ const perPage = storage.normalizePerPage(perPageInput, 100);
1923
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1924
+ try {
1925
+ const tableName = getTableName({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName(this.schema) });
1926
+ const countResult = await this.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
1927
+ const total = parseInt(countResult.count, 10);
1928
+ if (total === 0) {
1929
+ return {
1930
+ agents: [],
1931
+ total: 0,
1932
+ page,
1933
+ perPage: perPageForResponse,
1934
+ hasMore: false
1935
+ };
1936
+ }
1937
+ const limitValue = perPageInput === false ? total : perPage;
1938
+ const dataResult = await this.client.manyOrNone(
1939
+ `SELECT * FROM ${tableName} ORDER BY "${field}" ${direction} LIMIT $1 OFFSET $2`,
1940
+ [limitValue, offset]
1941
+ );
1942
+ const agents = (dataResult || []).map((row) => this.parseRow(row));
1943
+ return {
1944
+ agents,
1945
+ total,
1946
+ page,
1947
+ perPage: perPageForResponse,
1948
+ hasMore: perPageInput === false ? false : offset + perPage < total
1949
+ };
1950
+ } catch (error$1) {
1951
+ throw new error.MastraError(
1952
+ {
1953
+ id: storage.createStorageErrorId("PG", "LIST_AGENTS", "FAILED"),
1954
+ domain: error.ErrorDomain.STORAGE,
1955
+ category: error.ErrorCategory.THIRD_PARTY
1956
+ },
1957
+ error$1
1958
+ );
1959
+ }
1960
+ }
1961
+ };
1667
1962
  var MemoryPG = class extends storage.MemoryStorage {
1668
1963
  client;
1669
1964
  schema;
@@ -4214,12 +4509,14 @@ var PostgresStore = class extends storage.MastraStorage {
4214
4509
  const workflows = new WorkflowsPG({ client: this.#db, operations, schema: this.schema });
4215
4510
  const memory = new MemoryPG({ client: this.#db, schema: this.schema, operations });
4216
4511
  const observability = new ObservabilityPG({ client: this.#db, operations, schema: this.schema });
4512
+ const agents = new AgentsPG({ client: this.#db, schema: this.schema });
4217
4513
  this.stores = {
4218
4514
  operations,
4219
4515
  scores,
4220
4516
  workflows,
4221
4517
  memory,
4222
- observability
4518
+ observability,
4519
+ agents
4223
4520
  };
4224
4521
  } catch (e) {
4225
4522
  throw new error.MastraError(
@@ -4271,7 +4568,8 @@ var PostgresStore = class extends storage.MastraStorage {
4271
4568
  deleteMessages: true,
4272
4569
  observabilityInstance: true,
4273
4570
  indexManagement: true,
4274
- listScoresBySpan: true
4571
+ listScoresBySpan: true,
4572
+ agents: true
4275
4573
  };
4276
4574
  }
4277
4575
  async createTable({