@mastra/dynamodb 1.0.0-beta.6 → 1.0.0-beta.8
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 +234 -0
- package/dist/index.cjs +210 -514
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +209 -516
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +32 -0
- package/dist/storage/db/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +4 -4
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/{score → scores}/index.d.ts +9 -22
- package/dist/storage/domains/scores/index.d.ts.map +1 -0
- package/dist/storage/domains/utils.d.ts +7 -0
- package/dist/storage/domains/utils.d.ts.map +1 -0
- package/dist/storage/domains/workflows/index.d.ts +8 -7
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +71 -166
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/storage/domains/operations/index.d.ts +0 -69
- package/dist/storage/domains/operations/index.d.ts.map +0 -1
- package/dist/storage/domains/score/index.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -939,11 +939,113 @@ function getElectroDbService(client, tableName) {
|
|
|
939
939
|
}
|
|
940
940
|
);
|
|
941
941
|
}
|
|
942
|
+
function resolveDynamoDBConfig(config) {
|
|
943
|
+
if ("service" in config) {
|
|
944
|
+
return config.service;
|
|
945
|
+
}
|
|
946
|
+
const dynamoClient = new clientDynamodb.DynamoDBClient({
|
|
947
|
+
region: config.region || "us-east-1",
|
|
948
|
+
endpoint: config.endpoint,
|
|
949
|
+
credentials: config.credentials
|
|
950
|
+
});
|
|
951
|
+
const client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
|
|
952
|
+
return getElectroDbService(client, config.tableName);
|
|
953
|
+
}
|
|
954
|
+
var ENTITY_MAP = {
|
|
955
|
+
[storage.TABLE_THREADS]: "thread",
|
|
956
|
+
[storage.TABLE_MESSAGES]: "message",
|
|
957
|
+
[storage.TABLE_RESOURCES]: "resource",
|
|
958
|
+
[storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
|
|
959
|
+
[storage.TABLE_SCORERS]: "score"
|
|
960
|
+
};
|
|
961
|
+
function getDeleteKey(entityName, item) {
|
|
962
|
+
const key = { entity: entityName };
|
|
963
|
+
switch (entityName) {
|
|
964
|
+
case "thread":
|
|
965
|
+
case "message":
|
|
966
|
+
case "resource":
|
|
967
|
+
case "score":
|
|
968
|
+
key.id = item.id;
|
|
969
|
+
break;
|
|
970
|
+
case "workflow_snapshot":
|
|
971
|
+
key.workflow_name = item.workflow_name;
|
|
972
|
+
key.run_id = item.run_id;
|
|
973
|
+
break;
|
|
974
|
+
default:
|
|
975
|
+
key.id = item.id;
|
|
976
|
+
}
|
|
977
|
+
return key;
|
|
978
|
+
}
|
|
979
|
+
async function deleteTableData(service, tableName) {
|
|
980
|
+
const entityName = ENTITY_MAP[tableName];
|
|
981
|
+
if (!entityName || !service.entities[entityName]) {
|
|
982
|
+
throw new Error(`No entity mapping found for table: ${tableName}`);
|
|
983
|
+
}
|
|
984
|
+
const entity = service.entities[entityName];
|
|
985
|
+
const result = await entity.scan.go({ pages: "all" });
|
|
986
|
+
if (!result.data.length) {
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
const batchSize = 25;
|
|
990
|
+
for (let i = 0; i < result.data.length; i += batchSize) {
|
|
991
|
+
const batch = result.data.slice(i, i + batchSize);
|
|
992
|
+
const keysToDelete = batch.map((item) => getDeleteKey(entityName, item));
|
|
993
|
+
await entity.delete(keysToDelete).go();
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// src/storage/domains/memory/index.ts
|
|
942
998
|
var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
943
999
|
service;
|
|
944
|
-
constructor(
|
|
1000
|
+
constructor(config) {
|
|
945
1001
|
super();
|
|
946
|
-
this.service =
|
|
1002
|
+
this.service = resolveDynamoDBConfig(config);
|
|
1003
|
+
}
|
|
1004
|
+
async dangerouslyClearAll() {
|
|
1005
|
+
await deleteTableData(this.service, storage.TABLE_THREADS);
|
|
1006
|
+
await deleteTableData(this.service, storage.TABLE_MESSAGES);
|
|
1007
|
+
await deleteTableData(this.service, storage.TABLE_RESOURCES);
|
|
1008
|
+
}
|
|
1009
|
+
async deleteMessages(messageIds) {
|
|
1010
|
+
if (!messageIds || messageIds.length === 0) {
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
this.logger.debug("Deleting messages", { count: messageIds.length });
|
|
1014
|
+
try {
|
|
1015
|
+
const threadIds = /* @__PURE__ */ new Set();
|
|
1016
|
+
const batchSize = 25;
|
|
1017
|
+
for (let i = 0; i < messageIds.length; i += batchSize) {
|
|
1018
|
+
const batch = messageIds.slice(i, i + batchSize);
|
|
1019
|
+
const messagesToDelete = await Promise.all(
|
|
1020
|
+
batch.map(async (id) => {
|
|
1021
|
+
const result = await this.service.entities.message.get({ entity: "message", id }).go();
|
|
1022
|
+
return result.data;
|
|
1023
|
+
})
|
|
1024
|
+
);
|
|
1025
|
+
for (const message of messagesToDelete) {
|
|
1026
|
+
if (message) {
|
|
1027
|
+
if (message.threadId) {
|
|
1028
|
+
threadIds.add(message.threadId);
|
|
1029
|
+
}
|
|
1030
|
+
await this.service.entities.message.delete({ entity: "message", id: message.id }).go();
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1035
|
+
for (const threadId of threadIds) {
|
|
1036
|
+
await this.service.entities.thread.update({ entity: "thread", id: threadId }).set({ updatedAt: now }).go();
|
|
1037
|
+
}
|
|
1038
|
+
} catch (error$1) {
|
|
1039
|
+
throw new error.MastraError(
|
|
1040
|
+
{
|
|
1041
|
+
id: storage.createStorageErrorId("DYNAMODB", "DELETE_MESSAGES", "FAILED"),
|
|
1042
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1043
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1044
|
+
details: { count: messageIds.length }
|
|
1045
|
+
},
|
|
1046
|
+
error$1
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
947
1049
|
}
|
|
948
1050
|
// Helper function to parse message data (handle JSON fields)
|
|
949
1051
|
parseMessageData(data) {
|
|
@@ -1637,334 +1739,14 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1637
1739
|
}
|
|
1638
1740
|
}
|
|
1639
1741
|
};
|
|
1640
|
-
var StoreOperationsDynamoDB = class extends storage.StoreOperations {
|
|
1641
|
-
client;
|
|
1642
|
-
tableName;
|
|
1643
|
-
service;
|
|
1644
|
-
constructor({
|
|
1645
|
-
service,
|
|
1646
|
-
tableName,
|
|
1647
|
-
client
|
|
1648
|
-
}) {
|
|
1649
|
-
super();
|
|
1650
|
-
this.service = service;
|
|
1651
|
-
this.client = client;
|
|
1652
|
-
this.tableName = tableName;
|
|
1653
|
-
}
|
|
1654
|
-
async hasColumn() {
|
|
1655
|
-
return true;
|
|
1656
|
-
}
|
|
1657
|
-
async dropTable() {
|
|
1658
|
-
}
|
|
1659
|
-
// Helper methods for entity/table mapping
|
|
1660
|
-
getEntityNameForTable(tableName) {
|
|
1661
|
-
const mapping = {
|
|
1662
|
-
[storage.TABLE_THREADS]: "thread",
|
|
1663
|
-
[storage.TABLE_MESSAGES]: "message",
|
|
1664
|
-
[storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
|
|
1665
|
-
[storage.TABLE_SCORERS]: "score",
|
|
1666
|
-
[storage.TABLE_TRACES]: "trace",
|
|
1667
|
-
[storage.TABLE_RESOURCES]: "resource",
|
|
1668
|
-
[storage.TABLE_SPANS]: "ai_span",
|
|
1669
|
-
mastra_agents: "agent"
|
|
1670
|
-
};
|
|
1671
|
-
return mapping[tableName] || null;
|
|
1672
|
-
}
|
|
1673
|
-
/**
|
|
1674
|
-
* Pre-processes a record to ensure Date objects are converted to ISO strings
|
|
1675
|
-
* This is necessary because ElectroDB validation happens before setters are applied
|
|
1676
|
-
*/
|
|
1677
|
-
preprocessRecord(record) {
|
|
1678
|
-
const processed = { ...record };
|
|
1679
|
-
if (processed.createdAt instanceof Date) {
|
|
1680
|
-
processed.createdAt = processed.createdAt.toISOString();
|
|
1681
|
-
}
|
|
1682
|
-
if (processed.updatedAt instanceof Date) {
|
|
1683
|
-
processed.updatedAt = processed.updatedAt.toISOString();
|
|
1684
|
-
}
|
|
1685
|
-
if (processed.created_at instanceof Date) {
|
|
1686
|
-
processed.created_at = processed.created_at.toISOString();
|
|
1687
|
-
}
|
|
1688
|
-
if (processed.result && typeof processed.result === "object") {
|
|
1689
|
-
processed.result = JSON.stringify(processed.result);
|
|
1690
|
-
}
|
|
1691
|
-
if (processed.test_info && typeof processed.test_info === "object") {
|
|
1692
|
-
processed.test_info = JSON.stringify(processed.test_info);
|
|
1693
|
-
} else if (processed.test_info === void 0 || processed.test_info === null) {
|
|
1694
|
-
delete processed.test_info;
|
|
1695
|
-
}
|
|
1696
|
-
if (processed.snapshot && typeof processed.snapshot === "object") {
|
|
1697
|
-
processed.snapshot = JSON.stringify(processed.snapshot);
|
|
1698
|
-
}
|
|
1699
|
-
if (processed.attributes && typeof processed.attributes === "object") {
|
|
1700
|
-
processed.attributes = JSON.stringify(processed.attributes);
|
|
1701
|
-
}
|
|
1702
|
-
if (processed.status && typeof processed.status === "object") {
|
|
1703
|
-
processed.status = JSON.stringify(processed.status);
|
|
1704
|
-
}
|
|
1705
|
-
if (processed.events && typeof processed.events === "object") {
|
|
1706
|
-
processed.events = JSON.stringify(processed.events);
|
|
1707
|
-
}
|
|
1708
|
-
if (processed.links && typeof processed.links === "object") {
|
|
1709
|
-
processed.links = JSON.stringify(processed.links);
|
|
1710
|
-
}
|
|
1711
|
-
return processed;
|
|
1712
|
-
}
|
|
1713
|
-
/**
|
|
1714
|
-
* Validates that the required DynamoDB table exists and is accessible.
|
|
1715
|
-
* This does not check the table structure - it assumes the table
|
|
1716
|
-
* was created with the correct structure via CDK/CloudFormation.
|
|
1717
|
-
*/
|
|
1718
|
-
async validateTableExists() {
|
|
1719
|
-
try {
|
|
1720
|
-
const command = new clientDynamodb.DescribeTableCommand({
|
|
1721
|
-
TableName: this.tableName
|
|
1722
|
-
});
|
|
1723
|
-
await this.client.send(command);
|
|
1724
|
-
return true;
|
|
1725
|
-
} catch (error$1) {
|
|
1726
|
-
if (error$1.name === "ResourceNotFoundException") {
|
|
1727
|
-
return false;
|
|
1728
|
-
}
|
|
1729
|
-
throw new error.MastraError(
|
|
1730
|
-
{
|
|
1731
|
-
id: storage.createStorageErrorId("DYNAMODB", "VALIDATE_TABLE_EXISTS", "FAILED"),
|
|
1732
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1733
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1734
|
-
details: { tableName: this.tableName }
|
|
1735
|
-
},
|
|
1736
|
-
error$1
|
|
1737
|
-
);
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
/**
|
|
1741
|
-
* This method is modified for DynamoDB with ElectroDB single-table design.
|
|
1742
|
-
* It assumes the table is created and managed externally via CDK/CloudFormation.
|
|
1743
|
-
*
|
|
1744
|
-
* This implementation only validates that the required table exists and is accessible.
|
|
1745
|
-
* No table creation is attempted - we simply check if we can access the table.
|
|
1746
|
-
*/
|
|
1747
|
-
async createTable({ tableName }) {
|
|
1748
|
-
this.logger.debug("Validating access to externally managed table", { tableName, physicalTable: this.tableName });
|
|
1749
|
-
try {
|
|
1750
|
-
const tableExists = await this.validateTableExists();
|
|
1751
|
-
if (!tableExists) {
|
|
1752
|
-
this.logger.error(
|
|
1753
|
-
`Table ${this.tableName} does not exist or is not accessible. It should be created via CDK/CloudFormation.`
|
|
1754
|
-
);
|
|
1755
|
-
throw new Error(
|
|
1756
|
-
`Table ${this.tableName} does not exist or is not accessible. Ensure it's created via CDK/CloudFormation before using this store.`
|
|
1757
|
-
);
|
|
1758
|
-
}
|
|
1759
|
-
this.logger.debug(`Table ${this.tableName} exists and is accessible`);
|
|
1760
|
-
} catch (error$1) {
|
|
1761
|
-
this.logger.error("Error validating table access", { tableName: this.tableName, error: error$1 });
|
|
1762
|
-
throw new error.MastraError(
|
|
1763
|
-
{
|
|
1764
|
-
id: storage.createStorageErrorId("DYNAMODB", "VALIDATE_TABLE_ACCESS", "FAILED"),
|
|
1765
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1766
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1767
|
-
details: { tableName: this.tableName }
|
|
1768
|
-
},
|
|
1769
|
-
error$1
|
|
1770
|
-
);
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
async insert({ tableName, record }) {
|
|
1774
|
-
this.logger.debug("DynamoDB insert called", { tableName });
|
|
1775
|
-
const entityName = this.getEntityNameForTable(tableName);
|
|
1776
|
-
if (!entityName || !this.service.entities[entityName]) {
|
|
1777
|
-
throw new error.MastraError({
|
|
1778
|
-
id: storage.createStorageErrorId("DYNAMODB", "INSERT", "INVALID_ARGS"),
|
|
1779
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1780
|
-
category: error.ErrorCategory.USER,
|
|
1781
|
-
text: "No entity defined for tableName",
|
|
1782
|
-
details: { tableName }
|
|
1783
|
-
});
|
|
1784
|
-
}
|
|
1785
|
-
try {
|
|
1786
|
-
const dataToSave = { entity: entityName, ...this.preprocessRecord(record) };
|
|
1787
|
-
await this.service.entities[entityName].create(dataToSave).go();
|
|
1788
|
-
} catch (error$1) {
|
|
1789
|
-
throw new error.MastraError(
|
|
1790
|
-
{
|
|
1791
|
-
id: storage.createStorageErrorId("DYNAMODB", "INSERT", "FAILED"),
|
|
1792
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1793
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1794
|
-
details: { tableName }
|
|
1795
|
-
},
|
|
1796
|
-
error$1
|
|
1797
|
-
);
|
|
1798
|
-
}
|
|
1799
|
-
}
|
|
1800
|
-
async alterTable(_args) {
|
|
1801
|
-
}
|
|
1802
|
-
/**
|
|
1803
|
-
* Clear all items from a logical "table" (entity type)
|
|
1804
|
-
*/
|
|
1805
|
-
async clearTable({ tableName }) {
|
|
1806
|
-
this.logger.debug("DynamoDB clearTable called", { tableName });
|
|
1807
|
-
const entityName = this.getEntityNameForTable(tableName);
|
|
1808
|
-
if (!entityName || !this.service.entities[entityName]) {
|
|
1809
|
-
throw new error.MastraError({
|
|
1810
|
-
id: storage.createStorageErrorId("DYNAMODB", "CLEAR_TABLE", "INVALID_ARGS"),
|
|
1811
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1812
|
-
category: error.ErrorCategory.USER,
|
|
1813
|
-
text: "No entity defined for tableName",
|
|
1814
|
-
details: { tableName }
|
|
1815
|
-
});
|
|
1816
|
-
}
|
|
1817
|
-
try {
|
|
1818
|
-
const result = await this.service.entities[entityName].scan.go({ pages: "all" });
|
|
1819
|
-
if (!result.data.length) {
|
|
1820
|
-
this.logger.debug(`No records found to clear for ${tableName}`);
|
|
1821
|
-
return;
|
|
1822
|
-
}
|
|
1823
|
-
this.logger.debug(`Found ${result.data.length} records to delete for ${tableName}`);
|
|
1824
|
-
const keysToDelete = result.data.map((item) => {
|
|
1825
|
-
const key = { entity: entityName };
|
|
1826
|
-
switch (entityName) {
|
|
1827
|
-
case "thread":
|
|
1828
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'thread'`);
|
|
1829
|
-
key.id = item.id;
|
|
1830
|
-
break;
|
|
1831
|
-
case "message":
|
|
1832
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'message'`);
|
|
1833
|
-
key.id = item.id;
|
|
1834
|
-
break;
|
|
1835
|
-
case "workflow_snapshot":
|
|
1836
|
-
if (!item.workflow_name)
|
|
1837
|
-
throw new Error(`Missing required key 'workflow_name' for entity 'workflow_snapshot'`);
|
|
1838
|
-
if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'workflow_snapshot'`);
|
|
1839
|
-
key.workflow_name = item.workflow_name;
|
|
1840
|
-
key.run_id = item.run_id;
|
|
1841
|
-
break;
|
|
1842
|
-
case "eval":
|
|
1843
|
-
if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'eval'`);
|
|
1844
|
-
key.run_id = item.run_id;
|
|
1845
|
-
break;
|
|
1846
|
-
case "trace":
|
|
1847
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'trace'`);
|
|
1848
|
-
key.id = item.id;
|
|
1849
|
-
break;
|
|
1850
|
-
case "score":
|
|
1851
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'score'`);
|
|
1852
|
-
key.id = item.id;
|
|
1853
|
-
break;
|
|
1854
|
-
case "resource":
|
|
1855
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'resource'`);
|
|
1856
|
-
key.id = item.id;
|
|
1857
|
-
break;
|
|
1858
|
-
default:
|
|
1859
|
-
this.logger.warn(`Unknown entity type encountered during clearTable: ${entityName}`);
|
|
1860
|
-
throw new Error(`Cannot construct delete key for unknown entity type: ${entityName}`);
|
|
1861
|
-
}
|
|
1862
|
-
return key;
|
|
1863
|
-
});
|
|
1864
|
-
const batchSize = 25;
|
|
1865
|
-
for (let i = 0; i < keysToDelete.length; i += batchSize) {
|
|
1866
|
-
const batchKeys = keysToDelete.slice(i, i + batchSize);
|
|
1867
|
-
await this.service.entities[entityName].delete(batchKeys).go();
|
|
1868
|
-
}
|
|
1869
|
-
this.logger.debug(`Successfully cleared all records for ${tableName}`);
|
|
1870
|
-
} catch (error$1) {
|
|
1871
|
-
throw new error.MastraError(
|
|
1872
|
-
{
|
|
1873
|
-
id: storage.createStorageErrorId("DYNAMODB", "CLEAR_TABLE", "FAILED"),
|
|
1874
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1875
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1876
|
-
details: { tableName }
|
|
1877
|
-
},
|
|
1878
|
-
error$1
|
|
1879
|
-
);
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
/**
|
|
1883
|
-
* Insert multiple records as a batch
|
|
1884
|
-
*/
|
|
1885
|
-
async batchInsert({ tableName, records }) {
|
|
1886
|
-
this.logger.debug("DynamoDB batchInsert called", { tableName, count: records.length });
|
|
1887
|
-
const entityName = this.getEntityNameForTable(tableName);
|
|
1888
|
-
if (!entityName || !this.service.entities[entityName]) {
|
|
1889
|
-
throw new error.MastraError({
|
|
1890
|
-
id: storage.createStorageErrorId("DYNAMODB", "BATCH_INSERT", "INVALID_ARGS"),
|
|
1891
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1892
|
-
category: error.ErrorCategory.USER,
|
|
1893
|
-
text: "No entity defined for tableName",
|
|
1894
|
-
details: { tableName }
|
|
1895
|
-
});
|
|
1896
|
-
}
|
|
1897
|
-
const recordsToSave = records.map((rec) => ({ entity: entityName, ...this.preprocessRecord(rec) }));
|
|
1898
|
-
const batchSize = 25;
|
|
1899
|
-
const batches = [];
|
|
1900
|
-
for (let i = 0; i < recordsToSave.length; i += batchSize) {
|
|
1901
|
-
const batch = recordsToSave.slice(i, i + batchSize);
|
|
1902
|
-
batches.push(batch);
|
|
1903
|
-
}
|
|
1904
|
-
try {
|
|
1905
|
-
for (const batch of batches) {
|
|
1906
|
-
for (const recordData of batch) {
|
|
1907
|
-
if (!recordData.entity) {
|
|
1908
|
-
this.logger.error("Missing entity property in record data for batchInsert", { recordData, tableName });
|
|
1909
|
-
throw new Error(`Internal error: Missing entity property during batchInsert for ${tableName}`);
|
|
1910
|
-
}
|
|
1911
|
-
this.logger.debug("Attempting to create record in batchInsert:", { entityName, recordData });
|
|
1912
|
-
await this.service.entities[entityName].create(recordData).go();
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
} catch (error$1) {
|
|
1916
|
-
throw new error.MastraError(
|
|
1917
|
-
{
|
|
1918
|
-
id: storage.createStorageErrorId("DYNAMODB", "BATCH_INSERT", "FAILED"),
|
|
1919
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1920
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1921
|
-
details: { tableName }
|
|
1922
|
-
},
|
|
1923
|
-
error$1
|
|
1924
|
-
);
|
|
1925
|
-
}
|
|
1926
|
-
}
|
|
1927
|
-
/**
|
|
1928
|
-
* Load a record by its keys
|
|
1929
|
-
*/
|
|
1930
|
-
async load({ tableName, keys }) {
|
|
1931
|
-
this.logger.debug("DynamoDB load called", { tableName, keys });
|
|
1932
|
-
const entityName = this.getEntityNameForTable(tableName);
|
|
1933
|
-
if (!entityName || !this.service.entities[entityName]) {
|
|
1934
|
-
throw new error.MastraError({
|
|
1935
|
-
id: storage.createStorageErrorId("DYNAMODB", "LOAD", "INVALID_ARGS"),
|
|
1936
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1937
|
-
category: error.ErrorCategory.USER,
|
|
1938
|
-
text: "No entity defined for tableName",
|
|
1939
|
-
details: { tableName }
|
|
1940
|
-
});
|
|
1941
|
-
}
|
|
1942
|
-
try {
|
|
1943
|
-
const keyObject = { entity: entityName, ...keys };
|
|
1944
|
-
const result = await this.service.entities[entityName].get(keyObject).go();
|
|
1945
|
-
if (!result.data) {
|
|
1946
|
-
return null;
|
|
1947
|
-
}
|
|
1948
|
-
let data = result.data;
|
|
1949
|
-
return data;
|
|
1950
|
-
} catch (error$1) {
|
|
1951
|
-
throw new error.MastraError(
|
|
1952
|
-
{
|
|
1953
|
-
id: storage.createStorageErrorId("DYNAMODB", "LOAD", "FAILED"),
|
|
1954
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1955
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1956
|
-
details: { tableName }
|
|
1957
|
-
},
|
|
1958
|
-
error$1
|
|
1959
|
-
);
|
|
1960
|
-
}
|
|
1961
|
-
}
|
|
1962
|
-
};
|
|
1963
1742
|
var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
1964
1743
|
service;
|
|
1965
|
-
constructor(
|
|
1744
|
+
constructor(config) {
|
|
1966
1745
|
super();
|
|
1967
|
-
this.service =
|
|
1746
|
+
this.service = resolveDynamoDBConfig(config);
|
|
1747
|
+
}
|
|
1748
|
+
async dangerouslyClearAll() {
|
|
1749
|
+
await deleteTableData(this.service, storage.TABLE_SCORERS);
|
|
1968
1750
|
}
|
|
1969
1751
|
/**
|
|
1970
1752
|
* DynamoDB-specific score row transformation.
|
|
@@ -2021,7 +1803,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2021
1803
|
domain: error.ErrorDomain.STORAGE,
|
|
2022
1804
|
category: error.ErrorCategory.USER,
|
|
2023
1805
|
details: {
|
|
2024
|
-
scorer: score.scorer?.id ?? "unknown",
|
|
1806
|
+
scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
|
|
2025
1807
|
entityId: score.entityId ?? "unknown",
|
|
2026
1808
|
entityType: score.entityType ?? "unknown",
|
|
2027
1809
|
traceId: score.traceId ?? "",
|
|
@@ -2264,44 +2046,104 @@ function formatWorkflowRun(snapshotData) {
|
|
|
2264
2046
|
}
|
|
2265
2047
|
var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
2266
2048
|
service;
|
|
2267
|
-
constructor(
|
|
2049
|
+
constructor(config) {
|
|
2268
2050
|
super();
|
|
2269
|
-
this.service =
|
|
2051
|
+
this.service = resolveDynamoDBConfig(config);
|
|
2270
2052
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2053
|
+
async dangerouslyClearAll() {
|
|
2054
|
+
await deleteTableData(this.service, storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
2055
|
+
}
|
|
2056
|
+
async updateWorkflowResults({
|
|
2057
|
+
workflowName,
|
|
2058
|
+
runId,
|
|
2059
|
+
stepId,
|
|
2060
|
+
result,
|
|
2061
|
+
requestContext
|
|
2277
2062
|
}) {
|
|
2278
|
-
|
|
2063
|
+
try {
|
|
2064
|
+
const existingSnapshot = await this.loadWorkflowSnapshot({ workflowName, runId });
|
|
2065
|
+
let snapshot;
|
|
2066
|
+
if (!existingSnapshot) {
|
|
2067
|
+
snapshot = {
|
|
2068
|
+
context: {},
|
|
2069
|
+
activePaths: [],
|
|
2070
|
+
timestamp: Date.now(),
|
|
2071
|
+
suspendedPaths: {},
|
|
2072
|
+
activeStepsPath: {},
|
|
2073
|
+
resumeLabels: {},
|
|
2074
|
+
serializedStepGraph: [],
|
|
2075
|
+
status: "pending",
|
|
2076
|
+
value: {},
|
|
2077
|
+
waitingPaths: {},
|
|
2078
|
+
runId,
|
|
2079
|
+
requestContext: {}
|
|
2080
|
+
};
|
|
2081
|
+
} else {
|
|
2082
|
+
snapshot = existingSnapshot;
|
|
2083
|
+
}
|
|
2084
|
+
snapshot.context[stepId] = result;
|
|
2085
|
+
snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
|
|
2086
|
+
await this.persistWorkflowSnapshot({ workflowName, runId, snapshot });
|
|
2087
|
+
return snapshot.context;
|
|
2088
|
+
} catch (error$1) {
|
|
2089
|
+
if (error$1 instanceof error.MastraError) throw error$1;
|
|
2090
|
+
throw new error.MastraError(
|
|
2091
|
+
{
|
|
2092
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_RESULTS", "FAILED"),
|
|
2093
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2094
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2095
|
+
details: { workflowName, runId, stepId }
|
|
2096
|
+
},
|
|
2097
|
+
error$1
|
|
2098
|
+
);
|
|
2099
|
+
}
|
|
2279
2100
|
}
|
|
2280
|
-
updateWorkflowState({
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2101
|
+
async updateWorkflowState({
|
|
2102
|
+
workflowName,
|
|
2103
|
+
runId,
|
|
2104
|
+
opts
|
|
2284
2105
|
}) {
|
|
2285
|
-
|
|
2106
|
+
try {
|
|
2107
|
+
const existingSnapshot = await this.loadWorkflowSnapshot({ workflowName, runId });
|
|
2108
|
+
if (!existingSnapshot || !existingSnapshot.context) {
|
|
2109
|
+
return void 0;
|
|
2110
|
+
}
|
|
2111
|
+
const updatedSnapshot = { ...existingSnapshot, ...opts };
|
|
2112
|
+
await this.persistWorkflowSnapshot({ workflowName, runId, snapshot: updatedSnapshot });
|
|
2113
|
+
return updatedSnapshot;
|
|
2114
|
+
} catch (error$1) {
|
|
2115
|
+
if (error$1 instanceof error.MastraError) throw error$1;
|
|
2116
|
+
throw new error.MastraError(
|
|
2117
|
+
{
|
|
2118
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_STATE", "FAILED"),
|
|
2119
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2120
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2121
|
+
details: { workflowName, runId }
|
|
2122
|
+
},
|
|
2123
|
+
error$1
|
|
2124
|
+
);
|
|
2125
|
+
}
|
|
2286
2126
|
}
|
|
2287
2127
|
// Workflow operations
|
|
2288
2128
|
async persistWorkflowSnapshot({
|
|
2289
2129
|
workflowName,
|
|
2290
2130
|
runId,
|
|
2291
2131
|
resourceId,
|
|
2292
|
-
snapshot
|
|
2132
|
+
snapshot,
|
|
2133
|
+
createdAt,
|
|
2134
|
+
updatedAt
|
|
2293
2135
|
}) {
|
|
2294
2136
|
this.logger.debug("Persisting workflow snapshot", { workflowName, runId });
|
|
2295
2137
|
try {
|
|
2296
|
-
const now =
|
|
2138
|
+
const now = /* @__PURE__ */ new Date();
|
|
2297
2139
|
const data = {
|
|
2298
2140
|
entity: "workflow_snapshot",
|
|
2299
2141
|
// Add entity type
|
|
2300
2142
|
workflow_name: workflowName,
|
|
2301
2143
|
run_id: runId,
|
|
2302
2144
|
snapshot: JSON.stringify(snapshot),
|
|
2303
|
-
createdAt: now,
|
|
2304
|
-
updatedAt: now,
|
|
2145
|
+
createdAt: (createdAt ?? now).toISOString(),
|
|
2146
|
+
updatedAt: (updatedAt ?? now).toISOString(),
|
|
2305
2147
|
resourceId
|
|
2306
2148
|
};
|
|
2307
2149
|
await this.service.entities.workflow_snapshot.upsert(data).go();
|
|
@@ -2509,6 +2351,9 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2509
2351
|
};
|
|
2510
2352
|
|
|
2511
2353
|
// src/storage/index.ts
|
|
2354
|
+
var isClientConfig = (config) => {
|
|
2355
|
+
return "client" in config;
|
|
2356
|
+
};
|
|
2512
2357
|
var DynamoDBStore = class extends storage.MastraStorage {
|
|
2513
2358
|
tableName;
|
|
2514
2359
|
client;
|
|
@@ -2526,24 +2371,23 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2526
2371
|
`DynamoDBStore: config.tableName "${config.tableName}" contains invalid characters or is not between 3 and 255 characters long.`
|
|
2527
2372
|
);
|
|
2528
2373
|
}
|
|
2529
|
-
const dynamoClient = new clientDynamodb.DynamoDBClient({
|
|
2530
|
-
region: config.region || "us-east-1",
|
|
2531
|
-
endpoint: config.endpoint,
|
|
2532
|
-
credentials: config.credentials
|
|
2533
|
-
});
|
|
2534
2374
|
this.tableName = config.tableName;
|
|
2535
|
-
|
|
2375
|
+
if (isClientConfig(config)) {
|
|
2376
|
+
this.client = config.client;
|
|
2377
|
+
} else {
|
|
2378
|
+
const dynamoClient = new clientDynamodb.DynamoDBClient({
|
|
2379
|
+
region: config.region || "us-east-1",
|
|
2380
|
+
endpoint: config.endpoint,
|
|
2381
|
+
credentials: config.credentials
|
|
2382
|
+
});
|
|
2383
|
+
this.client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
|
|
2384
|
+
}
|
|
2536
2385
|
this.service = getElectroDbService(this.client, this.tableName);
|
|
2537
|
-
const
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
});
|
|
2542
|
-
const workflows = new WorkflowStorageDynamoDB({ service: this.service });
|
|
2543
|
-
const memory = new MemoryStorageDynamoDB({ service: this.service });
|
|
2544
|
-
const scores = new ScoresStorageDynamoDB({ service: this.service });
|
|
2386
|
+
const domainConfig = { service: this.service };
|
|
2387
|
+
const workflows = new WorkflowStorageDynamoDB(domainConfig);
|
|
2388
|
+
const memory = new MemoryStorageDynamoDB(domainConfig);
|
|
2389
|
+
const scores = new ScoresStorageDynamoDB(domainConfig);
|
|
2545
2390
|
this.stores = {
|
|
2546
|
-
operations,
|
|
2547
2391
|
workflows,
|
|
2548
2392
|
memory,
|
|
2549
2393
|
scores
|
|
@@ -2559,16 +2403,6 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2559
2403
|
);
|
|
2560
2404
|
}
|
|
2561
2405
|
}
|
|
2562
|
-
get supports() {
|
|
2563
|
-
return {
|
|
2564
|
-
selectByIncludeResourceScope: true,
|
|
2565
|
-
resourceWorkingMemory: true,
|
|
2566
|
-
hasColumn: false,
|
|
2567
|
-
createTable: false,
|
|
2568
|
-
deleteMessages: false,
|
|
2569
|
-
listScoresBySpan: true
|
|
2570
|
-
};
|
|
2571
|
-
}
|
|
2572
2406
|
/**
|
|
2573
2407
|
* Validates that the required DynamoDB table exists and is accessible.
|
|
2574
2408
|
* This does not check the table structure - it assumes the table
|
|
@@ -2636,109 +2470,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2636
2470
|
throw err;
|
|
2637
2471
|
});
|
|
2638
2472
|
}
|
|
2639
|
-
async createTable({ tableName, schema }) {
|
|
2640
|
-
return this.stores.operations.createTable({ tableName, schema });
|
|
2641
|
-
}
|
|
2642
|
-
async alterTable(_args) {
|
|
2643
|
-
return this.stores.operations.alterTable(_args);
|
|
2644
|
-
}
|
|
2645
|
-
async clearTable({ tableName }) {
|
|
2646
|
-
return this.stores.operations.clearTable({ tableName });
|
|
2647
|
-
}
|
|
2648
|
-
async dropTable({ tableName }) {
|
|
2649
|
-
return this.stores.operations.dropTable({ tableName });
|
|
2650
|
-
}
|
|
2651
|
-
async insert({ tableName, record }) {
|
|
2652
|
-
return this.stores.operations.insert({ tableName, record });
|
|
2653
|
-
}
|
|
2654
|
-
async batchInsert({ tableName, records }) {
|
|
2655
|
-
return this.stores.operations.batchInsert({ tableName, records });
|
|
2656
|
-
}
|
|
2657
|
-
async load({ tableName, keys }) {
|
|
2658
|
-
return this.stores.operations.load({ tableName, keys });
|
|
2659
|
-
}
|
|
2660
|
-
// Thread operations
|
|
2661
|
-
async getThreadById({ threadId }) {
|
|
2662
|
-
return this.stores.memory.getThreadById({ threadId });
|
|
2663
|
-
}
|
|
2664
|
-
async saveThread({ thread }) {
|
|
2665
|
-
return this.stores.memory.saveThread({ thread });
|
|
2666
|
-
}
|
|
2667
|
-
async updateThread({
|
|
2668
|
-
id,
|
|
2669
|
-
title,
|
|
2670
|
-
metadata
|
|
2671
|
-
}) {
|
|
2672
|
-
return this.stores.memory.updateThread({ id, title, metadata });
|
|
2673
|
-
}
|
|
2674
|
-
async deleteThread({ threadId }) {
|
|
2675
|
-
return this.stores.memory.deleteThread({ threadId });
|
|
2676
|
-
}
|
|
2677
|
-
async listMessagesById(args) {
|
|
2678
|
-
return this.stores.memory.listMessagesById(args);
|
|
2679
|
-
}
|
|
2680
|
-
async saveMessages(args) {
|
|
2681
|
-
return this.stores.memory.saveMessages(args);
|
|
2682
|
-
}
|
|
2683
|
-
async updateMessages(_args) {
|
|
2684
|
-
return this.stores.memory.updateMessages(_args);
|
|
2685
|
-
}
|
|
2686
|
-
// Workflow operations
|
|
2687
|
-
async updateWorkflowResults({
|
|
2688
|
-
workflowName,
|
|
2689
|
-
runId,
|
|
2690
|
-
stepId,
|
|
2691
|
-
result,
|
|
2692
|
-
requestContext
|
|
2693
|
-
}) {
|
|
2694
|
-
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
|
|
2695
|
-
}
|
|
2696
|
-
async updateWorkflowState({
|
|
2697
|
-
workflowName,
|
|
2698
|
-
runId,
|
|
2699
|
-
opts
|
|
2700
|
-
}) {
|
|
2701
|
-
return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
|
|
2702
|
-
}
|
|
2703
|
-
async persistWorkflowSnapshot({
|
|
2704
|
-
workflowName,
|
|
2705
|
-
runId,
|
|
2706
|
-
resourceId,
|
|
2707
|
-
snapshot
|
|
2708
|
-
}) {
|
|
2709
|
-
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
2710
|
-
}
|
|
2711
|
-
async loadWorkflowSnapshot({
|
|
2712
|
-
workflowName,
|
|
2713
|
-
runId
|
|
2714
|
-
}) {
|
|
2715
|
-
return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
|
|
2716
|
-
}
|
|
2717
|
-
async listWorkflowRuns(args) {
|
|
2718
|
-
return this.stores.workflows.listWorkflowRuns(args);
|
|
2719
|
-
}
|
|
2720
|
-
async getWorkflowRunById(args) {
|
|
2721
|
-
return this.stores.workflows.getWorkflowRunById(args);
|
|
2722
|
-
}
|
|
2723
|
-
async deleteWorkflowRunById({ runId, workflowName }) {
|
|
2724
|
-
return this.stores.workflows.deleteWorkflowRunById({ runId, workflowName });
|
|
2725
|
-
}
|
|
2726
|
-
async getResourceById({ resourceId }) {
|
|
2727
|
-
return this.stores.memory.getResourceById({ resourceId });
|
|
2728
|
-
}
|
|
2729
|
-
async saveResource({ resource }) {
|
|
2730
|
-
return this.stores.memory.saveResource({ resource });
|
|
2731
|
-
}
|
|
2732
|
-
async updateResource({
|
|
2733
|
-
resourceId,
|
|
2734
|
-
workingMemory,
|
|
2735
|
-
metadata
|
|
2736
|
-
}) {
|
|
2737
|
-
return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
|
|
2738
|
-
}
|
|
2739
2473
|
/**
|
|
2740
2474
|
* Closes the DynamoDB client connection and cleans up resources.
|
|
2741
|
-
*
|
|
2475
|
+
*
|
|
2476
|
+
* This will close the DynamoDB client, including pre-configured clients.
|
|
2742
2477
|
*/
|
|
2743
2478
|
async close() {
|
|
2744
2479
|
this.logger.debug("Closing DynamoDB client for store:", { name: this.name });
|
|
@@ -2756,50 +2491,11 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2756
2491
|
);
|
|
2757
2492
|
}
|
|
2758
2493
|
}
|
|
2759
|
-
/**
|
|
2760
|
-
* SCORERS - Not implemented
|
|
2761
|
-
*/
|
|
2762
|
-
async getScoreById({ id: _id }) {
|
|
2763
|
-
return this.stores.scores.getScoreById({ id: _id });
|
|
2764
|
-
}
|
|
2765
|
-
async saveScore(score) {
|
|
2766
|
-
return this.stores.scores.saveScore(score);
|
|
2767
|
-
}
|
|
2768
|
-
async listScoresByRunId({
|
|
2769
|
-
runId: _runId,
|
|
2770
|
-
pagination: _pagination
|
|
2771
|
-
}) {
|
|
2772
|
-
return this.stores.scores.listScoresByRunId({ runId: _runId, pagination: _pagination });
|
|
2773
|
-
}
|
|
2774
|
-
async listScoresByEntityId({
|
|
2775
|
-
entityId: _entityId,
|
|
2776
|
-
entityType: _entityType,
|
|
2777
|
-
pagination: _pagination
|
|
2778
|
-
}) {
|
|
2779
|
-
return this.stores.scores.listScoresByEntityId({
|
|
2780
|
-
entityId: _entityId,
|
|
2781
|
-
entityType: _entityType,
|
|
2782
|
-
pagination: _pagination
|
|
2783
|
-
});
|
|
2784
|
-
}
|
|
2785
|
-
async listScoresByScorerId({
|
|
2786
|
-
scorerId,
|
|
2787
|
-
source,
|
|
2788
|
-
entityId,
|
|
2789
|
-
entityType,
|
|
2790
|
-
pagination
|
|
2791
|
-
}) {
|
|
2792
|
-
return this.stores.scores.listScoresByScorerId({ scorerId, source, entityId, entityType, pagination });
|
|
2793
|
-
}
|
|
2794
|
-
async listScoresBySpan({
|
|
2795
|
-
traceId,
|
|
2796
|
-
spanId,
|
|
2797
|
-
pagination
|
|
2798
|
-
}) {
|
|
2799
|
-
return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
|
|
2800
|
-
}
|
|
2801
2494
|
};
|
|
2802
2495
|
|
|
2803
2496
|
exports.DynamoDBStore = DynamoDBStore;
|
|
2497
|
+
exports.MemoryStorageDynamoDB = MemoryStorageDynamoDB;
|
|
2498
|
+
exports.ScoresStorageDynamoDB = ScoresStorageDynamoDB;
|
|
2499
|
+
exports.WorkflowStorageDynamoDB = WorkflowStorageDynamoDB;
|
|
2804
2500
|
//# sourceMappingURL=index.cjs.map
|
|
2805
2501
|
//# sourceMappingURL=index.cjs.map
|