@mastra/mongodb 1.5.6 → 1.6.0-alpha.0

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.cjs CHANGED
@@ -14,7 +14,7 @@ var evals = require('@mastra/core/evals');
14
14
 
15
15
  // package.json
16
16
  var package_default = {
17
- version: "1.5.6"};
17
+ version: "1.6.0-alpha.0"};
18
18
  var MongoDBFilterTranslator = class extends filter.BaseFilterTranslator {
19
19
  getSupportedOperators() {
20
20
  return {
@@ -1700,6 +1700,1357 @@ var MongoDBBlobStore = class _MongoDBBlobStore extends storage.BlobStore {
1700
1700
  };
1701
1701
  }
1702
1702
  };
1703
+ var MANAGED_COLLECTIONS = [storage.TABLE_DATASETS, storage.TABLE_DATASET_ITEMS, storage.TABLE_DATASET_VERSIONS];
1704
+ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
1705
+ #connector;
1706
+ #skipDefaultIndexes;
1707
+ #indexes;
1708
+ constructor(config) {
1709
+ super();
1710
+ this.#connector = resolveMongoDBConfig(config);
1711
+ this.#skipDefaultIndexes = config.skipDefaultIndexes ?? false;
1712
+ this.#indexes = (config.indexes ?? []).filter(
1713
+ (i) => MANAGED_COLLECTIONS.includes(i.collection)
1714
+ );
1715
+ }
1716
+ getCollection(name) {
1717
+ return this.#connector.getCollection(name);
1718
+ }
1719
+ // --- Index management ---
1720
+ getDefaultIndexDefinitions() {
1721
+ return [
1722
+ { collection: storage.TABLE_DATASETS, keys: { id: 1 }, options: { name: "idx_datasets_id", unique: true } },
1723
+ { collection: storage.TABLE_DATASETS, keys: { createdAt: -1, id: 1 }, options: { name: "idx_datasets_createdat_id" } },
1724
+ { collection: storage.TABLE_DATASET_ITEMS, keys: { datasetId: 1 }, options: { name: "idx_dataset_items_datasetid" } },
1725
+ {
1726
+ collection: storage.TABLE_DATASET_ITEMS,
1727
+ keys: { datasetId: 1, validTo: 1 },
1728
+ options: { name: "idx_dataset_items_datasetid_validto" }
1729
+ },
1730
+ {
1731
+ collection: storage.TABLE_DATASET_ITEMS,
1732
+ keys: { datasetId: 1, isDeleted: 1 },
1733
+ options: { name: "idx_dataset_items_datasetid_isdeleted" }
1734
+ },
1735
+ {
1736
+ collection: storage.TABLE_DATASET_ITEMS,
1737
+ keys: { id: 1, validTo: 1 },
1738
+ options: { name: "idx_dataset_items_id_validto" }
1739
+ },
1740
+ {
1741
+ collection: storage.TABLE_DATASET_ITEMS,
1742
+ keys: { datasetId: 1, datasetVersion: 1 },
1743
+ options: { name: "idx_dataset_items_datasetid_version" }
1744
+ },
1745
+ {
1746
+ collection: storage.TABLE_DATASET_ITEMS,
1747
+ keys: { datasetId: 1, validTo: 1, isDeleted: 1, createdAt: -1, id: 1 },
1748
+ options: { name: "idx_dataset_items_list" }
1749
+ },
1750
+ {
1751
+ collection: storage.TABLE_DATASET_VERSIONS,
1752
+ keys: { datasetId: 1 },
1753
+ options: { name: "idx_dataset_versions_datasetid" }
1754
+ },
1755
+ {
1756
+ collection: storage.TABLE_DATASET_VERSIONS,
1757
+ keys: { datasetId: 1, version: 1 },
1758
+ options: { name: "idx_dataset_versions_datasetid_version", unique: true }
1759
+ }
1760
+ ];
1761
+ }
1762
+ async createDefaultIndexes() {
1763
+ if (this.#skipDefaultIndexes) return;
1764
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
1765
+ try {
1766
+ const collection = await this.getCollection(indexDef.collection);
1767
+ await collection.createIndex(indexDef.keys, indexDef.options);
1768
+ } catch (error) {
1769
+ this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
1770
+ }
1771
+ }
1772
+ }
1773
+ async createCustomIndexes() {
1774
+ for (const indexDef of this.#indexes) {
1775
+ try {
1776
+ const collection = await this.getCollection(indexDef.collection);
1777
+ await collection.createIndex(indexDef.keys, indexDef.options);
1778
+ } catch (error) {
1779
+ this.logger?.warn?.(`Failed to create custom index on ${indexDef.collection}:`, error);
1780
+ }
1781
+ }
1782
+ }
1783
+ async init() {
1784
+ await this.createDefaultIndexes();
1785
+ await this.createCustomIndexes();
1786
+ }
1787
+ // --- Row transformations ---
1788
+ transformDatasetRow(row) {
1789
+ return {
1790
+ id: row.id,
1791
+ name: row.name,
1792
+ description: row.description ?? void 0,
1793
+ metadata: typeof row.metadata === "string" ? storage.safelyParseJSON(row.metadata) : row.metadata ?? void 0,
1794
+ inputSchema: typeof row.inputSchema === "string" ? storage.safelyParseJSON(row.inputSchema) : row.inputSchema,
1795
+ groundTruthSchema: typeof row.groundTruthSchema === "string" ? storage.safelyParseJSON(row.groundTruthSchema) : row.groundTruthSchema,
1796
+ requestContextSchema: typeof row.requestContextSchema === "string" ? storage.safelyParseJSON(row.requestContextSchema) : row.requestContextSchema,
1797
+ tags: typeof row.tags === "string" ? storage.safelyParseJSON(row.tags) : row.tags ?? void 0,
1798
+ targetType: row.targetType ?? void 0,
1799
+ targetIds: typeof row.targetIds === "string" ? storage.safelyParseJSON(row.targetIds) : row.targetIds ?? void 0,
1800
+ version: row.version ?? 0,
1801
+ createdAt: storage.ensureDate(row.createdAt),
1802
+ updatedAt: storage.ensureDate(row.updatedAt)
1803
+ };
1804
+ }
1805
+ transformItemRow(row) {
1806
+ return {
1807
+ id: row.id,
1808
+ datasetId: row.datasetId,
1809
+ datasetVersion: row.datasetVersion,
1810
+ input: typeof row.input === "string" ? storage.safelyParseJSON(row.input) : row.input,
1811
+ groundTruth: typeof row.groundTruth === "string" ? storage.safelyParseJSON(row.groundTruth) : row.groundTruth,
1812
+ requestContext: typeof row.requestContext === "string" ? storage.safelyParseJSON(row.requestContext) : row.requestContext,
1813
+ metadata: typeof row.metadata === "string" ? storage.safelyParseJSON(row.metadata) : row.metadata,
1814
+ source: typeof row.source === "string" ? storage.safelyParseJSON(row.source) : row.source,
1815
+ createdAt: storage.ensureDate(row.createdAt),
1816
+ updatedAt: storage.ensureDate(row.updatedAt)
1817
+ };
1818
+ }
1819
+ transformItemRowFull(row) {
1820
+ return {
1821
+ ...this.transformItemRow(row),
1822
+ validTo: row.validTo ?? null,
1823
+ isDeleted: row.isDeleted ?? false
1824
+ };
1825
+ }
1826
+ transformDatasetVersionRow(row) {
1827
+ return {
1828
+ id: row.id,
1829
+ datasetId: row.datasetId,
1830
+ version: row.version,
1831
+ createdAt: storage.ensureDate(row.createdAt)
1832
+ };
1833
+ }
1834
+ // --- Dataset CRUD ---
1835
+ async createDataset(input) {
1836
+ try {
1837
+ const id = crypto.randomUUID();
1838
+ const now = /* @__PURE__ */ new Date();
1839
+ const collection = await this.getCollection(storage.TABLE_DATASETS);
1840
+ const record = {
1841
+ id,
1842
+ name: input.name,
1843
+ description: input.description ?? null,
1844
+ metadata: input.metadata ?? null,
1845
+ inputSchema: input.inputSchema ?? null,
1846
+ groundTruthSchema: input.groundTruthSchema ?? null,
1847
+ requestContextSchema: input.requestContextSchema ?? null,
1848
+ targetType: input.targetType ?? null,
1849
+ targetIds: input.targetIds ?? null,
1850
+ version: 0,
1851
+ createdAt: now,
1852
+ updatedAt: now
1853
+ };
1854
+ await collection.insertOne(record);
1855
+ return this.transformDatasetRow(record);
1856
+ } catch (error$1) {
1857
+ if (error$1 instanceof error.MastraError) throw error$1;
1858
+ throw new error.MastraError(
1859
+ {
1860
+ id: storage.createStorageErrorId("MONGODB", "CREATE_DATASET", "FAILED"),
1861
+ domain: error.ErrorDomain.STORAGE,
1862
+ category: error.ErrorCategory.THIRD_PARTY
1863
+ },
1864
+ error$1
1865
+ );
1866
+ }
1867
+ }
1868
+ async getDatasetById({ id }) {
1869
+ try {
1870
+ const collection = await this.getCollection(storage.TABLE_DATASETS);
1871
+ const row = await collection.findOne({ id });
1872
+ return row ? this.transformDatasetRow(row) : null;
1873
+ } catch (error$1) {
1874
+ throw new error.MastraError(
1875
+ {
1876
+ id: storage.createStorageErrorId("MONGODB", "GET_DATASET", "FAILED"),
1877
+ domain: error.ErrorDomain.STORAGE,
1878
+ category: error.ErrorCategory.THIRD_PARTY
1879
+ },
1880
+ error$1
1881
+ );
1882
+ }
1883
+ }
1884
+ async _doUpdateDataset(args) {
1885
+ try {
1886
+ const existing = await this.getDatasetById({ id: args.id });
1887
+ if (!existing) {
1888
+ throw new error.MastraError({
1889
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_DATASET", "NOT_FOUND"),
1890
+ domain: error.ErrorDomain.STORAGE,
1891
+ category: error.ErrorCategory.USER,
1892
+ details: { datasetId: args.id }
1893
+ });
1894
+ }
1895
+ const collection = await this.getCollection(storage.TABLE_DATASETS);
1896
+ const now = /* @__PURE__ */ new Date();
1897
+ const updateDoc = { updatedAt: now };
1898
+ if (args.name !== void 0) updateDoc.name = args.name;
1899
+ if (args.description !== void 0) updateDoc.description = args.description;
1900
+ if (args.metadata !== void 0) updateDoc.metadata = args.metadata;
1901
+ if (args.inputSchema !== void 0) updateDoc.inputSchema = args.inputSchema;
1902
+ if (args.groundTruthSchema !== void 0) updateDoc.groundTruthSchema = args.groundTruthSchema;
1903
+ if (args.requestContextSchema !== void 0) updateDoc.requestContextSchema = args.requestContextSchema;
1904
+ if (args.tags !== void 0) updateDoc.tags = args.tags;
1905
+ if (args.targetType !== void 0) updateDoc.targetType = args.targetType;
1906
+ if (args.targetIds !== void 0) updateDoc.targetIds = args.targetIds;
1907
+ await collection.updateOne({ id: args.id }, { $set: updateDoc });
1908
+ const updated = await this.getDatasetById({ id: args.id });
1909
+ return updated;
1910
+ } catch (error$1) {
1911
+ if (error$1 instanceof error.MastraError) throw error$1;
1912
+ throw new error.MastraError(
1913
+ {
1914
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_DATASET", "FAILED"),
1915
+ domain: error.ErrorDomain.STORAGE,
1916
+ category: error.ErrorCategory.THIRD_PARTY
1917
+ },
1918
+ error$1
1919
+ );
1920
+ }
1921
+ }
1922
+ async deleteDataset({ id }) {
1923
+ try {
1924
+ try {
1925
+ const experimentsCollection = await this.getCollection(storage.TABLE_EXPERIMENTS);
1926
+ const experimentIds = await experimentsCollection.find({ datasetId: id }, { projection: { id: 1 } }).toArray();
1927
+ if (experimentIds.length > 0) {
1928
+ const resultsCollection = await this.getCollection(storage.TABLE_EXPERIMENT_RESULTS);
1929
+ await resultsCollection.deleteMany({
1930
+ experimentId: { $in: experimentIds.map((e) => e.id) }
1931
+ });
1932
+ }
1933
+ await experimentsCollection.updateMany({ datasetId: id }, { $set: { datasetId: null, datasetVersion: null } });
1934
+ } catch (e) {
1935
+ const isNamespaceNotFound = e instanceof Error && "code" in e && e.code === 26;
1936
+ if (!isNamespaceNotFound) throw e;
1937
+ }
1938
+ const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
1939
+ const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
1940
+ const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
1941
+ await versionsCollection.deleteMany({ datasetId: id });
1942
+ await itemsCollection.deleteMany({ datasetId: id });
1943
+ await datasetsCollection.deleteOne({ id });
1944
+ } catch (error$1) {
1945
+ if (error$1 instanceof error.MastraError) throw error$1;
1946
+ throw new error.MastraError(
1947
+ {
1948
+ id: storage.createStorageErrorId("MONGODB", "DELETE_DATASET", "FAILED"),
1949
+ domain: error.ErrorDomain.STORAGE,
1950
+ category: error.ErrorCategory.THIRD_PARTY
1951
+ },
1952
+ error$1
1953
+ );
1954
+ }
1955
+ }
1956
+ async listDatasets(args) {
1957
+ try {
1958
+ const { page, perPage: perPageInput } = args.pagination;
1959
+ const collection = await this.getCollection(storage.TABLE_DATASETS);
1960
+ const total = await collection.countDocuments({});
1961
+ if (total === 0) {
1962
+ return { datasets: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
1963
+ }
1964
+ const perPage = storage.normalizePerPage(perPageInput, 100);
1965
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1966
+ if (perPage === 0) {
1967
+ return { datasets: [], pagination: { total, page, perPage: perPageForResponse, hasMore: total > 0 } };
1968
+ }
1969
+ const limitValue = perPageInput === false ? total : perPage;
1970
+ const rows = await collection.find({}).sort({ createdAt: -1, id: 1 }).skip(offset).limit(limitValue).toArray();
1971
+ return {
1972
+ datasets: rows.map((row) => this.transformDatasetRow(row)),
1973
+ pagination: {
1974
+ total,
1975
+ page,
1976
+ perPage: perPageForResponse,
1977
+ hasMore: perPageInput === false ? false : offset + perPage < total
1978
+ }
1979
+ };
1980
+ } catch (error$1) {
1981
+ throw new error.MastraError(
1982
+ {
1983
+ id: storage.createStorageErrorId("MONGODB", "LIST_DATASETS", "FAILED"),
1984
+ domain: error.ErrorDomain.STORAGE,
1985
+ category: error.ErrorCategory.THIRD_PARTY
1986
+ },
1987
+ error$1
1988
+ );
1989
+ }
1990
+ }
1991
+ // --- Item mutations (SCD-2) ---
1992
+ async _doAddItem(args) {
1993
+ try {
1994
+ const id = crypto.randomUUID();
1995
+ const versionId = crypto.randomUUID();
1996
+ const now = /* @__PURE__ */ new Date();
1997
+ const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
1998
+ const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
1999
+ const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2000
+ const result = await datasetsCollection.findOneAndUpdate(
2001
+ { id: args.datasetId },
2002
+ { $inc: { version: 1 } },
2003
+ { returnDocument: "after" }
2004
+ );
2005
+ if (!result) {
2006
+ throw new error.MastraError({
2007
+ id: storage.createStorageErrorId("MONGODB", "ADD_ITEM", "DATASET_NOT_FOUND"),
2008
+ domain: error.ErrorDomain.STORAGE,
2009
+ category: error.ErrorCategory.USER,
2010
+ details: { datasetId: args.datasetId }
2011
+ });
2012
+ }
2013
+ const newVersion = result.version;
2014
+ await itemsCollection.insertOne({
2015
+ id,
2016
+ datasetId: args.datasetId,
2017
+ datasetVersion: newVersion,
2018
+ validTo: null,
2019
+ isDeleted: false,
2020
+ input: args.input,
2021
+ groundTruth: args.groundTruth ?? null,
2022
+ requestContext: args.requestContext ?? null,
2023
+ metadata: args.metadata ?? null,
2024
+ source: args.source ?? null,
2025
+ createdAt: now,
2026
+ updatedAt: now
2027
+ });
2028
+ await versionsCollection.insertOne({
2029
+ id: versionId,
2030
+ datasetId: args.datasetId,
2031
+ version: newVersion,
2032
+ createdAt: now
2033
+ });
2034
+ return {
2035
+ id,
2036
+ datasetId: args.datasetId,
2037
+ datasetVersion: newVersion,
2038
+ input: args.input,
2039
+ groundTruth: args.groundTruth,
2040
+ requestContext: args.requestContext,
2041
+ metadata: args.metadata,
2042
+ source: args.source,
2043
+ createdAt: now,
2044
+ updatedAt: now
2045
+ };
2046
+ } catch (error$1) {
2047
+ if (error$1 instanceof error.MastraError) throw error$1;
2048
+ throw new error.MastraError(
2049
+ {
2050
+ id: storage.createStorageErrorId("MONGODB", "ADD_ITEM", "FAILED"),
2051
+ domain: error.ErrorDomain.STORAGE,
2052
+ category: error.ErrorCategory.THIRD_PARTY
2053
+ },
2054
+ error$1
2055
+ );
2056
+ }
2057
+ }
2058
+ async _doUpdateItem(args) {
2059
+ try {
2060
+ const existing = await this.getItemById({ id: args.id });
2061
+ if (!existing) {
2062
+ throw new error.MastraError({
2063
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_ITEM", "NOT_FOUND"),
2064
+ domain: error.ErrorDomain.STORAGE,
2065
+ category: error.ErrorCategory.USER,
2066
+ details: { itemId: args.id }
2067
+ });
2068
+ }
2069
+ if (existing.datasetId !== args.datasetId) {
2070
+ throw new error.MastraError({
2071
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_ITEM", "DATASET_MISMATCH"),
2072
+ domain: error.ErrorDomain.STORAGE,
2073
+ category: error.ErrorCategory.USER,
2074
+ details: { itemId: args.id, expectedDatasetId: args.datasetId, actualDatasetId: existing.datasetId }
2075
+ });
2076
+ }
2077
+ const hasChanges = args.input !== void 0 || args.groundTruth !== void 0 || args.requestContext !== void 0 || args.metadata !== void 0 || args.source !== void 0;
2078
+ if (!hasChanges) {
2079
+ return existing;
2080
+ }
2081
+ const now = /* @__PURE__ */ new Date();
2082
+ const versionId = crypto.randomUUID();
2083
+ const mergedInput = args.input !== void 0 ? args.input : existing.input;
2084
+ const mergedGroundTruth = args.groundTruth !== void 0 ? args.groundTruth : existing.groundTruth;
2085
+ const mergedRequestContext = args.requestContext !== void 0 ? args.requestContext : existing.requestContext;
2086
+ const mergedMetadata = args.metadata !== void 0 ? args.metadata : existing.metadata;
2087
+ const mergedSource = args.source !== void 0 ? args.source : existing.source;
2088
+ const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2089
+ const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2090
+ const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2091
+ const result = await datasetsCollection.findOneAndUpdate(
2092
+ { id: args.datasetId },
2093
+ { $inc: { version: 1 } },
2094
+ { returnDocument: "after" }
2095
+ );
2096
+ if (!result) {
2097
+ throw new error.MastraError({
2098
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_ITEM", "DATASET_NOT_FOUND"),
2099
+ domain: error.ErrorDomain.STORAGE,
2100
+ category: error.ErrorCategory.USER,
2101
+ details: { datasetId: args.datasetId }
2102
+ });
2103
+ }
2104
+ const newVersion = result.version;
2105
+ await itemsCollection.updateOne(
2106
+ { id: args.id, validTo: null, isDeleted: false },
2107
+ { $set: { validTo: newVersion } }
2108
+ );
2109
+ await itemsCollection.insertOne({
2110
+ id: args.id,
2111
+ datasetId: args.datasetId,
2112
+ datasetVersion: newVersion,
2113
+ validTo: null,
2114
+ isDeleted: false,
2115
+ input: mergedInput,
2116
+ groundTruth: mergedGroundTruth,
2117
+ requestContext: mergedRequestContext,
2118
+ metadata: mergedMetadata,
2119
+ source: mergedSource,
2120
+ createdAt: existing.createdAt,
2121
+ updatedAt: now
2122
+ });
2123
+ await versionsCollection.insertOne({
2124
+ id: versionId,
2125
+ datasetId: args.datasetId,
2126
+ version: newVersion,
2127
+ createdAt: now
2128
+ });
2129
+ return {
2130
+ ...existing,
2131
+ datasetVersion: newVersion,
2132
+ input: mergedInput,
2133
+ groundTruth: mergedGroundTruth,
2134
+ requestContext: mergedRequestContext,
2135
+ metadata: mergedMetadata,
2136
+ source: mergedSource,
2137
+ updatedAt: now
2138
+ };
2139
+ } catch (error$1) {
2140
+ if (error$1 instanceof error.MastraError) throw error$1;
2141
+ throw new error.MastraError(
2142
+ {
2143
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_ITEM", "FAILED"),
2144
+ domain: error.ErrorDomain.STORAGE,
2145
+ category: error.ErrorCategory.THIRD_PARTY
2146
+ },
2147
+ error$1
2148
+ );
2149
+ }
2150
+ }
2151
+ async _doDeleteItem({ id, datasetId }) {
2152
+ try {
2153
+ const existing = await this.getItemById({ id });
2154
+ if (!existing) return;
2155
+ if (existing.datasetId !== datasetId) {
2156
+ throw new error.MastraError({
2157
+ id: storage.createStorageErrorId("MONGODB", "DELETE_ITEM", "DATASET_MISMATCH"),
2158
+ domain: error.ErrorDomain.STORAGE,
2159
+ category: error.ErrorCategory.USER,
2160
+ details: { itemId: id, expectedDatasetId: datasetId, actualDatasetId: existing.datasetId }
2161
+ });
2162
+ }
2163
+ const now = /* @__PURE__ */ new Date();
2164
+ const versionId = crypto.randomUUID();
2165
+ const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2166
+ const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2167
+ const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2168
+ const result = await datasetsCollection.findOneAndUpdate(
2169
+ { id: datasetId },
2170
+ { $inc: { version: 1 } },
2171
+ { returnDocument: "after" }
2172
+ );
2173
+ if (!result) {
2174
+ throw new error.MastraError({
2175
+ id: storage.createStorageErrorId("MONGODB", "DELETE_ITEM", "DATASET_NOT_FOUND"),
2176
+ domain: error.ErrorDomain.STORAGE,
2177
+ category: error.ErrorCategory.USER,
2178
+ details: { datasetId }
2179
+ });
2180
+ }
2181
+ const newVersion = result.version;
2182
+ await itemsCollection.updateOne({ id, validTo: null, isDeleted: false }, { $set: { validTo: newVersion } });
2183
+ await itemsCollection.insertOne({
2184
+ id,
2185
+ datasetId,
2186
+ datasetVersion: newVersion,
2187
+ validTo: null,
2188
+ isDeleted: true,
2189
+ input: existing.input,
2190
+ groundTruth: existing.groundTruth,
2191
+ requestContext: existing.requestContext,
2192
+ metadata: existing.metadata,
2193
+ source: existing.source,
2194
+ createdAt: existing.createdAt,
2195
+ updatedAt: now
2196
+ });
2197
+ await versionsCollection.insertOne({
2198
+ id: versionId,
2199
+ datasetId,
2200
+ version: newVersion,
2201
+ createdAt: now
2202
+ });
2203
+ } catch (error$1) {
2204
+ if (error$1 instanceof error.MastraError) throw error$1;
2205
+ throw new error.MastraError(
2206
+ {
2207
+ id: storage.createStorageErrorId("MONGODB", "DELETE_ITEM", "FAILED"),
2208
+ domain: error.ErrorDomain.STORAGE,
2209
+ category: error.ErrorCategory.THIRD_PARTY
2210
+ },
2211
+ error$1
2212
+ );
2213
+ }
2214
+ }
2215
+ // --- Batch operations ---
2216
+ async _doBatchInsertItems(input) {
2217
+ try {
2218
+ const dataset = await this.getDatasetById({ id: input.datasetId });
2219
+ if (!dataset) {
2220
+ throw new error.MastraError({
2221
+ id: storage.createStorageErrorId("MONGODB", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
2222
+ domain: error.ErrorDomain.STORAGE,
2223
+ category: error.ErrorCategory.USER,
2224
+ details: { datasetId: input.datasetId }
2225
+ });
2226
+ }
2227
+ if (!input.items || input.items.length === 0) {
2228
+ return [];
2229
+ }
2230
+ const now = /* @__PURE__ */ new Date();
2231
+ const versionId = crypto.randomUUID();
2232
+ const itemsWithIds = input.items.map((itemInput) => ({
2233
+ generatedId: crypto.randomUUID(),
2234
+ itemInput
2235
+ }));
2236
+ const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2237
+ const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2238
+ const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2239
+ const result = await datasetsCollection.findOneAndUpdate(
2240
+ { id: input.datasetId },
2241
+ { $inc: { version: 1 } },
2242
+ { returnDocument: "after" }
2243
+ );
2244
+ if (!result) {
2245
+ throw new error.MastraError({
2246
+ id: storage.createStorageErrorId("MONGODB", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
2247
+ domain: error.ErrorDomain.STORAGE,
2248
+ category: error.ErrorCategory.USER,
2249
+ details: { datasetId: input.datasetId }
2250
+ });
2251
+ }
2252
+ const newVersion = result.version;
2253
+ if (itemsWithIds.length > 0) {
2254
+ const docs = itemsWithIds.map(({ generatedId, itemInput }) => ({
2255
+ id: generatedId,
2256
+ datasetId: input.datasetId,
2257
+ datasetVersion: newVersion,
2258
+ validTo: null,
2259
+ isDeleted: false,
2260
+ input: itemInput.input,
2261
+ groundTruth: itemInput.groundTruth ?? null,
2262
+ requestContext: itemInput.requestContext ?? null,
2263
+ metadata: itemInput.metadata ?? null,
2264
+ source: itemInput.source ?? null,
2265
+ createdAt: now,
2266
+ updatedAt: now
2267
+ }));
2268
+ await itemsCollection.insertMany(docs);
2269
+ }
2270
+ await versionsCollection.insertOne({
2271
+ id: versionId,
2272
+ datasetId: input.datasetId,
2273
+ version: newVersion,
2274
+ createdAt: now
2275
+ });
2276
+ return itemsWithIds.map(({ generatedId, itemInput }) => ({
2277
+ id: generatedId,
2278
+ datasetId: input.datasetId,
2279
+ datasetVersion: newVersion,
2280
+ input: itemInput.input,
2281
+ groundTruth: itemInput.groundTruth,
2282
+ requestContext: itemInput.requestContext,
2283
+ metadata: itemInput.metadata,
2284
+ source: itemInput.source,
2285
+ createdAt: now,
2286
+ updatedAt: now
2287
+ }));
2288
+ } catch (error$1) {
2289
+ if (error$1 instanceof error.MastraError) throw error$1;
2290
+ throw new error.MastraError(
2291
+ {
2292
+ id: storage.createStorageErrorId("MONGODB", "BULK_ADD_ITEMS", "FAILED"),
2293
+ domain: error.ErrorDomain.STORAGE,
2294
+ category: error.ErrorCategory.THIRD_PARTY
2295
+ },
2296
+ error$1
2297
+ );
2298
+ }
2299
+ }
2300
+ async _doBatchDeleteItems(input) {
2301
+ try {
2302
+ const dataset = await this.getDatasetById({ id: input.datasetId });
2303
+ if (!dataset) {
2304
+ throw new error.MastraError({
2305
+ id: storage.createStorageErrorId("MONGODB", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
2306
+ domain: error.ErrorDomain.STORAGE,
2307
+ category: error.ErrorCategory.USER,
2308
+ details: { datasetId: input.datasetId }
2309
+ });
2310
+ }
2311
+ const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2312
+ const currentRows = await itemsCollection.find({
2313
+ id: { $in: input.itemIds },
2314
+ datasetId: input.datasetId,
2315
+ validTo: null,
2316
+ isDeleted: false
2317
+ }).toArray();
2318
+ const currentItems = currentRows.map((row) => this.transformItemRow(row));
2319
+ if (currentItems.length === 0) return;
2320
+ const now = /* @__PURE__ */ new Date();
2321
+ const versionId = crypto.randomUUID();
2322
+ const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2323
+ const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2324
+ const result = await datasetsCollection.findOneAndUpdate(
2325
+ { id: input.datasetId },
2326
+ { $inc: { version: 1 } },
2327
+ { returnDocument: "after" }
2328
+ );
2329
+ if (!result) {
2330
+ throw new error.MastraError({
2331
+ id: storage.createStorageErrorId("MONGODB", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
2332
+ domain: error.ErrorDomain.STORAGE,
2333
+ category: error.ErrorCategory.USER,
2334
+ details: { datasetId: input.datasetId }
2335
+ });
2336
+ }
2337
+ const newVersion = result.version;
2338
+ const currentIds = currentItems.map((i) => i.id);
2339
+ await itemsCollection.updateMany(
2340
+ { id: { $in: currentIds }, validTo: null, isDeleted: false },
2341
+ { $set: { validTo: newVersion } }
2342
+ );
2343
+ const tombstones = currentItems.map((item) => ({
2344
+ id: item.id,
2345
+ datasetId: input.datasetId,
2346
+ datasetVersion: newVersion,
2347
+ validTo: null,
2348
+ isDeleted: true,
2349
+ input: item.input,
2350
+ groundTruth: item.groundTruth,
2351
+ requestContext: item.requestContext,
2352
+ metadata: item.metadata,
2353
+ source: item.source,
2354
+ createdAt: item.createdAt,
2355
+ updatedAt: now
2356
+ }));
2357
+ await itemsCollection.insertMany(tombstones);
2358
+ await versionsCollection.insertOne({
2359
+ id: versionId,
2360
+ datasetId: input.datasetId,
2361
+ version: newVersion,
2362
+ createdAt: now
2363
+ });
2364
+ } catch (error$1) {
2365
+ if (error$1 instanceof error.MastraError) throw error$1;
2366
+ throw new error.MastraError(
2367
+ {
2368
+ id: storage.createStorageErrorId("MONGODB", "BULK_DELETE_ITEMS", "FAILED"),
2369
+ domain: error.ErrorDomain.STORAGE,
2370
+ category: error.ErrorCategory.THIRD_PARTY
2371
+ },
2372
+ error$1
2373
+ );
2374
+ }
2375
+ }
2376
+ // --- SCD-2 queries ---
2377
+ async getItemById(args) {
2378
+ try {
2379
+ const collection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2380
+ let row;
2381
+ if (args.datasetVersion !== void 0) {
2382
+ row = await collection.findOne(
2383
+ {
2384
+ id: args.id,
2385
+ datasetVersion: { $lte: args.datasetVersion },
2386
+ $or: [{ validTo: null }, { validTo: { $gt: args.datasetVersion } }],
2387
+ isDeleted: false
2388
+ },
2389
+ { sort: { datasetVersion: -1 } }
2390
+ );
2391
+ } else {
2392
+ row = await collection.findOne({
2393
+ id: args.id,
2394
+ validTo: null,
2395
+ isDeleted: false
2396
+ });
2397
+ }
2398
+ return row ? this.transformItemRow(row) : null;
2399
+ } catch (error$1) {
2400
+ throw new error.MastraError(
2401
+ {
2402
+ id: storage.createStorageErrorId("MONGODB", "GET_ITEM", "FAILED"),
2403
+ domain: error.ErrorDomain.STORAGE,
2404
+ category: error.ErrorCategory.THIRD_PARTY
2405
+ },
2406
+ error$1
2407
+ );
2408
+ }
2409
+ }
2410
+ async getItemsByVersion({ datasetId, version }) {
2411
+ try {
2412
+ const collection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2413
+ const rows = await collection.find({
2414
+ datasetId,
2415
+ datasetVersion: { $lte: version },
2416
+ $or: [{ validTo: null }, { validTo: { $gt: version } }],
2417
+ isDeleted: false
2418
+ }).sort({ createdAt: -1, id: 1 }).toArray();
2419
+ return rows.map((row) => this.transformItemRow(row));
2420
+ } catch (error$1) {
2421
+ throw new error.MastraError(
2422
+ {
2423
+ id: storage.createStorageErrorId("MONGODB", "GET_ITEMS_BY_VERSION", "FAILED"),
2424
+ domain: error.ErrorDomain.STORAGE,
2425
+ category: error.ErrorCategory.THIRD_PARTY
2426
+ },
2427
+ error$1
2428
+ );
2429
+ }
2430
+ }
2431
+ async getItemHistory(itemId) {
2432
+ try {
2433
+ const collection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2434
+ const rows = await collection.find({ id: itemId }).sort({ datasetVersion: -1 }).toArray();
2435
+ return rows.map((row) => this.transformItemRowFull(row));
2436
+ } catch (error$1) {
2437
+ throw new error.MastraError(
2438
+ {
2439
+ id: storage.createStorageErrorId("MONGODB", "GET_ITEM_HISTORY", "FAILED"),
2440
+ domain: error.ErrorDomain.STORAGE,
2441
+ category: error.ErrorCategory.THIRD_PARTY
2442
+ },
2443
+ error$1
2444
+ );
2445
+ }
2446
+ }
2447
+ async listItems(args) {
2448
+ try {
2449
+ const { page, perPage: perPageInput } = args.pagination;
2450
+ const collection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2451
+ const filter = { datasetId: args.datasetId };
2452
+ if (args.version !== void 0) {
2453
+ filter.datasetVersion = { $lte: args.version };
2454
+ filter.$or = [{ validTo: null }, { validTo: { $gt: args.version } }];
2455
+ filter.isDeleted = false;
2456
+ } else {
2457
+ filter.validTo = null;
2458
+ filter.isDeleted = false;
2459
+ }
2460
+ if (args.search) {
2461
+ const escaped = args.search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2462
+ const regex = new RegExp(escaped, "i");
2463
+ const safeStr = (field) => ({
2464
+ $convert: { input: field, to: "string", onError: "", onNull: "" }
2465
+ });
2466
+ const searchCondition = [{ $expr: { $regexMatch: { input: safeStr("$input"), regex } } }];
2467
+ if (filter.$or) {
2468
+ filter.$and = [{ $or: filter.$or }, { $or: searchCondition }];
2469
+ delete filter.$or;
2470
+ } else {
2471
+ filter.$or = searchCondition;
2472
+ }
2473
+ }
2474
+ const total = await collection.countDocuments(filter);
2475
+ if (total === 0) {
2476
+ return { items: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
2477
+ }
2478
+ const perPage = storage.normalizePerPage(perPageInput, 100);
2479
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2480
+ if (perPage === 0) {
2481
+ return { items: [], pagination: { total, page, perPage: perPageForResponse, hasMore: total > 0 } };
2482
+ }
2483
+ const limitValue = perPageInput === false ? total : perPage;
2484
+ const rows = await collection.find(filter).sort({ createdAt: -1, id: 1 }).skip(offset).limit(limitValue).toArray();
2485
+ return {
2486
+ items: rows.map((row) => this.transformItemRow(row)),
2487
+ pagination: {
2488
+ total,
2489
+ page,
2490
+ perPage: perPageForResponse,
2491
+ hasMore: perPageInput === false ? false : offset + perPage < total
2492
+ }
2493
+ };
2494
+ } catch (error$1) {
2495
+ throw new error.MastraError(
2496
+ {
2497
+ id: storage.createStorageErrorId("MONGODB", "LIST_ITEMS", "FAILED"),
2498
+ domain: error.ErrorDomain.STORAGE,
2499
+ category: error.ErrorCategory.THIRD_PARTY
2500
+ },
2501
+ error$1
2502
+ );
2503
+ }
2504
+ }
2505
+ // --- Dataset versions ---
2506
+ async createDatasetVersion(datasetId, version) {
2507
+ try {
2508
+ const id = crypto.randomUUID();
2509
+ const now = /* @__PURE__ */ new Date();
2510
+ const collection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2511
+ await collection.insertOne({ id, datasetId, version, createdAt: now });
2512
+ return { id, datasetId, version, createdAt: now };
2513
+ } catch (error$1) {
2514
+ throw new error.MastraError(
2515
+ {
2516
+ id: storage.createStorageErrorId("MONGODB", "CREATE_DATASET_VERSION", "FAILED"),
2517
+ domain: error.ErrorDomain.STORAGE,
2518
+ category: error.ErrorCategory.THIRD_PARTY
2519
+ },
2520
+ error$1
2521
+ );
2522
+ }
2523
+ }
2524
+ async listDatasetVersions(input) {
2525
+ try {
2526
+ const { page, perPage: perPageInput } = input.pagination;
2527
+ const collection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2528
+ const filter = { datasetId: input.datasetId };
2529
+ const total = await collection.countDocuments(filter);
2530
+ if (total === 0) {
2531
+ return { versions: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
2532
+ }
2533
+ const perPage = storage.normalizePerPage(perPageInput, 100);
2534
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2535
+ if (perPage === 0) {
2536
+ return { versions: [], pagination: { total, page, perPage: perPageForResponse, hasMore: total > 0 } };
2537
+ }
2538
+ const limitValue = perPageInput === false ? total : perPage;
2539
+ const rows = await collection.find(filter).sort({ version: -1 }).skip(offset).limit(limitValue).toArray();
2540
+ return {
2541
+ versions: rows.map((row) => this.transformDatasetVersionRow(row)),
2542
+ pagination: {
2543
+ total,
2544
+ page,
2545
+ perPage: perPageForResponse,
2546
+ hasMore: perPageInput === false ? false : offset + perPage < total
2547
+ }
2548
+ };
2549
+ } catch (error$1) {
2550
+ throw new error.MastraError(
2551
+ {
2552
+ id: storage.createStorageErrorId("MONGODB", "LIST_DATASET_VERSIONS", "FAILED"),
2553
+ domain: error.ErrorDomain.STORAGE,
2554
+ category: error.ErrorCategory.THIRD_PARTY
2555
+ },
2556
+ error$1
2557
+ );
2558
+ }
2559
+ }
2560
+ // --- Clear all ---
2561
+ async dangerouslyClearAll() {
2562
+ const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2563
+ const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2564
+ const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2565
+ const results = await Promise.allSettled([
2566
+ datasetsCollection.deleteMany({}),
2567
+ itemsCollection.deleteMany({}),
2568
+ versionsCollection.deleteMany({})
2569
+ ]);
2570
+ const failures = results.filter((r) => r.status === "rejected");
2571
+ if (failures.length > 0) {
2572
+ throw new error.MastraError(
2573
+ {
2574
+ id: storage.createStorageErrorId("MONGODB", "CLEAR_ALL", "FAILED"),
2575
+ domain: error.ErrorDomain.STORAGE,
2576
+ category: error.ErrorCategory.THIRD_PARTY,
2577
+ details: { failedCollections: failures.length }
2578
+ },
2579
+ failures[0].reason
2580
+ );
2581
+ }
2582
+ }
2583
+ };
2584
+ function toDate(value) {
2585
+ if (value instanceof Date) return value;
2586
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
2587
+ return /* @__PURE__ */ new Date();
2588
+ }
2589
+ function toDateOrNull(value) {
2590
+ if (value === null || value === void 0) return null;
2591
+ return toDate(value);
2592
+ }
2593
+ function parseJsonField(value) {
2594
+ if (value === null || value === void 0) return void 0;
2595
+ if (typeof value === "string") return storage.safelyParseJSON(value);
2596
+ return value;
2597
+ }
2598
+ function transformExperimentRow(row) {
2599
+ return {
2600
+ id: row.id,
2601
+ name: row.name ?? void 0,
2602
+ description: row.description ?? void 0,
2603
+ metadata: parseJsonField(row.metadata) ?? void 0,
2604
+ datasetId: row.datasetId ?? null,
2605
+ datasetVersion: row.datasetVersion != null ? Number(row.datasetVersion) : null,
2606
+ targetType: row.targetType,
2607
+ targetId: row.targetId,
2608
+ status: row.status,
2609
+ totalItems: Number(row.totalItems ?? 0),
2610
+ succeededCount: Number(row.succeededCount ?? 0),
2611
+ failedCount: Number(row.failedCount ?? 0),
2612
+ skippedCount: Number(row.skippedCount ?? 0),
2613
+ agentVersion: row.agentVersion ?? null,
2614
+ startedAt: toDateOrNull(row.startedAt),
2615
+ completedAt: toDateOrNull(row.completedAt),
2616
+ createdAt: toDate(row.createdAt),
2617
+ updatedAt: toDate(row.updatedAt)
2618
+ };
2619
+ }
2620
+ function transformExperimentResultRow(row) {
2621
+ return {
2622
+ id: row.id,
2623
+ experimentId: row.experimentId,
2624
+ itemId: row.itemId,
2625
+ itemDatasetVersion: row.itemDatasetVersion != null ? Number(row.itemDatasetVersion) : null,
2626
+ input: parseJsonField(row.input),
2627
+ output: parseJsonField(row.output) ?? null,
2628
+ groundTruth: parseJsonField(row.groundTruth) ?? null,
2629
+ error: parseJsonField(row.error) ?? null,
2630
+ startedAt: toDate(row.startedAt),
2631
+ completedAt: toDate(row.completedAt),
2632
+ retryCount: Number(row.retryCount ?? 0),
2633
+ traceId: row.traceId ?? null,
2634
+ status: row.status ?? null,
2635
+ tags: Array.isArray(row.tags) ? row.tags : parseJsonField(row.tags) ?? null,
2636
+ createdAt: toDate(row.createdAt)
2637
+ };
2638
+ }
2639
+ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage.ExperimentsStorage {
2640
+ #connector;
2641
+ #skipDefaultIndexes;
2642
+ #indexes;
2643
+ static MANAGED_COLLECTIONS = [storage.TABLE_EXPERIMENTS, storage.TABLE_EXPERIMENT_RESULTS];
2644
+ constructor(config) {
2645
+ super();
2646
+ this.#connector = resolveMongoDBConfig(config);
2647
+ this.#skipDefaultIndexes = config.skipDefaultIndexes;
2648
+ this.#indexes = config.indexes?.filter(
2649
+ (idx) => _MongoDBExperimentsStorage.MANAGED_COLLECTIONS.includes(idx.collection)
2650
+ );
2651
+ }
2652
+ async getCollection(name) {
2653
+ return this.#connector.getCollection(name);
2654
+ }
2655
+ // -------------------------------------------------------------------------
2656
+ // Index Management
2657
+ // -------------------------------------------------------------------------
2658
+ getDefaultIndexDefinitions() {
2659
+ return [
2660
+ { collection: storage.TABLE_EXPERIMENTS, keys: { id: 1 }, options: { unique: true } },
2661
+ { collection: storage.TABLE_EXPERIMENTS, keys: { datasetId: 1 } },
2662
+ { collection: storage.TABLE_EXPERIMENTS, keys: { createdAt: -1, id: 1 } },
2663
+ { collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { id: 1 }, options: { unique: true } },
2664
+ { collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1 } },
2665
+ { collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, itemId: 1 }, options: { unique: true } },
2666
+ { collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { createdAt: -1 } },
2667
+ { collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, startedAt: 1, id: 1 } }
2668
+ ];
2669
+ }
2670
+ async createDefaultIndexes() {
2671
+ if (this.#skipDefaultIndexes) return;
2672
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
2673
+ try {
2674
+ const collection = await this.getCollection(indexDef.collection);
2675
+ await collection.createIndex(indexDef.keys, indexDef.options);
2676
+ } catch (error) {
2677
+ this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
2678
+ }
2679
+ }
2680
+ }
2681
+ async createCustomIndexes() {
2682
+ if (!this.#indexes || this.#indexes.length === 0) return;
2683
+ for (const indexDef of this.#indexes) {
2684
+ try {
2685
+ const collection = await this.getCollection(indexDef.collection);
2686
+ await collection.createIndex(indexDef.keys, indexDef.options);
2687
+ } catch (error) {
2688
+ this.logger?.warn?.(`Failed to create custom index on ${indexDef.collection}:`, error);
2689
+ }
2690
+ }
2691
+ }
2692
+ async init() {
2693
+ await this.createDefaultIndexes();
2694
+ await this.createCustomIndexes();
2695
+ }
2696
+ // -------------------------------------------------------------------------
2697
+ // Experiment CRUD
2698
+ // -------------------------------------------------------------------------
2699
+ async createExperiment(input) {
2700
+ const id = input.id ?? crypto.randomUUID();
2701
+ const now = /* @__PURE__ */ new Date();
2702
+ const doc = {
2703
+ id,
2704
+ name: input.name ?? null,
2705
+ description: input.description ?? null,
2706
+ metadata: input.metadata ?? null,
2707
+ datasetId: input.datasetId ?? null,
2708
+ datasetVersion: input.datasetVersion ?? null,
2709
+ targetType: input.targetType,
2710
+ targetId: input.targetId,
2711
+ status: "pending",
2712
+ totalItems: input.totalItems,
2713
+ succeededCount: 0,
2714
+ failedCount: 0,
2715
+ skippedCount: 0,
2716
+ agentVersion: null,
2717
+ startedAt: null,
2718
+ completedAt: null,
2719
+ createdAt: now,
2720
+ updatedAt: now
2721
+ };
2722
+ try {
2723
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENTS);
2724
+ await collection.insertOne(doc);
2725
+ return {
2726
+ id,
2727
+ name: input.name,
2728
+ description: input.description,
2729
+ metadata: input.metadata,
2730
+ datasetId: input.datasetId ?? null,
2731
+ datasetVersion: input.datasetVersion ?? null,
2732
+ targetType: input.targetType,
2733
+ targetId: input.targetId,
2734
+ status: "pending",
2735
+ totalItems: input.totalItems,
2736
+ succeededCount: 0,
2737
+ failedCount: 0,
2738
+ skippedCount: 0,
2739
+ agentVersion: null,
2740
+ startedAt: null,
2741
+ completedAt: null,
2742
+ createdAt: now,
2743
+ updatedAt: now
2744
+ };
2745
+ } catch (error$1) {
2746
+ throw new error.MastraError(
2747
+ {
2748
+ id: storage.createStorageErrorId("MONGODB", "CREATE_EXPERIMENT", "FAILED"),
2749
+ domain: error.ErrorDomain.STORAGE,
2750
+ category: error.ErrorCategory.THIRD_PARTY,
2751
+ details: { name: input.name ?? "unnamed" }
2752
+ },
2753
+ error$1
2754
+ );
2755
+ }
2756
+ }
2757
+ async updateExperiment(input) {
2758
+ const updateFields = { updatedAt: /* @__PURE__ */ new Date() };
2759
+ if (input.name !== void 0) updateFields.name = input.name;
2760
+ if (input.description !== void 0) updateFields.description = input.description;
2761
+ if (input.metadata !== void 0) updateFields.metadata = input.metadata;
2762
+ if (input.status !== void 0) updateFields.status = input.status;
2763
+ if (input.totalItems !== void 0) updateFields.totalItems = input.totalItems;
2764
+ if (input.succeededCount !== void 0) updateFields.succeededCount = input.succeededCount;
2765
+ if (input.failedCount !== void 0) updateFields.failedCount = input.failedCount;
2766
+ if (input.skippedCount !== void 0) updateFields.skippedCount = input.skippedCount;
2767
+ if (input.startedAt !== void 0) updateFields.startedAt = input.startedAt;
2768
+ if (input.completedAt !== void 0) updateFields.completedAt = input.completedAt;
2769
+ try {
2770
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENTS);
2771
+ const result = await collection.updateOne({ id: input.id }, { $set: updateFields });
2772
+ if (result.matchedCount === 0) {
2773
+ throw new error.MastraError({
2774
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_EXPERIMENT", "NOT_FOUND"),
2775
+ domain: error.ErrorDomain.STORAGE,
2776
+ category: error.ErrorCategory.USER,
2777
+ details: { experimentId: input.id }
2778
+ });
2779
+ }
2780
+ const updated = await this.getExperimentById({ id: input.id });
2781
+ return updated;
2782
+ } catch (error$1) {
2783
+ if (error$1 instanceof error.MastraError) throw error$1;
2784
+ throw new error.MastraError(
2785
+ {
2786
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_EXPERIMENT", "FAILED"),
2787
+ domain: error.ErrorDomain.STORAGE,
2788
+ category: error.ErrorCategory.THIRD_PARTY,
2789
+ details: { experimentId: input.id }
2790
+ },
2791
+ error$1
2792
+ );
2793
+ }
2794
+ }
2795
+ async getExperimentById({ id }) {
2796
+ try {
2797
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENTS);
2798
+ const doc = await collection.findOne({ id });
2799
+ if (!doc) return null;
2800
+ return transformExperimentRow(doc);
2801
+ } catch (error$1) {
2802
+ throw new error.MastraError(
2803
+ {
2804
+ id: storage.createStorageErrorId("MONGODB", "GET_EXPERIMENT", "FAILED"),
2805
+ domain: error.ErrorDomain.STORAGE,
2806
+ category: error.ErrorCategory.THIRD_PARTY,
2807
+ details: { id }
2808
+ },
2809
+ error$1
2810
+ );
2811
+ }
2812
+ }
2813
+ async listExperiments(args) {
2814
+ try {
2815
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENTS);
2816
+ const { page, perPage: perPageInput } = args.pagination;
2817
+ const filter = {};
2818
+ if (args.datasetId) {
2819
+ filter.datasetId = args.datasetId;
2820
+ }
2821
+ const total = await collection.countDocuments(filter);
2822
+ if (total === 0) {
2823
+ return { experiments: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
2824
+ }
2825
+ const normalizedPerPage = storage.normalizePerPage(perPageInput, 100);
2826
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, normalizedPerPage);
2827
+ if (normalizedPerPage === 0) {
2828
+ return { experiments: [], pagination: { total, page, perPage: perPageForResponse, hasMore: total > 0 } };
2829
+ }
2830
+ const limitValue = perPageInput === false ? total : normalizedPerPage;
2831
+ const docs = await collection.find(filter).sort({ createdAt: -1, id: 1 }).skip(offset).limit(limitValue).toArray();
2832
+ return {
2833
+ experiments: docs.map((d) => transformExperimentRow(d)),
2834
+ pagination: {
2835
+ total,
2836
+ page,
2837
+ perPage: perPageForResponse,
2838
+ hasMore: perPageInput === false ? false : offset + normalizedPerPage < total
2839
+ }
2840
+ };
2841
+ } catch (error$1) {
2842
+ throw new error.MastraError(
2843
+ {
2844
+ id: storage.createStorageErrorId("MONGODB", "LIST_EXPERIMENTS", "FAILED"),
2845
+ domain: error.ErrorDomain.STORAGE,
2846
+ category: error.ErrorCategory.THIRD_PARTY
2847
+ },
2848
+ error$1
2849
+ );
2850
+ }
2851
+ }
2852
+ async deleteExperiment({ id }) {
2853
+ try {
2854
+ const resultsCollection = await this.getCollection(storage.TABLE_EXPERIMENT_RESULTS);
2855
+ await resultsCollection.deleteMany({ experimentId: id });
2856
+ const experimentsCollection = await this.getCollection(storage.TABLE_EXPERIMENTS);
2857
+ await experimentsCollection.deleteOne({ id });
2858
+ } catch (error$1) {
2859
+ throw new error.MastraError(
2860
+ {
2861
+ id: storage.createStorageErrorId("MONGODB", "DELETE_EXPERIMENT", "FAILED"),
2862
+ domain: error.ErrorDomain.STORAGE,
2863
+ category: error.ErrorCategory.THIRD_PARTY,
2864
+ details: { id }
2865
+ },
2866
+ error$1
2867
+ );
2868
+ }
2869
+ }
2870
+ // -------------------------------------------------------------------------
2871
+ // Experiment Results
2872
+ // -------------------------------------------------------------------------
2873
+ async addExperimentResult(input) {
2874
+ const id = input.id ?? crypto.randomUUID();
2875
+ const now = /* @__PURE__ */ new Date();
2876
+ const doc = {
2877
+ id,
2878
+ experimentId: input.experimentId,
2879
+ itemId: input.itemId,
2880
+ itemDatasetVersion: input.itemDatasetVersion ?? null,
2881
+ input: input.input,
2882
+ output: input.output ?? null,
2883
+ groundTruth: input.groundTruth ?? null,
2884
+ error: input.error ?? null,
2885
+ startedAt: input.startedAt,
2886
+ completedAt: input.completedAt,
2887
+ retryCount: input.retryCount,
2888
+ traceId: input.traceId ?? null,
2889
+ status: input.status ?? null,
2890
+ tags: input.tags ?? null,
2891
+ createdAt: now
2892
+ };
2893
+ try {
2894
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENT_RESULTS);
2895
+ await collection.insertOne(doc);
2896
+ return {
2897
+ id,
2898
+ experimentId: input.experimentId,
2899
+ itemId: input.itemId,
2900
+ itemDatasetVersion: input.itemDatasetVersion ?? null,
2901
+ input: input.input,
2902
+ output: input.output ?? null,
2903
+ groundTruth: input.groundTruth ?? null,
2904
+ error: input.error ?? null,
2905
+ startedAt: input.startedAt,
2906
+ completedAt: input.completedAt,
2907
+ retryCount: input.retryCount,
2908
+ traceId: input.traceId ?? null,
2909
+ status: input.status ?? null,
2910
+ tags: input.tags ?? null,
2911
+ createdAt: now
2912
+ };
2913
+ } catch (error$1) {
2914
+ throw new error.MastraError(
2915
+ {
2916
+ id: storage.createStorageErrorId("MONGODB", "ADD_EXPERIMENT_RESULT", "FAILED"),
2917
+ domain: error.ErrorDomain.STORAGE,
2918
+ category: error.ErrorCategory.THIRD_PARTY,
2919
+ details: { experimentId: input.experimentId }
2920
+ },
2921
+ error$1
2922
+ );
2923
+ }
2924
+ }
2925
+ async updateExperimentResult(input) {
2926
+ const updateFields = {};
2927
+ if (input.status !== void 0) updateFields.status = input.status;
2928
+ if (input.tags !== void 0) updateFields.tags = input.tags;
2929
+ if (Object.keys(updateFields).length === 0) {
2930
+ const existing = await this.getExperimentResultById({ id: input.id });
2931
+ if (!existing || input.experimentId && existing.experimentId !== input.experimentId) {
2932
+ throw new error.MastraError({
2933
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
2934
+ domain: error.ErrorDomain.STORAGE,
2935
+ category: error.ErrorCategory.USER,
2936
+ details: { resultId: input.id }
2937
+ });
2938
+ }
2939
+ return existing;
2940
+ }
2941
+ try {
2942
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENT_RESULTS);
2943
+ const filter = { id: input.id };
2944
+ if (input.experimentId) {
2945
+ filter.experimentId = input.experimentId;
2946
+ }
2947
+ const result = await collection.findOneAndUpdate(filter, { $set: updateFields }, { returnDocument: "after" });
2948
+ if (!result) {
2949
+ throw new error.MastraError({
2950
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
2951
+ domain: error.ErrorDomain.STORAGE,
2952
+ category: error.ErrorCategory.USER,
2953
+ details: { resultId: input.id }
2954
+ });
2955
+ }
2956
+ return transformExperimentResultRow(result);
2957
+ } catch (error$1) {
2958
+ if (error$1 instanceof error.MastraError) throw error$1;
2959
+ throw new error.MastraError(
2960
+ {
2961
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_EXPERIMENT_RESULT", "FAILED"),
2962
+ domain: error.ErrorDomain.STORAGE,
2963
+ category: error.ErrorCategory.THIRD_PARTY,
2964
+ details: { resultId: input.id }
2965
+ },
2966
+ error$1
2967
+ );
2968
+ }
2969
+ }
2970
+ async getExperimentResultById({ id }) {
2971
+ try {
2972
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENT_RESULTS);
2973
+ const doc = await collection.findOne({ id });
2974
+ if (!doc) return null;
2975
+ return transformExperimentResultRow(doc);
2976
+ } catch (error$1) {
2977
+ throw new error.MastraError(
2978
+ {
2979
+ id: storage.createStorageErrorId("MONGODB", "GET_EXPERIMENT_RESULT", "FAILED"),
2980
+ domain: error.ErrorDomain.STORAGE,
2981
+ category: error.ErrorCategory.THIRD_PARTY,
2982
+ details: { id }
2983
+ },
2984
+ error$1
2985
+ );
2986
+ }
2987
+ }
2988
+ async listExperimentResults(args) {
2989
+ try {
2990
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENT_RESULTS);
2991
+ const { page, perPage: perPageInput } = args.pagination;
2992
+ const filter = { experimentId: args.experimentId };
2993
+ const total = await collection.countDocuments(filter);
2994
+ if (total === 0) {
2995
+ return { results: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
2996
+ }
2997
+ const normalizedPerPage = storage.normalizePerPage(perPageInput, 100);
2998
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, normalizedPerPage);
2999
+ if (normalizedPerPage === 0) {
3000
+ return { results: [], pagination: { total, page, perPage: perPageForResponse, hasMore: total > 0 } };
3001
+ }
3002
+ const limitValue = perPageInput === false ? total : normalizedPerPage;
3003
+ const docs = await collection.find(filter).sort({ startedAt: 1, id: 1 }).skip(offset).limit(limitValue).toArray();
3004
+ return {
3005
+ results: docs.map((d) => transformExperimentResultRow(d)),
3006
+ pagination: {
3007
+ total,
3008
+ page,
3009
+ perPage: perPageForResponse,
3010
+ hasMore: perPageInput === false ? false : offset + normalizedPerPage < total
3011
+ }
3012
+ };
3013
+ } catch (error$1) {
3014
+ throw new error.MastraError(
3015
+ {
3016
+ id: storage.createStorageErrorId("MONGODB", "LIST_EXPERIMENT_RESULTS", "FAILED"),
3017
+ domain: error.ErrorDomain.STORAGE,
3018
+ category: error.ErrorCategory.THIRD_PARTY,
3019
+ details: { experimentId: args.experimentId }
3020
+ },
3021
+ error$1
3022
+ );
3023
+ }
3024
+ }
3025
+ async deleteExperimentResults({ experimentId }) {
3026
+ try {
3027
+ const collection = await this.getCollection(storage.TABLE_EXPERIMENT_RESULTS);
3028
+ await collection.deleteMany({ experimentId });
3029
+ } catch (error$1) {
3030
+ throw new error.MastraError(
3031
+ {
3032
+ id: storage.createStorageErrorId("MONGODB", "DELETE_EXPERIMENT_RESULTS", "FAILED"),
3033
+ domain: error.ErrorDomain.STORAGE,
3034
+ category: error.ErrorCategory.THIRD_PARTY,
3035
+ details: { experimentId }
3036
+ },
3037
+ error$1
3038
+ );
3039
+ }
3040
+ }
3041
+ // -------------------------------------------------------------------------
3042
+ // Cleanup
3043
+ // -------------------------------------------------------------------------
3044
+ async dangerouslyClearAll() {
3045
+ for (const collectionName of _MongoDBExperimentsStorage.MANAGED_COLLECTIONS) {
3046
+ try {
3047
+ const collection = await this.getCollection(collectionName);
3048
+ await collection.deleteMany({});
3049
+ } catch {
3050
+ }
3051
+ }
3052
+ }
3053
+ };
1703
3054
  var SNAPSHOT_FIELDS2 = ["name", "description", "servers"];
1704
3055
  var MongoDBMCPClientsStorage = class _MongoDBMCPClientsStorage extends storage.MCPClientsStorage {
1705
3056
  #connector;
@@ -8409,6 +9760,8 @@ var MongoDBStore = class extends storage.MastraCompositeStore {
8409
9760
  const workspaces = new MongoDBWorkspacesStorage(domainConfig);
8410
9761
  const skills = new MongoDBSkillsStorage(domainConfig);
8411
9762
  const blobs = new MongoDBBlobStore(domainConfig);
9763
+ const datasets = new MongoDBDatasetsStorage(domainConfig);
9764
+ const experiments = new MongoDBExperimentsStorage(domainConfig);
8412
9765
  this.stores = {
8413
9766
  memory,
8414
9767
  scores,
@@ -8421,7 +9774,9 @@ var MongoDBStore = class extends storage.MastraCompositeStore {
8421
9774
  mcpServers,
8422
9775
  workspaces,
8423
9776
  skills,
8424
- blobs
9777
+ blobs,
9778
+ datasets,
9779
+ experiments
8425
9780
  };
8426
9781
  }
8427
9782
  /**
@@ -8544,6 +9899,8 @@ exports.MONGODB_PROMPT = MONGODB_PROMPT;
8544
9899
  exports.MemoryStorageMongoDB = MemoryStorageMongoDB;
8545
9900
  exports.MongoDBAgentsStorage = MongoDBAgentsStorage;
8546
9901
  exports.MongoDBBlobStore = MongoDBBlobStore;
9902
+ exports.MongoDBDatasetsStorage = MongoDBDatasetsStorage;
9903
+ exports.MongoDBExperimentsStorage = MongoDBExperimentsStorage;
8547
9904
  exports.MongoDBMCPClientsStorage = MongoDBMCPClientsStorage;
8548
9905
  exports.MongoDBMCPServersStorage = MongoDBMCPServersStorage;
8549
9906
  exports.MongoDBPromptBlocksStorage = MongoDBPromptBlocksStorage;