@mastra/libsql 1.21.1-alpha.0 → 1.21.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 +90 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-rag-retrieval.md +113 -5
- package/dist/index.cjs +108 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +108 -12
- 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 +2 -1
- package/dist/storage/domains/experiments/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,95 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 1.21.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Added HTTP endpoints for caller-driven experiments: `POST /datasets/:datasetId/experiments` now accepts `start: false` to create an experiment without spawning the runner (with an optional target and run-level `scorerIds`), and new routes `POST /datasets/:datasetId/experiments/:experimentId/items/:itemId/run`, `POST /datasets/:datasetId/experiments/:experimentId/results`, and `POST /datasets/:datasetId/experiments/:experimentId/finalize` let external orchestrators run one item server-side, submit externally computed per-item results (idempotent upsert on retries), and finalize the run with server-computed counts. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
8
|
+
|
|
9
|
+
- Fixed concurrent resume() calls on the same suspended workflow run executing downstream steps more than once. A resume now atomically claims the run before executing anything, so only one caller continues a given suspension. Losing callers throw WORKFLOW_RESUME_ALREADY_CLAIMED without running any steps. Fixes #20443 ([#21725](https://github.com/mastra-ai/mastra/pull/21725))
|
|
10
|
+
|
|
11
|
+
- Added `createDatasetExperiment()`, `runExperimentItem()`, `submitExperimentResult()`, and `finalizeExperiment()` methods so a caller-owned orchestrator (for example Temporal) can drive an experiment loop while Mastra either executes each item server-side or ingests externally computed results. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
12
|
+
|
|
13
|
+
- Fixed versioned dataset item lookups to return the item visible in the requested dataset snapshot. ([#21979](https://github.com/mastra-ai/mastra/pull/21979))
|
|
14
|
+
|
|
15
|
+
- Workflow state updates now support an optional expectedStatus guard, so a status change is only applied when the stored run is in an expected state. This is what makes concurrent workflow resumes safe. ([#21725](https://github.com/mastra-ai/mastra/pull/21725))
|
|
16
|
+
|
|
17
|
+
- Added `upsertExperimentResult()` to the experiments storage domain plus an `attempt` column on experiment results and a nullable target with an optional `scorerIds` column on experiments, enabling retry-safe result writes for caller-driven experiments (retried submissions with the same `(experimentId, itemId, attempt)` key converge on a single row). `saveScore()` now accepts an optional caller-supplied `id` and upserts on it, so retried experiment submissions replace their previous score rows (latest wins) instead of accumulating duplicates. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
18
|
+
|
|
19
|
+
- Resume conflicts now return 409 Conflict. When a suspended workflow run has already been resumed by another caller, the resume endpoints respond with 409 instead of a generic error. ([#21725](https://github.com/mastra-ai/mastra/pull/21725))
|
|
20
|
+
|
|
21
|
+
- Added caller-driven experiments so an external orchestrator (for example Temporal workers) can own the experiment loop while Mastra stays the system of record. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
22
|
+
|
|
23
|
+
Create an experiment with `dataset.createExperiment()` (idempotent when you pass your own id). With a target, Mastra runs each item for you: call `dataset.runExperimentItem()` per item and Mastra executes the registered agent or workflow, resolves scorers (experiment `scorers`, falling back to item `scorerIds`, then dataset `scorerIds`), and upserts the result. Without a target, run everything yourself and report per-item results with `dataset.submitExperimentResult()` (upsert semantics on `(experimentId, itemId, attempt)` so retried workers converge on a single row). Either way, close the run with `dataset.finalizeExperiment()` and Mastra computes per-item succeeded/failed/skipped counts from the persisted rows. Results go into the same storage as native runs, so Studio views, comparisons, and review summaries work unchanged.
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// Caller drives the loop, Mastra runs each item
|
|
27
|
+
const { experimentId } = await dataset.createExperiment({
|
|
28
|
+
id: workflowRunId,
|
|
29
|
+
targetType: 'agent',
|
|
30
|
+
targetId: 'support-agent',
|
|
31
|
+
scorers: ['accuracy'],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
await dataset.runExperimentItem({ experimentId, itemId });
|
|
35
|
+
|
|
36
|
+
// Or: caller runs everything, Mastra ingests results
|
|
37
|
+
const ingest = await dataset.createExperiment({ id: workflowRunId });
|
|
38
|
+
await dataset.submitExperimentResult({
|
|
39
|
+
experimentId: ingest.experimentId,
|
|
40
|
+
itemId,
|
|
41
|
+
output,
|
|
42
|
+
scores: [{ scorerId: 'accuracy', score: 0.92 }],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const experiment = await dataset.finalizeExperiment({ experimentId });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Updated dependencies [[`88d14ca`](https://github.com/mastra-ai/mastra/commit/88d14cac008582a618fecc3d5c7fd3bdf4f6ddc3), [`480e491`](https://github.com/mastra-ai/mastra/commit/480e491588bd6a7a1c9ee4407590ad625dd33952), [`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`acc3471`](https://github.com/mastra-ai/mastra/commit/acc3471de5f3fde8027ee4e355af292b2bc1bc30), [`b6a771e`](https://github.com/mastra-ai/mastra/commit/b6a771ef23d203ddb348efca8065eff65def8191), [`84a5b69`](https://github.com/mastra-ai/mastra/commit/84a5b699f84d6bae0a34efe5a970d891090b9f41), [`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`3bb88dd`](https://github.com/mastra-ai/mastra/commit/3bb88ddf07fb98f3cd16d3bff94e51cd3b45d011), [`d23e75d`](https://github.com/mastra-ai/mastra/commit/d23e75d57cc7cf5b9bfdbee896bf5a6a2484fed7), [`c8faa4e`](https://github.com/mastra-ai/mastra/commit/c8faa4e1cfebaec56b65e754e90b9fe46d153359), [`d378d75`](https://github.com/mastra-ai/mastra/commit/d378d7511f71309ed61a8f6b93cd0361dc6cb70f), [`84a5b69`](https://github.com/mastra-ai/mastra/commit/84a5b699f84d6bae0a34efe5a970d891090b9f41), [`26d4016`](https://github.com/mastra-ai/mastra/commit/26d40160ff7f7d8bf95fee2039a52cbc83863533), [`7c60df5`](https://github.com/mastra-ai/mastra/commit/7c60df5c7872343fbac5c3e5b1175c8076a5abfd), [`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`84a5b69`](https://github.com/mastra-ai/mastra/commit/84a5b699f84d6bae0a34efe5a970d891090b9f41), [`f2031a4`](https://github.com/mastra-ai/mastra/commit/f2031a47445e8f67a89ba1309036816f97ab7a65), [`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`cad4208`](https://github.com/mastra-ai/mastra/commit/cad42082e6aa1776168a94914f523334be45d929), [`8e529d4`](https://github.com/mastra-ai/mastra/commit/8e529d4ac754efef04b225841349e0da9edf89a6), [`57c5103`](https://github.com/mastra-ai/mastra/commit/57c51035a2a36e3df3c4f32f46bb789a66ed5946), [`038b7b4`](https://github.com/mastra-ai/mastra/commit/038b7b405cb4ac25ab3f3031334111b1f87ac112), [`4132d61`](https://github.com/mastra-ai/mastra/commit/4132d61f8367077120ee9e6420d3224dffd93c93), [`d378d75`](https://github.com/mastra-ai/mastra/commit/d378d7511f71309ed61a8f6b93cd0361dc6cb70f)]:
|
|
49
|
+
- @mastra/core@1.61.0
|
|
50
|
+
|
|
51
|
+
## 1.21.1-alpha.1
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- Added HTTP endpoints for caller-driven experiments: `POST /datasets/:datasetId/experiments` now accepts `start: false` to create an experiment without spawning the runner (with an optional target and run-level `scorerIds`), and new routes `POST /datasets/:datasetId/experiments/:experimentId/items/:itemId/run`, `POST /datasets/:datasetId/experiments/:experimentId/results`, and `POST /datasets/:datasetId/experiments/:experimentId/finalize` let external orchestrators run one item server-side, submit externally computed per-item results (idempotent upsert on retries), and finalize the run with server-computed counts. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
56
|
+
|
|
57
|
+
- Added `createDatasetExperiment()`, `runExperimentItem()`, `submitExperimentResult()`, and `finalizeExperiment()` methods so a caller-owned orchestrator (for example Temporal) can drive an experiment loop while Mastra either executes each item server-side or ingests externally computed results. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
58
|
+
|
|
59
|
+
- Fixed versioned dataset item lookups to return the item visible in the requested dataset snapshot. ([#21979](https://github.com/mastra-ai/mastra/pull/21979))
|
|
60
|
+
|
|
61
|
+
- Added `upsertExperimentResult()` to the experiments storage domain plus an `attempt` column on experiment results and a nullable target with an optional `scorerIds` column on experiments, enabling retry-safe result writes for caller-driven experiments (retried submissions with the same `(experimentId, itemId, attempt)` key converge on a single row). `saveScore()` now accepts an optional caller-supplied `id` and upserts on it, so retried experiment submissions replace their previous score rows (latest wins) instead of accumulating duplicates. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
62
|
+
|
|
63
|
+
- Added caller-driven experiments so an external orchestrator (for example Temporal workers) can own the experiment loop while Mastra stays the system of record. ([#21888](https://github.com/mastra-ai/mastra/pull/21888))
|
|
64
|
+
|
|
65
|
+
Create an experiment with `dataset.createExperiment()` (idempotent when you pass your own id). With a target, Mastra runs each item for you: call `dataset.runExperimentItem()` per item and Mastra executes the registered agent or workflow, resolves scorers (experiment `scorers`, falling back to item `scorerIds`, then dataset `scorerIds`), and upserts the result. Without a target, run everything yourself and report per-item results with `dataset.submitExperimentResult()` (upsert semantics on `(experimentId, itemId, attempt)` so retried workers converge on a single row). Either way, close the run with `dataset.finalizeExperiment()` and Mastra computes per-item succeeded/failed/skipped counts from the persisted rows. Results go into the same storage as native runs, so Studio views, comparisons, and review summaries work unchanged.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Caller drives the loop, Mastra runs each item
|
|
69
|
+
const { experimentId } = await dataset.createExperiment({
|
|
70
|
+
id: workflowRunId,
|
|
71
|
+
targetType: 'agent',
|
|
72
|
+
targetId: 'support-agent',
|
|
73
|
+
scorers: ['accuracy'],
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await dataset.runExperimentItem({ experimentId, itemId });
|
|
77
|
+
|
|
78
|
+
// Or: caller runs everything, Mastra ingests results
|
|
79
|
+
const ingest = await dataset.createExperiment({ id: workflowRunId });
|
|
80
|
+
await dataset.submitExperimentResult({
|
|
81
|
+
experimentId: ingest.experimentId,
|
|
82
|
+
itemId,
|
|
83
|
+
output,
|
|
84
|
+
scores: [{ scorerId: 'accuracy', score: 0.92 }],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const experiment = await dataset.finalizeExperiment({ experimentId });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- Updated dependencies [[`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`acc3471`](https://github.com/mastra-ai/mastra/commit/acc3471de5f3fde8027ee4e355af292b2bc1bc30), [`b6a771e`](https://github.com/mastra-ai/mastra/commit/b6a771ef23d203ddb348efca8065eff65def8191), [`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`26d4016`](https://github.com/mastra-ai/mastra/commit/26d40160ff7f7d8bf95fee2039a52cbc83863533), [`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`9267e9b`](https://github.com/mastra-ai/mastra/commit/9267e9b3d9c2fcf16936050495a787054c2431ab), [`57c5103`](https://github.com/mastra-ai/mastra/commit/57c51035a2a36e3df3c4f32f46bb789a66ed5946)]:
|
|
91
|
+
- @mastra/core@1.61.0-alpha.3
|
|
92
|
+
|
|
3
93
|
## 1.21.1-alpha.0
|
|
4
94
|
|
|
5
95
|
### Patch Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -77,9 +77,19 @@ For detailed information about available operators and syntax, see the [Metadata
|
|
|
77
77
|
|
|
78
78
|
Basic filtering examples:
|
|
79
79
|
|
|
80
|
+
**MongoDB**:
|
|
81
|
+
|
|
80
82
|
```ts
|
|
83
|
+
import { MongoDBVector } from '@mastra/mongodb'
|
|
84
|
+
|
|
85
|
+
const mongoVector = new MongoDBVector({
|
|
86
|
+
id: 'mongodb-vector',
|
|
87
|
+
uri: process.env.MONGODB_URI,
|
|
88
|
+
dbName: process.env.MONGODB_DB_NAME,
|
|
89
|
+
})
|
|
90
|
+
|
|
81
91
|
// Simple equality filter
|
|
82
|
-
const
|
|
92
|
+
const equalityResults = await mongoVector.query({
|
|
83
93
|
indexName: 'embeddings',
|
|
84
94
|
queryVector: embedding,
|
|
85
95
|
topK: 10,
|
|
@@ -89,7 +99,7 @@ const results = await pgVector.query({
|
|
|
89
99
|
})
|
|
90
100
|
|
|
91
101
|
// Numeric comparison
|
|
92
|
-
const
|
|
102
|
+
const priceResults = await mongoVector.query({
|
|
93
103
|
indexName: 'embeddings',
|
|
94
104
|
queryVector: embedding,
|
|
95
105
|
topK: 10,
|
|
@@ -99,7 +109,7 @@ const results = await pgVector.query({
|
|
|
99
109
|
})
|
|
100
110
|
|
|
101
111
|
// Multiple conditions
|
|
102
|
-
const
|
|
112
|
+
const compoundResults = await mongoVector.query({
|
|
103
113
|
indexName: 'embeddings',
|
|
104
114
|
queryVector: embedding,
|
|
105
115
|
topK: 10,
|
|
@@ -111,7 +121,7 @@ const results = await pgVector.query({
|
|
|
111
121
|
})
|
|
112
122
|
|
|
113
123
|
// Array operations
|
|
114
|
-
const
|
|
124
|
+
const tagResults = await mongoVector.query({
|
|
115
125
|
indexName: 'embeddings',
|
|
116
126
|
queryVector: embedding,
|
|
117
127
|
topK: 10,
|
|
@@ -121,7 +131,64 @@ const results = await pgVector.query({
|
|
|
121
131
|
})
|
|
122
132
|
|
|
123
133
|
// Logical operators
|
|
124
|
-
const
|
|
134
|
+
const categoryResults = await mongoVector.query({
|
|
135
|
+
indexName: 'embeddings',
|
|
136
|
+
queryVector: embedding,
|
|
137
|
+
topK: 10,
|
|
138
|
+
filter: {
|
|
139
|
+
$or: [{ category: 'electronics' }, { category: 'accessories' }],
|
|
140
|
+
$and: [{ price: { $gt: 50 } }, { price: { $lt: 200 } }],
|
|
141
|
+
},
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**pgVector**:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
// Simple equality filter
|
|
149
|
+
const equalityResults = await pgVector.query({
|
|
150
|
+
indexName: 'embeddings',
|
|
151
|
+
queryVector: embedding,
|
|
152
|
+
topK: 10,
|
|
153
|
+
filter: {
|
|
154
|
+
source: 'article1.txt',
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Numeric comparison
|
|
159
|
+
const priceResults = await pgVector.query({
|
|
160
|
+
indexName: 'embeddings',
|
|
161
|
+
queryVector: embedding,
|
|
162
|
+
topK: 10,
|
|
163
|
+
filter: {
|
|
164
|
+
price: { $gt: 100 },
|
|
165
|
+
},
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
// Multiple conditions
|
|
169
|
+
const compoundResults = await pgVector.query({
|
|
170
|
+
indexName: 'embeddings',
|
|
171
|
+
queryVector: embedding,
|
|
172
|
+
topK: 10,
|
|
173
|
+
filter: {
|
|
174
|
+
category: 'electronics',
|
|
175
|
+
price: { $lt: 1000 },
|
|
176
|
+
inStock: true,
|
|
177
|
+
},
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
// Array operations
|
|
181
|
+
const tagResults = await pgVector.query({
|
|
182
|
+
indexName: 'embeddings',
|
|
183
|
+
queryVector: embedding,
|
|
184
|
+
topK: 10,
|
|
185
|
+
filter: {
|
|
186
|
+
tags: { $in: ['sale', 'new'] },
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// Logical operators
|
|
191
|
+
const categoryResults = await pgVector.query({
|
|
125
192
|
indexName: 'embeddings',
|
|
126
193
|
queryVector: embedding,
|
|
127
194
|
topK: 10,
|
|
@@ -141,6 +208,47 @@ Common use cases for metadata filtering:
|
|
|
141
208
|
- Combine multiple conditions for precise querying
|
|
142
209
|
- Filter by document attributes (e.g., language, author)
|
|
143
210
|
|
|
211
|
+
### Where the filter is applied
|
|
212
|
+
|
|
213
|
+
Vector stores differ in _when_ they apply a metadata filter, which affects how filtered queries scale.
|
|
214
|
+
|
|
215
|
+
MongoDB can evaluate the filter inside the vector index itself. This keeps the query on a single round trip to `$vectorSearch`, so it avoids the pre-filter pass that collects matching document IDs and the 16 MB BSON limit that pass is subject to. Declaring the fields you filter on in `filterFields` when you create the index is what enables it:
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
// Declare the metadata fields you want to filter on
|
|
219
|
+
await mongoVector.createIndex({
|
|
220
|
+
indexName: 'embeddings',
|
|
221
|
+
dimension: 1536,
|
|
222
|
+
filterFields: ['source', 'price', 'category', 'inStock', 'tags'],
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
// createIndex() returns before the index finishes building
|
|
226
|
+
await mongoVector.waitForIndexReady({ indexName: 'embeddings' })
|
|
227
|
+
|
|
228
|
+
// The filter is applied during the index search
|
|
229
|
+
const results = await mongoVector.query({
|
|
230
|
+
indexName: 'embeddings',
|
|
231
|
+
queryVector: embedding,
|
|
232
|
+
topK: 10,
|
|
233
|
+
filter: { source: 'article1.txt' },
|
|
234
|
+
})
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Mastra passes the filter to the index only when every field it references is declared in `filterFields` and every operator is one the index accepts: `$and`, `$or`, `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, and `$nin`. A filter that uses an undeclared field or any other operator takes a fallback path: Mastra matches the collection first and passes the matching document IDs into the vector search. That fallback holds only while the ID set fits within MongoDB's 16 MB BSON document limit. On large collections the query fails once that limit is exceeded, so declare your filter fields when you expect selective filters over large data sets.
|
|
238
|
+
|
|
239
|
+
pgVector applies the filter as an ordinary query condition:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const results = await pgVector.query({
|
|
243
|
+
indexName: 'embeddings',
|
|
244
|
+
queryVector: embedding,
|
|
245
|
+
topK: 10,
|
|
246
|
+
filter: { source: 'article1.txt' },
|
|
247
|
+
})
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Postgres vector indexes (HNSW and IVFFlat) can't restrict that search to rows matching a condition. When a filter is present, pgVector instead compares the query vector against every matching row and returns the closest `topK`. Results are exact, but the work grows with the number of rows the filter matches. Indexing the metadata column speeds up row retrieval. The distance comparisons still happen per row.
|
|
251
|
+
|
|
144
252
|
### Vector Query Tool
|
|
145
253
|
|
|
146
254
|
Sometimes you want to give your agent the ability to query a vector database directly. The Vector Query Tool allows your agent to be in charge of retrieval decisions, combining semantic search with optional filtering and reranking based on the agent's understanding of the user's needs.
|
package/dist/index.cjs
CHANGED
|
@@ -4136,8 +4136,12 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
|
4136
4136
|
try {
|
|
4137
4137
|
let result;
|
|
4138
4138
|
if (args.datasetVersion !== void 0) result = await this.#client.execute({
|
|
4139
|
-
sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASET_ITEMS)} FROM ${_mastra_core_storage.TABLE_DATASET_ITEMS} WHERE id = ? AND datasetVersion
|
|
4140
|
-
args: [
|
|
4139
|
+
sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASET_ITEMS)} FROM ${_mastra_core_storage.TABLE_DATASET_ITEMS} WHERE id = ? AND datasetVersion <= ? AND (validTo IS NULL OR validTo > ?) AND isDeleted = 0 ORDER BY datasetVersion DESC LIMIT 1`,
|
|
4140
|
+
args: [
|
|
4141
|
+
args.id,
|
|
4142
|
+
args.datasetVersion,
|
|
4143
|
+
args.datasetVersion
|
|
4144
|
+
]
|
|
4141
4145
|
});
|
|
4142
4146
|
else result = await this.#client.execute({
|
|
4143
4147
|
sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASET_ITEMS)} FROM ${_mastra_core_storage.TABLE_DATASET_ITEMS} WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
|
|
@@ -4601,7 +4605,8 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
4601
4605
|
"experimentSetId",
|
|
4602
4606
|
"comparisonId",
|
|
4603
4607
|
"variantId",
|
|
4604
|
-
"trialIndex"
|
|
4608
|
+
"trialIndex",
|
|
4609
|
+
"scorerIds"
|
|
4605
4610
|
]
|
|
4606
4611
|
});
|
|
4607
4612
|
await this.#db.alterTable({
|
|
@@ -4613,7 +4618,8 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
4613
4618
|
"comment",
|
|
4614
4619
|
"toolMockReport",
|
|
4615
4620
|
"organizationId",
|
|
4616
|
-
"projectId"
|
|
4621
|
+
"projectId",
|
|
4622
|
+
"attempt"
|
|
4617
4623
|
]
|
|
4618
4624
|
});
|
|
4619
4625
|
await this.#client.batch([
|
|
@@ -4630,7 +4636,11 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
4630
4636
|
args: []
|
|
4631
4637
|
},
|
|
4632
4638
|
{
|
|
4633
|
-
sql: `
|
|
4639
|
+
sql: `DROP INDEX IF EXISTS idx_experiment_results_exp_item`,
|
|
4640
|
+
args: []
|
|
4641
|
+
},
|
|
4642
|
+
{
|
|
4643
|
+
sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_experiment_results_exp_item_attempt ON "${_mastra_core_storage.TABLE_EXPERIMENT_RESULTS}" ("experimentId", "itemId", "attempt")`,
|
|
4634
4644
|
args: []
|
|
4635
4645
|
},
|
|
4636
4646
|
{
|
|
@@ -4719,8 +4729,9 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
4719
4729
|
agentVersion: row.agentVersion ?? null,
|
|
4720
4730
|
organizationId: row.organizationId ?? null,
|
|
4721
4731
|
projectId: row.projectId ?? null,
|
|
4722
|
-
targetType: row.targetType,
|
|
4723
|
-
targetId: row.targetId,
|
|
4732
|
+
targetType: row.targetType ?? null,
|
|
4733
|
+
targetId: row.targetId ?? null,
|
|
4734
|
+
scorerIds: row.scorerIds ? (0, _mastra_core_storage.safelyParseJSON)(row.scorerIds) : null,
|
|
4724
4735
|
name: row.name ?? void 0,
|
|
4725
4736
|
description: row.description ?? void 0,
|
|
4726
4737
|
metadata: row.metadata ? (0, _mastra_core_storage.safelyParseJSON)(row.metadata) : void 0,
|
|
@@ -4756,6 +4767,7 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
4756
4767
|
startedAt: (0, _mastra_core_storage.ensureDate)(row.startedAt),
|
|
4757
4768
|
completedAt: (0, _mastra_core_storage.ensureDate)(row.completedAt),
|
|
4758
4769
|
retryCount: row.retryCount,
|
|
4770
|
+
attempt: row.attempt != null ? Number(row.attempt) : 0,
|
|
4759
4771
|
traceId: row.traceId ?? null,
|
|
4760
4772
|
status: row.status ?? null,
|
|
4761
4773
|
tags: row.tags ? (0, _mastra_core_storage.safelyParseJSON)(row.tags) : null,
|
|
@@ -4778,8 +4790,9 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
4778
4790
|
agentVersion: input.agentVersion ?? null,
|
|
4779
4791
|
organizationId: input.organizationId ?? null,
|
|
4780
4792
|
projectId: input.projectId ?? null,
|
|
4781
|
-
targetType: input.targetType,
|
|
4782
|
-
targetId: input.targetId,
|
|
4793
|
+
targetType: input.targetType ?? null,
|
|
4794
|
+
targetId: input.targetId ?? null,
|
|
4795
|
+
scorerIds: input.scorerIds ?? null,
|
|
4783
4796
|
name: input.name ?? null,
|
|
4784
4797
|
description: input.description ?? null,
|
|
4785
4798
|
metadata: input.metadata ?? null,
|
|
@@ -4807,8 +4820,9 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
4807
4820
|
agentVersion: input.agentVersion ?? null,
|
|
4808
4821
|
organizationId: input.organizationId ?? null,
|
|
4809
4822
|
projectId: input.projectId ?? null,
|
|
4810
|
-
targetType: input.targetType,
|
|
4811
|
-
targetId: input.targetId,
|
|
4823
|
+
targetType: input.targetType ?? null,
|
|
4824
|
+
targetId: input.targetId ?? null,
|
|
4825
|
+
scorerIds: input.scorerIds ?? null,
|
|
4812
4826
|
name: input.name,
|
|
4813
4827
|
description: input.description,
|
|
4814
4828
|
metadata: input.metadata,
|
|
@@ -5055,6 +5069,7 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
5055
5069
|
startedAt: input.startedAt.toISOString(),
|
|
5056
5070
|
completedAt: input.completedAt.toISOString(),
|
|
5057
5071
|
retryCount: input.retryCount,
|
|
5072
|
+
attempt: input.attempt ?? 0,
|
|
5058
5073
|
traceId: input.traceId ?? null,
|
|
5059
5074
|
status: input.status ?? null,
|
|
5060
5075
|
tags: input.tags !== void 0 && input.tags !== null ? JSON.stringify(input.tags) : null,
|
|
@@ -5076,6 +5091,7 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
5076
5091
|
startedAt: input.startedAt,
|
|
5077
5092
|
completedAt: input.completedAt,
|
|
5078
5093
|
retryCount: input.retryCount,
|
|
5094
|
+
attempt: input.attempt ?? 0,
|
|
5079
5095
|
traceId: input.traceId ?? null,
|
|
5080
5096
|
status: input.status ?? null,
|
|
5081
5097
|
tags: input.tags ?? null,
|
|
@@ -5090,6 +5106,81 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
|
|
|
5090
5106
|
}, error);
|
|
5091
5107
|
}
|
|
5092
5108
|
}
|
|
5109
|
+
async upsertExperimentResult(input) {
|
|
5110
|
+
try {
|
|
5111
|
+
const attempt = input.attempt ?? 0;
|
|
5112
|
+
let existingId = (await this.#client.execute({
|
|
5113
|
+
sql: `SELECT "id" FROM ${_mastra_core_storage.TABLE_EXPERIMENT_RESULTS} WHERE "experimentId" = ? AND "itemId" = ? AND COALESCE("attempt", 0) = ?`,
|
|
5114
|
+
args: [
|
|
5115
|
+
input.experimentId,
|
|
5116
|
+
input.itemId,
|
|
5117
|
+
attempt
|
|
5118
|
+
]
|
|
5119
|
+
})).rows[0]?.id;
|
|
5120
|
+
if (!existingId) try {
|
|
5121
|
+
return await this.addExperimentResult({
|
|
5122
|
+
...input,
|
|
5123
|
+
attempt
|
|
5124
|
+
});
|
|
5125
|
+
} catch (insertError) {
|
|
5126
|
+
if (!(0, _mastra_core_storage.hasErrorCode)(insertError, /* @__PURE__ */ new Set([
|
|
5127
|
+
"SQLITE_CONSTRAINT",
|
|
5128
|
+
"SQLITE_CONSTRAINT_PRIMARYKEY",
|
|
5129
|
+
"SQLITE_CONSTRAINT_UNIQUE"
|
|
5130
|
+
]))) throw insertError;
|
|
5131
|
+
existingId = (await this.#client.execute({
|
|
5132
|
+
sql: `SELECT "id" FROM ${_mastra_core_storage.TABLE_EXPERIMENT_RESULTS} WHERE "experimentId" = ? AND "itemId" = ? AND COALESCE("attempt", 0) = ?`,
|
|
5133
|
+
args: [
|
|
5134
|
+
input.experimentId,
|
|
5135
|
+
input.itemId,
|
|
5136
|
+
attempt
|
|
5137
|
+
]
|
|
5138
|
+
})).rows[0]?.id;
|
|
5139
|
+
if (!existingId) throw insertError;
|
|
5140
|
+
}
|
|
5141
|
+
await this.#client.execute({
|
|
5142
|
+
sql: `UPDATE ${_mastra_core_storage.TABLE_EXPERIMENT_RESULTS} SET
|
|
5143
|
+
"itemDatasetVersion" = ?, "organizationId" = ?, "projectId" = ?,
|
|
5144
|
+
"input" = ?, "output" = ?, "groundTruth" = ?, "error" = ?,
|
|
5145
|
+
"startedAt" = ?, "completedAt" = ?, "retryCount" = ?, "attempt" = ?,
|
|
5146
|
+
"traceId" = ?, "status" = ?, "tags" = ?, "toolMockReport" = ?
|
|
5147
|
+
WHERE "id" = ?`,
|
|
5148
|
+
args: [
|
|
5149
|
+
input.itemDatasetVersion ?? null,
|
|
5150
|
+
input.organizationId ?? null,
|
|
5151
|
+
input.projectId ?? null,
|
|
5152
|
+
JSON.stringify(input.input),
|
|
5153
|
+
input.output != null ? JSON.stringify(input.output) : null,
|
|
5154
|
+
input.groundTruth != null ? JSON.stringify(input.groundTruth) : null,
|
|
5155
|
+
input.error != null ? JSON.stringify(input.error) : null,
|
|
5156
|
+
input.startedAt.toISOString(),
|
|
5157
|
+
input.completedAt.toISOString(),
|
|
5158
|
+
input.retryCount,
|
|
5159
|
+
attempt,
|
|
5160
|
+
input.traceId ?? null,
|
|
5161
|
+
input.status ?? null,
|
|
5162
|
+
input.tags != null ? JSON.stringify(input.tags) : null,
|
|
5163
|
+
input.toolMockReport != null ? JSON.stringify(input.toolMockReport) : null,
|
|
5164
|
+
existingId
|
|
5165
|
+
]
|
|
5166
|
+
});
|
|
5167
|
+
const result = await this.getExperimentResultById({ id: existingId });
|
|
5168
|
+
if (!result) throw new _mastra_core_error.MastraError({
|
|
5169
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("LIBSQL", "UPSERT_EXPERIMENT_RESULT", "NOT_FOUND"),
|
|
5170
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
5171
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
5172
|
+
details: { resultId: existingId }
|
|
5173
|
+
});
|
|
5174
|
+
return result;
|
|
5175
|
+
} catch (error) {
|
|
5176
|
+
if (error instanceof _mastra_core_error.MastraError) throw error;
|
|
5177
|
+
throw new _mastra_core_error.MastraError({
|
|
5178
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("LIBSQL", "UPSERT_EXPERIMENT_RESULT", "FAILED"),
|
|
5179
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
5180
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY
|
|
5181
|
+
}, error);
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
5093
5184
|
async updateExperimentResult(input) {
|
|
5094
5185
|
try {
|
|
5095
5186
|
const setClauses = [];
|
|
@@ -11609,8 +11700,13 @@ var ScoresLibSQL = class ScoresLibSQL extends _mastra_core_storage.ScoresStorage
|
|
|
11609
11700
|
}, error);
|
|
11610
11701
|
}
|
|
11611
11702
|
try {
|
|
11612
|
-
const
|
|
11703
|
+
const suppliedId = parsedScore.id;
|
|
11704
|
+
const id = suppliedId ?? crypto.randomUUID();
|
|
11613
11705
|
const now = /* @__PURE__ */ new Date();
|
|
11706
|
+
if (suppliedId) await this.#client.execute({
|
|
11707
|
+
sql: `DELETE FROM ${_mastra_core_storage.TABLE_SCORERS} WHERE id = ?`,
|
|
11708
|
+
args: [suppliedId]
|
|
11709
|
+
});
|
|
11614
11710
|
await this.#db.insert({
|
|
11615
11711
|
tableName: _mastra_core_storage.TABLE_SCORERS,
|
|
11616
11712
|
record: {
|