@mastra/libsql 1.16.0-alpha.0 → 1.16.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 +54 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-overview.md +4 -4
- package/dist/index.cjs +123 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +124 -69
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +5 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/datasets/index.d.ts.map +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 1.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added atomic caller-defined dataset IDs for idempotent dataset creation across built-in storage adapters. Supplying `id` to `mastra.datasets.create()` now creates the dataset once and resolves compatible retries to the persisted record; incompatible immutable identity fields throw `DATASET_ID_CONFLICT`. ([#19370](https://github.com/mastra-ai/mastra/pull/19370))
|
|
8
|
+
|
|
9
|
+
- Added `LibSQLVector.close()` to release the underlying libsql client. For local file databases it checkpoints the WAL and switches back to `journal_mode=DELETE` before closing (mirroring `LibSQLStore.close()`), so the `-wal`/`-shm` sidecar files and OS handles are released promptly. Safe to call more than once. ([#19059](https://github.com/mastra-ai/mastra/pull/19059))
|
|
10
|
+
|
|
11
|
+
- Added caller-defined dataset item identities for safe retries across all dataset storage adapters. ([#19384](https://github.com/mastra-ai/mastra/pull/19384))
|
|
12
|
+
|
|
13
|
+
Dataset items can now include an `externalId` when calling `addItem` or `addItems`:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
await dataset.addItem({
|
|
17
|
+
externalId: 'source-item-123',
|
|
18
|
+
input: { prompt: 'Hello' },
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Retrying with the same identity and payload returns the existing item. Reusing an identity with different content returns a typed conflict, including during concurrent writes. Updates and deletes preserve the identity, Spanner retries transactions without changing the outcome, and MySQL batch writes now preserve every supported dataset item field.
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Raised the `@mastra/core` peer dependency floor to `>=1.51.0-0` so the dataset item identity helpers used by the storage adapters are available at runtime. ([#19384](https://github.com/mastra-ai/mastra/pull/19384))
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [[`bd6d240`](https://github.com/mastra-ai/mastra/commit/bd6d2402db93dddaef0721667e7e8a030e7c6e16), [`0111486`](https://github.com/mastra-ai/mastra/commit/01114867612593eef5cfa2fda6a1194dfedda841), [`96a3749`](https://github.com/mastra-ai/mastra/commit/96a37492235f5b8076b3e3177d83ed5a5e44a640), [`fe1bda0`](https://github.com/mastra-ai/mastra/commit/fe1bda06f6af92a694a51712db747cda1e7185f0), [`25e7c12`](https://github.com/mastra-ai/mastra/commit/25e7c126a770069ae7fb7ecf1d2adb40e017b009), [`1ce5121`](https://github.com/mastra-ai/mastra/commit/1ce512155d122bb21f47d98383e82ffbf84b39e8), [`fb8aea3`](https://github.com/mastra-ai/mastra/commit/fb8aea384291e77311be3a64ee1717320d5c3c73), [`4adc391`](https://github.com/mastra-ai/mastra/commit/4adc3911075249c352bb4832d2471922826344de), [`a5c6337`](https://github.com/mastra-ai/mastra/commit/a5c6337d23c7686c81a32ce62f550f610543a240), [`3cfc47a`](https://github.com/mastra-ai/mastra/commit/3cfc47a6b89940aadd0f46fb01ae9624a73a865d), [`2bb7817`](https://github.com/mastra-ai/mastra/commit/2bb78176112fde628483de2830528f7eee911e56), [`51d9870`](https://github.com/mastra-ai/mastra/commit/51d987032c689c2855374d0f244f5d654da809d1), [`5cab274`](https://github.com/mastra-ai/mastra/commit/5cab2744250e22d12fefa7b32637dce224233cee), [`7fa27d3`](https://github.com/mastra-ai/mastra/commit/7fa27d3b6f5ed68cd34e454a4d3ad9c482a0cfbc), [`8b97958`](https://github.com/mastra-ai/mastra/commit/8b979589f9aa59ba67cac565949475f2ffeb4ac3), [`8410541`](https://github.com/mastra-ai/mastra/commit/84105412c60ecd3bb33a9838146f59c4b588228f), [`a58dcbb`](https://github.com/mastra-ai/mastra/commit/a58dcbb546d7e1d65ebdc1f39e55f0908fcd9391), [`aa38805`](https://github.com/mastra-ai/mastra/commit/aa38805b878b827403be785eb90688d7172f5a40), [`153bd3b`](https://github.com/mastra-ai/mastra/commit/153bd3b396bdfed6b74cf43de12db8fd2d83c04a), [`45a8e65`](https://github.com/mastra-ai/mastra/commit/45a8e65e1556d1362cb3f25187023c36de26661d), [`e955965`](https://github.com/mastra-ai/mastra/commit/e955965dce575a903e37cf054d28ea99aa48785e), [`2d22570`](https://github.com/mastra-ai/mastra/commit/2d22570c7dfdd02123d0ecc529efb05ccba2d9fc), [`07bb863`](https://github.com/mastra-ai/mastra/commit/07bb8631919c6f7cf377dccd45b096e0f17fbed0), [`c8ed116`](https://github.com/mastra-ai/mastra/commit/c8ed11699f62bcac70102ab4ec84d80d20541da6), [`01b338c`](https://github.com/mastra-ai/mastra/commit/01b338c56271f0219606710e3e8b26dee27ac6c2), [`a99eae8`](https://github.com/mastra-ai/mastra/commit/a99eae8908e500c1b2d12f9d277be616b98617a5), [`860ef7e`](https://github.com/mastra-ai/mastra/commit/860ef7e77d92b63469cbe5857aa1e626197e43e9), [`17e818c`](https://github.com/mastra-ai/mastra/commit/17e818c51a958ba90641b1a959dc38faf8c034e9), [`edce8d2`](https://github.com/mastra-ai/mastra/commit/edce8d2769f19e27a05737c627af2d765472a4f8), [`8a586ec`](https://github.com/mastra-ai/mastra/commit/8a586eca9a4914f31dff6140d0d45ac375b00669), [`4451dfe`](https://github.com/mastra-ai/mastra/commit/4451dfe857428e7abcc0261a507a2e186dae6d47), [`8b7361d`](https://github.com/mastra-ai/mastra/commit/8b7361d35de68b80d05d30a74e0c69e7218fd612), [`1d39058`](https://github.com/mastra-ai/mastra/commit/1d39058e548efd691799985d5c8af2737f1c3bd2), [`3927473`](https://github.com/mastra-ai/mastra/commit/392747323ddb10c643d12be7b9ae913159dfaeed), [`dce50dc`](https://github.com/mastra-ai/mastra/commit/dce50dc9a1c1fcd0f427bb5f6250ec74910cb04b), [`fd13f8e`](https://github.com/mastra-ai/mastra/commit/fd13f8e21990f9904c3eedba3a626bb4a929cdb8), [`634caff`](https://github.com/mastra-ai/mastra/commit/634caff29a9200ad058b67d53f96d9e5832fb8a2), [`f703f87`](https://github.com/mastra-ai/mastra/commit/f703f878de072d51fda557f9c50867d8252bef05), [`3e26c87`](https://github.com/mastra-ai/mastra/commit/3e26c87de0c5bc2583b795ce6ca5889b6b161acb), [`33f2b88`](https://github.com/mastra-ai/mastra/commit/33f2b88842c09a567f906fac4cb61cd5277ced59), [`177010f`](https://github.com/mastra-ai/mastra/commit/177010ff096d2e4b28d89803be5b1a4cad2a0d6b), [`0ad646f`](https://github.com/mastra-ai/mastra/commit/0ad646f71a530f2454664299e5e01bfd13fa12e5), [`b486abf`](https://github.com/mastra-ai/mastra/commit/b486abfa2a7528c6f527e4015c819ea9fa54aaad), [`54a51e0`](https://github.com/mastra-ai/mastra/commit/54a51e0a484fe1ebad3fb1f7ef5282a075709eb7), [`c43f3a9`](https://github.com/mastra-ai/mastra/commit/c43f3a9d1efde99b38789364ba4d0ba670f430e3), [`a5008f2`](https://github.com/mastra-ai/mastra/commit/a5008f22ae710ad9402ea9f2547d8c02f74d384b), [`e2d5f37`](https://github.com/mastra-ai/mastra/commit/e2d5f373bd289be534d5f8694d34465010533df6), [`4ce0163`](https://github.com/mastra-ai/mastra/commit/4ce0163dc86e675a86809685c8ce6c49f1aeb87e), [`4378341`](https://github.com/mastra-ai/mastra/commit/43783412df5ea3dd35f5b1f6e4851e79c346fc89)]:
|
|
29
|
+
- @mastra/core@1.51.0
|
|
30
|
+
|
|
31
|
+
## 1.16.0-alpha.1
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- Added atomic caller-defined dataset IDs for idempotent dataset creation across built-in storage adapters. Supplying `id` to `mastra.datasets.create()` now creates the dataset once and resolves compatible retries to the persisted record; incompatible immutable identity fields throw `DATASET_ID_CONFLICT`. ([#19370](https://github.com/mastra-ai/mastra/pull/19370))
|
|
36
|
+
|
|
37
|
+
- Added caller-defined dataset item identities for safe retries across all dataset storage adapters. ([#19384](https://github.com/mastra-ai/mastra/pull/19384))
|
|
38
|
+
|
|
39
|
+
Dataset items can now include an `externalId` when calling `addItem` or `addItems`:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
await dataset.addItem({
|
|
43
|
+
externalId: 'source-item-123',
|
|
44
|
+
input: { prompt: 'Hello' },
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Retrying with the same identity and payload returns the existing item. Reusing an identity with different content returns a typed conflict, including during concurrent writes. Updates and deletes preserve the identity, Spanner retries transactions without changing the outcome, and MySQL batch writes now preserve every supported dataset item field.
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Raised the `@mastra/core` peer dependency floor to `>=1.51.0-0` so the dataset item identity helpers used by the storage adapters are available at runtime. ([#19384](https://github.com/mastra-ai/mastra/pull/19384))
|
|
53
|
+
|
|
54
|
+
- Updated dependencies [[`a99eae8`](https://github.com/mastra-ai/mastra/commit/a99eae8908e500c1b2d12f9d277be616b98617a5), [`fd13f8e`](https://github.com/mastra-ai/mastra/commit/fd13f8e21990f9904c3eedba3a626bb4a929cdb8), [`f703f87`](https://github.com/mastra-ai/mastra/commit/f703f878de072d51fda557f9c50867d8252bef05), [`0ad646f`](https://github.com/mastra-ai/mastra/commit/0ad646f71a530f2454664299e5e01bfd13fa12e5)]:
|
|
55
|
+
- @mastra/core@1.51.0-alpha.13
|
|
56
|
+
|
|
3
57
|
## 1.16.0-alpha.0
|
|
4
58
|
|
|
5
59
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -77,7 +77,7 @@ Use memory when your agent needs to maintain multi-turn conversations that refer
|
|
|
77
77
|
bun add @mastra/libsql@latest
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
For more details on available providers and how storage works in Mastra, visit the [storage](https://mastra.ai/docs/storage/overview) documentation.
|
|
81
81
|
|
|
82
82
|
3. Add the storage provider to your main Mastra instance to enable memory across all configured agents.
|
|
83
83
|
|
|
@@ -110,7 +110,7 @@ Use memory when your agent needs to maintain multi-turn conversations that refer
|
|
|
110
110
|
})
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
Visit [Memory Class](https://mastra.ai/reference/memory/memory-class) for a full list of configuration options.
|
|
114
114
|
|
|
115
115
|
5. Call your agent, for example in [Studio](https://mastra.ai/docs/studio/overview). Inside Studio, start a new chat with your agent and take a look at the right sidebar. It'll now display various memory-related information.
|
|
116
116
|
|
|
@@ -166,7 +166,7 @@ export const memoryAgent = new Agent({
|
|
|
166
166
|
})
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
See [Observational Memory](https://mastra.ai/docs/memory/observational-memory) for details on how observations and reflections work, and [the reference](https://mastra.ai/reference/memory/observational-memory) for all configuration options.
|
|
170
170
|
|
|
171
171
|
## Memory in multi-agent systems
|
|
172
172
|
|
|
@@ -238,7 +238,7 @@ export const memoryAgent = new Agent({
|
|
|
238
238
|
})
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
Visit [Request Context](https://mastra.ai/docs/server/request-context) for more information.
|
|
242
242
|
|
|
243
243
|
## Related
|
|
244
244
|
|
package/dist/index.cjs
CHANGED
|
@@ -1597,6 +1597,19 @@ var LibSQLDB = class extends base.MastraBase {
|
|
|
1597
1597
|
insert(args) {
|
|
1598
1598
|
return this.executeWriteOperationWithRetry(() => this.doInsert(args), `insert into table ${args.tableName}`);
|
|
1599
1599
|
}
|
|
1600
|
+
/** Inserts a record without replacing an existing primary key. */
|
|
1601
|
+
insertOnly(args) {
|
|
1602
|
+
return this.executeWriteOperationWithRetry(async () => {
|
|
1603
|
+
const filteredRecord = await this.filterRecordToKnownColumns(args.tableName, args.record);
|
|
1604
|
+
if (Object.keys(filteredRecord).length === 0) return;
|
|
1605
|
+
const statement = prepareStatement({ tableName: args.tableName, record: filteredRecord });
|
|
1606
|
+
if (!statement.sql.startsWith("INSERT OR REPLACE")) {
|
|
1607
|
+
throw new Error(`Unexpected insert statement generated for table ${args.tableName}`);
|
|
1608
|
+
}
|
|
1609
|
+
statement.sql = statement.sql.replace("INSERT OR REPLACE", "INSERT");
|
|
1610
|
+
await withClientWriteLock(this.client, () => this.client.execute(statement));
|
|
1611
|
+
}, `insert into table ${args.tableName}`);
|
|
1612
|
+
}
|
|
1600
1613
|
/**
|
|
1601
1614
|
* Internal update implementation without retry logic.
|
|
1602
1615
|
*/
|
|
@@ -3906,6 +3919,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
3906
3919
|
await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "organizationId", "TEXT");
|
|
3907
3920
|
await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "projectId", "TEXT");
|
|
3908
3921
|
await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "toolMocks", "TEXT");
|
|
3922
|
+
await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "externalId", "TEXT");
|
|
3909
3923
|
await this.#client.batch(
|
|
3910
3924
|
[
|
|
3911
3925
|
{
|
|
@@ -3916,6 +3930,10 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
3916
3930
|
sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_version ON "${storage.TABLE_DATASET_ITEMS}" ("datasetId", "datasetVersion")`,
|
|
3917
3931
|
args: []
|
|
3918
3932
|
},
|
|
3933
|
+
{
|
|
3934
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_externalid_version ON "${storage.TABLE_DATASET_ITEMS}" ("datasetId", "externalId", "datasetVersion")`,
|
|
3935
|
+
args: []
|
|
3936
|
+
},
|
|
3919
3937
|
{
|
|
3920
3938
|
sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto_deleted ON "${storage.TABLE_DATASET_ITEMS}" ("datasetId", "validTo", "isDeleted")`,
|
|
3921
3939
|
args: []
|
|
@@ -3995,6 +4013,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
3995
4013
|
id: row.id,
|
|
3996
4014
|
datasetId: row.datasetId,
|
|
3997
4015
|
datasetVersion: row.datasetVersion,
|
|
4016
|
+
externalId: row.externalId ?? null,
|
|
3998
4017
|
organizationId: row.organizationId ?? null,
|
|
3999
4018
|
projectId: row.projectId ?? null,
|
|
4000
4019
|
input: storage.safelyParseJSON(row.input),
|
|
@@ -4013,6 +4032,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4013
4032
|
id: row.id,
|
|
4014
4033
|
datasetId: row.datasetId,
|
|
4015
4034
|
datasetVersion: row.datasetVersion,
|
|
4035
|
+
externalId: row.externalId ?? null,
|
|
4016
4036
|
organizationId: row.organizationId ?? null,
|
|
4017
4037
|
projectId: row.projectId ?? null,
|
|
4018
4038
|
validTo: row.validTo,
|
|
@@ -4039,10 +4059,11 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4039
4059
|
// --- Dataset CRUD ---
|
|
4040
4060
|
async createDataset(input) {
|
|
4041
4061
|
try {
|
|
4042
|
-
const id = crypto.randomUUID();
|
|
4062
|
+
const id = input.id ?? crypto.randomUUID();
|
|
4063
|
+
if (input.id !== void 0) this.validateCallerDefinedDatasetId(input.id);
|
|
4043
4064
|
const now = /* @__PURE__ */ new Date();
|
|
4044
4065
|
const nowIso = now.toISOString();
|
|
4045
|
-
await this.#db.
|
|
4066
|
+
await this.#db.insertOnly({
|
|
4046
4067
|
tableName: storage.TABLE_DATASETS,
|
|
4047
4068
|
record: {
|
|
4048
4069
|
id,
|
|
@@ -4084,6 +4105,11 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4084
4105
|
updatedAt: now
|
|
4085
4106
|
};
|
|
4086
4107
|
} catch (error$1) {
|
|
4108
|
+
if (input.id !== void 0 && storage.hasErrorCode(error$1, /* @__PURE__ */ new Set(["SQLITE_CONSTRAINT", "SQLITE_CONSTRAINT_PRIMARYKEY", "SQLITE_CONSTRAINT_UNIQUE"]))) {
|
|
4109
|
+
const existing = await this.getDatasetById({ id: input.id });
|
|
4110
|
+
if (existing) return this.resolveExistingDataset(existing, { ...input, id: input.id });
|
|
4111
|
+
}
|
|
4112
|
+
if (error$1 instanceof error.MastraError) throw error$1;
|
|
4087
4113
|
throw new error.MastraError(
|
|
4088
4114
|
{
|
|
4089
4115
|
id: storage.createStorageErrorId("LIBSQL", "CREATE_DATASET", "FAILED"),
|
|
@@ -4329,11 +4355,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4329
4355
|
args: [args.datasetId]
|
|
4330
4356
|
},
|
|
4331
4357
|
{
|
|
4332
|
-
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(?), ?, ?)`,
|
|
4358
|
+
sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, externalId, 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(?), ?, ?)`,
|
|
4333
4359
|
args: [
|
|
4334
4360
|
id,
|
|
4335
4361
|
args.datasetId,
|
|
4336
4362
|
args.datasetId,
|
|
4363
|
+
args.externalId ?? null,
|
|
4337
4364
|
args.datasetId,
|
|
4338
4365
|
args.datasetId,
|
|
4339
4366
|
jsonbArg(args.input),
|
|
@@ -4359,6 +4386,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4359
4386
|
id,
|
|
4360
4387
|
datasetId: args.datasetId,
|
|
4361
4388
|
datasetVersion: newVersion,
|
|
4389
|
+
externalId: args.externalId ?? null,
|
|
4362
4390
|
organizationId: dataset?.organizationId ?? null,
|
|
4363
4391
|
projectId: dataset?.projectId ?? null,
|
|
4364
4392
|
input: args.input,
|
|
@@ -4424,11 +4452,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4424
4452
|
args: [args.datasetId, args.id]
|
|
4425
4453
|
},
|
|
4426
4454
|
{
|
|
4427
|
-
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(?), ?, ?)`,
|
|
4455
|
+
sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, externalId, 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(?), ?, ?)`,
|
|
4428
4456
|
args: [
|
|
4429
4457
|
args.id,
|
|
4430
4458
|
args.datasetId,
|
|
4431
4459
|
args.datasetId,
|
|
4460
|
+
existing.externalId ?? null,
|
|
4432
4461
|
args.datasetId,
|
|
4433
4462
|
args.datasetId,
|
|
4434
4463
|
jsonbArg(mergedInput),
|
|
@@ -4501,11 +4530,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4501
4530
|
args: [datasetId, id]
|
|
4502
4531
|
},
|
|
4503
4532
|
{
|
|
4504
|
-
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(?), ?, ?)`,
|
|
4533
|
+
sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, externalId, 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(?), ?, ?)`,
|
|
4505
4534
|
args: [
|
|
4506
4535
|
id,
|
|
4507
4536
|
datasetId,
|
|
4508
4537
|
datasetId,
|
|
4538
|
+
existing.externalId ?? null,
|
|
4509
4539
|
datasetId,
|
|
4510
4540
|
datasetId,
|
|
4511
4541
|
jsonbArg(existing.input),
|
|
@@ -4787,70 +4817,94 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4787
4817
|
// --- Bulk operations (SCD-2 internally) ---
|
|
4788
4818
|
async _doBatchInsertItems(input) {
|
|
4789
4819
|
try {
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4820
|
+
if (input.items.length === 0) return [];
|
|
4821
|
+
return await withClientWriteLock(this.#client, async () => {
|
|
4822
|
+
const tx = await this.#client.transaction("write");
|
|
4823
|
+
try {
|
|
4824
|
+
const datasetResult = await tx.execute({
|
|
4825
|
+
sql: `SELECT version, organizationId, projectId FROM ${storage.TABLE_DATASETS} WHERE id = ?`,
|
|
4826
|
+
args: [input.datasetId]
|
|
4827
|
+
});
|
|
4828
|
+
const dataset = datasetResult.rows[0];
|
|
4829
|
+
if (!dataset)
|
|
4830
|
+
throw new error.MastraError({
|
|
4831
|
+
id: storage.createStorageErrorId("LIBSQL", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
|
|
4832
|
+
domain: error.ErrorDomain.STORAGE,
|
|
4833
|
+
category: error.ErrorCategory.USER,
|
|
4834
|
+
details: { datasetId: input.datasetId }
|
|
4835
|
+
});
|
|
4836
|
+
const externalIds = [...new Set(input.items.flatMap((item) => item.externalId ? [item.externalId] : []))];
|
|
4837
|
+
const historyResult = externalIds.length ? await tx.execute({
|
|
4838
|
+
sql: `SELECT id, datasetId, datasetVersion, externalId, organizationId, projectId, validTo, isDeleted, json(input) AS input, json(groundTruth) AS groundTruth, json(expectedTrajectory) AS expectedTrajectory, json(toolMocks) AS toolMocks, json(requestContext) AS requestContext, json(metadata) AS metadata, json(source) AS source, createdAt, updatedAt FROM ${storage.TABLE_DATASET_ITEMS} WHERE datasetId = ? AND externalId IN (${externalIds.map(() => "?").join(",")}) ORDER BY datasetVersion`,
|
|
4839
|
+
args: [input.datasetId, ...externalIds]
|
|
4840
|
+
}) : { rows: [] };
|
|
4841
|
+
const plan = this.planDatasetItemBatch(
|
|
4842
|
+
input.items,
|
|
4843
|
+
historyResult.rows.map((row) => this.transformItemRowFull(row)),
|
|
4844
|
+
() => crypto.randomUUID()
|
|
4845
|
+
);
|
|
4846
|
+
const resolved = new Map(
|
|
4847
|
+
[...plan.existingCurrentItems].map(([id, row]) => [id, this.datasetItemFromRow(row)])
|
|
4848
|
+
);
|
|
4849
|
+
if (plan.inserts.length > 0) {
|
|
4850
|
+
const newVersion = Number(dataset.version) + 1;
|
|
4851
|
+
const now = /* @__PURE__ */ new Date();
|
|
4852
|
+
const nowIso = now.toISOString();
|
|
4853
|
+
await tx.execute({
|
|
4854
|
+
sql: `UPDATE ${storage.TABLE_DATASETS} SET version = ? WHERE id = ?`,
|
|
4855
|
+
args: [newVersion, input.datasetId]
|
|
4856
|
+
});
|
|
4857
|
+
for (const { id, item } of plan.inserts) {
|
|
4858
|
+
await tx.execute({
|
|
4859
|
+
sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, externalId, organizationId, projectId, validTo, isDeleted, input, groundTruth, expectedTrajectory, toolMocks, requestContext, metadata, source, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?, NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
|
|
4860
|
+
args: [
|
|
4861
|
+
id,
|
|
4862
|
+
input.datasetId,
|
|
4863
|
+
newVersion,
|
|
4864
|
+
item.externalId ?? null,
|
|
4865
|
+
dataset.organizationId ?? null,
|
|
4866
|
+
dataset.projectId ?? null,
|
|
4867
|
+
jsonbArg(item.input),
|
|
4868
|
+
jsonbArg(item.groundTruth),
|
|
4869
|
+
jsonbArg(item.expectedTrajectory),
|
|
4870
|
+
jsonbArg(item.toolMocks),
|
|
4871
|
+
jsonbArg(item.requestContext),
|
|
4872
|
+
jsonbArg(item.metadata),
|
|
4873
|
+
jsonbArg(item.source),
|
|
4874
|
+
nowIso,
|
|
4875
|
+
nowIso
|
|
4876
|
+
]
|
|
4877
|
+
});
|
|
4878
|
+
resolved.set(id, {
|
|
4879
|
+
id,
|
|
4880
|
+
datasetId: input.datasetId,
|
|
4881
|
+
datasetVersion: newVersion,
|
|
4882
|
+
externalId: item.externalId ?? null,
|
|
4883
|
+
organizationId: dataset.organizationId,
|
|
4884
|
+
projectId: dataset.projectId,
|
|
4885
|
+
input: item.input,
|
|
4886
|
+
groundTruth: item.groundTruth,
|
|
4887
|
+
expectedTrajectory: item.expectedTrajectory,
|
|
4888
|
+
toolMocks: item.toolMocks,
|
|
4889
|
+
requestContext: item.requestContext,
|
|
4890
|
+
metadata: item.metadata,
|
|
4891
|
+
source: item.source,
|
|
4892
|
+
createdAt: now,
|
|
4893
|
+
updatedAt: now
|
|
4894
|
+
});
|
|
4895
|
+
}
|
|
4896
|
+
await tx.execute({
|
|
4897
|
+
sql: `INSERT INTO ${storage.TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, ?, ?)`,
|
|
4898
|
+
args: [crypto.randomUUID(), input.datasetId, newVersion, nowIso]
|
|
4899
|
+
});
|
|
4900
|
+
}
|
|
4901
|
+
await tx.commit();
|
|
4902
|
+
return plan.resolvedIds.map((id) => resolved.get(id));
|
|
4903
|
+
} catch (error) {
|
|
4904
|
+
if (!tx.closed) await tx.rollback();
|
|
4905
|
+
throw error;
|
|
4806
4906
|
}
|
|
4807
|
-
];
|
|
4808
|
-
const items = [];
|
|
4809
|
-
for (const itemInput of input.items) {
|
|
4810
|
-
const id = crypto.randomUUID();
|
|
4811
|
-
items.push({ id, input: itemInput });
|
|
4812
|
-
statements.push({
|
|
4813
|
-
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(?), ?, ?)`,
|
|
4814
|
-
args: [
|
|
4815
|
-
id,
|
|
4816
|
-
input.datasetId,
|
|
4817
|
-
input.datasetId,
|
|
4818
|
-
dataset.organizationId ?? null,
|
|
4819
|
-
dataset.projectId ?? null,
|
|
4820
|
-
jsonbArg(itemInput.input),
|
|
4821
|
-
jsonbArg(itemInput.groundTruth),
|
|
4822
|
-
jsonbArg(itemInput.expectedTrajectory),
|
|
4823
|
-
jsonbArg(itemInput.toolMocks),
|
|
4824
|
-
jsonbArg(itemInput.requestContext),
|
|
4825
|
-
jsonbArg(itemInput.metadata),
|
|
4826
|
-
jsonbArg(itemInput.source),
|
|
4827
|
-
nowIso,
|
|
4828
|
-
nowIso
|
|
4829
|
-
]
|
|
4830
|
-
});
|
|
4831
|
-
}
|
|
4832
|
-
statements.push({
|
|
4833
|
-
sql: `INSERT INTO ${storage.TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?)`,
|
|
4834
|
-
args: [versionId, input.datasetId, input.datasetId, nowIso]
|
|
4835
4907
|
});
|
|
4836
|
-
const results = await this.#client.batch(statements, "write");
|
|
4837
|
-
const newVersion = Number(results[0].rows[0].version);
|
|
4838
|
-
return items.map(({ id, input: itemInput }) => ({
|
|
4839
|
-
id,
|
|
4840
|
-
datasetId: input.datasetId,
|
|
4841
|
-
datasetVersion: newVersion,
|
|
4842
|
-
organizationId: dataset.organizationId ?? null,
|
|
4843
|
-
projectId: dataset.projectId ?? null,
|
|
4844
|
-
input: itemInput.input,
|
|
4845
|
-
groundTruth: itemInput.groundTruth,
|
|
4846
|
-
expectedTrajectory: itemInput.expectedTrajectory,
|
|
4847
|
-
toolMocks: itemInput.toolMocks,
|
|
4848
|
-
requestContext: itemInput.requestContext,
|
|
4849
|
-
metadata: itemInput.metadata,
|
|
4850
|
-
source: itemInput.source,
|
|
4851
|
-
createdAt: now,
|
|
4852
|
-
updatedAt: now
|
|
4853
|
-
}));
|
|
4854
4908
|
} catch (error$1) {
|
|
4855
4909
|
if (error$1 instanceof error.MastraError) throw error$1;
|
|
4856
4910
|
throw new error.MastraError(
|
|
@@ -4896,11 +4950,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
|
|
|
4896
4950
|
args: [input.datasetId, item.id]
|
|
4897
4951
|
});
|
|
4898
4952
|
statements.push({
|
|
4899
|
-
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(?), ?, ?)`,
|
|
4953
|
+
sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, externalId, 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(?), ?, ?)`,
|
|
4900
4954
|
args: [
|
|
4901
4955
|
item.id,
|
|
4902
4956
|
input.datasetId,
|
|
4903
4957
|
input.datasetId,
|
|
4958
|
+
item.externalId ?? null,
|
|
4904
4959
|
dataset.organizationId ?? null,
|
|
4905
4960
|
dataset.projectId ?? null,
|
|
4906
4961
|
jsonbArg(item.input),
|