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