@mastra/libsql 1.14.0 → 1.14.1-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 CHANGED
@@ -1,5 +1,87 @@
1
1
  # @mastra/libsql
2
2
 
3
+ ## 1.14.1-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 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))
8
+
9
+ `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.
10
+
11
+ 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.
12
+
13
+ This release also clarifies the `targetType` contract via JSDoc:
14
+ - `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.
15
+ - `Experiment.targetType` / `CreateExperimentInput.targetType` stay required. An experiment by definition replays inputs against a specific target.
16
+
17
+ No behavior change for existing OSS-created experiments; the new fields are additive and optional.
18
+
19
+ Example:
20
+
21
+ ```ts
22
+ // Create an experiment scoped to a tenancy bucket. When the parent dataset
23
+ // already carries `organizationId` / `projectId`, `runExperiment` hydrates
24
+ // these fields automatically from the dataset record.
25
+ const experiment = await storage.createExperiment({
26
+ name: 'qa-regression',
27
+ datasetId: 'ds_123',
28
+ datasetVersion: 1,
29
+ targetType: 'agent',
30
+ targetId: 'agent_qa',
31
+ totalItems: 10,
32
+ organizationId: 'org_123',
33
+ projectId: 'proj_123',
34
+ });
35
+
36
+ // List experiments within a tenancy bucket.
37
+ const experiments = await storage.listExperiments({
38
+ pagination: { page: 0, perPage: 20 },
39
+ filters: { organizationId: 'org_123', projectId: 'proj_123' },
40
+ });
41
+
42
+ // List per-item results within the same bucket.
43
+ const results = await storage.listExperimentResults({
44
+ experimentId: experiment.id,
45
+ pagination: { page: 0, perPage: 50 },
46
+ filters: { organizationId: 'org_123', projectId: 'proj_123' },
47
+ });
48
+ ```
49
+
50
+ - Persist and filter dataset tenancy + candidate identity in storage adapters. ([#18314](https://github.com/mastra-ai/mastra/pull/18314))
51
+
52
+ `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).
53
+
54
+ 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.
55
+
56
+ ```ts
57
+ await storage.createDataset({
58
+ name: 'candidates/missing-tool-call/incident-123',
59
+ organizationId: 'org_abc',
60
+ projectId: 'project_xyz',
61
+ candidateKey: 'missing-tool-call',
62
+ candidateId: 'incident-123',
63
+ });
64
+
65
+ await storage.listDatasets({
66
+ pagination: { page: 0, perPage: 20 },
67
+ filters: { organizationId: 'org_abc', projectId: 'project_xyz' },
68
+ });
69
+ ```
70
+
71
+ - 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)]:
72
+ - @mastra/core@1.46.0-alpha.4
73
+
74
+ ## 1.14.1-alpha.0
75
+
76
+ ### Patch Changes
77
+
78
+ - Fixed: `mastra build` output no longer hangs on the first storage-touching request when an app uses `LibSQLStore`, `PostgresStore`, or `MySQLStore` with observational memory. `mastra dev` was unaffected; only the bundled `mastra start` output deadlocked. No code changes or `bundler.externals` workaround required on the app side after upgrading. ([#18302](https://github.com/mastra-ai/mastra/pull/18302))
79
+
80
+ - 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))
81
+
82
+ - 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)]:
83
+ - @mastra/core@1.46.0-alpha.3
84
+
3
85
  ## 1.14.0
4
86
 
5
87
  ### Minor Changes
@@ -3,7 +3,7 @@ name: mastra-libsql
3
3
  description: Documentation for @mastra/libsql. Use when working with @mastra/libsql APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/libsql"
6
- version: "1.14.0"
6
+ version: "1.14.1-alpha.1"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.14.0",
2
+ "version": "1.14.1-alpha.1",
3
3
  "package": "@mastra/libsql",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -2,6 +2,8 @@
2
2
 
3
3
  > **Note:** The Agent Builder is part of the Mastra Enterprise Edition. Production deployments require a valid EE license. [Contact sales](https://mastra.ai/contact) for more information.
4
4
 
5
+ [YouTube video player](https://www.youtube-nocookie.com/embed/AbdgIu4Z07I)
6
+
5
7
  The Agent Builder lets you build, configure, and operate Mastra agents all within the UI. It runs inside your Mastra server, persists everything to `Mastra.storage`, and supports multi-tenant agent workflows with RBAC and channel integrations.
6
8
 
7
9
  - [**Configuration**](https://mastra.ai/docs/agent-builder/configuration): Toggle UI sections and pin admin-controlled defaults for every new agent.
package/dist/index.cjs CHANGED
@@ -3622,9 +3622,16 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3622
3622
  await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "targetType", "TEXT");
3623
3623
  await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "targetIds", "TEXT");
3624
3624
  await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "scorerIds", "TEXT");
3625
+ await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "organizationId", "TEXT");
3626
+ await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "projectId", "TEXT");
3627
+ await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "candidateKey", "TEXT");
3628
+ await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "candidateId", "TEXT");
3625
3629
  await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "requestContext", "TEXT");
3626
3630
  await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "source", "TEXT");
3627
3631
  await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "expectedTrajectory", "TEXT");
3632
+ await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "organizationId", "TEXT");
3633
+ await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "projectId", "TEXT");
3634
+ await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "toolMocks", "TEXT");
3628
3635
  await this.#client.batch(
3629
3636
  [
3630
3637
  {
@@ -3646,6 +3653,18 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3646
3653
  {
3647
3654
  sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_dataset_versions_dataset_version_unique ON "${storage.TABLE_DATASET_VERSIONS}" ("datasetId", "version")`,
3648
3655
  args: []
3656
+ },
3657
+ {
3658
+ sql: `CREATE INDEX IF NOT EXISTS idx_datasets_tenancy_createdat ON "${storage.TABLE_DATASETS}" ("organizationId", "projectId", "createdAt", "id")`,
3659
+ args: []
3660
+ },
3661
+ {
3662
+ sql: `CREATE INDEX IF NOT EXISTS idx_datasets_tenancy_candidate ON "${storage.TABLE_DATASETS}" ("organizationId", "projectId", "candidateKey", "candidateId")`,
3663
+ args: []
3664
+ },
3665
+ {
3666
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_tenancy_list ON "${storage.TABLE_DATASET_ITEMS}" ("organizationId", "projectId", "datasetId", "validTo", "isDeleted")`,
3667
+ args: []
3649
3668
  }
3650
3669
  ],
3651
3670
  "write"
@@ -3677,6 +3696,10 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3677
3696
  targetIds: row.targetIds ? storage.safelyParseJSON(row.targetIds) : void 0,
3678
3697
  scorerIds: row.scorerIds ? storage.safelyParseJSON(row.scorerIds) : void 0,
3679
3698
  version: row.version,
3699
+ organizationId: row.organizationId ?? null,
3700
+ projectId: row.projectId ?? null,
3701
+ candidateKey: row.candidateKey ?? null,
3702
+ candidateId: row.candidateId ?? null,
3680
3703
  createdAt: storage.ensureDate(row.createdAt),
3681
3704
  updatedAt: storage.ensureDate(row.updatedAt)
3682
3705
  };
@@ -3686,9 +3709,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3686
3709
  id: row.id,
3687
3710
  datasetId: row.datasetId,
3688
3711
  datasetVersion: row.datasetVersion,
3712
+ organizationId: row.organizationId ?? null,
3713
+ projectId: row.projectId ?? null,
3689
3714
  input: storage.safelyParseJSON(row.input),
3690
3715
  groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
3691
3716
  expectedTrajectory: row.expectedTrajectory ? storage.safelyParseJSON(row.expectedTrajectory) : void 0,
3717
+ toolMocks: row.toolMocks ? storage.safelyParseJSON(row.toolMocks) : void 0,
3692
3718
  requestContext: row.requestContext ? storage.safelyParseJSON(row.requestContext) : void 0,
3693
3719
  metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
3694
3720
  source: row.source ? storage.safelyParseJSON(row.source) : void 0,
@@ -3701,11 +3727,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3701
3727
  id: row.id,
3702
3728
  datasetId: row.datasetId,
3703
3729
  datasetVersion: row.datasetVersion,
3730
+ organizationId: row.organizationId ?? null,
3731
+ projectId: row.projectId ?? null,
3704
3732
  validTo: row.validTo,
3705
3733
  isDeleted: Boolean(row.isDeleted),
3706
3734
  input: storage.safelyParseJSON(row.input),
3707
3735
  groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
3708
3736
  expectedTrajectory: row.expectedTrajectory ? storage.safelyParseJSON(row.expectedTrajectory) : void 0,
3737
+ toolMocks: row.toolMocks ? storage.safelyParseJSON(row.toolMocks) : void 0,
3709
3738
  requestContext: row.requestContext ? storage.safelyParseJSON(row.requestContext) : void 0,
3710
3739
  metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
3711
3740
  source: row.source ? storage.safelyParseJSON(row.source) : void 0,
@@ -3741,6 +3770,10 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3741
3770
  targetIds: input.targetIds ? JSON.stringify(input.targetIds) : null,
3742
3771
  scorerIds: input.scorerIds ? JSON.stringify(input.scorerIds) : null,
3743
3772
  version: 0,
3773
+ organizationId: input.organizationId ?? null,
3774
+ projectId: input.projectId ?? null,
3775
+ candidateKey: input.candidateKey ?? null,
3776
+ candidateId: input.candidateId ?? null,
3744
3777
  createdAt: nowIso,
3745
3778
  updatedAt: nowIso
3746
3779
  }
@@ -3757,6 +3790,10 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3757
3790
  targetIds: input.targetIds ?? void 0,
3758
3791
  scorerIds: input.scorerIds ?? void 0,
3759
3792
  version: 0,
3793
+ organizationId: input.organizationId ?? null,
3794
+ projectId: input.projectId ?? null,
3795
+ candidateKey: input.candidateKey ?? null,
3796
+ candidateId: input.candidateId ?? null,
3760
3797
  createdAt: now,
3761
3798
  updatedAt: now
3762
3799
  };
@@ -3912,9 +3949,28 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3912
3949
  async listDatasets(args) {
3913
3950
  try {
3914
3951
  const { page, perPage: perPageInput } = args.pagination;
3952
+ const filterConditions = [];
3953
+ const filterParams = [];
3954
+ if (args.filters?.organizationId !== void 0) {
3955
+ filterConditions.push("organizationId = ?");
3956
+ filterParams.push(args.filters.organizationId);
3957
+ }
3958
+ if (args.filters?.projectId !== void 0) {
3959
+ filterConditions.push("projectId = ?");
3960
+ filterParams.push(args.filters.projectId);
3961
+ }
3962
+ if (args.filters?.candidateKey !== void 0) {
3963
+ filterConditions.push("candidateKey = ?");
3964
+ filterParams.push(args.filters.candidateKey);
3965
+ }
3966
+ if (args.filters?.candidateId !== void 0) {
3967
+ filterConditions.push("candidateId = ?");
3968
+ filterParams.push(args.filters.candidateId);
3969
+ }
3970
+ const whereClause = filterConditions.length > 0 ? `WHERE ${filterConditions.join(" AND ")}` : "";
3915
3971
  const countResult = await this.#client.execute({
3916
- sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_DATASETS}`,
3917
- args: []
3972
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_DATASETS} ${whereClause}`,
3973
+ args: filterParams
3918
3974
  });
3919
3975
  const total = Number(countResult.rows?.[0]?.count ?? 0);
3920
3976
  if (total === 0) {
@@ -3928,8 +3984,8 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3928
3984
  const limitValue = perPageInput === false ? total : perPage;
3929
3985
  const end = perPageInput === false ? total : start + perPage;
3930
3986
  const result = await this.#client.execute({
3931
- sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASETS)} FROM ${storage.TABLE_DATASETS} ORDER BY createdAt DESC, id ASC LIMIT ? OFFSET ?`,
3932
- args: [limitValue, start]
3987
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASETS)} FROM ${storage.TABLE_DATASETS} ${whereClause} ORDER BY createdAt DESC, id ASC LIMIT ? OFFSET ?`,
3988
+ args: [...filterParams, limitValue, start]
3933
3989
  });
3934
3990
  return {
3935
3991
  datasets: result.rows?.map((row) => this.transformDatasetRow(row)) ?? [],
@@ -3954,6 +4010,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3954
4010
  // --- SCD-2 item mutations ---
3955
4011
  async _doAddItem(args) {
3956
4012
  try {
4013
+ const dataset = await this.getDatasetById({ id: args.datasetId });
3957
4014
  const id = crypto.randomUUID();
3958
4015
  const versionId = crypto.randomUUID();
3959
4016
  const now = /* @__PURE__ */ new Date();
@@ -3965,14 +4022,17 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3965
4022
  args: [args.datasetId]
3966
4023
  },
3967
4024
  {
3968
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, expectedTrajectory, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4025
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, organizationId, projectId, validTo, isDeleted, input, groundTruth, expectedTrajectory, toolMocks, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), (SELECT organizationId FROM ${storage.TABLE_DATASETS} WHERE id = ?), (SELECT projectId FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3969
4026
  args: [
3970
4027
  id,
3971
4028
  args.datasetId,
3972
4029
  args.datasetId,
4030
+ args.datasetId,
4031
+ args.datasetId,
3973
4032
  jsonbArg(args.input),
3974
4033
  jsonbArg(args.groundTruth),
3975
4034
  jsonbArg(args.expectedTrajectory),
4035
+ jsonbArg(args.toolMocks),
3976
4036
  jsonbArg(args.requestContext),
3977
4037
  jsonbArg(args.metadata),
3978
4038
  jsonbArg(args.source),
@@ -3992,9 +4052,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3992
4052
  id,
3993
4053
  datasetId: args.datasetId,
3994
4054
  datasetVersion: newVersion,
4055
+ organizationId: dataset?.organizationId ?? null,
4056
+ projectId: dataset?.projectId ?? null,
3995
4057
  input: args.input,
3996
4058
  groundTruth: args.groundTruth,
3997
4059
  expectedTrajectory: args.expectedTrajectory,
4060
+ toolMocks: args.toolMocks,
3998
4061
  requestContext: args.requestContext,
3999
4062
  metadata: args.metadata,
4000
4063
  source: args.source,
@@ -4032,12 +4095,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4032
4095
  details: { itemId: args.id, expectedDatasetId: args.datasetId, actualDatasetId: existing.datasetId }
4033
4096
  });
4034
4097
  }
4098
+ const dataset = await this.getDatasetById({ id: args.datasetId });
4035
4099
  const versionId = crypto.randomUUID();
4036
4100
  const now = /* @__PURE__ */ new Date();
4037
4101
  const nowIso = now.toISOString();
4038
4102
  const mergedInput = args.input !== void 0 ? args.input : existing.input;
4039
4103
  const mergedGroundTruth = args.groundTruth !== void 0 ? args.groundTruth : existing.groundTruth;
4040
4104
  const mergedExpectedTrajectory = args.expectedTrajectory !== void 0 ? args.expectedTrajectory : existing.expectedTrajectory;
4105
+ const mergedToolMocks = args.toolMocks !== void 0 ? args.toolMocks : existing.toolMocks;
4041
4106
  const mergedRequestContext = args.requestContext !== void 0 ? args.requestContext : existing.requestContext;
4042
4107
  const mergedMetadata = args.metadata !== void 0 ? args.metadata : existing.metadata;
4043
4108
  const mergedSource = args.source !== void 0 ? args.source : existing.source;
@@ -4052,14 +4117,17 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4052
4117
  args: [args.datasetId, args.id]
4053
4118
  },
4054
4119
  {
4055
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, expectedTrajectory, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4120
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, organizationId, projectId, validTo, isDeleted, input, groundTruth, expectedTrajectory, toolMocks, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), (SELECT organizationId FROM ${storage.TABLE_DATASETS} WHERE id = ?), (SELECT projectId FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4056
4121
  args: [
4057
4122
  args.id,
4058
4123
  args.datasetId,
4059
4124
  args.datasetId,
4125
+ args.datasetId,
4126
+ args.datasetId,
4060
4127
  jsonbArg(mergedInput),
4061
4128
  jsonbArg(mergedGroundTruth),
4062
4129
  jsonbArg(mergedExpectedTrajectory),
4130
+ jsonbArg(mergedToolMocks),
4063
4131
  jsonbArg(mergedRequestContext),
4064
4132
  jsonbArg(mergedMetadata),
4065
4133
  jsonbArg(mergedSource),
@@ -4078,9 +4146,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4078
4146
  return {
4079
4147
  ...existing,
4080
4148
  datasetVersion: newVersion,
4149
+ organizationId: dataset?.organizationId ?? null,
4150
+ projectId: dataset?.projectId ?? null,
4081
4151
  input: mergedInput,
4082
4152
  groundTruth: mergedGroundTruth,
4083
4153
  expectedTrajectory: mergedExpectedTrajectory,
4154
+ toolMocks: mergedToolMocks,
4084
4155
  requestContext: mergedRequestContext,
4085
4156
  metadata: mergedMetadata,
4086
4157
  source: mergedSource,
@@ -4123,13 +4194,17 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4123
4194
  args: [datasetId, id]
4124
4195
  },
4125
4196
  {
4126
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4197
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, organizationId, projectId, validTo, isDeleted, input, groundTruth, expectedTrajectory, toolMocks, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), (SELECT organizationId FROM ${storage.TABLE_DATASETS} WHERE id = ?), (SELECT projectId FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4127
4198
  args: [
4128
4199
  id,
4129
4200
  datasetId,
4130
4201
  datasetId,
4202
+ datasetId,
4203
+ datasetId,
4131
4204
  jsonbArg(existing.input),
4132
4205
  jsonbArg(existing.groundTruth),
4206
+ jsonbArg(existing.expectedTrajectory),
4207
+ jsonbArg(existing.toolMocks),
4133
4208
  jsonbArg(existing.requestContext),
4134
4209
  jsonbArg(existing.metadata),
4135
4210
  jsonbArg(existing.source),
@@ -4230,6 +4305,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4230
4305
  "isDeleted = 0"
4231
4306
  ];
4232
4307
  const queryParams2 = [args.datasetId, args.version, args.version];
4308
+ if (args.filters?.organizationId !== void 0) {
4309
+ conditions2.push("organizationId = ?");
4310
+ queryParams2.push(args.filters.organizationId);
4311
+ }
4312
+ if (args.filters?.projectId !== void 0) {
4313
+ conditions2.push("projectId = ?");
4314
+ queryParams2.push(args.filters.projectId);
4315
+ }
4233
4316
  if (args.search) {
4234
4317
  conditions2.push(`(LOWER(json(input)) LIKE ? OR LOWER(COALESCE(json(groundTruth), '')) LIKE ?)`);
4235
4318
  const searchPattern = `%${args.search.toLowerCase()}%`;
@@ -4267,6 +4350,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4267
4350
  }
4268
4351
  const conditions = ["datasetId = ?", "validTo IS NULL", "isDeleted = 0"];
4269
4352
  const queryParams = [args.datasetId];
4353
+ if (args.filters?.organizationId !== void 0) {
4354
+ conditions.push("organizationId = ?");
4355
+ queryParams.push(args.filters.organizationId);
4356
+ }
4357
+ if (args.filters?.projectId !== void 0) {
4358
+ conditions.push("projectId = ?");
4359
+ queryParams.push(args.filters.projectId);
4360
+ }
4270
4361
  if (args.search) {
4271
4362
  conditions.push(`(LOWER(json(input)) LIKE ? OR LOWER(COALESCE(json(groundTruth), '')) LIKE ?)`);
4272
4363
  const searchPattern = `%${args.search.toLowerCase()}%`;
@@ -4412,14 +4503,17 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4412
4503
  const id = crypto.randomUUID();
4413
4504
  items.push({ id, input: itemInput });
4414
4505
  statements.push({
4415
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, expectedTrajectory, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4506
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, organizationId, projectId, validTo, isDeleted, input, groundTruth, expectedTrajectory, toolMocks, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?, ?, NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4416
4507
  args: [
4417
4508
  id,
4418
4509
  input.datasetId,
4419
4510
  input.datasetId,
4511
+ dataset.organizationId ?? null,
4512
+ dataset.projectId ?? null,
4420
4513
  jsonbArg(itemInput.input),
4421
4514
  jsonbArg(itemInput.groundTruth),
4422
4515
  jsonbArg(itemInput.expectedTrajectory),
4516
+ jsonbArg(itemInput.toolMocks),
4423
4517
  jsonbArg(itemInput.requestContext),
4424
4518
  jsonbArg(itemInput.metadata),
4425
4519
  jsonbArg(itemInput.source),
@@ -4438,9 +4532,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4438
4532
  id,
4439
4533
  datasetId: input.datasetId,
4440
4534
  datasetVersion: newVersion,
4535
+ organizationId: dataset.organizationId ?? null,
4536
+ projectId: dataset.projectId ?? null,
4441
4537
  input: itemInput.input,
4442
4538
  groundTruth: itemInput.groundTruth,
4443
4539
  expectedTrajectory: itemInput.expectedTrajectory,
4540
+ toolMocks: itemInput.toolMocks,
4444
4541
  requestContext: itemInput.requestContext,
4445
4542
  metadata: itemInput.metadata,
4446
4543
  source: itemInput.source,
@@ -4492,13 +4589,17 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
4492
4589
  args: [input.datasetId, item.id]
4493
4590
  });
4494
4591
  statements.push({
4495
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4592
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, organizationId, projectId, validTo, isDeleted, input, groundTruth, expectedTrajectory, toolMocks, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?, ?, NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
4496
4593
  args: [
4497
4594
  item.id,
4498
4595
  input.datasetId,
4499
4596
  input.datasetId,
4597
+ dataset.organizationId ?? null,
4598
+ dataset.projectId ?? null,
4500
4599
  jsonbArg(item.input),
4501
4600
  jsonbArg(item.groundTruth),
4601
+ jsonbArg(item.expectedTrajectory),
4602
+ jsonbArg(item.toolMocks),
4502
4603
  jsonbArg(item.requestContext),
4503
4604
  jsonbArg(item.metadata),
4504
4605
  jsonbArg(item.source),
@@ -4543,12 +4644,12 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4543
4644
  await this.#db.alterTable({
4544
4645
  tableName: storage.TABLE_EXPERIMENTS,
4545
4646
  schema: storage.EXPERIMENTS_SCHEMA,
4546
- ifNotExists: ["agentVersion"]
4647
+ ifNotExists: ["agentVersion", "organizationId", "projectId"]
4547
4648
  });
4548
4649
  await this.#db.alterTable({
4549
4650
  tableName: storage.TABLE_EXPERIMENT_RESULTS,
4550
4651
  schema: storage.EXPERIMENT_RESULTS_SCHEMA,
4551
- ifNotExists: ["status", "tags"]
4652
+ ifNotExists: ["status", "tags", "toolMockReport", "organizationId", "projectId"]
4552
4653
  });
4553
4654
  await this.#client.batch(
4554
4655
  [
@@ -4563,6 +4664,15 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4563
4664
  {
4564
4665
  sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_experiment_results_exp_item ON "${storage.TABLE_EXPERIMENT_RESULTS}" ("experimentId", "itemId")`,
4565
4666
  args: []
4667
+ },
4668
+ // Tenancy: leading-tenant indexes for multi-tenant scans (parity with datasets domain).
4669
+ {
4670
+ sql: `CREATE INDEX IF NOT EXISTS idx_experiments_org_project ON "${storage.TABLE_EXPERIMENTS}" ("organizationId", "projectId")`,
4671
+ args: []
4672
+ },
4673
+ {
4674
+ sql: `CREATE INDEX IF NOT EXISTS idx_experiment_results_org_project ON "${storage.TABLE_EXPERIMENT_RESULTS}" ("organizationId", "projectId")`,
4675
+ args: []
4566
4676
  }
4567
4677
  ],
4568
4678
  "write"
@@ -4579,6 +4689,8 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4579
4689
  datasetId: row.datasetId ?? null,
4580
4690
  datasetVersion: row.datasetVersion != null ? row.datasetVersion : null,
4581
4691
  agentVersion: row.agentVersion ?? null,
4692
+ organizationId: row.organizationId ?? null,
4693
+ projectId: row.projectId ?? null,
4582
4694
  targetType: row.targetType,
4583
4695
  targetId: row.targetId,
4584
4696
  name: row.name ?? void 0,
@@ -4602,6 +4714,8 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4602
4714
  experimentId: row.experimentId,
4603
4715
  itemId: row.itemId,
4604
4716
  itemDatasetVersion: row.itemDatasetVersion != null ? row.itemDatasetVersion : null,
4717
+ organizationId: row.organizationId ?? null,
4718
+ projectId: row.projectId ?? null,
4605
4719
  input: storage.safelyParseJSON(row.input),
4606
4720
  output: row.output ? storage.safelyParseJSON(row.output) : null,
4607
4721
  groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : null,
@@ -4612,6 +4726,7 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4612
4726
  traceId: row.traceId ?? null,
4613
4727
  status: row.status ?? null,
4614
4728
  tags: row.tags ? storage.safelyParseJSON(row.tags) : null,
4729
+ toolMockReport: row.toolMockReport ? storage.safelyParseJSON(row.toolMockReport) : null,
4615
4730
  createdAt: storage.ensureDate(row.createdAt)
4616
4731
  };
4617
4732
  }
@@ -4628,6 +4743,8 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4628
4743
  datasetId: input.datasetId ?? null,
4629
4744
  datasetVersion: input.datasetVersion ?? null,
4630
4745
  agentVersion: input.agentVersion ?? null,
4746
+ organizationId: input.organizationId ?? null,
4747
+ projectId: input.projectId ?? null,
4631
4748
  targetType: input.targetType,
4632
4749
  targetId: input.targetId,
4633
4750
  name: input.name ?? null,
@@ -4649,6 +4766,8 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4649
4766
  datasetId: input.datasetId,
4650
4767
  datasetVersion: input.datasetVersion,
4651
4768
  agentVersion: input.agentVersion ?? null,
4769
+ organizationId: input.organizationId ?? null,
4770
+ projectId: input.projectId ?? null,
4652
4771
  targetType: input.targetType,
4653
4772
  targetId: input.targetId,
4654
4773
  name: input.name,
@@ -4791,6 +4910,17 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4791
4910
  conditions.push("status = ?");
4792
4911
  queryParams.push(args.status);
4793
4912
  }
4913
+ if (args.filters) {
4914
+ const { organizationId, projectId } = args.filters;
4915
+ if (organizationId !== void 0) {
4916
+ conditions.push("organizationId = ?");
4917
+ queryParams.push(organizationId);
4918
+ }
4919
+ if (projectId !== void 0) {
4920
+ conditions.push("projectId = ?");
4921
+ queryParams.push(projectId);
4922
+ }
4923
+ }
4794
4924
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
4795
4925
  const countResult = await this.#client.execute({
4796
4926
  sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_EXPERIMENTS} ${whereClause}`,
@@ -4865,6 +4995,8 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4865
4995
  experimentId: input.experimentId,
4866
4996
  itemId: input.itemId,
4867
4997
  itemDatasetVersion: input.itemDatasetVersion ?? null,
4998
+ organizationId: input.organizationId ?? null,
4999
+ projectId: input.projectId ?? null,
4868
5000
  input: input.input,
4869
5001
  output: input.output,
4870
5002
  groundTruth: input.groundTruth,
@@ -4875,6 +5007,7 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4875
5007
  traceId: input.traceId ?? null,
4876
5008
  status: input.status ?? null,
4877
5009
  tags: input.tags !== void 0 && input.tags !== null ? JSON.stringify(input.tags) : null,
5010
+ toolMockReport: input.toolMockReport ?? null,
4878
5011
  createdAt: nowIso
4879
5012
  }
4880
5013
  });
@@ -4883,6 +5016,8 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4883
5016
  experimentId: input.experimentId,
4884
5017
  itemId: input.itemId,
4885
5018
  itemDatasetVersion: input.itemDatasetVersion,
5019
+ organizationId: input.organizationId ?? null,
5020
+ projectId: input.projectId ?? null,
4886
5021
  input: input.input,
4887
5022
  output: input.output,
4888
5023
  groundTruth: input.groundTruth,
@@ -4893,6 +5028,7 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4893
5028
  traceId: input.traceId ?? null,
4894
5029
  status: input.status ?? null,
4895
5030
  tags: input.tags ?? null,
5031
+ toolMockReport: input.toolMockReport ?? null,
4896
5032
  createdAt: now
4897
5033
  };
4898
5034
  } catch (error$1) {
@@ -5001,6 +5137,17 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
5001
5137
  conditions.push("status = ?");
5002
5138
  queryParams.push(args.status);
5003
5139
  }
5140
+ if (args.filters) {
5141
+ const { organizationId, projectId } = args.filters;
5142
+ if (organizationId !== void 0) {
5143
+ conditions.push("organizationId = ?");
5144
+ queryParams.push(organizationId);
5145
+ }
5146
+ if (projectId !== void 0) {
5147
+ conditions.push("projectId = ?");
5148
+ queryParams.push(projectId);
5149
+ }
5150
+ }
5004
5151
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
5005
5152
  const countResult = await this.#client.execute({
5006
5153
  sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_EXPERIMENT_RESULTS} ${whereClause}`,
@@ -6437,12 +6584,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
6437
6584
  await this.#db.createTable({ tableName: storage.TABLE_THREADS, schema: storage.TABLE_SCHEMAS[storage.TABLE_THREADS] });
6438
6585
  await this.#db.createTable({ tableName: storage.TABLE_MESSAGES, schema: storage.TABLE_SCHEMAS[storage.TABLE_MESSAGES] });
6439
6586
  await this.#db.createTable({ tableName: storage.TABLE_RESOURCES, schema: storage.TABLE_SCHEMAS[storage.TABLE_RESOURCES] });
6440
- let omSchema;
6441
- try {
6442
- const { OBSERVATIONAL_MEMORY_TABLE_SCHEMA } = await import('@mastra/core/storage');
6443
- omSchema = OBSERVATIONAL_MEMORY_TABLE_SCHEMA?.[OM_TABLE];
6444
- } catch {
6445
- }
6587
+ const omSchema = storage.OBSERVATIONAL_MEMORY_TABLE_SCHEMA?.[OM_TABLE];
6446
6588
  if (omSchema) {
6447
6589
  await this.#db.createTable({
6448
6590
  tableName: OM_TABLE,