@mastra/lance 0.0.0-new-scorer-api-20250801075530 → 0.0.0-partial-response-backport-20251204204441

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +505 -3
  2. package/README.md +3 -3
  3. package/dist/index.cjs +418 -84
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +418 -84
  7. package/dist/index.js.map +1 -1
  8. package/dist/storage/domains/memory/index.d.ts +10 -1
  9. package/dist/storage/domains/memory/index.d.ts.map +1 -1
  10. package/dist/storage/domains/operations/index.d.ts.map +1 -1
  11. package/dist/storage/domains/scores/index.d.ts +13 -2
  12. package/dist/storage/domains/scores/index.d.ts.map +1 -1
  13. package/dist/storage/domains/traces/index.d.ts +1 -1
  14. package/dist/storage/domains/utils.d.ts.map +1 -1
  15. package/dist/storage/domains/workflows/index.d.ts +23 -11
  16. package/dist/storage/domains/workflows/index.d.ts.map +1 -1
  17. package/dist/storage/index.d.ts +45 -13
  18. package/dist/storage/index.d.ts.map +1 -1
  19. package/dist/vector/filter.d.ts +5 -5
  20. package/dist/vector/index.d.ts +5 -4
  21. package/dist/vector/index.d.ts.map +1 -1
  22. package/package.json +29 -8
  23. package/eslint.config.js +0 -6
  24. package/src/index.ts +0 -2
  25. package/src/storage/domains/legacy-evals/index.ts +0 -156
  26. package/src/storage/domains/memory/index.ts +0 -947
  27. package/src/storage/domains/operations/index.ts +0 -489
  28. package/src/storage/domains/scores/index.ts +0 -221
  29. package/src/storage/domains/traces/index.ts +0 -212
  30. package/src/storage/domains/utils.ts +0 -158
  31. package/src/storage/domains/workflows/index.ts +0 -207
  32. package/src/storage/index.test.ts +0 -10
  33. package/src/storage/index.ts +0 -442
  34. package/src/vector/filter.test.ts +0 -295
  35. package/src/vector/filter.ts +0 -443
  36. package/src/vector/index.test.ts +0 -1493
  37. package/src/vector/index.ts +0 -941
  38. package/src/vector/types.ts +0 -16
  39. package/tsconfig.build.json +0 -9
  40. package/tsconfig.json +0 -5
  41. package/tsup.config.ts +0 -22
  42. package/vitest.config.ts +0 -11
package/dist/index.cjs CHANGED
@@ -5,6 +5,7 @@ var error = require('@mastra/core/error');
5
5
  var storage = require('@mastra/core/storage');
6
6
  var agent = require('@mastra/core/agent');
7
7
  var apacheArrow = require('apache-arrow');
8
+ var scores = require('@mastra/core/scores');
8
9
  var vector = require('@mastra/core/vector');
9
10
  var filter = require('@mastra/core/vector/filter');
10
11
 
@@ -61,9 +62,9 @@ var StoreLegacyEvalsLance = class extends storage.LegacyEvalsStorage {
61
62
  conditions.push(`agent_name = '${options.agentName}'`);
62
63
  }
63
64
  if (options.type === "live") {
64
- conditions.push("length(test_info) = 0");
65
+ conditions.push("test_info IS NULL");
65
66
  } else if (options.type === "test") {
66
- conditions.push("length(test_info) > 0");
67
+ conditions.push("test_info IS NOT NULL");
67
68
  }
68
69
  const startDate = options.dateRange?.start || options.fromDate;
69
70
  const endDate = options.dateRange?.end || options.toDate;
@@ -189,7 +190,6 @@ function processResultWithTypeConversion(rawResult, tableSchema) {
189
190
  } else if (fieldTypeStr.includes("float64") && ["createdAt", "updatedAt"].includes(key)) {
190
191
  processedResult[key] = new Date(processedResult[key]);
191
192
  }
192
- console.log(key, "processedResult", processedResult);
193
193
  }
194
194
  return processedResult;
195
195
  }
@@ -381,6 +381,20 @@ var StoreMemoryLance = class extends storage.MemoryStorage {
381
381
  );
382
382
  }
383
383
  }
384
+ normalizeMessage(message) {
385
+ const { thread_id, ...rest } = message;
386
+ return {
387
+ ...rest,
388
+ threadId: thread_id,
389
+ content: typeof message.content === "string" ? (() => {
390
+ try {
391
+ return JSON.parse(message.content);
392
+ } catch {
393
+ return message.content;
394
+ }
395
+ })() : message.content
396
+ };
397
+ }
384
398
  async getMessages({
385
399
  threadId,
386
400
  resourceId,
@@ -389,6 +403,7 @@ var StoreMemoryLance = class extends storage.MemoryStorage {
389
403
  threadConfig
390
404
  }) {
391
405
  try {
406
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
392
407
  if (threadConfig) {
393
408
  throw new Error("ThreadConfig is not supported by LanceDB storage");
394
409
  }
@@ -421,21 +436,7 @@ var StoreMemoryLance = class extends storage.MemoryStorage {
421
436
  allRecords,
422
437
  await getTableSchema({ tableName: storage.TABLE_MESSAGES, client: this.client })
423
438
  );
424
- const normalized = messages.map((msg) => {
425
- const { thread_id, ...rest } = msg;
426
- return {
427
- ...rest,
428
- threadId: thread_id,
429
- content: typeof msg.content === "string" ? (() => {
430
- try {
431
- return JSON.parse(msg.content);
432
- } catch {
433
- return msg.content;
434
- }
435
- })() : msg.content
436
- };
437
- });
438
- const list = new agent.MessageList({ threadId, resourceId }).add(normalized, "memory");
439
+ const list = new agent.MessageList({ threadId, resourceId }).add(messages.map(this.normalizeMessage), "memory");
439
440
  if (format === "v2") return list.get.all.v2();
440
441
  return list.get.all.v1();
441
442
  } catch (error$1) {
@@ -443,7 +444,41 @@ var StoreMemoryLance = class extends storage.MemoryStorage {
443
444
  {
444
445
  id: "LANCE_STORE_GET_MESSAGES_FAILED",
445
446
  domain: error.ErrorDomain.STORAGE,
446
- category: error.ErrorCategory.THIRD_PARTY
447
+ category: error.ErrorCategory.THIRD_PARTY,
448
+ details: {
449
+ threadId,
450
+ resourceId: resourceId ?? ""
451
+ }
452
+ },
453
+ error$1
454
+ );
455
+ }
456
+ }
457
+ async getMessagesById({
458
+ messageIds,
459
+ format
460
+ }) {
461
+ if (messageIds.length === 0) return [];
462
+ try {
463
+ const table = await this.client.openTable(storage.TABLE_MESSAGES);
464
+ const quotedIds = messageIds.map((id) => `'${id}'`).join(", ");
465
+ const allRecords = await table.query().where(`id IN (${quotedIds})`).toArray();
466
+ const messages = processResultWithTypeConversion(
467
+ allRecords,
468
+ await getTableSchema({ tableName: storage.TABLE_MESSAGES, client: this.client })
469
+ );
470
+ const list = new agent.MessageList().add(messages.map(this.normalizeMessage), "memory");
471
+ if (format === `v1`) return list.get.all.v1();
472
+ return list.get.all.v2();
473
+ } catch (error$1) {
474
+ throw new error.MastraError(
475
+ {
476
+ id: "LANCE_STORE_GET_MESSAGES_BY_ID_FAILED",
477
+ domain: error.ErrorDomain.STORAGE,
478
+ category: error.ErrorCategory.THIRD_PARTY,
479
+ details: {
480
+ messageIds: JSON.stringify(messageIds)
481
+ }
447
482
  },
448
483
  error$1
449
484
  );
@@ -584,13 +619,11 @@ var StoreMemoryLance = class extends storage.MemoryStorage {
584
619
  return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
585
620
  }
586
621
  async getMessagesPaginated(args) {
622
+ const { threadId, resourceId, selectBy, format = "v1" } = args;
623
+ const page = selectBy?.pagination?.page ?? 0;
624
+ const perPage = selectBy?.pagination?.perPage ?? 10;
587
625
  try {
588
- const { threadId, resourceId, selectBy, format = "v1" } = args;
589
- if (!threadId) {
590
- throw new Error("Thread ID is required for getMessagesPaginated");
591
- }
592
- const page = selectBy?.pagination?.page ?? 0;
593
- const perPage = selectBy?.pagination?.perPage ?? 10;
626
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
594
627
  const dateRange = selectBy?.pagination?.dateRange;
595
628
  const fromDate = dateRange?.start;
596
629
  const toDate = dateRange?.end;
@@ -692,14 +725,21 @@ var StoreMemoryLance = class extends storage.MemoryStorage {
692
725
  hasMore: total > (page + 1) * perPage
693
726
  };
694
727
  } catch (error$1) {
695
- throw new error.MastraError(
728
+ const mastraError = new error.MastraError(
696
729
  {
697
730
  id: "LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED",
698
731
  domain: error.ErrorDomain.STORAGE,
699
- category: error.ErrorCategory.THIRD_PARTY
732
+ category: error.ErrorCategory.THIRD_PARTY,
733
+ details: {
734
+ threadId,
735
+ resourceId: resourceId ?? ""
736
+ }
700
737
  },
701
738
  error$1
702
739
  );
740
+ this.logger?.trackException?.(mastraError);
741
+ this.logger?.error?.(mastraError.toString());
742
+ return { messages: [], total: 0, page, perPage, hasMore: false };
703
743
  }
704
744
  }
705
745
  /**
@@ -1226,7 +1266,7 @@ var StoreOperationsLance = class extends storage.StoreOperations {
1226
1266
  processedRecord[key] = JSON.stringify(processedRecord[key]);
1227
1267
  }
1228
1268
  }
1229
- console.log(await table.schema());
1269
+ console.info(await table.schema());
1230
1270
  await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([processedRecord]);
1231
1271
  } catch (error$1) {
1232
1272
  throw new error.MastraError(
@@ -1276,7 +1316,6 @@ var StoreOperationsLance = class extends storage.StoreOperations {
1276
1316
  }
1277
1317
  return processedRecord;
1278
1318
  });
1279
- console.log(processedRecords);
1280
1319
  await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(processedRecords);
1281
1320
  } catch (error$1) {
1282
1321
  throw new error.MastraError(
@@ -1360,12 +1399,27 @@ var StoreScoresLance = class extends storage.ScoresStorage {
1360
1399
  this.client = client;
1361
1400
  }
1362
1401
  async saveScore(score) {
1402
+ let validatedScore;
1403
+ try {
1404
+ validatedScore = scores.saveScorePayloadSchema.parse(score);
1405
+ } catch (error$1) {
1406
+ throw new error.MastraError(
1407
+ {
1408
+ id: "LANCE_STORAGE_SAVE_SCORE_FAILED",
1409
+ text: "Failed to save score in LanceStorage",
1410
+ domain: error.ErrorDomain.STORAGE,
1411
+ category: error.ErrorCategory.THIRD_PARTY
1412
+ },
1413
+ error$1
1414
+ );
1415
+ }
1363
1416
  try {
1417
+ const id = crypto.randomUUID();
1364
1418
  const table = await this.client.openTable(storage.TABLE_SCORERS);
1365
1419
  const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1366
1420
  const allowedFields = new Set(schema.fields.map((f) => f.name));
1367
1421
  const filteredScore = {};
1368
- Object.keys(score).forEach((key) => {
1422
+ Object.keys(validatedScore).forEach((key) => {
1369
1423
  if (allowedFields.has(key)) {
1370
1424
  filteredScore[key] = score[key];
1371
1425
  }
@@ -1375,7 +1429,9 @@ var StoreScoresLance = class extends storage.ScoresStorage {
1375
1429
  filteredScore[key] = JSON.stringify(filteredScore[key]);
1376
1430
  }
1377
1431
  }
1378
- console.log("Saving score to LanceStorage:", filteredScore);
1432
+ filteredScore.createdAt = /* @__PURE__ */ new Date();
1433
+ filteredScore.updatedAt = /* @__PURE__ */ new Date();
1434
+ filteredScore.id = id;
1379
1435
  await table.add([filteredScore], { mode: "append" });
1380
1436
  return { score };
1381
1437
  } catch (error$1) {
@@ -1414,18 +1470,35 @@ var StoreScoresLance = class extends storage.ScoresStorage {
1414
1470
  }
1415
1471
  async getScoresByScorerId({
1416
1472
  scorerId,
1417
- pagination
1473
+ pagination,
1474
+ entityId,
1475
+ entityType,
1476
+ source
1418
1477
  }) {
1419
1478
  try {
1420
1479
  const table = await this.client.openTable(storage.TABLE_SCORERS);
1421
1480
  const { page = 0, perPage = 10 } = pagination || {};
1422
1481
  const offset = page * perPage;
1423
- const query = table.query().where(`\`scorerId\` = '${scorerId}'`).limit(perPage);
1482
+ let query = table.query().where(`\`scorerId\` = '${scorerId}'`);
1483
+ if (source) {
1484
+ query = query.where(`\`source\` = '${source}'`);
1485
+ }
1486
+ if (entityId) {
1487
+ query = query.where(`\`entityId\` = '${entityId}'`);
1488
+ }
1489
+ if (entityType) {
1490
+ query = query.where(`\`entityType\` = '${entityType}'`);
1491
+ }
1492
+ query = query.limit(perPage);
1424
1493
  if (offset > 0) query.offset(offset);
1425
1494
  const records = await query.toArray();
1426
1495
  const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1427
1496
  const scores = processResultWithTypeConversion(records, schema);
1428
- const allRecords = await table.query().where(`\`scorerId\` = '${scorerId}'`).toArray();
1497
+ let totalQuery = table.query().where(`\`scorerId\` = '${scorerId}'`);
1498
+ if (source) {
1499
+ totalQuery = totalQuery.where(`\`source\` = '${source}'`);
1500
+ }
1501
+ const allRecords = await totalQuery.toArray();
1429
1502
  const total = allRecords.length;
1430
1503
  return {
1431
1504
  pagination: {
@@ -1524,6 +1597,44 @@ var StoreScoresLance = class extends storage.ScoresStorage {
1524
1597
  );
1525
1598
  }
1526
1599
  }
1600
+ async getScoresBySpan({
1601
+ traceId,
1602
+ spanId,
1603
+ pagination
1604
+ }) {
1605
+ try {
1606
+ const table = await this.client.openTable(storage.TABLE_SCORERS);
1607
+ const { page = 0, perPage = 10 } = pagination || {};
1608
+ const offset = page * perPage;
1609
+ const query = table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`).limit(perPage);
1610
+ if (offset > 0) query.offset(offset);
1611
+ const records = await query.toArray();
1612
+ const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1613
+ const scores = processResultWithTypeConversion(records, schema);
1614
+ const allRecords = await table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`).toArray();
1615
+ const total = allRecords.length;
1616
+ return {
1617
+ pagination: {
1618
+ page,
1619
+ perPage,
1620
+ total,
1621
+ hasMore: offset + scores.length < total
1622
+ },
1623
+ scores
1624
+ };
1625
+ } catch (error$1) {
1626
+ throw new error.MastraError(
1627
+ {
1628
+ id: "LANCE_STORAGE_GET_SCORES_BY_SPAN_FAILED",
1629
+ text: "Failed to get scores by traceId and spanId in LanceStorage",
1630
+ domain: error.ErrorDomain.STORAGE,
1631
+ category: error.ErrorCategory.THIRD_PARTY,
1632
+ details: { error: error$1?.message }
1633
+ },
1634
+ error$1
1635
+ );
1636
+ }
1637
+ }
1527
1638
  };
1528
1639
  var StoreTracesLance = class extends storage.TracesStorage {
1529
1640
  client;
@@ -1741,9 +1852,26 @@ var StoreWorkflowsLance = class extends storage.WorkflowsStorage {
1741
1852
  super();
1742
1853
  this.client = client;
1743
1854
  }
1855
+ updateWorkflowResults({
1856
+ // workflowName,
1857
+ // runId,
1858
+ // stepId,
1859
+ // result,
1860
+ // runtimeContext,
1861
+ }) {
1862
+ throw new Error("Method not implemented.");
1863
+ }
1864
+ updateWorkflowState({
1865
+ // workflowName,
1866
+ // runId,
1867
+ // opts,
1868
+ }) {
1869
+ throw new Error("Method not implemented.");
1870
+ }
1744
1871
  async persistWorkflowSnapshot({
1745
1872
  workflowName,
1746
1873
  runId,
1874
+ resourceId,
1747
1875
  snapshot
1748
1876
  }) {
1749
1877
  try {
@@ -1757,10 +1885,13 @@ var StoreWorkflowsLance = class extends storage.WorkflowsStorage {
1757
1885
  } else {
1758
1886
  createdAt = now;
1759
1887
  }
1888
+ const { status, value, ...rest } = snapshot;
1760
1889
  const record = {
1761
1890
  workflow_name: workflowName,
1762
1891
  run_id: runId,
1763
- snapshot: JSON.stringify(snapshot),
1892
+ resourceId,
1893
+ snapshot: JSON.stringify({ status, value, ...rest }),
1894
+ // this is to ensure status is always just before value, for when querying the db by status
1764
1895
  createdAt,
1765
1896
  updatedAt: now
1766
1897
  };
@@ -1830,6 +1961,10 @@ var StoreWorkflowsLance = class extends storage.WorkflowsStorage {
1830
1961
  if (args?.workflowName) {
1831
1962
  conditions.push(`workflow_name = '${args.workflowName.replace(/'/g, "''")}'`);
1832
1963
  }
1964
+ if (args?.status) {
1965
+ const escapedStatus = args.status.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/%/g, "\\%").replace(/_/g, "\\_");
1966
+ conditions.push(`\`snapshot\` LIKE '%"status":"${escapedStatus}","value"%'`);
1967
+ }
1833
1968
  if (args?.resourceId) {
1834
1969
  conditions.push(`\`resourceId\` = '${args.resourceId}'`);
1835
1970
  }
@@ -1863,7 +1998,7 @@ var StoreWorkflowsLance = class extends storage.WorkflowsStorage {
1863
1998
  id: "LANCE_STORE_GET_WORKFLOW_RUNS_FAILED",
1864
1999
  domain: error.ErrorDomain.STORAGE,
1865
2000
  category: error.ErrorCategory.THIRD_PARTY,
1866
- details: { namespace: args?.namespace ?? "", workflowName: args?.workflowName ?? "" }
2001
+ details: { resourceId: args?.resourceId ?? "", workflowName: args?.workflowName ?? "" }
1867
2002
  },
1868
2003
  error$1
1869
2004
  );
@@ -1998,7 +2133,8 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
1998
2133
  resourceWorkingMemory: true,
1999
2134
  hasColumn: true,
2000
2135
  createTable: true,
2001
- deleteMessages: false
2136
+ deleteMessages: false,
2137
+ getScoresBySpan: true
2002
2138
  };
2003
2139
  }
2004
2140
  async getResourceById({ resourceId }) {
@@ -2071,6 +2207,12 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
2071
2207
  }) {
2072
2208
  return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format, threadConfig });
2073
2209
  }
2210
+ async getMessagesById({
2211
+ messageIds,
2212
+ format
2213
+ }) {
2214
+ return this.stores.memory.getMessagesById({ messageIds, format });
2215
+ }
2074
2216
  async saveMessages(args) {
2075
2217
  return this.stores.memory.saveMessages(args);
2076
2218
  }
@@ -2104,12 +2246,29 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
2104
2246
  async getWorkflowRunById(args) {
2105
2247
  return this.stores.workflows.getWorkflowRunById(args);
2106
2248
  }
2249
+ async updateWorkflowResults({
2250
+ workflowName,
2251
+ runId,
2252
+ stepId,
2253
+ result,
2254
+ runtimeContext
2255
+ }) {
2256
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
2257
+ }
2258
+ async updateWorkflowState({
2259
+ workflowName,
2260
+ runId,
2261
+ opts
2262
+ }) {
2263
+ return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
2264
+ }
2107
2265
  async persistWorkflowSnapshot({
2108
2266
  workflowName,
2109
2267
  runId,
2268
+ resourceId,
2110
2269
  snapshot
2111
2270
  }) {
2112
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
2271
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
2113
2272
  }
2114
2273
  async loadWorkflowSnapshot({
2115
2274
  workflowName,
@@ -2122,9 +2281,12 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
2122
2281
  }
2123
2282
  async getScoresByScorerId({
2124
2283
  scorerId,
2284
+ source,
2285
+ entityId,
2286
+ entityType,
2125
2287
  pagination
2126
2288
  }) {
2127
- return this.stores.scores.getScoresByScorerId({ scorerId, pagination });
2289
+ return this.stores.scores.getScoresByScorerId({ scorerId, source, pagination, entityId, entityType });
2128
2290
  }
2129
2291
  async saveScore(_score) {
2130
2292
  return this.stores.scores.saveScore(_score);
@@ -2142,6 +2304,13 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
2142
2304
  }) {
2143
2305
  return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
2144
2306
  }
2307
+ async getScoresBySpan({
2308
+ traceId,
2309
+ spanId,
2310
+ pagination
2311
+ }) {
2312
+ return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });
2313
+ }
2145
2314
  };
2146
2315
  var LanceFilterTranslator = class extends filter.BaseFilterTranslator {
2147
2316
  translate(filter) {
@@ -3033,7 +3202,44 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3033
3202
  );
3034
3203
  }
3035
3204
  }
3036
- async updateVector({ indexName, id, update }) {
3205
+ async updateVector(params) {
3206
+ const { indexName, update } = params;
3207
+ if ("id" in params && "filter" in params && params.id && params.filter) {
3208
+ throw new error.MastraError({
3209
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3210
+ domain: error.ErrorDomain.STORAGE,
3211
+ category: error.ErrorCategory.USER,
3212
+ text: "id and filter are mutually exclusive",
3213
+ details: { indexName }
3214
+ });
3215
+ }
3216
+ if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
3217
+ throw new error.MastraError({
3218
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3219
+ domain: error.ErrorDomain.STORAGE,
3220
+ category: error.ErrorCategory.USER,
3221
+ text: "Either id or filter must be provided",
3222
+ details: { indexName }
3223
+ });
3224
+ }
3225
+ if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
3226
+ throw new error.MastraError({
3227
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3228
+ domain: error.ErrorDomain.STORAGE,
3229
+ category: error.ErrorCategory.USER,
3230
+ text: "Cannot update with empty filter",
3231
+ details: { indexName }
3232
+ });
3233
+ }
3234
+ if (!update.vector && !update.metadata) {
3235
+ throw new error.MastraError({
3236
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3237
+ domain: error.ErrorDomain.STORAGE,
3238
+ category: error.ErrorCategory.USER,
3239
+ text: "No updates provided",
3240
+ details: { indexName }
3241
+ });
3242
+ }
3037
3243
  try {
3038
3244
  if (!this.lanceClient) {
3039
3245
  throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
@@ -3041,21 +3247,6 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3041
3247
  if (!indexName) {
3042
3248
  throw new Error("indexName is required");
3043
3249
  }
3044
- if (!id) {
3045
- throw new Error("id is required");
3046
- }
3047
- } catch (err) {
3048
- throw new error.MastraError(
3049
- {
3050
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
3051
- domain: error.ErrorDomain.STORAGE,
3052
- category: error.ErrorCategory.USER,
3053
- details: { indexName, id }
3054
- },
3055
- err
3056
- );
3057
- }
3058
- try {
3059
3250
  const tables = await this.lanceClient.tableNames();
3060
3251
  for (const tableName of tables) {
3061
3252
  this.logger.debug("Checking table:" + tableName);
@@ -3065,39 +3256,66 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3065
3256
  const hasColumn = schema.fields.some((field) => field.name === indexName);
3066
3257
  if (hasColumn) {
3067
3258
  this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3068
- const existingRecord = await table.query().where(`id = '${id}'`).select(schema.fields.map((field) => field.name)).limit(1).toArray();
3069
- if (existingRecord.length === 0) {
3070
- throw new Error(`Record with id '${id}' not found in table ${tableName}`);
3259
+ let whereClause;
3260
+ if ("id" in params && params.id) {
3261
+ whereClause = `id = '${params.id}'`;
3262
+ } else if ("filter" in params && params.filter) {
3263
+ const translator = new LanceFilterTranslator();
3264
+ const processFilterKeys = (filter) => {
3265
+ const processedFilter = {};
3266
+ Object.entries(filter).forEach(([key, value]) => {
3267
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3268
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3269
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3270
+ });
3271
+ } else {
3272
+ processedFilter[`metadata_${key}`] = value;
3273
+ }
3274
+ });
3275
+ return processedFilter;
3276
+ };
3277
+ const prefixedFilter = processFilterKeys(params.filter);
3278
+ whereClause = translator.translate(prefixedFilter) || "";
3279
+ if (!whereClause) {
3280
+ throw new Error("Failed to translate filter to SQL");
3281
+ }
3282
+ } else {
3283
+ throw new Error("Either id or filter must be provided");
3071
3284
  }
3072
- const rowData = {
3073
- id
3074
- };
3075
- Object.entries(existingRecord[0]).forEach(([key, value]) => {
3076
- if (key !== "id" && key !== "_distance") {
3077
- if (key === indexName) {
3078
- if (!update.vector) {
3079
- if (Array.isArray(value)) {
3080
- rowData[key] = [...value];
3081
- } else if (typeof value === "object" && value !== null) {
3082
- rowData[key] = Array.from(value);
3285
+ const existingRecords = await table.query().where(whereClause).select(schema.fields.map((field) => field.name)).toArray();
3286
+ if (existingRecords.length === 0) {
3287
+ this.logger.info(`No records found matching criteria in table ${tableName}`);
3288
+ return;
3289
+ }
3290
+ const updatedRecords = existingRecords.map((record) => {
3291
+ const rowData = {};
3292
+ Object.entries(record).forEach(([key, value]) => {
3293
+ if (key !== "_distance") {
3294
+ if (key === indexName) {
3295
+ if (update.vector) {
3296
+ rowData[key] = update.vector;
3083
3297
  } else {
3084
- rowData[key] = value;
3298
+ if (Array.isArray(value)) {
3299
+ rowData[key] = [...value];
3300
+ } else if (typeof value === "object" && value !== null) {
3301
+ rowData[key] = Array.from(value);
3302
+ } else {
3303
+ rowData[key] = value;
3304
+ }
3085
3305
  }
3306
+ } else {
3307
+ rowData[key] = value;
3086
3308
  }
3087
- } else {
3088
- rowData[key] = value;
3089
3309
  }
3310
+ });
3311
+ if (update.metadata) {
3312
+ Object.entries(update.metadata).forEach(([key, value]) => {
3313
+ rowData[`metadata_${key}`] = value;
3314
+ });
3090
3315
  }
3316
+ return rowData;
3091
3317
  });
3092
- if (update.vector) {
3093
- rowData[indexName] = update.vector;
3094
- }
3095
- if (update.metadata) {
3096
- Object.entries(update.metadata).forEach(([key, value]) => {
3097
- rowData[`metadata_${key}`] = value;
3098
- });
3099
- }
3100
- await table.add([rowData], { mode: "overwrite" });
3318
+ await table.add(updatedRecords, { mode: "overwrite" });
3101
3319
  return;
3102
3320
  }
3103
3321
  } catch (err) {
@@ -3107,12 +3325,19 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3107
3325
  }
3108
3326
  throw new Error(`No table found with column/index '${indexName}'`);
3109
3327
  } catch (error$1) {
3328
+ if (error$1 instanceof error.MastraError) throw error$1;
3110
3329
  throw new error.MastraError(
3111
3330
  {
3112
3331
  id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
3113
3332
  domain: error.ErrorDomain.STORAGE,
3114
3333
  category: error.ErrorCategory.THIRD_PARTY,
3115
- details: { indexName, id, hasVector: !!update.vector, hasMetadata: !!update.metadata }
3334
+ details: {
3335
+ indexName,
3336
+ ..."id" in params && params.id && { id: params.id },
3337
+ ..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) },
3338
+ hasVector: !!update.vector,
3339
+ hasMetadata: !!update.metadata
3340
+ }
3116
3341
  },
3117
3342
  error$1
3118
3343
  );
@@ -3135,7 +3360,10 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3135
3360
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
3136
3361
  domain: error.ErrorDomain.STORAGE,
3137
3362
  category: error.ErrorCategory.USER,
3138
- details: { indexName, id }
3363
+ details: {
3364
+ indexName,
3365
+ ...id && { id }
3366
+ }
3139
3367
  },
3140
3368
  err
3141
3369
  );
@@ -3165,7 +3393,10 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3165
3393
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
3166
3394
  domain: error.ErrorDomain.STORAGE,
3167
3395
  category: error.ErrorCategory.THIRD_PARTY,
3168
- details: { indexName, id }
3396
+ details: {
3397
+ indexName,
3398
+ ...id && { id }
3399
+ }
3169
3400
  },
3170
3401
  error$1
3171
3402
  );
@@ -3196,6 +3427,109 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3196
3427
  });
3197
3428
  return result;
3198
3429
  }
3430
+ async deleteVectors({ indexName, filter, ids }) {
3431
+ if (ids && filter) {
3432
+ throw new error.MastraError({
3433
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3434
+ domain: error.ErrorDomain.STORAGE,
3435
+ category: error.ErrorCategory.USER,
3436
+ text: "ids and filter are mutually exclusive",
3437
+ details: { indexName }
3438
+ });
3439
+ }
3440
+ if (!ids && !filter) {
3441
+ throw new error.MastraError({
3442
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3443
+ domain: error.ErrorDomain.STORAGE,
3444
+ category: error.ErrorCategory.USER,
3445
+ text: "Either filter or ids must be provided",
3446
+ details: { indexName }
3447
+ });
3448
+ }
3449
+ if (ids && ids.length === 0) {
3450
+ throw new error.MastraError({
3451
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3452
+ domain: error.ErrorDomain.STORAGE,
3453
+ category: error.ErrorCategory.USER,
3454
+ text: "Cannot delete with empty ids array",
3455
+ details: { indexName }
3456
+ });
3457
+ }
3458
+ if (filter && Object.keys(filter).length === 0) {
3459
+ throw new error.MastraError({
3460
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3461
+ domain: error.ErrorDomain.STORAGE,
3462
+ category: error.ErrorCategory.USER,
3463
+ text: "Cannot delete with empty filter",
3464
+ details: { indexName }
3465
+ });
3466
+ }
3467
+ try {
3468
+ if (!this.lanceClient) {
3469
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3470
+ }
3471
+ if (!indexName) {
3472
+ throw new Error("indexName is required");
3473
+ }
3474
+ const tables = await this.lanceClient.tableNames();
3475
+ for (const tableName of tables) {
3476
+ this.logger.debug("Checking table:" + tableName);
3477
+ const table = await this.lanceClient.openTable(tableName);
3478
+ try {
3479
+ const schema = await table.schema();
3480
+ const hasColumn = schema.fields.some((field) => field.name === indexName);
3481
+ if (hasColumn) {
3482
+ this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3483
+ if (ids) {
3484
+ const idsConditions = ids.map((id) => `id = '${id}'`).join(" OR ");
3485
+ await table.delete(idsConditions);
3486
+ } else if (filter) {
3487
+ const translator = new LanceFilterTranslator();
3488
+ const processFilterKeys = (filter2) => {
3489
+ const processedFilter = {};
3490
+ Object.entries(filter2).forEach(([key, value]) => {
3491
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3492
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3493
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3494
+ });
3495
+ } else {
3496
+ processedFilter[`metadata_${key}`] = value;
3497
+ }
3498
+ });
3499
+ return processedFilter;
3500
+ };
3501
+ const prefixedFilter = processFilterKeys(filter);
3502
+ const whereClause = translator.translate(prefixedFilter);
3503
+ if (!whereClause) {
3504
+ throw new Error("Failed to translate filter to SQL");
3505
+ }
3506
+ await table.delete(whereClause);
3507
+ }
3508
+ return;
3509
+ }
3510
+ } catch (err) {
3511
+ this.logger.error(`Error checking schema for table ${tableName}:` + err);
3512
+ continue;
3513
+ }
3514
+ }
3515
+ throw new Error(`No table found with column/index '${indexName}'`);
3516
+ } catch (error$1) {
3517
+ if (error$1 instanceof error.MastraError) throw error$1;
3518
+ throw new error.MastraError(
3519
+ {
3520
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_FAILED",
3521
+ domain: error.ErrorDomain.STORAGE,
3522
+ category: error.ErrorCategory.THIRD_PARTY,
3523
+ details: {
3524
+ indexName,
3525
+ ...filter && { filter: JSON.stringify(filter) },
3526
+ ...ids && { idsCount: ids.length }
3527
+ }
3528
+ },
3529
+ error$1
3530
+ );
3531
+ }
3532
+ }
3199
3533
  };
3200
3534
 
3201
3535
  exports.LanceStorage = LanceStorage;