@mastra/mongodb 1.10.0 → 1.11.0-alpha.1
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 +84 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +157 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +157 -41
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/datasets/index.d.ts.map +1 -1
- package/dist/storage/domains/experiments/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +1 -0
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,89 @@
|
|
|
1
1
|
# @mastra/mongodb
|
|
2
2
|
|
|
3
|
+
## 1.11.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Fixed new observability span writes in MongoDB so `startedAt`, `endedAt`, `createdAt`, and `updatedAt` are stored as native BSON Date objects. Existing string-typed span dates remain readable and date filters support both old string values and new Date values. ([#18366](https://github.com/mastra-ai/mastra/pull/18366))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Added multi-tenant scoping columns (`organizationId`, `projectId`) to the experiments domain so experiment records and per-item results inherit the tenancy bucket of their parent dataset. ([#18388](https://github.com/mastra-ai/mastra/pull/18388))
|
|
12
|
+
|
|
13
|
+
`Experiment`, `ExperimentResult`, `CreateExperimentInput`, and `AddExperimentResultInput` now carry optional `organizationId` / `projectId` fields. `ListExperimentsInput` and `ListExperimentResultsInput` gain a `filters: ExperimentTenancyFilters` block (mirrors `DatasetTenancyFilters`) for scoping queries within a `(organizationId, projectId)` bucket. Tenancy is hydrated from the parent dataset on `createExperiment` and denormalized onto each `ExperimentResult` for efficient tenancy-scoped queries.
|
|
14
|
+
|
|
15
|
+
The corresponding columns are also added to the `mastra_experiments` and `mastra_experiment_results` table schemas. Existing rows backfill to `null`, matching the rest of the dataset-tenancy surface.
|
|
16
|
+
|
|
17
|
+
This release also clarifies the `targetType` contract via JSDoc:
|
|
18
|
+
- `CreateDatasetInput.targetType` remains optional. Datasets without a `TargetType` are **not experiment-eligible** — the experiment runner requires a non-null `CreateExperimentInput.targetType` to resolve an executor.
|
|
19
|
+
- `Experiment.targetType` / `CreateExperimentInput.targetType` stay required. An experiment by definition replays inputs against a specific target.
|
|
20
|
+
|
|
21
|
+
No behavior change for existing OSS-created experiments; the new fields are additive and optional.
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// Create an experiment scoped to a tenancy bucket. When the parent dataset
|
|
27
|
+
// already carries `organizationId` / `projectId`, `runExperiment` hydrates
|
|
28
|
+
// these fields automatically from the dataset record.
|
|
29
|
+
const experiment = await storage.createExperiment({
|
|
30
|
+
name: 'qa-regression',
|
|
31
|
+
datasetId: 'ds_123',
|
|
32
|
+
datasetVersion: 1,
|
|
33
|
+
targetType: 'agent',
|
|
34
|
+
targetId: 'agent_qa',
|
|
35
|
+
totalItems: 10,
|
|
36
|
+
organizationId: 'org_123',
|
|
37
|
+
projectId: 'proj_123',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// List experiments within a tenancy bucket.
|
|
41
|
+
const experiments = await storage.listExperiments({
|
|
42
|
+
pagination: { page: 0, perPage: 20 },
|
|
43
|
+
filters: { organizationId: 'org_123', projectId: 'proj_123' },
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// List per-item results within the same bucket.
|
|
47
|
+
const results = await storage.listExperimentResults({
|
|
48
|
+
experimentId: experiment.id,
|
|
49
|
+
pagination: { page: 0, perPage: 50 },
|
|
50
|
+
filters: { organizationId: 'org_123', projectId: 'proj_123' },
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- Persist and filter dataset tenancy + candidate identity in storage adapters. ([#18314](https://github.com/mastra-ai/mastra/pull/18314))
|
|
55
|
+
|
|
56
|
+
`createDataset` now persists `organizationId`, `projectId`, `candidateKey`, and `candidateId`. `listDatasets` and `listItems` accept matching tenancy filters. Dataset items inherit `organizationId` / `projectId` from their parent dataset on insert, update, delete, and batch insert/delete — items are never settable per call (item tenancy follows dataset tenancy).
|
|
57
|
+
|
|
58
|
+
All new columns are nullable and added retroactively via each adapter's existing column-migration path; no breaking DDL. Existing rows continue to read and write fine; new writes can choose to stamp tenancy.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
await storage.createDataset({
|
|
62
|
+
name: 'candidates/missing-tool-call/incident-123',
|
|
63
|
+
organizationId: 'org_abc',
|
|
64
|
+
projectId: 'project_xyz',
|
|
65
|
+
candidateKey: 'missing-tool-call',
|
|
66
|
+
candidateId: 'incident-123',
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await storage.listDatasets({
|
|
70
|
+
pagination: { page: 0, perPage: 20 },
|
|
71
|
+
filters: { organizationId: 'org_abc', projectId: 'project_xyz' },
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- Updated dependencies [[`5c4e9a4`](https://github.com/mastra-ai/mastra/commit/5c4e9a4cfb2216bb3ea7f8988ad3727f3b92bb3a), [`25961e3`](https://github.com/mastra-ai/mastra/commit/25961e3260ff3b1464637af8fcdb36210551c39f), [`7b29f33`](https://github.com/mastra-ai/mastra/commit/7b29f332a357a83e555f29e718e5f2fab9979943), [`24912b1`](https://github.com/mastra-ai/mastra/commit/24912b1f855d29ec36af4ef4bde1f7417e20cdf5), [`7686216`](https://github.com/mastra-ai/mastra/commit/7686216f37e74568feddec17cef3c3d24e10e60a), [`975c59a`](https://github.com/mastra-ai/mastra/commit/975c59ae363ee275fc55062392e1ffd2cbccbd53), [`d95f394`](https://github.com/mastra-ai/mastra/commit/d95f394fd24c8411886930d727679c4d5252aa26), [`f3f0c9d`](https://github.com/mastra-ai/mastra/commit/f3f0c9d7c878db5a13177871ce3523a14f14b311)]:
|
|
76
|
+
- @mastra/core@1.46.0-alpha.4
|
|
77
|
+
|
|
78
|
+
## 1.10.1-alpha.0
|
|
79
|
+
|
|
80
|
+
### Patch Changes
|
|
81
|
+
|
|
82
|
+
- Added storage for item-level tool mocks. Dataset items persist their `toolMocks` and experiment results persist their `toolMockReport`, so mocks and run diagnostics survive across sessions. ([#18036](https://github.com/mastra-ai/mastra/pull/18036))
|
|
83
|
+
|
|
84
|
+
- Updated dependencies [[`65f255a`](https://github.com/mastra-ai/mastra/commit/65f255a38667beb6ceeadabfa9eb5059bfec8298), [`4a88c6e`](https://github.com/mastra-ai/mastra/commit/4a88c6e2bdce316f8d7551b4ec3449b0b06fc71c), [`87a17ef`](https://github.com/mastra-ai/mastra/commit/87a17efbd725aca6639febdc5e69e2abb3048689), [`e11ff30`](https://github.com/mastra-ai/mastra/commit/e11ff301408bf1731dca2fb7fbfcd8c819500a35), [`9d2c946`](https://github.com/mastra-ai/mastra/commit/9d2c946d0859e90ae4bcec5beeb1da7398d2ad1e), [`f1ec385`](https://github.com/mastra-ai/mastra/commit/f1ec385386f62b1a0847ec5353ae2bb169d1c3d9), [`e14986f`](https://github.com/mastra-ai/mastra/commit/e14986f6e5478d6384d04ff9a7f9a79a46a8b529), [`0be490f`](https://github.com/mastra-ai/mastra/commit/0be490fabb538c5a7de796ea0aff7d04a0bea1f3), [`0be490f`](https://github.com/mastra-ai/mastra/commit/0be490fabb538c5a7de796ea0aff7d04a0bea1f3), [`974f614`](https://github.com/mastra-ai/mastra/commit/974f614e083bd68278536f94453f7b320b86a3c7), [`31be1cf`](https://github.com/mastra-ai/mastra/commit/31be1cf5f2a7b5eef12f6123a40653b4d8115c16)]:
|
|
85
|
+
- @mastra/core@1.46.0-alpha.3
|
|
86
|
+
|
|
3
87
|
## 1.10.0
|
|
4
88
|
|
|
5
89
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -15,7 +15,7 @@ var skills = require('@mastra/core/storage/domains/skills');
|
|
|
15
15
|
|
|
16
16
|
// package.json
|
|
17
17
|
var package_default = {
|
|
18
|
-
version: "1.
|
|
18
|
+
version: "1.11.0-alpha.1"};
|
|
19
19
|
var MongoDBFilterTranslator = class extends filter.BaseFilterTranslator {
|
|
20
20
|
getSupportedOperators() {
|
|
21
21
|
return {
|
|
@@ -1930,7 +1930,22 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
1930
1930
|
return [
|
|
1931
1931
|
{ collection: storage.TABLE_DATASETS, keys: { id: 1 }, options: { name: "idx_datasets_id", unique: true } },
|
|
1932
1932
|
{ collection: storage.TABLE_DATASETS, keys: { createdAt: -1, id: 1 }, options: { name: "idx_datasets_createdat_id" } },
|
|
1933
|
+
{
|
|
1934
|
+
collection: storage.TABLE_DATASETS,
|
|
1935
|
+
keys: { organizationId: 1, projectId: 1, createdAt: -1, id: 1 },
|
|
1936
|
+
options: { name: "idx_datasets_tenancy_createdat_id" }
|
|
1937
|
+
},
|
|
1938
|
+
{
|
|
1939
|
+
collection: storage.TABLE_DATASETS,
|
|
1940
|
+
keys: { organizationId: 1, projectId: 1, candidateKey: 1, candidateId: 1 },
|
|
1941
|
+
options: { name: "idx_datasets_tenancy_candidate" }
|
|
1942
|
+
},
|
|
1933
1943
|
{ collection: storage.TABLE_DATASET_ITEMS, keys: { datasetId: 1 }, options: { name: "idx_dataset_items_datasetid" } },
|
|
1944
|
+
{
|
|
1945
|
+
collection: storage.TABLE_DATASET_ITEMS,
|
|
1946
|
+
keys: { organizationId: 1, projectId: 1, datasetId: 1, validTo: 1, isDeleted: 1 },
|
|
1947
|
+
options: { name: "idx_dataset_items_tenancy_list" }
|
|
1948
|
+
},
|
|
1934
1949
|
{
|
|
1935
1950
|
collection: storage.TABLE_DATASET_ITEMS,
|
|
1936
1951
|
keys: { datasetId: 1, validTo: 1 },
|
|
@@ -2008,6 +2023,10 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2008
2023
|
targetIds: typeof row.targetIds === "string" ? storage.safelyParseJSON(row.targetIds) : row.targetIds ?? void 0,
|
|
2009
2024
|
scorerIds: typeof row.scorerIds === "string" ? storage.safelyParseJSON(row.scorerIds) : row.scorerIds ?? void 0,
|
|
2010
2025
|
version: row.version ?? 0,
|
|
2026
|
+
organizationId: row.organizationId ?? null,
|
|
2027
|
+
projectId: row.projectId ?? null,
|
|
2028
|
+
candidateKey: row.candidateKey ?? null,
|
|
2029
|
+
candidateId: row.candidateId ?? null,
|
|
2011
2030
|
createdAt: storage.ensureDate(row.createdAt),
|
|
2012
2031
|
updatedAt: storage.ensureDate(row.updatedAt)
|
|
2013
2032
|
};
|
|
@@ -2017,9 +2036,12 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2017
2036
|
id: row.id,
|
|
2018
2037
|
datasetId: row.datasetId,
|
|
2019
2038
|
datasetVersion: row.datasetVersion,
|
|
2039
|
+
organizationId: row.organizationId ?? null,
|
|
2040
|
+
projectId: row.projectId ?? null,
|
|
2020
2041
|
input: typeof row.input === "string" ? storage.safelyParseJSON(row.input) : row.input,
|
|
2021
2042
|
groundTruth: typeof row.groundTruth === "string" ? storage.safelyParseJSON(row.groundTruth) : row.groundTruth,
|
|
2022
2043
|
expectedTrajectory: typeof row.expectedTrajectory === "string" ? storage.safelyParseJSON(row.expectedTrajectory) : row.expectedTrajectory,
|
|
2044
|
+
toolMocks: (typeof row.toolMocks === "string" ? storage.safelyParseJSON(row.toolMocks) : row.toolMocks) ?? void 0,
|
|
2023
2045
|
requestContext: typeof row.requestContext === "string" ? storage.safelyParseJSON(row.requestContext) : row.requestContext,
|
|
2024
2046
|
metadata: typeof row.metadata === "string" ? storage.safelyParseJSON(row.metadata) : row.metadata,
|
|
2025
2047
|
source: typeof row.source === "string" ? storage.safelyParseJSON(row.source) : row.source,
|
|
@@ -2060,6 +2082,10 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2060
2082
|
targetIds: input.targetIds ?? null,
|
|
2061
2083
|
scorerIds: input.scorerIds ?? null,
|
|
2062
2084
|
version: 0,
|
|
2085
|
+
organizationId: input.organizationId ?? null,
|
|
2086
|
+
projectId: input.projectId ?? null,
|
|
2087
|
+
candidateKey: input.candidateKey ?? null,
|
|
2088
|
+
candidateId: input.candidateId ?? null,
|
|
2063
2089
|
createdAt: now,
|
|
2064
2090
|
updatedAt: now
|
|
2065
2091
|
};
|
|
@@ -2170,7 +2196,12 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2170
2196
|
try {
|
|
2171
2197
|
const { page, perPage: perPageInput } = args.pagination;
|
|
2172
2198
|
const collection = await this.getCollection(storage.TABLE_DATASETS);
|
|
2173
|
-
const
|
|
2199
|
+
const filter = {};
|
|
2200
|
+
if (args.filters?.organizationId !== void 0) filter.organizationId = args.filters.organizationId;
|
|
2201
|
+
if (args.filters?.projectId !== void 0) filter.projectId = args.filters.projectId;
|
|
2202
|
+
if (args.filters?.candidateKey !== void 0) filter.candidateKey = args.filters.candidateKey;
|
|
2203
|
+
if (args.filters?.candidateId !== void 0) filter.candidateId = args.filters.candidateId;
|
|
2204
|
+
const total = await collection.countDocuments(filter);
|
|
2174
2205
|
if (total === 0) {
|
|
2175
2206
|
return { datasets: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
2176
2207
|
}
|
|
@@ -2180,7 +2211,7 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2180
2211
|
return { datasets: [], pagination: { total, page, perPage: perPageForResponse, hasMore: total > 0 } };
|
|
2181
2212
|
}
|
|
2182
2213
|
const limitValue = perPageInput === false ? total : perPage;
|
|
2183
|
-
const rows = await collection.find(
|
|
2214
|
+
const rows = await collection.find(filter).sort({ createdAt: -1, id: 1 }).skip(offset).limit(limitValue).toArray();
|
|
2184
2215
|
return {
|
|
2185
2216
|
datasets: rows.map((row) => this.transformDatasetRow(row)),
|
|
2186
2217
|
pagination: {
|
|
@@ -2224,15 +2255,20 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2224
2255
|
});
|
|
2225
2256
|
}
|
|
2226
2257
|
const newVersion = result.version;
|
|
2258
|
+
const organizationId = result.organizationId ?? null;
|
|
2259
|
+
const projectId = result.projectId ?? null;
|
|
2227
2260
|
await itemsCollection.insertOne({
|
|
2228
2261
|
id,
|
|
2229
2262
|
datasetId: args.datasetId,
|
|
2230
2263
|
datasetVersion: newVersion,
|
|
2264
|
+
organizationId,
|
|
2265
|
+
projectId,
|
|
2231
2266
|
validTo: null,
|
|
2232
2267
|
isDeleted: false,
|
|
2233
2268
|
input: args.input,
|
|
2234
2269
|
groundTruth: args.groundTruth ?? null,
|
|
2235
2270
|
expectedTrajectory: args.expectedTrajectory ?? null,
|
|
2271
|
+
toolMocks: args.toolMocks ?? null,
|
|
2236
2272
|
requestContext: args.requestContext ?? null,
|
|
2237
2273
|
metadata: args.metadata ?? null,
|
|
2238
2274
|
source: args.source ?? null,
|
|
@@ -2249,9 +2285,12 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2249
2285
|
id,
|
|
2250
2286
|
datasetId: args.datasetId,
|
|
2251
2287
|
datasetVersion: newVersion,
|
|
2288
|
+
organizationId,
|
|
2289
|
+
projectId,
|
|
2252
2290
|
input: args.input,
|
|
2253
2291
|
groundTruth: args.groundTruth,
|
|
2254
2292
|
expectedTrajectory: args.expectedTrajectory,
|
|
2293
|
+
toolMocks: args.toolMocks,
|
|
2255
2294
|
requestContext: args.requestContext,
|
|
2256
2295
|
metadata: args.metadata,
|
|
2257
2296
|
source: args.source,
|
|
@@ -2289,7 +2328,7 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2289
2328
|
details: { itemId: args.id, expectedDatasetId: args.datasetId, actualDatasetId: existing.datasetId }
|
|
2290
2329
|
});
|
|
2291
2330
|
}
|
|
2292
|
-
const hasChanges = args.input !== void 0 || args.groundTruth !== void 0 || args.expectedTrajectory !== void 0 || args.requestContext !== void 0 || args.metadata !== void 0 || args.source !== void 0;
|
|
2331
|
+
const hasChanges = args.input !== void 0 || args.groundTruth !== void 0 || args.expectedTrajectory !== void 0 || args.toolMocks !== void 0 || args.requestContext !== void 0 || args.metadata !== void 0 || args.source !== void 0;
|
|
2293
2332
|
if (!hasChanges) {
|
|
2294
2333
|
return existing;
|
|
2295
2334
|
}
|
|
@@ -2298,6 +2337,7 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2298
2337
|
const mergedInput = args.input !== void 0 ? args.input : existing.input;
|
|
2299
2338
|
const mergedGroundTruth = args.groundTruth !== void 0 ? args.groundTruth : existing.groundTruth;
|
|
2300
2339
|
const mergedExpectedTrajectory = args.expectedTrajectory !== void 0 ? args.expectedTrajectory : existing.expectedTrajectory;
|
|
2340
|
+
const mergedToolMocks = args.toolMocks !== void 0 ? args.toolMocks : existing.toolMocks;
|
|
2301
2341
|
const mergedRequestContext = args.requestContext !== void 0 ? args.requestContext : existing.requestContext;
|
|
2302
2342
|
const mergedMetadata = args.metadata !== void 0 ? args.metadata : existing.metadata;
|
|
2303
2343
|
const mergedSource = args.source !== void 0 ? args.source : existing.source;
|
|
@@ -2318,6 +2358,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2318
2358
|
});
|
|
2319
2359
|
}
|
|
2320
2360
|
const newVersion = result.version;
|
|
2361
|
+
const parentOrganizationId = result.organizationId ?? null;
|
|
2362
|
+
const parentProjectId = result.projectId ?? null;
|
|
2321
2363
|
await itemsCollection.updateOne(
|
|
2322
2364
|
{ id: args.id, validTo: null, isDeleted: false },
|
|
2323
2365
|
{ $set: { validTo: newVersion } }
|
|
@@ -2326,11 +2368,14 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2326
2368
|
id: args.id,
|
|
2327
2369
|
datasetId: args.datasetId,
|
|
2328
2370
|
datasetVersion: newVersion,
|
|
2371
|
+
organizationId: parentOrganizationId,
|
|
2372
|
+
projectId: parentProjectId,
|
|
2329
2373
|
validTo: null,
|
|
2330
2374
|
isDeleted: false,
|
|
2331
2375
|
input: mergedInput,
|
|
2332
2376
|
groundTruth: mergedGroundTruth,
|
|
2333
2377
|
expectedTrajectory: mergedExpectedTrajectory ?? null,
|
|
2378
|
+
toolMocks: mergedToolMocks ?? null,
|
|
2334
2379
|
requestContext: mergedRequestContext,
|
|
2335
2380
|
metadata: mergedMetadata,
|
|
2336
2381
|
source: mergedSource,
|
|
@@ -2346,9 +2391,12 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2346
2391
|
return {
|
|
2347
2392
|
...existing,
|
|
2348
2393
|
datasetVersion: newVersion,
|
|
2394
|
+
organizationId: parentOrganizationId,
|
|
2395
|
+
projectId: parentProjectId,
|
|
2349
2396
|
input: mergedInput,
|
|
2350
2397
|
groundTruth: mergedGroundTruth,
|
|
2351
2398
|
expectedTrajectory: mergedExpectedTrajectory,
|
|
2399
|
+
toolMocks: mergedToolMocks,
|
|
2352
2400
|
requestContext: mergedRequestContext,
|
|
2353
2401
|
metadata: mergedMetadata,
|
|
2354
2402
|
source: mergedSource,
|
|
@@ -2397,15 +2445,21 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2397
2445
|
});
|
|
2398
2446
|
}
|
|
2399
2447
|
const newVersion = result.version;
|
|
2448
|
+
const parentOrganizationId = result.organizationId ?? null;
|
|
2449
|
+
const parentProjectId = result.projectId ?? null;
|
|
2400
2450
|
await itemsCollection.updateOne({ id, validTo: null, isDeleted: false }, { $set: { validTo: newVersion } });
|
|
2401
2451
|
await itemsCollection.insertOne({
|
|
2402
2452
|
id,
|
|
2403
2453
|
datasetId,
|
|
2404
2454
|
datasetVersion: newVersion,
|
|
2455
|
+
organizationId: parentOrganizationId,
|
|
2456
|
+
projectId: parentProjectId,
|
|
2405
2457
|
validTo: null,
|
|
2406
2458
|
isDeleted: true,
|
|
2407
2459
|
input: existing.input,
|
|
2408
2460
|
groundTruth: existing.groundTruth,
|
|
2461
|
+
expectedTrajectory: existing.expectedTrajectory ?? null,
|
|
2462
|
+
toolMocks: existing.toolMocks ?? null,
|
|
2409
2463
|
requestContext: existing.requestContext,
|
|
2410
2464
|
metadata: existing.metadata,
|
|
2411
2465
|
source: existing.source,
|
|
@@ -2468,16 +2522,21 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2468
2522
|
});
|
|
2469
2523
|
}
|
|
2470
2524
|
const newVersion = result.version;
|
|
2525
|
+
const organizationId = result.organizationId ?? null;
|
|
2526
|
+
const projectId = result.projectId ?? null;
|
|
2471
2527
|
if (itemsWithIds.length > 0) {
|
|
2472
2528
|
const docs = itemsWithIds.map(({ generatedId, itemInput }) => ({
|
|
2473
2529
|
id: generatedId,
|
|
2474
2530
|
datasetId: input.datasetId,
|
|
2475
2531
|
datasetVersion: newVersion,
|
|
2532
|
+
organizationId,
|
|
2533
|
+
projectId,
|
|
2476
2534
|
validTo: null,
|
|
2477
2535
|
isDeleted: false,
|
|
2478
2536
|
input: itemInput.input,
|
|
2479
2537
|
groundTruth: itemInput.groundTruth ?? null,
|
|
2480
2538
|
expectedTrajectory: itemInput.expectedTrajectory ?? null,
|
|
2539
|
+
toolMocks: itemInput.toolMocks ?? null,
|
|
2481
2540
|
requestContext: itemInput.requestContext ?? null,
|
|
2482
2541
|
metadata: itemInput.metadata ?? null,
|
|
2483
2542
|
source: itemInput.source ?? null,
|
|
@@ -2496,9 +2555,12 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2496
2555
|
id: generatedId,
|
|
2497
2556
|
datasetId: input.datasetId,
|
|
2498
2557
|
datasetVersion: newVersion,
|
|
2558
|
+
organizationId,
|
|
2559
|
+
projectId,
|
|
2499
2560
|
input: itemInput.input,
|
|
2500
2561
|
groundTruth: itemInput.groundTruth,
|
|
2501
2562
|
expectedTrajectory: itemInput.expectedTrajectory,
|
|
2563
|
+
toolMocks: itemInput.toolMocks,
|
|
2502
2564
|
requestContext: itemInput.requestContext,
|
|
2503
2565
|
metadata: itemInput.metadata,
|
|
2504
2566
|
source: itemInput.source,
|
|
@@ -2555,6 +2617,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2555
2617
|
});
|
|
2556
2618
|
}
|
|
2557
2619
|
const newVersion = result.version;
|
|
2620
|
+
const parentOrganizationId = result.organizationId ?? null;
|
|
2621
|
+
const parentProjectId = result.projectId ?? null;
|
|
2558
2622
|
const currentIds = currentItems.map((i) => i.id);
|
|
2559
2623
|
await itemsCollection.updateMany(
|
|
2560
2624
|
{ id: { $in: currentIds }, validTo: null, isDeleted: false },
|
|
@@ -2564,10 +2628,14 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2564
2628
|
id: item.id,
|
|
2565
2629
|
datasetId: input.datasetId,
|
|
2566
2630
|
datasetVersion: newVersion,
|
|
2631
|
+
organizationId: parentOrganizationId,
|
|
2632
|
+
projectId: parentProjectId,
|
|
2567
2633
|
validTo: null,
|
|
2568
2634
|
isDeleted: true,
|
|
2569
2635
|
input: item.input,
|
|
2570
2636
|
groundTruth: item.groundTruth,
|
|
2637
|
+
expectedTrajectory: item.expectedTrajectory ?? null,
|
|
2638
|
+
toolMocks: item.toolMocks ?? null,
|
|
2571
2639
|
requestContext: item.requestContext,
|
|
2572
2640
|
metadata: item.metadata,
|
|
2573
2641
|
source: item.source,
|
|
@@ -2669,6 +2737,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2669
2737
|
const { page, perPage: perPageInput } = args.pagination;
|
|
2670
2738
|
const collection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
|
|
2671
2739
|
const filter = { datasetId: args.datasetId };
|
|
2740
|
+
if (args.filters?.organizationId !== void 0) filter.organizationId = args.filters.organizationId;
|
|
2741
|
+
if (args.filters?.projectId !== void 0) filter.projectId = args.filters.projectId;
|
|
2672
2742
|
if (args.version !== void 0) {
|
|
2673
2743
|
filter.datasetVersion = { $lte: args.version };
|
|
2674
2744
|
filter.$or = [{ validTo: null }, { validTo: { $gt: args.version } }];
|
|
@@ -2823,6 +2893,8 @@ function transformExperimentRow(row) {
|
|
|
2823
2893
|
metadata: parseJsonField(row.metadata) ?? void 0,
|
|
2824
2894
|
datasetId: row.datasetId ?? null,
|
|
2825
2895
|
datasetVersion: row.datasetVersion != null ? Number(row.datasetVersion) : null,
|
|
2896
|
+
organizationId: row.organizationId ?? null,
|
|
2897
|
+
projectId: row.projectId ?? null,
|
|
2826
2898
|
targetType: row.targetType,
|
|
2827
2899
|
targetId: row.targetId,
|
|
2828
2900
|
status: row.status,
|
|
@@ -2843,6 +2915,8 @@ function transformExperimentResultRow(row) {
|
|
|
2843
2915
|
experimentId: row.experimentId,
|
|
2844
2916
|
itemId: row.itemId,
|
|
2845
2917
|
itemDatasetVersion: row.itemDatasetVersion != null ? Number(row.itemDatasetVersion) : null,
|
|
2918
|
+
organizationId: row.organizationId ?? null,
|
|
2919
|
+
projectId: row.projectId ?? null,
|
|
2846
2920
|
input: parseJsonField(row.input),
|
|
2847
2921
|
output: parseJsonField(row.output) ?? null,
|
|
2848
2922
|
groundTruth: parseJsonField(row.groundTruth) ?? null,
|
|
@@ -2853,6 +2927,7 @@ function transformExperimentResultRow(row) {
|
|
|
2853
2927
|
traceId: row.traceId ?? null,
|
|
2854
2928
|
status: row.status ?? null,
|
|
2855
2929
|
tags: Array.isArray(row.tags) ? row.tags : parseJsonField(row.tags) ?? null,
|
|
2930
|
+
toolMockReport: parseJsonField(row.toolMockReport) ?? null,
|
|
2856
2931
|
createdAt: toDate(row.createdAt)
|
|
2857
2932
|
};
|
|
2858
2933
|
}
|
|
@@ -2880,11 +2955,14 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
2880
2955
|
{ collection: storage.TABLE_EXPERIMENTS, keys: { id: 1 }, options: { unique: true } },
|
|
2881
2956
|
{ collection: storage.TABLE_EXPERIMENTS, keys: { datasetId: 1 } },
|
|
2882
2957
|
{ collection: storage.TABLE_EXPERIMENTS, keys: { createdAt: -1, id: 1 } },
|
|
2958
|
+
// Tenancy: leading-tenant indexes for multi-tenant scans (parity with datasets domain).
|
|
2959
|
+
{ collection: storage.TABLE_EXPERIMENTS, keys: { organizationId: 1, projectId: 1 } },
|
|
2883
2960
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { id: 1 }, options: { unique: true } },
|
|
2884
2961
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1 } },
|
|
2885
2962
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, itemId: 1 }, options: { unique: true } },
|
|
2886
2963
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { createdAt: -1 } },
|
|
2887
|
-
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, startedAt: 1, id: 1 } }
|
|
2964
|
+
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, startedAt: 1, id: 1 } },
|
|
2965
|
+
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { organizationId: 1, projectId: 1 } }
|
|
2888
2966
|
];
|
|
2889
2967
|
}
|
|
2890
2968
|
async createDefaultIndexes() {
|
|
@@ -2926,6 +3004,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
2926
3004
|
metadata: input.metadata ?? null,
|
|
2927
3005
|
datasetId: input.datasetId ?? null,
|
|
2928
3006
|
datasetVersion: input.datasetVersion ?? null,
|
|
3007
|
+
organizationId: input.organizationId ?? null,
|
|
3008
|
+
projectId: input.projectId ?? null,
|
|
2929
3009
|
targetType: input.targetType,
|
|
2930
3010
|
targetId: input.targetId,
|
|
2931
3011
|
status: "pending",
|
|
@@ -2949,6 +3029,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
2949
3029
|
metadata: input.metadata,
|
|
2950
3030
|
datasetId: input.datasetId ?? null,
|
|
2951
3031
|
datasetVersion: input.datasetVersion ?? null,
|
|
3032
|
+
organizationId: input.organizationId ?? null,
|
|
3033
|
+
projectId: input.projectId ?? null,
|
|
2952
3034
|
targetType: input.targetType,
|
|
2953
3035
|
targetId: input.targetId,
|
|
2954
3036
|
status: "pending",
|
|
@@ -3050,6 +3132,15 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3050
3132
|
if (args.status) {
|
|
3051
3133
|
filter.status = args.status;
|
|
3052
3134
|
}
|
|
3135
|
+
if (args.filters) {
|
|
3136
|
+
const { organizationId, projectId } = args.filters;
|
|
3137
|
+
if (organizationId !== void 0) {
|
|
3138
|
+
filter.organizationId = organizationId;
|
|
3139
|
+
}
|
|
3140
|
+
if (projectId !== void 0) {
|
|
3141
|
+
filter.projectId = projectId;
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3053
3144
|
const total = await collection.countDocuments(filter);
|
|
3054
3145
|
if (total === 0) {
|
|
3055
3146
|
return { experiments: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
@@ -3110,6 +3201,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3110
3201
|
experimentId: input.experimentId,
|
|
3111
3202
|
itemId: input.itemId,
|
|
3112
3203
|
itemDatasetVersion: input.itemDatasetVersion ?? null,
|
|
3204
|
+
organizationId: input.organizationId ?? null,
|
|
3205
|
+
projectId: input.projectId ?? null,
|
|
3113
3206
|
input: input.input,
|
|
3114
3207
|
output: input.output ?? null,
|
|
3115
3208
|
groundTruth: input.groundTruth ?? null,
|
|
@@ -3120,6 +3213,7 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3120
3213
|
traceId: input.traceId ?? null,
|
|
3121
3214
|
status: input.status ?? null,
|
|
3122
3215
|
tags: input.tags ?? null,
|
|
3216
|
+
toolMockReport: input.toolMockReport ?? null,
|
|
3123
3217
|
createdAt: now
|
|
3124
3218
|
};
|
|
3125
3219
|
try {
|
|
@@ -3130,6 +3224,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3130
3224
|
experimentId: input.experimentId,
|
|
3131
3225
|
itemId: input.itemId,
|
|
3132
3226
|
itemDatasetVersion: input.itemDatasetVersion ?? null,
|
|
3227
|
+
organizationId: input.organizationId ?? null,
|
|
3228
|
+
projectId: input.projectId ?? null,
|
|
3133
3229
|
input: input.input,
|
|
3134
3230
|
output: input.output ?? null,
|
|
3135
3231
|
groundTruth: input.groundTruth ?? null,
|
|
@@ -3140,6 +3236,7 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3140
3236
|
traceId: input.traceId ?? null,
|
|
3141
3237
|
status: input.status ?? null,
|
|
3142
3238
|
tags: input.tags ?? null,
|
|
3239
|
+
toolMockReport: input.toolMockReport ?? null,
|
|
3143
3240
|
createdAt: now
|
|
3144
3241
|
};
|
|
3145
3242
|
} catch (error$1) {
|
|
@@ -3228,6 +3325,15 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3228
3325
|
if (args.status) {
|
|
3229
3326
|
filter.status = args.status;
|
|
3230
3327
|
}
|
|
3328
|
+
if (args.filters) {
|
|
3329
|
+
const { organizationId, projectId } = args.filters;
|
|
3330
|
+
if (organizationId !== void 0) {
|
|
3331
|
+
filter.organizationId = organizationId;
|
|
3332
|
+
}
|
|
3333
|
+
if (projectId !== void 0) {
|
|
3334
|
+
filter.projectId = projectId;
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3231
3337
|
const total = await collection.countDocuments(filter);
|
|
3232
3338
|
if (total === 0) {
|
|
3233
3339
|
return { results: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
@@ -6865,17 +6971,39 @@ Note: This migration may take some time for large collections.
|
|
|
6865
6971
|
supported: ["batch-with-updates", "insert-only"]
|
|
6866
6972
|
};
|
|
6867
6973
|
}
|
|
6974
|
+
createDateRangeCondition(field, range) {
|
|
6975
|
+
const dateFilter = {};
|
|
6976
|
+
const stringFilter = {};
|
|
6977
|
+
if (range.start) {
|
|
6978
|
+
const operator = range.startExclusive ? "$gt" : "$gte";
|
|
6979
|
+
const start = range.start instanceof Date ? range.start : new Date(range.start);
|
|
6980
|
+
dateFilter[operator] = start;
|
|
6981
|
+
stringFilter[operator] = start.toISOString();
|
|
6982
|
+
}
|
|
6983
|
+
if (range.end) {
|
|
6984
|
+
const operator = range.endExclusive ? "$lt" : "$lte";
|
|
6985
|
+
const end = range.end instanceof Date ? range.end : new Date(range.end);
|
|
6986
|
+
dateFilter[operator] = end;
|
|
6987
|
+
stringFilter[operator] = end.toISOString();
|
|
6988
|
+
}
|
|
6989
|
+
if (Object.keys(dateFilter).length === 0) {
|
|
6990
|
+
return null;
|
|
6991
|
+
}
|
|
6992
|
+
return {
|
|
6993
|
+
$or: [{ [field]: dateFilter }, { [field]: stringFilter }]
|
|
6994
|
+
};
|
|
6995
|
+
}
|
|
6868
6996
|
async createSpan(args) {
|
|
6869
6997
|
const { span } = args;
|
|
6870
6998
|
try {
|
|
6871
|
-
const startedAt = span.startedAt instanceof Date ? span.startedAt
|
|
6872
|
-
const endedAt = span.endedAt instanceof Date ? span.endedAt
|
|
6999
|
+
const startedAt = span.startedAt instanceof Date ? span.startedAt : new Date(span.startedAt);
|
|
7000
|
+
const endedAt = span.endedAt == null ? span.endedAt : span.endedAt instanceof Date ? span.endedAt : new Date(span.endedAt);
|
|
6873
7001
|
const record = {
|
|
6874
7002
|
...span,
|
|
6875
7003
|
startedAt,
|
|
6876
7004
|
endedAt,
|
|
6877
|
-
createdAt:
|
|
6878
|
-
updatedAt:
|
|
7005
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
7006
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
6879
7007
|
};
|
|
6880
7008
|
const collection = await this.getCollection(storage.TABLE_SPANS);
|
|
6881
7009
|
await collection.insertOne(record);
|
|
@@ -7010,15 +7138,15 @@ Note: This migration may take some time for large collections.
|
|
|
7010
7138
|
const { traceId, spanId, updates } = args;
|
|
7011
7139
|
try {
|
|
7012
7140
|
const data = { ...updates };
|
|
7013
|
-
if (data.endedAt instanceof Date) {
|
|
7014
|
-
data.endedAt = data.endedAt
|
|
7141
|
+
if (data.endedAt != null && !(data.endedAt instanceof Date)) {
|
|
7142
|
+
data.endedAt = new Date(data.endedAt);
|
|
7015
7143
|
}
|
|
7016
|
-
if (data.startedAt instanceof Date) {
|
|
7017
|
-
data.startedAt = data.startedAt
|
|
7144
|
+
if (data.startedAt != null && !(data.startedAt instanceof Date)) {
|
|
7145
|
+
data.startedAt = new Date(data.startedAt);
|
|
7018
7146
|
}
|
|
7019
7147
|
const updateData = {
|
|
7020
7148
|
...data,
|
|
7021
|
-
updatedAt:
|
|
7149
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7022
7150
|
};
|
|
7023
7151
|
const collection = await this.getCollection(storage.TABLE_SPANS);
|
|
7024
7152
|
await collection.updateOne({ spanId, traceId }, { $set: updateData });
|
|
@@ -7050,27 +7178,15 @@ Note: This migration may take some time for large collections.
|
|
|
7050
7178
|
const andConditions = [];
|
|
7051
7179
|
if (filters) {
|
|
7052
7180
|
if (filters.startedAt) {
|
|
7053
|
-
const
|
|
7054
|
-
if (
|
|
7055
|
-
|
|
7056
|
-
}
|
|
7057
|
-
if (filters.startedAt.end) {
|
|
7058
|
-
startedAtFilter.$lte = filters.startedAt.end.toISOString();
|
|
7059
|
-
}
|
|
7060
|
-
if (Object.keys(startedAtFilter).length > 0) {
|
|
7061
|
-
mongoFilter.startedAt = startedAtFilter;
|
|
7181
|
+
const startedAtCondition = this.createDateRangeCondition("startedAt", filters.startedAt);
|
|
7182
|
+
if (startedAtCondition) {
|
|
7183
|
+
andConditions.push(startedAtCondition);
|
|
7062
7184
|
}
|
|
7063
7185
|
}
|
|
7064
7186
|
if (filters.endedAt) {
|
|
7065
|
-
const
|
|
7066
|
-
if (
|
|
7067
|
-
|
|
7068
|
-
}
|
|
7069
|
-
if (filters.endedAt.end) {
|
|
7070
|
-
endedAtFilter.$lte = filters.endedAt.end.toISOString();
|
|
7071
|
-
}
|
|
7072
|
-
if (Object.keys(endedAtFilter).length > 0) {
|
|
7073
|
-
andConditions.push({ endedAt: endedAtFilter });
|
|
7187
|
+
const endedAtCondition = this.createDateRangeCondition("endedAt", filters.endedAt);
|
|
7188
|
+
if (endedAtCondition) {
|
|
7189
|
+
andConditions.push(endedAtCondition);
|
|
7074
7190
|
}
|
|
7075
7191
|
}
|
|
7076
7192
|
if (filters.spanType !== void 0) {
|
|
@@ -7278,14 +7394,14 @@ Note: This migration may take some time for large collections.
|
|
|
7278
7394
|
async batchCreateSpans(args) {
|
|
7279
7395
|
try {
|
|
7280
7396
|
const records = args.records.map((record) => {
|
|
7281
|
-
const startedAt = record.startedAt instanceof Date ? record.startedAt
|
|
7282
|
-
const endedAt = record.endedAt instanceof Date ? record.endedAt
|
|
7397
|
+
const startedAt = record.startedAt instanceof Date ? record.startedAt : new Date(record.startedAt);
|
|
7398
|
+
const endedAt = record.endedAt == null ? record.endedAt : record.endedAt instanceof Date ? record.endedAt : new Date(record.endedAt);
|
|
7283
7399
|
return {
|
|
7284
7400
|
...record,
|
|
7285
7401
|
startedAt,
|
|
7286
7402
|
endedAt,
|
|
7287
|
-
createdAt:
|
|
7288
|
-
updatedAt:
|
|
7403
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
7404
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7289
7405
|
};
|
|
7290
7406
|
});
|
|
7291
7407
|
if (records.length > 0) {
|
|
@@ -7310,15 +7426,15 @@ Note: This migration may take some time for large collections.
|
|
|
7310
7426
|
}
|
|
7311
7427
|
const bulkOps = args.records.map((record) => {
|
|
7312
7428
|
const data = { ...record.updates };
|
|
7313
|
-
if (data.endedAt instanceof Date) {
|
|
7314
|
-
data.endedAt = data.endedAt
|
|
7429
|
+
if (data.endedAt != null && !(data.endedAt instanceof Date)) {
|
|
7430
|
+
data.endedAt = new Date(data.endedAt);
|
|
7315
7431
|
}
|
|
7316
|
-
if (data.startedAt instanceof Date) {
|
|
7317
|
-
data.startedAt = data.startedAt
|
|
7432
|
+
if (data.startedAt != null && !(data.startedAt instanceof Date)) {
|
|
7433
|
+
data.startedAt = new Date(data.startedAt);
|
|
7318
7434
|
}
|
|
7319
7435
|
const updateData = {
|
|
7320
7436
|
...data,
|
|
7321
|
-
updatedAt:
|
|
7437
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7322
7438
|
};
|
|
7323
7439
|
return {
|
|
7324
7440
|
updateOne: {
|