@mastra/lance 0.3.10-alpha.0 → 0.3.11-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/lance
2
2
 
3
+ ## 0.3.11-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - deleteVectors, deleteFilter when upserting, updateVector filter (#10244) ([#10526](https://github.com/mastra-ai/mastra/pull/10526))
8
+
9
+ - fix: ensure score responses match saved payloads for Mastra Stores. ([#10570](https://github.com/mastra-ai/mastra/pull/10570))
10
+
11
+ - Updated dependencies [[`5657314`](https://github.com/mastra-ai/mastra/commit/5657314a1f9d49019bb53f357fa48f75a69247ca), [`e5aca78`](https://github.com/mastra-ai/mastra/commit/e5aca78bb7f263bb8b470bedae81efe9805d7544), [`33a607a`](https://github.com/mastra-ai/mastra/commit/33a607a1f716c2029d4a1ff1603dd756129a33b3), [`cc10fc1`](https://github.com/mastra-ai/mastra/commit/cc10fc192d9f527c71a23cc9def10d8718935ee1), [`1f7ee84`](https://github.com/mastra-ai/mastra/commit/1f7ee841a643ef12d90392125881f06fdf877293), [`e7d5149`](https://github.com/mastra-ai/mastra/commit/e7d514995260b63b2108308e85c64de37dcd0f71), [`f195082`](https://github.com/mastra-ai/mastra/commit/f1950822a2425d5ccae78c5d010e02ddb027a869), [`d9986dd`](https://github.com/mastra-ai/mastra/commit/d9986dd3513f7ca3244a8e599a440ccf4d8bc28b), [`a45b0f0`](https://github.com/mastra-ai/mastra/commit/a45b0f0cd19eab1fe4deceae3abf029442c22f74), [`f6e8eb3`](https://github.com/mastra-ai/mastra/commit/f6e8eb3dac53b70b06e906b2818b1d2a5b0486d7), [`ce57a2b`](https://github.com/mastra-ai/mastra/commit/ce57a2b62fd0d5f6532e4ecd1ba9ba93ac9b95fc), [`3236f35`](https://github.com/mastra-ai/mastra/commit/3236f352ae13cc8552c2965164e97bd125dae48d), [`ce57a2b`](https://github.com/mastra-ai/mastra/commit/ce57a2b62fd0d5f6532e4ecd1ba9ba93ac9b95fc), [`0230321`](https://github.com/mastra-ai/mastra/commit/02303217870bedea0ef009bea9a952f24ed38aaf), [`7b541f4`](https://github.com/mastra-ai/mastra/commit/7b541f49eda6f5a87b738198edbd136927599475), [`0eea842`](https://github.com/mastra-ai/mastra/commit/0eea8423cbdd37f2111593c6f7d2efcde4b7e4ce), [`63ae8a2`](https://github.com/mastra-ai/mastra/commit/63ae8a22c0c09bbb8b9779f5f38934cd75f616af), [`bf810c5`](https://github.com/mastra-ai/mastra/commit/bf810c5c561bd8ef221c0f6bd84e69770b9a38cc), [`ac7ef07`](https://github.com/mastra-ai/mastra/commit/ac7ef07633caee89707142171d2873c888ffef85), [`522f0b4`](https://github.com/mastra-ai/mastra/commit/522f0b45330719858794eabffffde4f343f55549), [`bf810c5`](https://github.com/mastra-ai/mastra/commit/bf810c5c561bd8ef221c0f6bd84e69770b9a38cc), [`8b51d55`](https://github.com/mastra-ai/mastra/commit/8b51d55bae531edf7e383958d7ecee04df31f5d5), [`2131ac5`](https://github.com/mastra-ai/mastra/commit/2131ac571d5065f0a656c57494bca98691bb7609)]:
12
+ - @mastra/core@0.24.6-alpha.0
13
+
14
+ ## 0.3.10
15
+
16
+ ### Patch Changes
17
+
18
+ - update peerdeps ([`5ca1cca`](https://github.com/mastra-ai/mastra/commit/5ca1ccac61ffa7141e6d9fa8f22d3ad4d03bf5dc))
19
+
20
+ - Updated dependencies [[`5ca1cca`](https://github.com/mastra-ai/mastra/commit/5ca1ccac61ffa7141e6d9fa8f22d3ad4d03bf5dc), [`6d7e90d`](https://github.com/mastra-ai/mastra/commit/6d7e90db09713e6250f4d6c3d3cff1b4740e50f9), [`f78b908`](https://github.com/mastra-ai/mastra/commit/f78b9080e11af765969b36b4a619761056030840), [`23c2614`](https://github.com/mastra-ai/mastra/commit/23c26140fdbf04b8c59e8d7d52106d67dad962ec), [`e365eda`](https://github.com/mastra-ai/mastra/commit/e365eda45795b43707310531cac1e2ce4e5a0712)]:
21
+ - @mastra/core@0.24.0
22
+
3
23
  ## 0.3.10-alpha.0
4
24
 
5
25
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1429,6 +1429,8 @@ var StoreScoresLance = class extends storage.ScoresStorage {
1429
1429
  filteredScore[key] = JSON.stringify(filteredScore[key]);
1430
1430
  }
1431
1431
  }
1432
+ filteredScore.createdAt = /* @__PURE__ */ new Date();
1433
+ filteredScore.updatedAt = /* @__PURE__ */ new Date();
1432
1434
  filteredScore.id = id;
1433
1435
  await table.add([filteredScore], { mode: "append" });
1434
1436
  return { score };
@@ -3194,7 +3196,44 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3194
3196
  );
3195
3197
  }
3196
3198
  }
3197
- async updateVector({ indexName, id, update }) {
3199
+ async updateVector(params) {
3200
+ const { indexName, update } = params;
3201
+ if ("id" in params && "filter" in params && params.id && params.filter) {
3202
+ throw new error.MastraError({
3203
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3204
+ domain: error.ErrorDomain.STORAGE,
3205
+ category: error.ErrorCategory.USER,
3206
+ text: "id and filter are mutually exclusive",
3207
+ details: { indexName }
3208
+ });
3209
+ }
3210
+ if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
3211
+ throw new error.MastraError({
3212
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3213
+ domain: error.ErrorDomain.STORAGE,
3214
+ category: error.ErrorCategory.USER,
3215
+ text: "Either id or filter must be provided",
3216
+ details: { indexName }
3217
+ });
3218
+ }
3219
+ if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
3220
+ throw new error.MastraError({
3221
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3222
+ domain: error.ErrorDomain.STORAGE,
3223
+ category: error.ErrorCategory.USER,
3224
+ text: "Cannot update with empty filter",
3225
+ details: { indexName }
3226
+ });
3227
+ }
3228
+ if (!update.vector && !update.metadata) {
3229
+ throw new error.MastraError({
3230
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3231
+ domain: error.ErrorDomain.STORAGE,
3232
+ category: error.ErrorCategory.USER,
3233
+ text: "No updates provided",
3234
+ details: { indexName }
3235
+ });
3236
+ }
3198
3237
  try {
3199
3238
  if (!this.lanceClient) {
3200
3239
  throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
@@ -3202,21 +3241,6 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3202
3241
  if (!indexName) {
3203
3242
  throw new Error("indexName is required");
3204
3243
  }
3205
- if (!id) {
3206
- throw new Error("id is required");
3207
- }
3208
- } catch (err) {
3209
- throw new error.MastraError(
3210
- {
3211
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
3212
- domain: error.ErrorDomain.STORAGE,
3213
- category: error.ErrorCategory.USER,
3214
- details: { indexName, id }
3215
- },
3216
- err
3217
- );
3218
- }
3219
- try {
3220
3244
  const tables = await this.lanceClient.tableNames();
3221
3245
  for (const tableName of tables) {
3222
3246
  this.logger.debug("Checking table:" + tableName);
@@ -3226,39 +3250,66 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3226
3250
  const hasColumn = schema.fields.some((field) => field.name === indexName);
3227
3251
  if (hasColumn) {
3228
3252
  this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3229
- const existingRecord = await table.query().where(`id = '${id}'`).select(schema.fields.map((field) => field.name)).limit(1).toArray();
3230
- if (existingRecord.length === 0) {
3231
- throw new Error(`Record with id '${id}' not found in table ${tableName}`);
3253
+ let whereClause;
3254
+ if ("id" in params && params.id) {
3255
+ whereClause = `id = '${params.id}'`;
3256
+ } else if ("filter" in params && params.filter) {
3257
+ const translator = new LanceFilterTranslator();
3258
+ const processFilterKeys = (filter) => {
3259
+ const processedFilter = {};
3260
+ Object.entries(filter).forEach(([key, value]) => {
3261
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3262
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3263
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3264
+ });
3265
+ } else {
3266
+ processedFilter[`metadata_${key}`] = value;
3267
+ }
3268
+ });
3269
+ return processedFilter;
3270
+ };
3271
+ const prefixedFilter = processFilterKeys(params.filter);
3272
+ whereClause = translator.translate(prefixedFilter) || "";
3273
+ if (!whereClause) {
3274
+ throw new Error("Failed to translate filter to SQL");
3275
+ }
3276
+ } else {
3277
+ throw new Error("Either id or filter must be provided");
3232
3278
  }
3233
- const rowData = {
3234
- id
3235
- };
3236
- Object.entries(existingRecord[0]).forEach(([key, value]) => {
3237
- if (key !== "id" && key !== "_distance") {
3238
- if (key === indexName) {
3239
- if (!update.vector) {
3240
- if (Array.isArray(value)) {
3241
- rowData[key] = [...value];
3242
- } else if (typeof value === "object" && value !== null) {
3243
- rowData[key] = Array.from(value);
3279
+ const existingRecords = await table.query().where(whereClause).select(schema.fields.map((field) => field.name)).toArray();
3280
+ if (existingRecords.length === 0) {
3281
+ this.logger.info(`No records found matching criteria in table ${tableName}`);
3282
+ return;
3283
+ }
3284
+ const updatedRecords = existingRecords.map((record) => {
3285
+ const rowData = {};
3286
+ Object.entries(record).forEach(([key, value]) => {
3287
+ if (key !== "_distance") {
3288
+ if (key === indexName) {
3289
+ if (update.vector) {
3290
+ rowData[key] = update.vector;
3244
3291
  } else {
3245
- rowData[key] = value;
3292
+ if (Array.isArray(value)) {
3293
+ rowData[key] = [...value];
3294
+ } else if (typeof value === "object" && value !== null) {
3295
+ rowData[key] = Array.from(value);
3296
+ } else {
3297
+ rowData[key] = value;
3298
+ }
3246
3299
  }
3300
+ } else {
3301
+ rowData[key] = value;
3247
3302
  }
3248
- } else {
3249
- rowData[key] = value;
3250
3303
  }
3304
+ });
3305
+ if (update.metadata) {
3306
+ Object.entries(update.metadata).forEach(([key, value]) => {
3307
+ rowData[`metadata_${key}`] = value;
3308
+ });
3251
3309
  }
3310
+ return rowData;
3252
3311
  });
3253
- if (update.vector) {
3254
- rowData[indexName] = update.vector;
3255
- }
3256
- if (update.metadata) {
3257
- Object.entries(update.metadata).forEach(([key, value]) => {
3258
- rowData[`metadata_${key}`] = value;
3259
- });
3260
- }
3261
- await table.add([rowData], { mode: "overwrite" });
3312
+ await table.add(updatedRecords, { mode: "overwrite" });
3262
3313
  return;
3263
3314
  }
3264
3315
  } catch (err) {
@@ -3268,12 +3319,19 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3268
3319
  }
3269
3320
  throw new Error(`No table found with column/index '${indexName}'`);
3270
3321
  } catch (error$1) {
3322
+ if (error$1 instanceof error.MastraError) throw error$1;
3271
3323
  throw new error.MastraError(
3272
3324
  {
3273
3325
  id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
3274
3326
  domain: error.ErrorDomain.STORAGE,
3275
3327
  category: error.ErrorCategory.THIRD_PARTY,
3276
- details: { indexName, id, hasVector: !!update.vector, hasMetadata: !!update.metadata }
3328
+ details: {
3329
+ indexName,
3330
+ ..."id" in params && params.id && { id: params.id },
3331
+ ..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) },
3332
+ hasVector: !!update.vector,
3333
+ hasMetadata: !!update.metadata
3334
+ }
3277
3335
  },
3278
3336
  error$1
3279
3337
  );
@@ -3296,7 +3354,10 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3296
3354
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
3297
3355
  domain: error.ErrorDomain.STORAGE,
3298
3356
  category: error.ErrorCategory.USER,
3299
- details: { indexName, id }
3357
+ details: {
3358
+ indexName,
3359
+ ...id && { id }
3360
+ }
3300
3361
  },
3301
3362
  err
3302
3363
  );
@@ -3326,7 +3387,10 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3326
3387
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
3327
3388
  domain: error.ErrorDomain.STORAGE,
3328
3389
  category: error.ErrorCategory.THIRD_PARTY,
3329
- details: { indexName, id }
3390
+ details: {
3391
+ indexName,
3392
+ ...id && { id }
3393
+ }
3330
3394
  },
3331
3395
  error$1
3332
3396
  );
@@ -3357,6 +3421,109 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3357
3421
  });
3358
3422
  return result;
3359
3423
  }
3424
+ async deleteVectors({ indexName, filter, ids }) {
3425
+ if (ids && filter) {
3426
+ throw new error.MastraError({
3427
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3428
+ domain: error.ErrorDomain.STORAGE,
3429
+ category: error.ErrorCategory.USER,
3430
+ text: "ids and filter are mutually exclusive",
3431
+ details: { indexName }
3432
+ });
3433
+ }
3434
+ if (!ids && !filter) {
3435
+ throw new error.MastraError({
3436
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3437
+ domain: error.ErrorDomain.STORAGE,
3438
+ category: error.ErrorCategory.USER,
3439
+ text: "Either filter or ids must be provided",
3440
+ details: { indexName }
3441
+ });
3442
+ }
3443
+ if (ids && ids.length === 0) {
3444
+ throw new error.MastraError({
3445
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3446
+ domain: error.ErrorDomain.STORAGE,
3447
+ category: error.ErrorCategory.USER,
3448
+ text: "Cannot delete with empty ids array",
3449
+ details: { indexName }
3450
+ });
3451
+ }
3452
+ if (filter && Object.keys(filter).length === 0) {
3453
+ throw new error.MastraError({
3454
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3455
+ domain: error.ErrorDomain.STORAGE,
3456
+ category: error.ErrorCategory.USER,
3457
+ text: "Cannot delete with empty filter",
3458
+ details: { indexName }
3459
+ });
3460
+ }
3461
+ try {
3462
+ if (!this.lanceClient) {
3463
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3464
+ }
3465
+ if (!indexName) {
3466
+ throw new Error("indexName is required");
3467
+ }
3468
+ const tables = await this.lanceClient.tableNames();
3469
+ for (const tableName of tables) {
3470
+ this.logger.debug("Checking table:" + tableName);
3471
+ const table = await this.lanceClient.openTable(tableName);
3472
+ try {
3473
+ const schema = await table.schema();
3474
+ const hasColumn = schema.fields.some((field) => field.name === indexName);
3475
+ if (hasColumn) {
3476
+ this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3477
+ if (ids) {
3478
+ const idsConditions = ids.map((id) => `id = '${id}'`).join(" OR ");
3479
+ await table.delete(idsConditions);
3480
+ } else if (filter) {
3481
+ const translator = new LanceFilterTranslator();
3482
+ const processFilterKeys = (filter2) => {
3483
+ const processedFilter = {};
3484
+ Object.entries(filter2).forEach(([key, value]) => {
3485
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3486
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3487
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3488
+ });
3489
+ } else {
3490
+ processedFilter[`metadata_${key}`] = value;
3491
+ }
3492
+ });
3493
+ return processedFilter;
3494
+ };
3495
+ const prefixedFilter = processFilterKeys(filter);
3496
+ const whereClause = translator.translate(prefixedFilter);
3497
+ if (!whereClause) {
3498
+ throw new Error("Failed to translate filter to SQL");
3499
+ }
3500
+ await table.delete(whereClause);
3501
+ }
3502
+ return;
3503
+ }
3504
+ } catch (err) {
3505
+ this.logger.error(`Error checking schema for table ${tableName}:` + err);
3506
+ continue;
3507
+ }
3508
+ }
3509
+ throw new Error(`No table found with column/index '${indexName}'`);
3510
+ } catch (error$1) {
3511
+ if (error$1 instanceof error.MastraError) throw error$1;
3512
+ throw new error.MastraError(
3513
+ {
3514
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_FAILED",
3515
+ domain: error.ErrorDomain.STORAGE,
3516
+ category: error.ErrorCategory.THIRD_PARTY,
3517
+ details: {
3518
+ indexName,
3519
+ ...filter && { filter: JSON.stringify(filter) },
3520
+ ...ids && { idsCount: ids.length }
3521
+ }
3522
+ },
3523
+ error$1
3524
+ );
3525
+ }
3526
+ }
3360
3527
  };
3361
3528
 
3362
3529
  exports.LanceStorage = LanceStorage;