@mastra/spanner 1.4.0 → 1.5.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @mastra/spanner
2
2
 
3
+ ## 1.5.0-alpha.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added persistence for dataset item undeclared tool policies. ([#19643](https://github.com/mastra-ai/mastra/pull/19643))
8
+
9
+ ```typescript
10
+ await dataset.addItem({
11
+ input: 'What is the weather?',
12
+ unmockedToolPolicy: 'deny',
13
+ });
14
+ ```
15
+
16
+ ### Patch Changes
17
+
18
+ - Added a comment column to experiment results so review comments persist. The column is added automatically and non-destructively on startup for existing databases (https://github.com/mastra-ai/mastra/issues/19857). ([#19865](https://github.com/mastra-ai/mastra/pull/19865))
19
+
20
+ - Updated dependencies [[`c5e56ff`](https://github.com/mastra-ai/mastra/commit/c5e56ff3bcabdf062708f2d48744fec304df6792), [`4e35a56`](https://github.com/mastra-ai/mastra/commit/4e35a56cdf8d74a5ff6d5eda01f2c1deaf6cc7be)]:
21
+ - @mastra/core@1.56.0-alpha.1
22
+
3
23
  ## 1.4.0
4
24
 
5
25
  ### Minor Changes
@@ -3,7 +3,7 @@ name: mastra-spanner
3
3
  description: Documentation for @mastra/spanner. Use when working with @mastra/spanner APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/spanner"
6
- version: "1.4.0"
6
+ version: "1.5.0-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.4.0",
2
+ "version": "1.5.0-alpha.0",
3
3
  "package": "@mastra/spanner",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Google Cloud Spanner storage
4
4
 
5
- The Google Cloud Spanner storage implementation provides a horizontally scalable, strongly consistent storage backend for Mastra. It targets the GoogleSQL dialect of Cloud Spanner.
5
+ The Google Cloud Spanner storage implementation provides a horizontally high-capacity, strongly consistent storage backend for Mastra. It targets the GoogleSQL dialect of Cloud Spanner.
6
6
 
7
7
  ## Installation
8
8
 
@@ -133,14 +133,14 @@ The storage adapter creates the following tables, all using the GoogleSQL dialec
133
133
 
134
134
  Tables are created with `STRING(MAX)` for text and JSON payloads, `INT64`, `FLOAT64`, `BOOL`, and `TIMESTAMP`.
135
135
 
136
- Two tables also carry Spanner-specific `STORED` generated columns that the adapter populates from JSON payloads so common filters can use a regular secondary index instead of a `JSON_VALUE` scan:
136
+ The following tables carry Spanner-specific `STORED` generated columns that the adapter populates from JSON payloads so common filters can use a regular secondary index instead of a `JSON_VALUE` scan:
137
137
 
138
- - `mastra_workflow_snapshot.snapshotStatus` extracts `$.status` from `snapshot`; backs `listWorkflowRuns({ status })`.
139
- - `mastra_schedules.target_workflow_id` extracts `$.workflowId` from `target`; backs `listSchedules({ workflowId })`.
138
+ - `mastra_workflow_snapshot.snapshotStatus`: Extracts `$.status` from `snapshot`. Backs `listWorkflowRuns({ status })`.
139
+ - `mastra_schedules.target_workflow_id`: Extracts `$.workflowId` from `target`. Backs `listSchedules({ workflowId })`.
140
140
 
141
141
  Both are added via `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` during `init()` and skipped under `initMode: 'validate'` (where the schema is owned externally). When the column is absent, the adapter falls back to a `JSON_VALUE` filter at runtime.
142
142
 
143
- The adapter doesn't create or use named schemas; use a dedicated database for isolation.
143
+ The adapter doesn't create or use schemas. Use a dedicated database for isolation.
144
144
 
145
145
  ### Initialization
146
146
 
@@ -184,11 +184,11 @@ const thread = await memory?.getThreadById({ threadId: '...' })
184
184
  A few behaviors differ from other relational adapters:
185
185
 
186
186
  - Upserts use `INSERT OR UPDATE`. Spanner doesn't provide a `RETURNING` clause for upserts, so callers needing the post-write state must read it back.
187
- - No `TRUNCATE` exists; `dangerouslyClearAll()` issues `DELETE WHERE TRUE`.
187
+ - No `TRUNCATE` exists. `dangerouslyClearAll()` issues `DELETE WHERE TRUE`.
188
188
  - Identifiers are quoted with backticks.
189
189
  - DDL is applied through `database.updateSchema(...)`, which is asynchronous (long-running operation).
190
190
  - `NULLS FIRST/LAST` isn't supported. Ordering with NULL handling is emulated through an `IS NULL` ordering key.
191
- - JSON containment isn't supported natively. `listTraces` `metadata` and `scope` filters compile to per-key `JSON_VALUE(...) = @v` equality checks, and `tags` filters compile to `EXISTS` over `JSON_QUERY_ARRAY(...)`. This differs from Postgres' `@>` containment operator (which can match nested structure in a single index scan) most one-shot lookups still work but deeply nested structural matches aren't expressible.
191
+ - JSON containment isn't supported natively. `listTraces` `metadata` and `scope` filters compile to per-key `JSON_VALUE(...) = @v` equality checks, and `tags` filters compile to `EXISTS` over `JSON_QUERY_ARRAY(...)`. This differs from Postgres' `@>` containment operator (which can match nested structure in a single index scan): most one-shot lookups still work but deeply nested structural matches aren't expressible.
192
192
 
193
193
  ### Direct database access
194
194
 
@@ -217,4 +217,4 @@ gcloud spanner instances create test-instance --config=emulator-config --nodes=1
217
217
  gcloud spanner databases create test-db --instance=test-instance
218
218
  ```
219
219
 
220
- Then connect with the same env var set in your Node.js process; the `@google-cloud/spanner` client detects the emulator automatically.
220
+ Then connect with the same env var set in your Node.js process. The `@google-cloud/spanner` client detects the emulator automatically.
package/dist/index.cjs CHANGED
@@ -2788,6 +2788,7 @@ function rowToItem(row) {
2788
2788
  groundTruth: t.groundTruth ?? void 0,
2789
2789
  expectedTrajectory: t.expectedTrajectory ?? void 0,
2790
2790
  toolMocks: t.toolMocks ?? void 0,
2791
+ unmockedToolPolicy: t.unmockedToolPolicy ?? void 0,
2791
2792
  requestContext: t.requestContext ?? void 0,
2792
2793
  metadata: t.metadata ?? void 0,
2793
2794
  source: t.source ?? void 0,
@@ -2885,7 +2886,8 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
2885
2886
  ifNotExists: [
2886
2887
  "organizationId",
2887
2888
  "projectId",
2888
- "externalId"
2889
+ "externalId",
2890
+ "unmockedToolPolicy"
2889
2891
  ]
2890
2892
  });
2891
2893
  await this.createDefaultIndexes();
@@ -3350,6 +3352,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3350
3352
  groundTruth: args.groundTruth ?? null,
3351
3353
  expectedTrajectory: args.expectedTrajectory ?? null,
3352
3354
  toolMocks: args.toolMocks ?? null,
3355
+ unmockedToolPolicy: args.unmockedToolPolicy ?? null,
3353
3356
  requestContext: args.requestContext ?? null,
3354
3357
  metadata: args.metadata ?? null,
3355
3358
  source: args.source ?? null,
@@ -3370,6 +3373,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3370
3373
  groundTruth: args.groundTruth,
3371
3374
  expectedTrajectory: args.expectedTrajectory,
3372
3375
  toolMocks: args.toolMocks,
3376
+ unmockedToolPolicy: args.unmockedToolPolicy,
3373
3377
  requestContext: args.requestContext,
3374
3378
  metadata: args.metadata,
3375
3379
  source: args.source,
@@ -3419,6 +3423,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3419
3423
  groundTruth: args.groundTruth !== void 0 ? args.groundTruth : existing.groundTruth,
3420
3424
  expectedTrajectory: args.expectedTrajectory !== void 0 ? args.expectedTrajectory : existing.expectedTrajectory,
3421
3425
  toolMocks: args.toolMocks !== void 0 ? args.toolMocks : existing.toolMocks,
3426
+ unmockedToolPolicy: args.unmockedToolPolicy !== void 0 ? args.unmockedToolPolicy : existing.unmockedToolPolicy,
3422
3427
  requestContext: args.requestContext !== void 0 ? args.requestContext : existing.requestContext,
3423
3428
  metadata: args.metadata !== void 0 ? args.metadata : existing.metadata,
3424
3429
  source: args.source !== void 0 ? args.source : existing.source
@@ -3444,6 +3449,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3444
3449
  groundTruth: merged.groundTruth ?? null,
3445
3450
  expectedTrajectory: merged.expectedTrajectory ?? null,
3446
3451
  toolMocks: merged.toolMocks ?? null,
3452
+ unmockedToolPolicy: merged.unmockedToolPolicy ?? null,
3447
3453
  requestContext: merged.requestContext ?? null,
3448
3454
  metadata: merged.metadata ?? null,
3449
3455
  source: merged.source ?? null,
@@ -3465,6 +3471,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3465
3471
  groundTruth: merged.groundTruth,
3466
3472
  expectedTrajectory: merged.expectedTrajectory,
3467
3473
  toolMocks: merged.toolMocks,
3474
+ unmockedToolPolicy: merged.unmockedToolPolicy,
3468
3475
  requestContext: merged.requestContext,
3469
3476
  metadata: merged.metadata,
3470
3477
  source: merged.source,
@@ -3523,6 +3530,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3523
3530
  groundTruth: existing.groundTruth ?? null,
3524
3531
  expectedTrajectory: existing.expectedTrajectory ?? null,
3525
3532
  toolMocks: existing.toolMocks ?? null,
3533
+ unmockedToolPolicy: existing.unmockedToolPolicy ?? null,
3526
3534
  requestContext: existing.requestContext ?? null,
3527
3535
  metadata: existing.metadata ?? null,
3528
3536
  source: existing.source ?? null,
@@ -3839,6 +3847,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3839
3847
  groundTruth: insert.item.groundTruth,
3840
3848
  expectedTrajectory: insert.item.expectedTrajectory,
3841
3849
  toolMocks: insert.item.toolMocks,
3850
+ unmockedToolPolicy: insert.item.unmockedToolPolicy,
3842
3851
  requestContext: insert.item.requestContext,
3843
3852
  metadata: insert.item.metadata,
3844
3853
  source: insert.item.source,
@@ -3907,6 +3916,7 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3907
3916
  groundTruth: existing.groundTruth ?? null,
3908
3917
  expectedTrajectory: existing.expectedTrajectory ?? null,
3909
3918
  toolMocks: existing.toolMocks ?? null,
3919
+ unmockedToolPolicy: existing.unmockedToolPolicy ?? null,
3910
3920
  requestContext: existing.requestContext ?? null,
3911
3921
  metadata: existing.metadata ?? null,
3912
3922
  source: existing.source ?? null,
@@ -3991,6 +4001,7 @@ function rowToExperimentResult(row) {
3991
4001
  traceId: t.traceId ?? null,
3992
4002
  status: t.status ?? null,
3993
4003
  tags: t.tags ?? null,
4004
+ comment: t.comment ?? null,
3994
4005
  toolMockReport: t.toolMockReport ?? null,
3995
4006
  createdAt: toDate(t.createdAt)
3996
4007
  };
@@ -4035,7 +4046,11 @@ var ExperimentsSpanner = class ExperimentsSpanner extends _mastra_core_storage.E
4035
4046
  await this.db.alterTable({
4036
4047
  tableName: _mastra_core_storage.TABLE_EXPERIMENT_RESULTS,
4037
4048
  schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_EXPERIMENT_RESULTS],
4038
- ifNotExists: ["organizationId", "projectId"]
4049
+ ifNotExists: [
4050
+ "comment",
4051
+ "organizationId",
4052
+ "projectId"
4053
+ ]
4039
4054
  });
4040
4055
  await this.createDefaultIndexes();
4041
4056
  await this.createCustomIndexes();
@@ -4428,7 +4443,7 @@ var ExperimentsSpanner = class ExperimentsSpanner extends _mastra_core_storage.E
4428
4443
  }
4429
4444
  async updateExperimentResult(input) {
4430
4445
  try {
4431
- if (input.status === void 0 && input.tags === void 0) {
4446
+ if (input.status === void 0 && input.tags === void 0 && input.comment === void 0) {
4432
4447
  const existing = await this.getExperimentResultById({ id: input.id });
4433
4448
  if (!existing || input.experimentId !== void 0 && existing.experimentId !== input.experimentId) throw new _mastra_core_error.MastraError({
4434
4449
  id: (0, _mastra_core_storage.createStorageErrorId)("SPANNER", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
@@ -4452,6 +4467,11 @@ var ExperimentsSpanner = class ExperimentsSpanner extends _mastra_core_storage.E
4452
4467
  params.tags = input.tags === null ? null : JSON.stringify(input.tags);
4453
4468
  types.tags = "json";
4454
4469
  }
4470
+ if (input.comment !== void 0) {
4471
+ setClauses.push(`${quoteIdent("comment", "column name")} = @comment`);
4472
+ params.comment = input.comment;
4473
+ if (input.comment === null) types.comment = "string";
4474
+ }
4455
4475
  const whereClauses = [`${quoteIdent("id", "column name")} = @id`];
4456
4476
  if (input.experimentId !== void 0) {
4457
4477
  whereClauses.push(`${quoteIdent("experimentId", "column name")} = @experimentId`);