@mastra/lance 0.0.0-scorers-ui-refactored-20250916094952 → 0.0.0-scorers-logs-20251208101616

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/dist/index.js CHANGED
@@ -1,132 +1,17 @@
1
1
  import { connect, Index } from '@lancedb/lancedb';
2
2
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
3
- import { MastraStorage, StoreOperations, LegacyEvalsStorage, TABLE_EVALS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, resolveMessageLimit, TABLE_RESOURCES, ScoresStorage, TABLE_SCORERS, TracesStorage, TABLE_TRACES, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, ensureDate } from '@mastra/core/storage';
3
+ import { MastraStorage, createStorageErrorId, createVectorErrorId, StoreOperations, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, normalizePerPage, calculatePagination, TABLE_RESOURCES, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, ensureDate } from '@mastra/core/storage';
4
4
  import { MessageList } from '@mastra/core/agent';
5
5
  import { Utf8, Float64, Binary, Float32, Int32, Field, Schema } from 'apache-arrow';
6
+ import { saveScorePayloadSchema } from '@mastra/core/evals';
6
7
  import { MastraVector } from '@mastra/core/vector';
7
8
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
8
9
 
9
10
  // src/storage/index.ts
10
- var StoreLegacyEvalsLance = class extends LegacyEvalsStorage {
11
- client;
12
- constructor({ client }) {
13
- super();
14
- this.client = client;
15
- }
16
- async getEvalsByAgentName(agentName, type) {
17
- try {
18
- const table = await this.client.openTable(TABLE_EVALS);
19
- const query = table.query().where(`agent_name = '${agentName}'`);
20
- const records = await query.toArray();
21
- let filteredRecords = records;
22
- if (type === "live") {
23
- filteredRecords = records.filter((record) => record.test_info === null);
24
- } else if (type === "test") {
25
- filteredRecords = records.filter((record) => record.test_info !== null);
26
- }
27
- return filteredRecords.map((record) => {
28
- return {
29
- id: record.id,
30
- input: record.input,
31
- output: record.output,
32
- agentName: record.agent_name,
33
- metricName: record.metric_name,
34
- result: JSON.parse(record.result),
35
- instructions: record.instructions,
36
- testInfo: record.test_info ? JSON.parse(record.test_info) : null,
37
- globalRunId: record.global_run_id,
38
- runId: record.run_id,
39
- createdAt: new Date(record.created_at).toString()
40
- };
41
- });
42
- } catch (error) {
43
- throw new MastraError(
44
- {
45
- id: "LANCE_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
46
- domain: ErrorDomain.STORAGE,
47
- category: ErrorCategory.THIRD_PARTY,
48
- details: { agentName }
49
- },
50
- error
51
- );
52
- }
53
- }
54
- async getEvals(options) {
55
- try {
56
- const table = await this.client.openTable(TABLE_EVALS);
57
- const conditions = [];
58
- if (options.agentName) {
59
- conditions.push(`agent_name = '${options.agentName}'`);
60
- }
61
- if (options.type === "live") {
62
- conditions.push("length(test_info) = 0");
63
- } else if (options.type === "test") {
64
- conditions.push("length(test_info) > 0");
65
- }
66
- const startDate = options.dateRange?.start || options.fromDate;
67
- const endDate = options.dateRange?.end || options.toDate;
68
- if (startDate) {
69
- conditions.push(`\`created_at\` >= ${startDate.getTime()}`);
70
- }
71
- if (endDate) {
72
- conditions.push(`\`created_at\` <= ${endDate.getTime()}`);
73
- }
74
- let total = 0;
75
- if (conditions.length > 0) {
76
- total = await table.countRows(conditions.join(" AND "));
77
- } else {
78
- total = await table.countRows();
79
- }
80
- const query = table.query();
81
- if (conditions.length > 0) {
82
- const whereClause = conditions.join(" AND ");
83
- query.where(whereClause);
84
- }
85
- const records = await query.toArray();
86
- const evals = records.sort((a, b) => b.created_at - a.created_at).map((record) => {
87
- return {
88
- id: record.id,
89
- input: record.input,
90
- output: record.output,
91
- agentName: record.agent_name,
92
- metricName: record.metric_name,
93
- result: JSON.parse(record.result),
94
- instructions: record.instructions,
95
- testInfo: record.test_info ? JSON.parse(record.test_info) : null,
96
- globalRunId: record.global_run_id,
97
- runId: record.run_id,
98
- createdAt: new Date(record.created_at).toISOString()
99
- };
100
- });
101
- const page = options.page || 0;
102
- const perPage = options.perPage || 10;
103
- const pagedEvals = evals.slice(page * perPage, (page + 1) * perPage);
104
- return {
105
- evals: pagedEvals,
106
- total,
107
- page,
108
- perPage,
109
- hasMore: total > (page + 1) * perPage
110
- };
111
- } catch (error) {
112
- throw new MastraError(
113
- {
114
- id: "LANCE_STORE_GET_EVALS_FAILED",
115
- domain: ErrorDomain.STORAGE,
116
- category: ErrorCategory.THIRD_PARTY,
117
- details: { agentName: options.agentName ?? "" }
118
- },
119
- error
120
- );
121
- }
122
- }
123
- };
124
11
  function getPrimaryKeys(tableName) {
125
12
  let primaryId = ["id"];
126
13
  if (tableName === TABLE_WORKFLOW_SNAPSHOT) {
127
14
  primaryId = ["workflow_name", "run_id"];
128
- } else if (tableName === TABLE_EVALS) {
129
- primaryId = ["agent_name", "metric_name", "run_id"];
130
15
  }
131
16
  return primaryId;
132
17
  }
@@ -187,7 +72,6 @@ function processResultWithTypeConversion(rawResult, tableSchema) {
187
72
  } else if (fieldTypeStr.includes("float64") && ["createdAt", "updatedAt"].includes(key)) {
188
73
  processedResult[key] = new Date(processedResult[key]);
189
74
  }
190
- console.log(key, "processedResult", processedResult);
191
75
  }
192
76
  return processedResult;
193
77
  }
@@ -205,7 +89,7 @@ async function getTableSchema({
205
89
  } catch (validationError) {
206
90
  throw new MastraError(
207
91
  {
208
- id: "STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_INVALID_ARGS",
92
+ id: createStorageErrorId("LANCE", "GET_TABLE_SCHEMA", "INVALID_ARGS"),
209
93
  domain: ErrorDomain.STORAGE,
210
94
  category: ErrorCategory.USER,
211
95
  text: validationError.message,
@@ -228,7 +112,7 @@ async function getTableSchema({
228
112
  } catch (error) {
229
113
  throw new MastraError(
230
114
  {
231
- id: "STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_FAILED",
115
+ id: createStorageErrorId("LANCE", "GET_TABLE_SCHEMA", "FAILED"),
232
116
  domain: ErrorDomain.STORAGE,
233
117
  category: ErrorCategory.THIRD_PARTY,
234
118
  details: { tableName }
@@ -247,6 +131,10 @@ var StoreMemoryLance = class extends MemoryStorage {
247
131
  this.client = client;
248
132
  this.operations = operations;
249
133
  }
134
+ // Utility to escape single quotes in SQL strings
135
+ escapeSql(str) {
136
+ return str.replace(/'/g, "''");
137
+ }
250
138
  async getThreadById({ threadId }) {
251
139
  try {
252
140
  const thread = await this.operations.load({ tableName: TABLE_THREADS, keys: { id: threadId } });
@@ -261,27 +149,7 @@ var StoreMemoryLance = class extends MemoryStorage {
261
149
  } catch (error) {
262
150
  throw new MastraError(
263
151
  {
264
- id: "LANCE_STORE_GET_THREAD_BY_ID_FAILED",
265
- domain: ErrorDomain.STORAGE,
266
- category: ErrorCategory.THIRD_PARTY
267
- },
268
- error
269
- );
270
- }
271
- }
272
- async getThreadsByResourceId({ resourceId }) {
273
- try {
274
- const table = await this.client.openTable(TABLE_THREADS);
275
- const query = table.query().where(`\`resourceId\` = '${resourceId}'`);
276
- const records = await query.toArray();
277
- return processResultWithTypeConversion(
278
- records,
279
- await getTableSchema({ tableName: TABLE_THREADS, client: this.client })
280
- );
281
- } catch (error) {
282
- throw new MastraError(
283
- {
284
- id: "LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
152
+ id: createStorageErrorId("LANCE", "GET_THREAD_BY_ID", "FAILED"),
285
153
  domain: ErrorDomain.STORAGE,
286
154
  category: ErrorCategory.THIRD_PARTY
287
155
  },
@@ -303,7 +171,7 @@ var StoreMemoryLance = class extends MemoryStorage {
303
171
  } catch (error) {
304
172
  throw new MastraError(
305
173
  {
306
- id: "LANCE_STORE_SAVE_THREAD_FAILED",
174
+ id: createStorageErrorId("LANCE", "SAVE_THREAD", "FAILED"),
307
175
  domain: ErrorDomain.STORAGE,
308
176
  category: ErrorCategory.THIRD_PARTY
309
177
  },
@@ -345,7 +213,7 @@ var StoreMemoryLance = class extends MemoryStorage {
345
213
  }
346
214
  throw new MastraError(
347
215
  {
348
- id: "LANCE_STORE_UPDATE_THREAD_FAILED",
216
+ id: createStorageErrorId("LANCE", "UPDATE_THREAD", "FAILED"),
349
217
  domain: ErrorDomain.STORAGE,
350
218
  category: ErrorCategory.THIRD_PARTY
351
219
  },
@@ -355,7 +223,7 @@ var StoreMemoryLance = class extends MemoryStorage {
355
223
  }
356
224
  throw new MastraError(
357
225
  {
358
- id: "LANCE_STORE_UPDATE_THREAD_FAILED",
226
+ id: createStorageErrorId("LANCE", "UPDATE_THREAD", "FAILED"),
359
227
  domain: ErrorDomain.STORAGE,
360
228
  category: ErrorCategory.THIRD_PARTY
361
229
  },
@@ -371,7 +239,7 @@ var StoreMemoryLance = class extends MemoryStorage {
371
239
  } catch (error) {
372
240
  throw new MastraError(
373
241
  {
374
- id: "LANCE_STORE_DELETE_THREAD_FAILED",
242
+ id: createStorageErrorId("LANCE", "DELETE_THREAD", "FAILED"),
375
243
  domain: ErrorDomain.STORAGE,
376
244
  category: ErrorCategory.THIRD_PARTY
377
245
  },
@@ -393,100 +261,176 @@ var StoreMemoryLance = class extends MemoryStorage {
393
261
  })() : message.content
394
262
  };
395
263
  }
396
- async getMessages({
397
- threadId,
398
- resourceId,
399
- selectBy,
400
- format,
401
- threadConfig
402
- }) {
264
+ async listMessagesById({ messageIds }) {
265
+ if (messageIds.length === 0) return { messages: [] };
403
266
  try {
404
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
405
- if (threadConfig) {
406
- throw new Error("ThreadConfig is not supported by LanceDB storage");
407
- }
408
- const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
409
267
  const table = await this.client.openTable(TABLE_MESSAGES);
410
- let allRecords = [];
411
- if (selectBy?.include && selectBy.include.length > 0) {
412
- const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
413
- for (const threadId2 of threadIds) {
414
- const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
415
- let threadRecords = await threadQuery.toArray();
416
- allRecords.push(...threadRecords);
417
- }
418
- } else {
419
- let query = table.query().where(`\`thread_id\` = '${threadId}'`);
420
- allRecords = await query.toArray();
421
- }
422
- allRecords.sort((a, b) => {
423
- const dateA = new Date(a.createdAt).getTime();
424
- const dateB = new Date(b.createdAt).getTime();
425
- return dateA - dateB;
426
- });
427
- if (selectBy?.include && selectBy.include.length > 0) {
428
- allRecords = this.processMessagesWithContext(allRecords, selectBy.include);
429
- }
430
- if (limit !== Number.MAX_SAFE_INTEGER) {
431
- allRecords = allRecords.slice(-limit);
432
- }
268
+ const quotedIds = messageIds.map((id) => `'${id}'`).join(", ");
269
+ const allRecords = await table.query().where(`id IN (${quotedIds})`).toArray();
433
270
  const messages = processResultWithTypeConversion(
434
271
  allRecords,
435
272
  await getTableSchema({ tableName: TABLE_MESSAGES, client: this.client })
436
273
  );
437
- const list = new MessageList({ threadId, resourceId }).add(messages.map(this.normalizeMessage), "memory");
438
- if (format === "v2") return list.get.all.v2();
439
- return list.get.all.v1();
274
+ const list = new MessageList().add(
275
+ messages.map(this.normalizeMessage),
276
+ "memory"
277
+ );
278
+ return { messages: list.get.all.db() };
440
279
  } catch (error) {
441
280
  throw new MastraError(
442
281
  {
443
- id: "LANCE_STORE_GET_MESSAGES_FAILED",
282
+ id: createStorageErrorId("LANCE", "LIST_MESSAGES_BY_ID", "FAILED"),
444
283
  domain: ErrorDomain.STORAGE,
445
284
  category: ErrorCategory.THIRD_PARTY,
446
285
  details: {
447
- threadId,
448
- resourceId: resourceId ?? ""
286
+ messageIds: JSON.stringify(messageIds)
449
287
  }
450
288
  },
451
289
  error
452
290
  );
453
291
  }
454
292
  }
455
- async getMessagesById({
456
- messageIds,
457
- format
458
- }) {
459
- if (messageIds.length === 0) return [];
293
+ async listMessages(args) {
294
+ const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
295
+ const threadIds = Array.isArray(threadId) ? threadId : [threadId];
296
+ if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) {
297
+ throw new MastraError(
298
+ {
299
+ id: createStorageErrorId("LANCE", "LIST_MESSAGES", "INVALID_THREAD_ID"),
300
+ domain: ErrorDomain.STORAGE,
301
+ category: ErrorCategory.THIRD_PARTY,
302
+ details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
303
+ },
304
+ new Error("threadId must be a non-empty string or array of non-empty strings")
305
+ );
306
+ }
307
+ const perPage = normalizePerPage(perPageInput, 40);
308
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
460
309
  try {
310
+ if (page < 0) {
311
+ throw new MastraError(
312
+ {
313
+ id: createStorageErrorId("LANCE", "LIST_MESSAGES", "INVALID_PAGE"),
314
+ domain: ErrorDomain.STORAGE,
315
+ category: ErrorCategory.USER,
316
+ details: { page }
317
+ },
318
+ new Error("page must be >= 0")
319
+ );
320
+ }
321
+ const { field, direction } = this.parseOrderBy(orderBy, "ASC");
461
322
  const table = await this.client.openTable(TABLE_MESSAGES);
462
- const quotedIds = messageIds.map((id) => `'${id}'`).join(", ");
463
- const allRecords = await table.query().where(`id IN (${quotedIds})`).toArray();
464
- const messages = processResultWithTypeConversion(
465
- allRecords,
466
- await getTableSchema({ tableName: TABLE_MESSAGES, client: this.client })
467
- );
468
- const list = new MessageList().add(messages.map(this.normalizeMessage), "memory");
469
- if (format === `v1`) return list.get.all.v1();
470
- return list.get.all.v2();
323
+ const threadCondition = threadIds.length === 1 ? `thread_id = '${this.escapeSql(threadIds[0])}'` : `thread_id IN (${threadIds.map((t) => `'${this.escapeSql(t)}'`).join(", ")})`;
324
+ const conditions = [threadCondition];
325
+ if (resourceId) {
326
+ conditions.push(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
327
+ }
328
+ if (filter?.dateRange?.start) {
329
+ const startTime = filter.dateRange.start instanceof Date ? filter.dateRange.start.getTime() : new Date(filter.dateRange.start).getTime();
330
+ conditions.push(`\`createdAt\` >= ${startTime}`);
331
+ }
332
+ if (filter?.dateRange?.end) {
333
+ const endTime = filter.dateRange.end instanceof Date ? filter.dateRange.end.getTime() : new Date(filter.dateRange.end).getTime();
334
+ conditions.push(`\`createdAt\` <= ${endTime}`);
335
+ }
336
+ const whereClause = conditions.join(" AND ");
337
+ const total = await table.countRows(whereClause);
338
+ const query = table.query().where(whereClause);
339
+ let allRecords = await query.toArray();
340
+ allRecords.sort((a, b) => {
341
+ const aValue = field === "createdAt" ? a.createdAt : a[field];
342
+ const bValue = field === "createdAt" ? b.createdAt : b[field];
343
+ if (aValue == null && bValue == null) return 0;
344
+ if (aValue == null) return direction === "ASC" ? -1 : 1;
345
+ if (bValue == null) return direction === "ASC" ? 1 : -1;
346
+ if (typeof aValue === "string" && typeof bValue === "string") {
347
+ return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
348
+ }
349
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
350
+ });
351
+ const paginatedRecords = allRecords.slice(offset, offset + perPage);
352
+ const messages = paginatedRecords.map((row) => this.normalizeMessage(row));
353
+ if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
354
+ return {
355
+ messages: [],
356
+ total: 0,
357
+ page,
358
+ perPage: perPageForResponse,
359
+ hasMore: false
360
+ };
361
+ }
362
+ const messageIds = new Set(messages.map((m) => m.id));
363
+ if (include && include.length > 0) {
364
+ const threadIds2 = [...new Set(include.map((item) => item.threadId || threadId))];
365
+ const allThreadMessages = [];
366
+ for (const tid of threadIds2) {
367
+ const threadQuery = table.query().where(`thread_id = '${tid}'`);
368
+ let threadRecords = await threadQuery.toArray();
369
+ allThreadMessages.push(...threadRecords);
370
+ }
371
+ allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
372
+ const contextMessages = this.processMessagesWithContext(allThreadMessages, include);
373
+ const includedMessages = contextMessages.map((row) => this.normalizeMessage(row));
374
+ for (const includeMsg of includedMessages) {
375
+ if (!messageIds.has(includeMsg.id)) {
376
+ messages.push(includeMsg);
377
+ messageIds.add(includeMsg.id);
378
+ }
379
+ }
380
+ }
381
+ const list = new MessageList().add(messages, "memory");
382
+ let finalMessages = list.get.all.db();
383
+ finalMessages = finalMessages.sort((a, b) => {
384
+ const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
385
+ const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
386
+ if (aValue == null && bValue == null) return 0;
387
+ if (aValue == null) return direction === "ASC" ? -1 : 1;
388
+ if (bValue == null) return direction === "ASC" ? 1 : -1;
389
+ if (typeof aValue === "string" && typeof bValue === "string") {
390
+ return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
391
+ }
392
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
393
+ });
394
+ const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
395
+ const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
396
+ const fetchedAll = perPageInput === false || allThreadMessagesReturned;
397
+ const hasMore = !fetchedAll && offset + perPage < total;
398
+ return {
399
+ messages: finalMessages,
400
+ total,
401
+ page,
402
+ perPage: perPageForResponse,
403
+ hasMore
404
+ };
471
405
  } catch (error) {
472
- throw new MastraError(
406
+ const mastraError = new MastraError(
473
407
  {
474
- id: "LANCE_STORE_GET_MESSAGES_BY_ID_FAILED",
408
+ id: createStorageErrorId("LANCE", "LIST_MESSAGES", "FAILED"),
475
409
  domain: ErrorDomain.STORAGE,
476
410
  category: ErrorCategory.THIRD_PARTY,
477
411
  details: {
478
- messageIds: JSON.stringify(messageIds)
412
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
413
+ resourceId: resourceId ?? ""
479
414
  }
480
415
  },
481
416
  error
482
417
  );
418
+ this.logger?.error?.(mastraError.toString());
419
+ this.logger?.trackException?.(mastraError);
420
+ return {
421
+ messages: [],
422
+ total: 0,
423
+ page,
424
+ perPage: perPageForResponse,
425
+ hasMore: false
426
+ };
483
427
  }
484
428
  }
485
429
  async saveMessages(args) {
486
430
  try {
487
- const { messages, format = "v1" } = args;
431
+ const { messages } = args;
488
432
  if (messages.length === 0) {
489
- return [];
433
+ return { messages: [] };
490
434
  }
491
435
  const threadId = messages[0]?.threadId;
492
436
  if (!threadId) {
@@ -522,12 +466,11 @@ var StoreMemoryLance = class extends MemoryStorage {
522
466
  const updateRecord = { id: threadId, updatedAt: currentTime };
523
467
  await threadsTable.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([updateRecord]);
524
468
  const list = new MessageList().add(messages, "memory");
525
- if (format === `v2`) return list.get.all.v2();
526
- return list.get.all.v1();
469
+ return { messages: list.get.all.db() };
527
470
  } catch (error) {
528
471
  throw new MastraError(
529
472
  {
530
- id: "LANCE_STORE_SAVE_MESSAGES_FAILED",
473
+ id: createStorageErrorId("LANCE", "SAVE_MESSAGES", "FAILED"),
531
474
  domain: ErrorDomain.STORAGE,
532
475
  category: ErrorCategory.THIRD_PARTY
533
476
  },
@@ -535,32 +478,54 @@ var StoreMemoryLance = class extends MemoryStorage {
535
478
  );
536
479
  }
537
480
  }
538
- async getThreadsByResourceIdPaginated(args) {
481
+ async listThreadsByResourceId(args) {
539
482
  try {
540
- const { resourceId, page = 0, perPage = 10 } = args;
541
- const table = await this.client.openTable(TABLE_THREADS);
542
- const total = await table.countRows(`\`resourceId\` = '${resourceId}'`);
543
- const query = table.query().where(`\`resourceId\` = '${resourceId}'`);
544
- const offset = page * perPage;
545
- query.limit(perPage);
546
- if (offset > 0) {
547
- query.offset(offset);
483
+ const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
484
+ const perPage = normalizePerPage(perPageInput, 100);
485
+ if (page < 0) {
486
+ throw new MastraError(
487
+ {
488
+ id: createStorageErrorId("LANCE", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
489
+ domain: ErrorDomain.STORAGE,
490
+ category: ErrorCategory.USER,
491
+ details: { page }
492
+ },
493
+ new Error("page must be >= 0")
494
+ );
548
495
  }
496
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
497
+ const { field, direction } = this.parseOrderBy(orderBy);
498
+ const table = await this.client.openTable(TABLE_THREADS);
499
+ const total = await table.countRows(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
500
+ const query = table.query().where(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
549
501
  const records = await query.toArray();
550
- records.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
502
+ records.sort((a, b) => {
503
+ const aValue = ["createdAt", "updatedAt"].includes(field) ? new Date(a[field]).getTime() : a[field];
504
+ const bValue = ["createdAt", "updatedAt"].includes(field) ? new Date(b[field]).getTime() : b[field];
505
+ if (aValue == null && bValue == null) return 0;
506
+ if (aValue == null) return direction === "ASC" ? -1 : 1;
507
+ if (bValue == null) return direction === "ASC" ? 1 : -1;
508
+ if (typeof aValue === "string" && typeof bValue === "string") {
509
+ return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
510
+ }
511
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
512
+ });
513
+ const paginatedRecords = records.slice(offset, offset + perPage);
551
514
  const schema = await getTableSchema({ tableName: TABLE_THREADS, client: this.client });
552
- const threads = records.map((record) => processResultWithTypeConversion(record, schema));
515
+ const threads = paginatedRecords.map(
516
+ (record) => processResultWithTypeConversion(record, schema)
517
+ );
553
518
  return {
554
519
  threads,
555
520
  total,
556
521
  page,
557
- perPage,
558
- hasMore: total > (page + 1) * perPage
522
+ perPage: perPageForResponse,
523
+ hasMore: offset + perPage < total
559
524
  };
560
525
  } catch (error) {
561
526
  throw new MastraError(
562
527
  {
563
- id: "LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
528
+ id: createStorageErrorId("LANCE", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
564
529
  domain: ErrorDomain.STORAGE,
565
530
  category: ErrorCategory.THIRD_PARTY
566
531
  },
@@ -616,132 +581,8 @@ var StoreMemoryLance = class extends MemoryStorage {
616
581
  });
617
582
  return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
618
583
  }
619
- async getMessagesPaginated(args) {
620
- const { threadId, resourceId, selectBy, format = "v1" } = args;
621
- const page = selectBy?.pagination?.page ?? 0;
622
- const perPage = selectBy?.pagination?.perPage ?? 10;
623
- try {
624
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
625
- const dateRange = selectBy?.pagination?.dateRange;
626
- const fromDate = dateRange?.start;
627
- const toDate = dateRange?.end;
628
- const table = await this.client.openTable(TABLE_MESSAGES);
629
- const messages = [];
630
- if (selectBy?.include && Array.isArray(selectBy.include)) {
631
- const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
632
- const allThreadMessages = [];
633
- for (const threadId2 of threadIds) {
634
- const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
635
- let threadRecords = await threadQuery.toArray();
636
- if (fromDate) threadRecords = threadRecords.filter((m) => m.createdAt >= fromDate.getTime());
637
- if (toDate) threadRecords = threadRecords.filter((m) => m.createdAt <= toDate.getTime());
638
- allThreadMessages.push(...threadRecords);
639
- }
640
- allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
641
- const contextMessages = this.processMessagesWithContext(allThreadMessages, selectBy.include);
642
- messages.push(...contextMessages);
643
- }
644
- const conditions = [`thread_id = '${threadId}'`];
645
- if (resourceId) {
646
- conditions.push(`\`resourceId\` = '${resourceId}'`);
647
- }
648
- if (fromDate) {
649
- conditions.push(`\`createdAt\` >= ${fromDate.getTime()}`);
650
- }
651
- if (toDate) {
652
- conditions.push(`\`createdAt\` <= ${toDate.getTime()}`);
653
- }
654
- let total = 0;
655
- if (conditions.length > 0) {
656
- total = await table.countRows(conditions.join(" AND "));
657
- } else {
658
- total = await table.countRows();
659
- }
660
- if (total === 0 && messages.length === 0) {
661
- return {
662
- messages: [],
663
- total: 0,
664
- page,
665
- perPage,
666
- hasMore: false
667
- };
668
- }
669
- const excludeIds = messages.map((m) => m.id);
670
- let selectedMessages = [];
671
- if (selectBy?.last && selectBy.last > 0) {
672
- const query = table.query();
673
- if (conditions.length > 0) {
674
- query.where(conditions.join(" AND "));
675
- }
676
- let records = await query.toArray();
677
- records = records.sort((a, b) => a.createdAt - b.createdAt);
678
- if (excludeIds.length > 0) {
679
- records = records.filter((m) => !excludeIds.includes(m.id));
680
- }
681
- selectedMessages = records.slice(-selectBy.last);
682
- } else {
683
- const query = table.query();
684
- if (conditions.length > 0) {
685
- query.where(conditions.join(" AND "));
686
- }
687
- let records = await query.toArray();
688
- records = records.sort((a, b) => a.createdAt - b.createdAt);
689
- if (excludeIds.length > 0) {
690
- records = records.filter((m) => !excludeIds.includes(m.id));
691
- }
692
- selectedMessages = records.slice(page * perPage, (page + 1) * perPage);
693
- }
694
- const allMessages = [...messages, ...selectedMessages];
695
- const seen = /* @__PURE__ */ new Set();
696
- const dedupedMessages = allMessages.filter((m) => {
697
- const key = `${m.id}:${m.thread_id}`;
698
- if (seen.has(key)) return false;
699
- seen.add(key);
700
- return true;
701
- });
702
- const formattedMessages = dedupedMessages.map((msg) => {
703
- const { thread_id, ...rest } = msg;
704
- return {
705
- ...rest,
706
- threadId: thread_id,
707
- content: typeof msg.content === "string" ? (() => {
708
- try {
709
- return JSON.parse(msg.content);
710
- } catch {
711
- return msg.content;
712
- }
713
- })() : msg.content
714
- };
715
- });
716
- const list = new MessageList().add(formattedMessages, "memory");
717
- return {
718
- messages: format === "v2" ? list.get.all.v2() : list.get.all.v1(),
719
- total,
720
- // Total should be the count of messages matching the filters
721
- page,
722
- perPage,
723
- hasMore: total > (page + 1) * perPage
724
- };
725
- } catch (error) {
726
- const mastraError = new MastraError(
727
- {
728
- id: "LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED",
729
- domain: ErrorDomain.STORAGE,
730
- category: ErrorCategory.THIRD_PARTY,
731
- details: {
732
- threadId,
733
- resourceId: resourceId ?? ""
734
- }
735
- },
736
- error
737
- );
738
- this.logger?.trackException?.(mastraError);
739
- this.logger?.error?.(mastraError.toString());
740
- return { messages: [], total: 0, page, perPage, hasMore: false };
741
- }
742
- }
743
584
  /**
744
- * Parse message data from LanceDB record format to MastraMessageV2 format
585
+ * Parse message data from LanceDB record format to MastraDBMessage format
745
586
  */
746
587
  parseMessageData(data) {
747
588
  const { thread_id, ...rest } = data;
@@ -819,7 +660,7 @@ var StoreMemoryLance = class extends MemoryStorage {
819
660
  } catch (error) {
820
661
  throw new MastraError(
821
662
  {
822
- id: "LANCE_STORE_UPDATE_MESSAGES_FAILED",
663
+ id: createStorageErrorId("LANCE", "UPDATE_MESSAGES", "FAILED"),
823
664
  domain: ErrorDomain.STORAGE,
824
665
  category: ErrorCategory.THIRD_PARTY,
825
666
  details: { count: messages.length }
@@ -896,7 +737,7 @@ var StoreMemoryLance = class extends MemoryStorage {
896
737
  } catch (error) {
897
738
  throw new MastraError(
898
739
  {
899
- id: "LANCE_STORE_GET_RESOURCE_BY_ID_FAILED",
740
+ id: createStorageErrorId("LANCE", "GET_RESOURCE_BY_ID", "FAILED"),
900
741
  domain: ErrorDomain.STORAGE,
901
742
  category: ErrorCategory.THIRD_PARTY
902
743
  },
@@ -920,7 +761,7 @@ var StoreMemoryLance = class extends MemoryStorage {
920
761
  } catch (error) {
921
762
  throw new MastraError(
922
763
  {
923
- id: "LANCE_STORE_SAVE_RESOURCE_FAILED",
764
+ id: createStorageErrorId("LANCE", "SAVE_RESOURCE", "FAILED"),
924
765
  domain: ErrorDomain.STORAGE,
925
766
  category: ErrorCategory.THIRD_PARTY
926
767
  },
@@ -974,7 +815,7 @@ var StoreMemoryLance = class extends MemoryStorage {
974
815
  }
975
816
  throw new MastraError(
976
817
  {
977
- id: "LANCE_STORE_UPDATE_RESOURCE_FAILED",
818
+ id: createStorageErrorId("LANCE", "UPDATE_RESOURCE", "FAILED"),
978
819
  domain: ErrorDomain.STORAGE,
979
820
  category: ErrorCategory.THIRD_PARTY
980
821
  },
@@ -1065,7 +906,7 @@ var StoreOperationsLance = class extends StoreOperations {
1065
906
  } catch (error) {
1066
907
  throw new MastraError(
1067
908
  {
1068
- id: "STORAGE_LANCE_STORAGE_CREATE_TABLE_INVALID_ARGS",
909
+ id: createStorageErrorId("LANCE", "CREATE_TABLE", "INVALID_ARGS"),
1069
910
  domain: ErrorDomain.STORAGE,
1070
911
  category: ErrorCategory.USER,
1071
912
  details: { tableName }
@@ -1083,7 +924,7 @@ var StoreOperationsLance = class extends StoreOperations {
1083
924
  }
1084
925
  throw new MastraError(
1085
926
  {
1086
- id: "STORAGE_LANCE_STORAGE_CREATE_TABLE_FAILED",
927
+ id: createStorageErrorId("LANCE", "CREATE_TABLE", "FAILED"),
1087
928
  domain: ErrorDomain.STORAGE,
1088
929
  category: ErrorCategory.THIRD_PARTY,
1089
930
  details: { tableName }
@@ -1103,7 +944,7 @@ var StoreOperationsLance = class extends StoreOperations {
1103
944
  } catch (validationError) {
1104
945
  throw new MastraError(
1105
946
  {
1106
- id: "STORAGE_LANCE_STORAGE_DROP_TABLE_INVALID_ARGS",
947
+ id: createStorageErrorId("LANCE", "DROP_TABLE", "INVALID_ARGS"),
1107
948
  domain: ErrorDomain.STORAGE,
1108
949
  category: ErrorCategory.USER,
1109
950
  text: validationError.message,
@@ -1121,7 +962,7 @@ var StoreOperationsLance = class extends StoreOperations {
1121
962
  }
1122
963
  throw new MastraError(
1123
964
  {
1124
- id: "STORAGE_LANCE_STORAGE_DROP_TABLE_FAILED",
965
+ id: createStorageErrorId("LANCE", "DROP_TABLE", "FAILED"),
1125
966
  domain: ErrorDomain.STORAGE,
1126
967
  category: ErrorCategory.THIRD_PARTY,
1127
968
  details: { tableName }
@@ -1152,7 +993,7 @@ var StoreOperationsLance = class extends StoreOperations {
1152
993
  } catch (validationError) {
1153
994
  throw new MastraError(
1154
995
  {
1155
- id: "STORAGE_LANCE_STORAGE_ALTER_TABLE_INVALID_ARGS",
996
+ id: createStorageErrorId("LANCE", "ALTER_TABLE", "INVALID_ARGS"),
1156
997
  domain: ErrorDomain.STORAGE,
1157
998
  category: ErrorCategory.USER,
1158
999
  text: validationError.message,
@@ -1187,7 +1028,7 @@ var StoreOperationsLance = class extends StoreOperations {
1187
1028
  } catch (error) {
1188
1029
  throw new MastraError(
1189
1030
  {
1190
- id: "STORAGE_LANCE_STORAGE_ALTER_TABLE_FAILED",
1031
+ id: createStorageErrorId("LANCE", "ALTER_TABLE", "FAILED"),
1191
1032
  domain: ErrorDomain.STORAGE,
1192
1033
  category: ErrorCategory.THIRD_PARTY,
1193
1034
  details: { tableName }
@@ -1207,7 +1048,7 @@ var StoreOperationsLance = class extends StoreOperations {
1207
1048
  } catch (validationError) {
1208
1049
  throw new MastraError(
1209
1050
  {
1210
- id: "STORAGE_LANCE_STORAGE_CLEAR_TABLE_INVALID_ARGS",
1051
+ id: createStorageErrorId("LANCE", "CLEAR_TABLE", "INVALID_ARGS"),
1211
1052
  domain: ErrorDomain.STORAGE,
1212
1053
  category: ErrorCategory.USER,
1213
1054
  text: validationError.message,
@@ -1222,7 +1063,7 @@ var StoreOperationsLance = class extends StoreOperations {
1222
1063
  } catch (error) {
1223
1064
  throw new MastraError(
1224
1065
  {
1225
- id: "STORAGE_LANCE_STORAGE_CLEAR_TABLE_FAILED",
1066
+ id: createStorageErrorId("LANCE", "CLEAR_TABLE", "FAILED"),
1226
1067
  domain: ErrorDomain.STORAGE,
1227
1068
  category: ErrorCategory.THIRD_PARTY,
1228
1069
  details: { tableName }
@@ -1245,7 +1086,7 @@ var StoreOperationsLance = class extends StoreOperations {
1245
1086
  } catch (validationError) {
1246
1087
  throw new MastraError(
1247
1088
  {
1248
- id: "STORAGE_LANCE_STORAGE_INSERT_INVALID_ARGS",
1089
+ id: createStorageErrorId("LANCE", "INSERT", "INVALID_ARGS"),
1249
1090
  domain: ErrorDomain.STORAGE,
1250
1091
  category: ErrorCategory.USER,
1251
1092
  text: validationError.message,
@@ -1264,12 +1105,11 @@ var StoreOperationsLance = class extends StoreOperations {
1264
1105
  processedRecord[key] = JSON.stringify(processedRecord[key]);
1265
1106
  }
1266
1107
  }
1267
- console.log(await table.schema());
1268
1108
  await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([processedRecord]);
1269
1109
  } catch (error) {
1270
1110
  throw new MastraError(
1271
1111
  {
1272
- id: "STORAGE_LANCE_STORAGE_INSERT_FAILED",
1112
+ id: createStorageErrorId("LANCE", "INSERT", "FAILED"),
1273
1113
  domain: ErrorDomain.STORAGE,
1274
1114
  category: ErrorCategory.THIRD_PARTY,
1275
1115
  details: { tableName }
@@ -1292,7 +1132,7 @@ var StoreOperationsLance = class extends StoreOperations {
1292
1132
  } catch (validationError) {
1293
1133
  throw new MastraError(
1294
1134
  {
1295
- id: "STORAGE_LANCE_STORAGE_BATCH_INSERT_INVALID_ARGS",
1135
+ id: createStorageErrorId("LANCE", "BATCH_INSERT", "INVALID_ARGS"),
1296
1136
  domain: ErrorDomain.STORAGE,
1297
1137
  category: ErrorCategory.USER,
1298
1138
  text: validationError.message,
@@ -1314,12 +1154,11 @@ var StoreOperationsLance = class extends StoreOperations {
1314
1154
  }
1315
1155
  return processedRecord;
1316
1156
  });
1317
- console.log(processedRecords);
1318
1157
  await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(processedRecords);
1319
1158
  } catch (error) {
1320
1159
  throw new MastraError(
1321
1160
  {
1322
- id: "STORAGE_LANCE_STORAGE_BATCH_INSERT_FAILED",
1161
+ id: createStorageErrorId("LANCE", "BATCH_INSERT", "FAILED"),
1323
1162
  domain: ErrorDomain.STORAGE,
1324
1163
  category: ErrorCategory.THIRD_PARTY,
1325
1164
  details: { tableName }
@@ -1342,7 +1181,7 @@ var StoreOperationsLance = class extends StoreOperations {
1342
1181
  } catch (validationError) {
1343
1182
  throw new MastraError(
1344
1183
  {
1345
- id: "STORAGE_LANCE_STORAGE_LOAD_INVALID_ARGS",
1184
+ id: createStorageErrorId("LANCE", "LOAD", "INVALID_ARGS"),
1346
1185
  domain: ErrorDomain.STORAGE,
1347
1186
  category: ErrorCategory.USER,
1348
1187
  text: validationError.message,
@@ -1381,7 +1220,7 @@ var StoreOperationsLance = class extends StoreOperations {
1381
1220
  if (error instanceof MastraError) throw error;
1382
1221
  throw new MastraError(
1383
1222
  {
1384
- id: "STORAGE_LANCE_STORAGE_LOAD_FAILED",
1223
+ id: createStorageErrorId("LANCE", "LOAD", "FAILED"),
1385
1224
  domain: ErrorDomain.STORAGE,
1386
1225
  category: ErrorCategory.THIRD_PARTY,
1387
1226
  details: { tableName, keyCount: Object.keys(keys).length, firstKey: Object.keys(keys)[0] ?? "" }
@@ -1398,29 +1237,53 @@ var StoreScoresLance = class extends ScoresStorage {
1398
1237
  this.client = client;
1399
1238
  }
1400
1239
  async saveScore(score) {
1240
+ let validatedScore;
1241
+ try {
1242
+ validatedScore = saveScorePayloadSchema.parse(score);
1243
+ } catch (error) {
1244
+ throw new MastraError(
1245
+ {
1246
+ id: createStorageErrorId("LANCE", "SAVE_SCORE", "VALIDATION_FAILED"),
1247
+ text: "Failed to save score in LanceStorage",
1248
+ domain: ErrorDomain.STORAGE,
1249
+ category: ErrorCategory.USER,
1250
+ details: {
1251
+ scorer: score.scorer?.id ?? "unknown",
1252
+ entityId: score.entityId ?? "unknown",
1253
+ entityType: score.entityType ?? "unknown",
1254
+ traceId: score.traceId ?? "",
1255
+ spanId: score.spanId ?? ""
1256
+ }
1257
+ },
1258
+ error
1259
+ );
1260
+ }
1261
+ const id = crypto.randomUUID();
1262
+ const now = /* @__PURE__ */ new Date();
1401
1263
  try {
1402
- const id = crypto.randomUUID();
1403
1264
  const table = await this.client.openTable(TABLE_SCORERS);
1404
1265
  const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1405
1266
  const allowedFields = new Set(schema.fields.map((f) => f.name));
1406
1267
  const filteredScore = {};
1407
- Object.keys(score).forEach((key) => {
1268
+ for (const key of Object.keys(validatedScore)) {
1408
1269
  if (allowedFields.has(key)) {
1409
- filteredScore[key] = score[key];
1270
+ filteredScore[key] = validatedScore[key];
1410
1271
  }
1411
- });
1272
+ }
1412
1273
  for (const key in filteredScore) {
1413
1274
  if (filteredScore[key] !== null && typeof filteredScore[key] === "object" && !(filteredScore[key] instanceof Date)) {
1414
1275
  filteredScore[key] = JSON.stringify(filteredScore[key]);
1415
1276
  }
1416
1277
  }
1417
1278
  filteredScore.id = id;
1279
+ filteredScore.createdAt = now;
1280
+ filteredScore.updatedAt = now;
1418
1281
  await table.add([filteredScore], { mode: "append" });
1419
- return { score };
1282
+ return { score: { ...validatedScore, id, createdAt: now, updatedAt: now } };
1420
1283
  } catch (error) {
1421
1284
  throw new MastraError(
1422
1285
  {
1423
- id: "LANCE_STORAGE_SAVE_SCORE_FAILED",
1286
+ id: createStorageErrorId("LANCE", "SAVE_SCORE", "FAILED"),
1424
1287
  text: "Failed to save score in LanceStorage",
1425
1288
  domain: ErrorDomain.STORAGE,
1426
1289
  category: ErrorCategory.THIRD_PARTY,
@@ -1436,12 +1299,11 @@ var StoreScoresLance = class extends ScoresStorage {
1436
1299
  const query = table.query().where(`id = '${id}'`).limit(1);
1437
1300
  const records = await query.toArray();
1438
1301
  if (records.length === 0) return null;
1439
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1440
- return processResultWithTypeConversion(records[0], schema);
1302
+ return await this.transformScoreRow(records[0]);
1441
1303
  } catch (error) {
1442
1304
  throw new MastraError(
1443
1305
  {
1444
- id: "LANCE_STORAGE_GET_SCORE_BY_ID_FAILED",
1306
+ id: createStorageErrorId("LANCE", "GET_SCORE_BY_ID", "FAILED"),
1445
1307
  text: "Failed to get score by id in LanceStorage",
1446
1308
  domain: ErrorDomain.STORAGE,
1447
1309
  category: ErrorCategory.THIRD_PARTY,
@@ -1451,7 +1313,23 @@ var StoreScoresLance = class extends ScoresStorage {
1451
1313
  );
1452
1314
  }
1453
1315
  }
1454
- async getScoresByScorerId({
1316
+ /**
1317
+ * LanceDB-specific score row transformation.
1318
+ *
1319
+ * Note: This implementation does NOT use coreTransformScoreRow because:
1320
+ * 1. LanceDB stores schema information in the table itself (requires async fetch)
1321
+ * 2. Uses processResultWithTypeConversion utility for LanceDB-specific type handling
1322
+ */
1323
+ async transformScoreRow(row) {
1324
+ const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1325
+ const transformed = processResultWithTypeConversion(row, schema);
1326
+ return {
1327
+ ...transformed,
1328
+ createdAt: row.createdAt,
1329
+ updatedAt: row.updatedAt
1330
+ };
1331
+ }
1332
+ async listScoresByScorerId({
1455
1333
  scorerId,
1456
1334
  pagination,
1457
1335
  entityId,
@@ -1459,9 +1337,10 @@ var StoreScoresLance = class extends ScoresStorage {
1459
1337
  source
1460
1338
  }) {
1461
1339
  try {
1340
+ const { page, perPage: perPageInput } = pagination;
1341
+ const perPage = normalizePerPage(perPageInput, 100);
1342
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1462
1343
  const table = await this.client.openTable(TABLE_SCORERS);
1463
- const { page = 0, perPage = 10 } = pagination || {};
1464
- const offset = page * perPage;
1465
1344
  let query = table.query().where(`\`scorerId\` = '${scorerId}'`);
1466
1345
  if (source) {
1467
1346
  query = query.where(`\`source\` = '${source}'`);
@@ -1472,30 +1351,38 @@ var StoreScoresLance = class extends ScoresStorage {
1472
1351
  if (entityType) {
1473
1352
  query = query.where(`\`entityType\` = '${entityType}'`);
1474
1353
  }
1475
- query = query.limit(perPage);
1476
- if (offset > 0) query.offset(offset);
1477
- const records = await query.toArray();
1478
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1479
- const scores = processResultWithTypeConversion(records, schema);
1480
1354
  let totalQuery = table.query().where(`\`scorerId\` = '${scorerId}'`);
1481
1355
  if (source) {
1482
1356
  totalQuery = totalQuery.where(`\`source\` = '${source}'`);
1483
1357
  }
1358
+ if (entityId) {
1359
+ totalQuery = totalQuery.where(`\`entityId\` = '${entityId}'`);
1360
+ }
1361
+ if (entityType) {
1362
+ totalQuery = totalQuery.where(`\`entityType\` = '${entityType}'`);
1363
+ }
1484
1364
  const allRecords = await totalQuery.toArray();
1485
1365
  const total = allRecords.length;
1366
+ const end = perPageInput === false ? total : start + perPage;
1367
+ if (perPageInput !== false) {
1368
+ query = query.limit(perPage);
1369
+ if (start > 0) query = query.offset(start);
1370
+ }
1371
+ const records = await query.toArray();
1372
+ const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
1486
1373
  return {
1487
1374
  pagination: {
1488
1375
  page,
1489
- perPage,
1376
+ perPage: perPageForResponse,
1490
1377
  total,
1491
- hasMore: offset + scores.length < total
1378
+ hasMore: end < total
1492
1379
  },
1493
1380
  scores
1494
1381
  };
1495
1382
  } catch (error) {
1496
1383
  throw new MastraError(
1497
1384
  {
1498
- id: "LANCE_STORAGE_GET_SCORES_BY_SCORER_ID_FAILED",
1385
+ id: createStorageErrorId("LANCE", "LIST_SCORES_BY_SCORER_ID", "FAILED"),
1499
1386
  text: "Failed to get scores by scorerId in LanceStorage",
1500
1387
  domain: ErrorDomain.STORAGE,
1501
1388
  category: ErrorCategory.THIRD_PARTY,
@@ -1505,34 +1392,38 @@ var StoreScoresLance = class extends ScoresStorage {
1505
1392
  );
1506
1393
  }
1507
1394
  }
1508
- async getScoresByRunId({
1395
+ async listScoresByRunId({
1509
1396
  runId,
1510
1397
  pagination
1511
1398
  }) {
1512
1399
  try {
1400
+ const { page, perPage: perPageInput } = pagination;
1401
+ const perPage = normalizePerPage(perPageInput, 100);
1402
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1513
1403
  const table = await this.client.openTable(TABLE_SCORERS);
1514
- const { page = 0, perPage = 10 } = pagination || {};
1515
- const offset = page * perPage;
1516
- const query = table.query().where(`\`runId\` = '${runId}'`).limit(perPage);
1517
- if (offset > 0) query.offset(offset);
1518
- const records = await query.toArray();
1519
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1520
- const scores = processResultWithTypeConversion(records, schema);
1521
1404
  const allRecords = await table.query().where(`\`runId\` = '${runId}'`).toArray();
1522
1405
  const total = allRecords.length;
1406
+ const end = perPageInput === false ? total : start + perPage;
1407
+ let query = table.query().where(`\`runId\` = '${runId}'`);
1408
+ if (perPageInput !== false) {
1409
+ query = query.limit(perPage);
1410
+ if (start > 0) query = query.offset(start);
1411
+ }
1412
+ const records = await query.toArray();
1413
+ const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
1523
1414
  return {
1524
1415
  pagination: {
1525
1416
  page,
1526
- perPage,
1417
+ perPage: perPageForResponse,
1527
1418
  total,
1528
- hasMore: offset + scores.length < total
1419
+ hasMore: end < total
1529
1420
  },
1530
1421
  scores
1531
1422
  };
1532
1423
  } catch (error) {
1533
1424
  throw new MastraError(
1534
1425
  {
1535
- id: "LANCE_STORAGE_GET_SCORES_BY_RUN_ID_FAILED",
1426
+ id: createStorageErrorId("LANCE", "LIST_SCORES_BY_RUN_ID", "FAILED"),
1536
1427
  text: "Failed to get scores by runId in LanceStorage",
1537
1428
  domain: ErrorDomain.STORAGE,
1538
1429
  category: ErrorCategory.THIRD_PARTY,
@@ -1542,35 +1433,39 @@ var StoreScoresLance = class extends ScoresStorage {
1542
1433
  );
1543
1434
  }
1544
1435
  }
1545
- async getScoresByEntityId({
1436
+ async listScoresByEntityId({
1546
1437
  entityId,
1547
1438
  entityType,
1548
1439
  pagination
1549
1440
  }) {
1550
1441
  try {
1442
+ const { page, perPage: perPageInput } = pagination;
1443
+ const perPage = normalizePerPage(perPageInput, 100);
1444
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1551
1445
  const table = await this.client.openTable(TABLE_SCORERS);
1552
- const { page = 0, perPage = 10 } = pagination || {};
1553
- const offset = page * perPage;
1554
- const query = table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).limit(perPage);
1555
- if (offset > 0) query.offset(offset);
1556
- const records = await query.toArray();
1557
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1558
- const scores = processResultWithTypeConversion(records, schema);
1559
1446
  const allRecords = await table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).toArray();
1560
1447
  const total = allRecords.length;
1448
+ const end = perPageInput === false ? total : start + perPage;
1449
+ let query = table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`);
1450
+ if (perPageInput !== false) {
1451
+ query = query.limit(perPage);
1452
+ if (start > 0) query = query.offset(start);
1453
+ }
1454
+ const records = await query.toArray();
1455
+ const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
1561
1456
  return {
1562
1457
  pagination: {
1563
1458
  page,
1564
- perPage,
1459
+ perPage: perPageForResponse,
1565
1460
  total,
1566
- hasMore: offset + scores.length < total
1461
+ hasMore: end < total
1567
1462
  },
1568
1463
  scores
1569
1464
  };
1570
1465
  } catch (error) {
1571
1466
  throw new MastraError(
1572
1467
  {
1573
- id: "LANCE_STORAGE_GET_SCORES_BY_ENTITY_ID_FAILED",
1468
+ id: createStorageErrorId("LANCE", "LIST_SCORES_BY_ENTITY_ID", "FAILED"),
1574
1469
  text: "Failed to get scores by entityId and entityType in LanceStorage",
1575
1470
  domain: ErrorDomain.STORAGE,
1576
1471
  category: ErrorCategory.THIRD_PARTY,
@@ -1580,198 +1475,48 @@ var StoreScoresLance = class extends ScoresStorage {
1580
1475
  );
1581
1476
  }
1582
1477
  }
1583
- };
1584
- var StoreTracesLance = class extends TracesStorage {
1585
- client;
1586
- operations;
1587
- constructor({ client, operations }) {
1588
- super();
1589
- this.client = client;
1590
- this.operations = operations;
1591
- }
1592
- async saveTrace({ trace }) {
1593
- try {
1594
- const table = await this.client.openTable(TABLE_TRACES);
1595
- const record = {
1596
- ...trace,
1597
- attributes: JSON.stringify(trace.attributes),
1598
- status: JSON.stringify(trace.status),
1599
- events: JSON.stringify(trace.events),
1600
- links: JSON.stringify(trace.links),
1601
- other: JSON.stringify(trace.other)
1602
- };
1603
- await table.add([record], { mode: "append" });
1604
- return trace;
1605
- } catch (error) {
1606
- throw new MastraError(
1607
- {
1608
- id: "LANCE_STORE_SAVE_TRACE_FAILED",
1609
- domain: ErrorDomain.STORAGE,
1610
- category: ErrorCategory.THIRD_PARTY
1611
- },
1612
- error
1613
- );
1614
- }
1615
- }
1616
- async getTraceById({ traceId }) {
1617
- try {
1618
- const table = await this.client.openTable(TABLE_TRACES);
1619
- const query = table.query().where(`id = '${traceId}'`);
1620
- const records = await query.toArray();
1621
- return records[0];
1622
- } catch (error) {
1623
- throw new MastraError(
1624
- {
1625
- id: "LANCE_STORE_GET_TRACE_BY_ID_FAILED",
1626
- domain: ErrorDomain.STORAGE,
1627
- category: ErrorCategory.THIRD_PARTY
1628
- },
1629
- error
1630
- );
1631
- }
1632
- }
1633
- async getTraces({
1634
- name,
1635
- scope,
1636
- page = 1,
1637
- perPage = 10,
1638
- attributes
1478
+ async listScoresBySpan({
1479
+ traceId,
1480
+ spanId,
1481
+ pagination
1639
1482
  }) {
1640
1483
  try {
1641
- const table = await this.client.openTable(TABLE_TRACES);
1642
- const query = table.query();
1643
- if (name) {
1644
- query.where(`name = '${name}'`);
1645
- }
1646
- if (scope) {
1647
- query.where(`scope = '${scope}'`);
1648
- }
1649
- if (attributes) {
1650
- query.where(`attributes = '${JSON.stringify(attributes)}'`);
1651
- }
1652
- const offset = (page - 1) * perPage;
1653
- query.limit(perPage);
1654
- if (offset > 0) {
1655
- query.offset(offset);
1656
- }
1657
- const records = await query.toArray();
1658
- return records.map((record) => {
1659
- const processed = {
1660
- ...record,
1661
- attributes: record.attributes ? JSON.parse(record.attributes) : {},
1662
- status: record.status ? JSON.parse(record.status) : {},
1663
- events: record.events ? JSON.parse(record.events) : [],
1664
- links: record.links ? JSON.parse(record.links) : [],
1665
- other: record.other ? JSON.parse(record.other) : {},
1666
- startTime: new Date(record.startTime),
1667
- endTime: new Date(record.endTime),
1668
- createdAt: new Date(record.createdAt)
1669
- };
1670
- if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
1671
- processed.parentSpanId = "";
1672
- } else {
1673
- processed.parentSpanId = String(processed.parentSpanId);
1674
- }
1675
- return processed;
1676
- });
1677
- } catch (error) {
1678
- throw new MastraError(
1679
- {
1680
- id: "LANCE_STORE_GET_TRACES_FAILED",
1681
- domain: ErrorDomain.STORAGE,
1682
- category: ErrorCategory.THIRD_PARTY,
1683
- details: { name: name ?? "", scope: scope ?? "" }
1684
- },
1685
- error
1686
- );
1687
- }
1688
- }
1689
- async getTracesPaginated(args) {
1690
- try {
1691
- const table = await this.client.openTable(TABLE_TRACES);
1692
- const query = table.query();
1693
- const conditions = [];
1694
- if (args.name) {
1695
- conditions.push(`name = '${args.name}'`);
1696
- }
1697
- if (args.scope) {
1698
- conditions.push(`scope = '${args.scope}'`);
1699
- }
1700
- if (args.attributes) {
1701
- const attributesStr = JSON.stringify(args.attributes);
1702
- conditions.push(`attributes LIKE '%${attributesStr.replace(/"/g, '\\"')}%'`);
1703
- }
1704
- if (args.dateRange?.start) {
1705
- conditions.push(`\`createdAt\` >= ${args.dateRange.start.getTime()}`);
1706
- }
1707
- if (args.dateRange?.end) {
1708
- conditions.push(`\`createdAt\` <= ${args.dateRange.end.getTime()}`);
1709
- }
1710
- if (conditions.length > 0) {
1711
- const whereClause = conditions.join(" AND ");
1712
- query.where(whereClause);
1713
- }
1714
- let total = 0;
1715
- if (conditions.length > 0) {
1716
- const countQuery = table.query().where(conditions.join(" AND "));
1717
- const allRecords = await countQuery.toArray();
1718
- total = allRecords.length;
1719
- } else {
1720
- total = await table.countRows();
1721
- }
1722
- const page = args.page || 0;
1723
- const perPage = args.perPage || 10;
1724
- const offset = page * perPage;
1725
- query.limit(perPage);
1726
- if (offset > 0) {
1727
- query.offset(offset);
1484
+ const { page, perPage: perPageInput } = pagination;
1485
+ const perPage = normalizePerPage(perPageInput, 100);
1486
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1487
+ const table = await this.client.openTable(TABLE_SCORERS);
1488
+ const allRecords = await table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`).toArray();
1489
+ const total = allRecords.length;
1490
+ const end = perPageInput === false ? total : start + perPage;
1491
+ let query = table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`);
1492
+ if (perPageInput !== false) {
1493
+ query = query.limit(perPage);
1494
+ if (start > 0) query = query.offset(start);
1728
1495
  }
1729
1496
  const records = await query.toArray();
1730
- const traces = records.map((record) => {
1731
- const processed = {
1732
- ...record,
1733
- attributes: record.attributes ? JSON.parse(record.attributes) : {},
1734
- status: record.status ? JSON.parse(record.status) : {},
1735
- events: record.events ? JSON.parse(record.events) : [],
1736
- links: record.links ? JSON.parse(record.links) : [],
1737
- other: record.other ? JSON.parse(record.other) : {},
1738
- startTime: new Date(record.startTime),
1739
- endTime: new Date(record.endTime),
1740
- createdAt: new Date(record.createdAt)
1741
- };
1742
- if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
1743
- processed.parentSpanId = "";
1744
- } else {
1745
- processed.parentSpanId = String(processed.parentSpanId);
1746
- }
1747
- return processed;
1748
- });
1497
+ const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
1749
1498
  return {
1750
- traces,
1751
- total,
1752
- page,
1753
- perPage,
1754
- hasMore: total > (page + 1) * perPage
1499
+ pagination: {
1500
+ page,
1501
+ perPage: perPageForResponse,
1502
+ total,
1503
+ hasMore: end < total
1504
+ },
1505
+ scores
1755
1506
  };
1756
1507
  } catch (error) {
1757
1508
  throw new MastraError(
1758
1509
  {
1759
- id: "LANCE_STORE_GET_TRACES_PAGINATED_FAILED",
1510
+ id: createStorageErrorId("LANCE", "LIST_SCORES_BY_SPAN", "FAILED"),
1511
+ text: "Failed to get scores by traceId and spanId in LanceStorage",
1760
1512
  domain: ErrorDomain.STORAGE,
1761
1513
  category: ErrorCategory.THIRD_PARTY,
1762
- details: { name: args.name ?? "", scope: args.scope ?? "" }
1514
+ details: { error: error?.message }
1763
1515
  },
1764
1516
  error
1765
1517
  );
1766
1518
  }
1767
1519
  }
1768
- async batchTraceInsert({ records }) {
1769
- this.logger.debug("Batch inserting traces", { count: records.length });
1770
- await this.operations.batchInsert({
1771
- tableName: TABLE_TRACES,
1772
- records
1773
- });
1774
- }
1775
1520
  };
1776
1521
  function parseWorkflowRun(row) {
1777
1522
  let parsedSnapshot = row.snapshot;
@@ -1802,7 +1547,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1802
1547
  // runId,
1803
1548
  // stepId,
1804
1549
  // result,
1805
- // runtimeContext,
1550
+ // requestContext,
1806
1551
  }) {
1807
1552
  throw new Error("Method not implemented.");
1808
1553
  }
@@ -1830,11 +1575,13 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1830
1575
  } else {
1831
1576
  createdAt = now;
1832
1577
  }
1578
+ const { status, value, ...rest } = snapshot;
1833
1579
  const record = {
1834
1580
  workflow_name: workflowName,
1835
1581
  run_id: runId,
1836
1582
  resourceId,
1837
- snapshot: JSON.stringify(snapshot),
1583
+ snapshot: JSON.stringify({ status, value, ...rest }),
1584
+ // this is to ensure status is always just before value, for when querying the db by status
1838
1585
  createdAt,
1839
1586
  updatedAt: now
1840
1587
  };
@@ -1842,7 +1589,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1842
1589
  } catch (error) {
1843
1590
  throw new MastraError(
1844
1591
  {
1845
- id: "LANCE_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
1592
+ id: createStorageErrorId("LANCE", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
1846
1593
  domain: ErrorDomain.STORAGE,
1847
1594
  category: ErrorCategory.THIRD_PARTY,
1848
1595
  details: { workflowName, runId }
@@ -1863,7 +1610,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1863
1610
  } catch (error) {
1864
1611
  throw new MastraError(
1865
1612
  {
1866
- id: "LANCE_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
1613
+ id: createStorageErrorId("LANCE", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
1867
1614
  domain: ErrorDomain.STORAGE,
1868
1615
  category: ErrorCategory.THIRD_PARTY,
1869
1616
  details: { workflowName, runId }
@@ -1887,7 +1634,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1887
1634
  } catch (error) {
1888
1635
  throw new MastraError(
1889
1636
  {
1890
- id: "LANCE_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
1637
+ id: createStorageErrorId("LANCE", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
1891
1638
  domain: ErrorDomain.STORAGE,
1892
1639
  category: ErrorCategory.THIRD_PARTY,
1893
1640
  details: { runId: args.runId, workflowName: args.workflowName ?? "" }
@@ -1896,7 +1643,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1896
1643
  );
1897
1644
  }
1898
1645
  }
1899
- async getWorkflowRuns(args) {
1646
+ async listWorkflowRuns(args) {
1900
1647
  try {
1901
1648
  const table = await this.client.openTable(TABLE_WORKFLOW_SNAPSHOT);
1902
1649
  let query = table.query();
@@ -1904,6 +1651,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1904
1651
  if (args?.workflowName) {
1905
1652
  conditions.push(`workflow_name = '${args.workflowName.replace(/'/g, "''")}'`);
1906
1653
  }
1654
+ if (args?.status) {
1655
+ const escapedStatus = args.status.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/%/g, "\\%").replace(/_/g, "\\_");
1656
+ conditions.push(`\`snapshot\` LIKE '%"status":"${escapedStatus}","value"%'`);
1657
+ }
1907
1658
  if (args?.resourceId) {
1908
1659
  conditions.push(`\`resourceId\` = '${args.resourceId}'`);
1909
1660
  }
@@ -1920,11 +1671,22 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1920
1671
  } else {
1921
1672
  total = await table.countRows();
1922
1673
  }
1923
- if (args?.limit) {
1924
- query.limit(args.limit);
1925
- }
1926
- if (args?.offset) {
1927
- query.offset(args.offset);
1674
+ if (args?.perPage !== void 0 && args?.page !== void 0) {
1675
+ const normalizedPerPage = normalizePerPage(args.perPage, Number.MAX_SAFE_INTEGER);
1676
+ if (args.page < 0 || !Number.isInteger(args.page)) {
1677
+ throw new MastraError(
1678
+ {
1679
+ id: createStorageErrorId("LANCE", "LIST_WORKFLOW_RUNS", "INVALID_PAGINATION"),
1680
+ domain: ErrorDomain.STORAGE,
1681
+ category: ErrorCategory.USER,
1682
+ details: { page: args.page, perPage: args.perPage }
1683
+ },
1684
+ new Error(`Invalid pagination parameters: page=${args.page}, perPage=${args.perPage}`)
1685
+ );
1686
+ }
1687
+ const offset = args.page * normalizedPerPage;
1688
+ query.limit(normalizedPerPage);
1689
+ query.offset(offset);
1928
1690
  }
1929
1691
  const records = await query.toArray();
1930
1692
  return {
@@ -1934,10 +1696,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1934
1696
  } catch (error) {
1935
1697
  throw new MastraError(
1936
1698
  {
1937
- id: "LANCE_STORE_GET_WORKFLOW_RUNS_FAILED",
1699
+ id: createStorageErrorId("LANCE", "LIST_WORKFLOW_RUNS", "FAILED"),
1938
1700
  domain: ErrorDomain.STORAGE,
1939
1701
  category: ErrorCategory.THIRD_PARTY,
1940
- details: { namespace: args?.namespace ?? "", workflowName: args?.workflowName ?? "" }
1702
+ details: { resourceId: args?.resourceId ?? "", workflowName: args?.workflowName ?? "" }
1941
1703
  },
1942
1704
  error
1943
1705
  );
@@ -1951,48 +1713,54 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
1951
1713
  lanceClient;
1952
1714
  /**
1953
1715
  * Creates a new instance of LanceStorage
1716
+ * @param id The unique identifier for this storage instance
1717
+ * @param name The name for this storage instance
1954
1718
  * @param uri The URI to connect to LanceDB
1955
- * @param options connection options
1719
+ * @param connectionOptions connection options for LanceDB
1720
+ * @param storageOptions storage options including disableInit
1956
1721
  *
1957
1722
  * Usage:
1958
1723
  *
1959
1724
  * Connect to a local database
1960
1725
  * ```ts
1961
- * const store = await LanceStorage.create('/path/to/db');
1726
+ * const store = await LanceStorage.create('my-storage-id', 'MyStorage', '/path/to/db');
1962
1727
  * ```
1963
1728
  *
1964
1729
  * Connect to a LanceDB cloud database
1965
1730
  * ```ts
1966
- * const store = await LanceStorage.create('db://host:port');
1731
+ * const store = await LanceStorage.create('my-storage-id', 'MyStorage', 'db://host:port');
1967
1732
  * ```
1968
1733
  *
1969
1734
  * Connect to a cloud database
1970
1735
  * ```ts
1971
- * const store = await LanceStorage.create('s3://bucket/db', { storageOptions: { timeout: '60s' } });
1736
+ * const store = await LanceStorage.create('my-storage-id', 'MyStorage', 's3://bucket/db', { storageOptions: { timeout: '60s' } });
1737
+ * ```
1738
+ *
1739
+ * Disable auto-init for runtime (after CI/CD has run migrations)
1740
+ * ```ts
1741
+ * const store = await LanceStorage.create('my-storage-id', 'MyStorage', '/path/to/db', undefined, { disableInit: true });
1972
1742
  * ```
1973
1743
  */
1974
- static async create(name, uri, options) {
1975
- const instance = new _LanceStorage(name);
1744
+ static async create(id, name, uri, connectionOptions, storageOptions) {
1745
+ const instance = new _LanceStorage(id, name, storageOptions?.disableInit);
1976
1746
  try {
1977
- instance.lanceClient = await connect(uri, options);
1747
+ instance.lanceClient = await connect(uri, connectionOptions);
1978
1748
  const operations = new StoreOperationsLance({ client: instance.lanceClient });
1979
1749
  instance.stores = {
1980
1750
  operations: new StoreOperationsLance({ client: instance.lanceClient }),
1981
1751
  workflows: new StoreWorkflowsLance({ client: instance.lanceClient }),
1982
- traces: new StoreTracesLance({ client: instance.lanceClient, operations }),
1983
1752
  scores: new StoreScoresLance({ client: instance.lanceClient }),
1984
- memory: new StoreMemoryLance({ client: instance.lanceClient, operations }),
1985
- legacyEvals: new StoreLegacyEvalsLance({ client: instance.lanceClient })
1753
+ memory: new StoreMemoryLance({ client: instance.lanceClient, operations })
1986
1754
  };
1987
1755
  return instance;
1988
1756
  } catch (e) {
1989
1757
  throw new MastraError(
1990
1758
  {
1991
- id: "STORAGE_LANCE_STORAGE_CONNECT_FAILED",
1759
+ id: createStorageErrorId("LANCE", "CONNECT", "FAILED"),
1992
1760
  domain: ErrorDomain.STORAGE,
1993
1761
  category: ErrorCategory.THIRD_PARTY,
1994
1762
  text: `Failed to connect to LanceDB: ${e.message || e}`,
1995
- details: { uri, optionsProvided: !!options }
1763
+ details: { uri, optionsProvided: !!connectionOptions }
1996
1764
  },
1997
1765
  e
1998
1766
  );
@@ -2002,15 +1770,13 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2002
1770
  * @internal
2003
1771
  * Private constructor to enforce using the create factory method
2004
1772
  */
2005
- constructor(name) {
2006
- super({ name });
1773
+ constructor(id, name, disableInit) {
1774
+ super({ id, name, disableInit });
2007
1775
  const operations = new StoreOperationsLance({ client: this.lanceClient });
2008
1776
  this.stores = {
2009
1777
  operations: new StoreOperationsLance({ client: this.lanceClient }),
2010
1778
  workflows: new StoreWorkflowsLance({ client: this.lanceClient }),
2011
- traces: new StoreTracesLance({ client: this.lanceClient, operations }),
2012
1779
  scores: new StoreScoresLance({ client: this.lanceClient }),
2013
- legacyEvals: new StoreLegacyEvalsLance({ client: this.lanceClient }),
2014
1780
  memory: new StoreMemoryLance({ client: this.lanceClient, operations })
2015
1781
  };
2016
1782
  }
@@ -2045,9 +1811,6 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2045
1811
  async getThreadById({ threadId }) {
2046
1812
  return this.stores.memory.getThreadById({ threadId });
2047
1813
  }
2048
- async getThreadsByResourceId({ resourceId }) {
2049
- return this.stores.memory.getThreadsByResourceId({ resourceId });
2050
- }
2051
1814
  /**
2052
1815
  * Saves a thread to the database. This function doesn't overwrite existing threads.
2053
1816
  * @param thread - The thread to save
@@ -2072,7 +1835,8 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2072
1835
  resourceWorkingMemory: true,
2073
1836
  hasColumn: true,
2074
1837
  createTable: true,
2075
- deleteMessages: false
1838
+ deleteMessages: false,
1839
+ listScoresBySpan: true
2076
1840
  };
2077
1841
  }
2078
1842
  async getResourceById({ resourceId }) {
@@ -2136,50 +1900,17 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2136
1900
  });
2137
1901
  return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
2138
1902
  }
2139
- async getMessages({
2140
- threadId,
2141
- resourceId,
2142
- selectBy,
2143
- format,
2144
- threadConfig
2145
- }) {
2146
- return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format, threadConfig });
2147
- }
2148
- async getMessagesById({
2149
- messageIds,
2150
- format
2151
- }) {
2152
- return this.stores.memory.getMessagesById({ messageIds, format });
1903
+ async listMessagesById({ messageIds }) {
1904
+ return this.stores.memory.listMessagesById({ messageIds });
2153
1905
  }
2154
1906
  async saveMessages(args) {
2155
1907
  return this.stores.memory.saveMessages(args);
2156
1908
  }
2157
- async getThreadsByResourceIdPaginated(args) {
2158
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
2159
- }
2160
- async getMessagesPaginated(args) {
2161
- return this.stores.memory.getMessagesPaginated(args);
2162
- }
2163
1909
  async updateMessages(_args) {
2164
1910
  return this.stores.memory.updateMessages(_args);
2165
1911
  }
2166
- async getTraceById(args) {
2167
- return this.stores.traces.getTraceById(args);
2168
- }
2169
- async getTraces(args) {
2170
- return this.stores.traces.getTraces(args);
2171
- }
2172
- async getTracesPaginated(args) {
2173
- return this.stores.traces.getTracesPaginated(args);
2174
- }
2175
- async getEvalsByAgentName(agentName, type) {
2176
- return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
2177
- }
2178
- async getEvals(options) {
2179
- return this.stores.legacyEvals.getEvals(options);
2180
- }
2181
- async getWorkflowRuns(args) {
2182
- return this.stores.workflows.getWorkflowRuns(args);
1912
+ async listWorkflowRuns(args) {
1913
+ return this.stores.workflows.listWorkflowRuns(args);
2183
1914
  }
2184
1915
  async getWorkflowRunById(args) {
2185
1916
  return this.stores.workflows.getWorkflowRunById(args);
@@ -2189,9 +1920,9 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2189
1920
  runId,
2190
1921
  stepId,
2191
1922
  result,
2192
- runtimeContext
1923
+ requestContext
2193
1924
  }) {
2194
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
1925
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
2195
1926
  }
2196
1927
  async updateWorkflowState({
2197
1928
  workflowName,
@@ -2217,30 +1948,37 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2217
1948
  async getScoreById({ id: _id }) {
2218
1949
  return this.stores.scores.getScoreById({ id: _id });
2219
1950
  }
2220
- async getScoresByScorerId({
1951
+ async listScoresByScorerId({
2221
1952
  scorerId,
2222
1953
  source,
2223
1954
  entityId,
2224
1955
  entityType,
2225
1956
  pagination
2226
1957
  }) {
2227
- return this.stores.scores.getScoresByScorerId({ scorerId, source, pagination, entityId, entityType });
1958
+ return this.stores.scores.listScoresByScorerId({ scorerId, source, pagination, entityId, entityType });
2228
1959
  }
2229
- async saveScore(_score) {
2230
- return this.stores.scores.saveScore(_score);
1960
+ async saveScore(score) {
1961
+ return this.stores.scores.saveScore(score);
2231
1962
  }
2232
- async getScoresByRunId({
1963
+ async listScoresByRunId({
2233
1964
  runId,
2234
1965
  pagination
2235
1966
  }) {
2236
- return this.stores.scores.getScoresByRunId({ runId, pagination });
1967
+ return this.stores.scores.listScoresByRunId({ runId, pagination });
2237
1968
  }
2238
- async getScoresByEntityId({
1969
+ async listScoresByEntityId({
2239
1970
  entityId,
2240
1971
  entityType,
2241
1972
  pagination
2242
1973
  }) {
2243
- return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
1974
+ return this.stores.scores.listScoresByEntityId({ entityId, entityType, pagination });
1975
+ }
1976
+ async listScoresBySpan({
1977
+ traceId,
1978
+ spanId,
1979
+ pagination
1980
+ }) {
1981
+ return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
2244
1982
  }
2245
1983
  };
2246
1984
  var LanceFilterTranslator = class extends BaseFilterTranslator {
@@ -2589,14 +2327,14 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2589
2327
  * ```
2590
2328
  */
2591
2329
  static async create(uri, options) {
2592
- const instance = new _LanceVectorStore();
2330
+ const instance = new _LanceVectorStore(options?.id || crypto.randomUUID());
2593
2331
  try {
2594
2332
  instance.lanceClient = await connect(uri, options);
2595
2333
  return instance;
2596
2334
  } catch (e) {
2597
2335
  throw new MastraError(
2598
2336
  {
2599
- id: "STORAGE_LANCE_VECTOR_CONNECT_FAILED",
2337
+ id: createVectorErrorId("LANCE", "CONNECT", "FAILED"),
2600
2338
  domain: ErrorDomain.STORAGE,
2601
2339
  category: ErrorCategory.THIRD_PARTY,
2602
2340
  details: { uri }
@@ -2609,8 +2347,8 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2609
2347
  * @internal
2610
2348
  * Private constructor to enforce using the create factory method
2611
2349
  */
2612
- constructor() {
2613
- super();
2350
+ constructor(id) {
2351
+ super({ id });
2614
2352
  }
2615
2353
  close() {
2616
2354
  if (this.lanceClient) {
@@ -2639,7 +2377,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2639
2377
  } catch (error) {
2640
2378
  throw new MastraError(
2641
2379
  {
2642
- id: "STORAGE_LANCE_VECTOR_QUERY_FAILED_INVALID_ARGS",
2380
+ id: createVectorErrorId("LANCE", "QUERY", "INVALID_ARGS"),
2643
2381
  domain: ErrorDomain.STORAGE,
2644
2382
  category: ErrorCategory.USER,
2645
2383
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2687,7 +2425,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2687
2425
  } catch (error) {
2688
2426
  throw new MastraError(
2689
2427
  {
2690
- id: "STORAGE_LANCE_VECTOR_QUERY_FAILED",
2428
+ id: createVectorErrorId("LANCE", "QUERY", "FAILED"),
2691
2429
  domain: ErrorDomain.STORAGE,
2692
2430
  category: ErrorCategory.THIRD_PARTY,
2693
2431
  details: { tableName, includeVector, columnsCount: columns?.length, includeAllColumns }
@@ -2739,7 +2477,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2739
2477
  } catch (error) {
2740
2478
  throw new MastraError(
2741
2479
  {
2742
- id: "STORAGE_LANCE_VECTOR_UPSERT_FAILED_INVALID_ARGS",
2480
+ id: createVectorErrorId("LANCE", "UPSERT", "INVALID_ARGS"),
2743
2481
  domain: ErrorDomain.STORAGE,
2744
2482
  category: ErrorCategory.USER,
2745
2483
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2775,7 +2513,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2775
2513
  } catch (error) {
2776
2514
  throw new MastraError(
2777
2515
  {
2778
- id: "STORAGE_LANCE_VECTOR_UPSERT_FAILED",
2516
+ id: createVectorErrorId("LANCE", "UPSERT", "FAILED"),
2779
2517
  domain: ErrorDomain.STORAGE,
2780
2518
  category: ErrorCategory.THIRD_PARTY,
2781
2519
  details: { tableName, vectorCount: vectors.length, metadataCount: metadata.length, idsCount: ids.length }
@@ -2802,7 +2540,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2802
2540
  async createTable(tableName, data, options) {
2803
2541
  if (!this.lanceClient) {
2804
2542
  throw new MastraError({
2805
- id: "STORAGE_LANCE_VECTOR_CREATE_TABLE_FAILED_INVALID_ARGS",
2543
+ id: createVectorErrorId("LANCE", "CREATE_TABLE", "INVALID_ARGS"),
2806
2544
  domain: ErrorDomain.STORAGE,
2807
2545
  category: ErrorCategory.USER,
2808
2546
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2817,7 +2555,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2817
2555
  } catch (error) {
2818
2556
  throw new MastraError(
2819
2557
  {
2820
- id: "STORAGE_LANCE_VECTOR_CREATE_TABLE_FAILED",
2558
+ id: createVectorErrorId("LANCE", "CREATE_TABLE", "FAILED"),
2821
2559
  domain: ErrorDomain.STORAGE,
2822
2560
  category: ErrorCategory.THIRD_PARTY,
2823
2561
  details: { tableName }
@@ -2829,7 +2567,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2829
2567
  async listTables() {
2830
2568
  if (!this.lanceClient) {
2831
2569
  throw new MastraError({
2832
- id: "STORAGE_LANCE_VECTOR_LIST_TABLES_FAILED_INVALID_ARGS",
2570
+ id: createVectorErrorId("LANCE", "LIST_TABLES", "INVALID_ARGS"),
2833
2571
  domain: ErrorDomain.STORAGE,
2834
2572
  category: ErrorCategory.USER,
2835
2573
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2841,7 +2579,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2841
2579
  } catch (error) {
2842
2580
  throw new MastraError(
2843
2581
  {
2844
- id: "STORAGE_LANCE_VECTOR_LIST_TABLES_FAILED",
2582
+ id: createVectorErrorId("LANCE", "LIST_TABLES", "FAILED"),
2845
2583
  domain: ErrorDomain.STORAGE,
2846
2584
  category: ErrorCategory.THIRD_PARTY
2847
2585
  },
@@ -2852,7 +2590,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2852
2590
  async getTableSchema(tableName) {
2853
2591
  if (!this.lanceClient) {
2854
2592
  throw new MastraError({
2855
- id: "STORAGE_LANCE_VECTOR_GET_TABLE_SCHEMA_FAILED_INVALID_ARGS",
2593
+ id: createVectorErrorId("LANCE", "GET_TABLE_SCHEMA", "INVALID_ARGS"),
2856
2594
  domain: ErrorDomain.STORAGE,
2857
2595
  category: ErrorCategory.USER,
2858
2596
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2865,7 +2603,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2865
2603
  } catch (error) {
2866
2604
  throw new MastraError(
2867
2605
  {
2868
- id: "STORAGE_LANCE_VECTOR_GET_TABLE_SCHEMA_FAILED",
2606
+ id: createVectorErrorId("LANCE", "GET_TABLE_SCHEMA", "FAILED"),
2869
2607
  domain: ErrorDomain.STORAGE,
2870
2608
  category: ErrorCategory.THIRD_PARTY,
2871
2609
  details: { tableName }
@@ -2900,7 +2638,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2900
2638
  } catch (err) {
2901
2639
  throw new MastraError(
2902
2640
  {
2903
- id: "STORAGE_LANCE_VECTOR_CREATE_INDEX_FAILED_INVALID_ARGS",
2641
+ id: createVectorErrorId("LANCE", "CREATE_INDEX", "INVALID_ARGS"),
2904
2642
  domain: ErrorDomain.STORAGE,
2905
2643
  category: ErrorCategory.USER,
2906
2644
  details: { tableName: tableName || "", indexName, dimension, metric }
@@ -2945,7 +2683,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2945
2683
  } catch (error) {
2946
2684
  throw new MastraError(
2947
2685
  {
2948
- id: "STORAGE_LANCE_VECTOR_CREATE_INDEX_FAILED",
2686
+ id: createVectorErrorId("LANCE", "CREATE_INDEX", "FAILED"),
2949
2687
  domain: ErrorDomain.STORAGE,
2950
2688
  category: ErrorCategory.THIRD_PARTY,
2951
2689
  details: { tableName: tableName || "", indexName, dimension }
@@ -2957,7 +2695,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2957
2695
  async listIndexes() {
2958
2696
  if (!this.lanceClient) {
2959
2697
  throw new MastraError({
2960
- id: "STORAGE_LANCE_VECTOR_LIST_INDEXES_FAILED_INVALID_ARGS",
2698
+ id: createVectorErrorId("LANCE", "LIST_INDEXES", "INVALID_ARGS"),
2961
2699
  domain: ErrorDomain.STORAGE,
2962
2700
  category: ErrorCategory.USER,
2963
2701
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2976,7 +2714,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2976
2714
  } catch (error) {
2977
2715
  throw new MastraError(
2978
2716
  {
2979
- id: "STORAGE_LANCE_VECTOR_LIST_INDEXES_FAILED",
2717
+ id: createVectorErrorId("LANCE", "LIST_INDEXES", "FAILED"),
2980
2718
  domain: ErrorDomain.STORAGE,
2981
2719
  category: ErrorCategory.THIRD_PARTY
2982
2720
  },
@@ -2995,7 +2733,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2995
2733
  } catch (err) {
2996
2734
  throw new MastraError(
2997
2735
  {
2998
- id: "STORAGE_LANCE_VECTOR_DESCRIBE_INDEX_FAILED_INVALID_ARGS",
2736
+ id: createVectorErrorId("LANCE", "DESCRIBE_INDEX", "INVALID_ARGS"),
2999
2737
  domain: ErrorDomain.STORAGE,
3000
2738
  category: ErrorCategory.USER,
3001
2739
  details: { indexName }
@@ -3030,7 +2768,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3030
2768
  } catch (error) {
3031
2769
  throw new MastraError(
3032
2770
  {
3033
- id: "STORAGE_LANCE_VECTOR_DESCRIBE_INDEX_FAILED",
2771
+ id: createVectorErrorId("LANCE", "DESCRIBE_INDEX", "FAILED"),
3034
2772
  domain: ErrorDomain.STORAGE,
3035
2773
  category: ErrorCategory.THIRD_PARTY,
3036
2774
  details: { indexName }
@@ -3050,7 +2788,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3050
2788
  } catch (err) {
3051
2789
  throw new MastraError(
3052
2790
  {
3053
- id: "STORAGE_LANCE_VECTOR_DELETE_INDEX_FAILED_INVALID_ARGS",
2791
+ id: createVectorErrorId("LANCE", "DELETE_INDEX", "INVALID_ARGS"),
3054
2792
  domain: ErrorDomain.STORAGE,
3055
2793
  category: ErrorCategory.USER,
3056
2794
  details: { indexName }
@@ -3073,7 +2811,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3073
2811
  } catch (error) {
3074
2812
  throw new MastraError(
3075
2813
  {
3076
- id: "STORAGE_LANCE_VECTOR_DELETE_INDEX_FAILED",
2814
+ id: createVectorErrorId("LANCE", "DELETE_INDEX", "FAILED"),
3077
2815
  domain: ErrorDomain.STORAGE,
3078
2816
  category: ErrorCategory.THIRD_PARTY,
3079
2817
  details: { indexName }
@@ -3088,7 +2826,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3088
2826
  async deleteAllTables() {
3089
2827
  if (!this.lanceClient) {
3090
2828
  throw new MastraError({
3091
- id: "STORAGE_LANCE_VECTOR_DELETE_ALL_TABLES_FAILED_INVALID_ARGS",
2829
+ id: createVectorErrorId("LANCE", "DELETE_ALL_TABLES", "INVALID_ARGS"),
3092
2830
  domain: ErrorDomain.STORAGE,
3093
2831
  category: ErrorCategory.USER,
3094
2832
  details: { methodName: "deleteAllTables" },
@@ -3100,7 +2838,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3100
2838
  } catch (error) {
3101
2839
  throw new MastraError(
3102
2840
  {
3103
- id: "STORAGE_LANCE_VECTOR_DELETE_ALL_TABLES_FAILED",
2841
+ id: createVectorErrorId("LANCE", "DELETE_ALL_TABLES", "FAILED"),
3104
2842
  domain: ErrorDomain.STORAGE,
3105
2843
  category: ErrorCategory.THIRD_PARTY,
3106
2844
  details: { methodName: "deleteAllTables" }
@@ -3112,7 +2850,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3112
2850
  async deleteTable(tableName) {
3113
2851
  if (!this.lanceClient) {
3114
2852
  throw new MastraError({
3115
- id: "STORAGE_LANCE_VECTOR_DELETE_TABLE_FAILED_INVALID_ARGS",
2853
+ id: createVectorErrorId("LANCE", "DELETE_TABLE", "INVALID_ARGS"),
3116
2854
  domain: ErrorDomain.STORAGE,
3117
2855
  category: ErrorCategory.USER,
3118
2856
  details: { tableName },
@@ -3124,7 +2862,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3124
2862
  } catch (error) {
3125
2863
  throw new MastraError(
3126
2864
  {
3127
- id: "STORAGE_LANCE_VECTOR_DELETE_TABLE_FAILED",
2865
+ id: createVectorErrorId("LANCE", "DELETE_TABLE", "FAILED"),
3128
2866
  domain: ErrorDomain.STORAGE,
3129
2867
  category: ErrorCategory.THIRD_PARTY,
3130
2868
  details: { tableName }
@@ -3133,7 +2871,44 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3133
2871
  );
3134
2872
  }
3135
2873
  }
3136
- async updateVector({ indexName, id, update }) {
2874
+ async updateVector(params) {
2875
+ const { indexName, update } = params;
2876
+ if ("id" in params && "filter" in params && params.id && params.filter) {
2877
+ throw new MastraError({
2878
+ id: createVectorErrorId("LANCE", "UPDATE_VECTOR", "MUTUALLY_EXCLUSIVE"),
2879
+ domain: ErrorDomain.STORAGE,
2880
+ category: ErrorCategory.USER,
2881
+ text: "id and filter are mutually exclusive",
2882
+ details: { indexName }
2883
+ });
2884
+ }
2885
+ if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
2886
+ throw new MastraError({
2887
+ id: createVectorErrorId("LANCE", "UPDATE_VECTOR", "NO_TARGET"),
2888
+ domain: ErrorDomain.STORAGE,
2889
+ category: ErrorCategory.USER,
2890
+ text: "Either id or filter must be provided",
2891
+ details: { indexName }
2892
+ });
2893
+ }
2894
+ if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
2895
+ throw new MastraError({
2896
+ id: createVectorErrorId("LANCE", "UPDATE_VECTOR", "EMPTY_FILTER"),
2897
+ domain: ErrorDomain.STORAGE,
2898
+ category: ErrorCategory.USER,
2899
+ text: "Cannot update with empty filter",
2900
+ details: { indexName }
2901
+ });
2902
+ }
2903
+ if (!update.vector && !update.metadata) {
2904
+ throw new MastraError({
2905
+ id: createVectorErrorId("LANCE", "UPDATE_VECTOR", "NO_PAYLOAD"),
2906
+ domain: ErrorDomain.STORAGE,
2907
+ category: ErrorCategory.USER,
2908
+ text: "No updates provided",
2909
+ details: { indexName }
2910
+ });
2911
+ }
3137
2912
  try {
3138
2913
  if (!this.lanceClient) {
3139
2914
  throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
@@ -3141,21 +2916,6 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3141
2916
  if (!indexName) {
3142
2917
  throw new Error("indexName is required");
3143
2918
  }
3144
- if (!id) {
3145
- throw new Error("id is required");
3146
- }
3147
- } catch (err) {
3148
- throw new MastraError(
3149
- {
3150
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
3151
- domain: ErrorDomain.STORAGE,
3152
- category: ErrorCategory.USER,
3153
- details: { indexName, id }
3154
- },
3155
- err
3156
- );
3157
- }
3158
- try {
3159
2919
  const tables = await this.lanceClient.tableNames();
3160
2920
  for (const tableName of tables) {
3161
2921
  this.logger.debug("Checking table:" + tableName);
@@ -3165,39 +2925,66 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3165
2925
  const hasColumn = schema.fields.some((field) => field.name === indexName);
3166
2926
  if (hasColumn) {
3167
2927
  this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3168
- const existingRecord = await table.query().where(`id = '${id}'`).select(schema.fields.map((field) => field.name)).limit(1).toArray();
3169
- if (existingRecord.length === 0) {
3170
- throw new Error(`Record with id '${id}' not found in table ${tableName}`);
2928
+ let whereClause;
2929
+ if ("id" in params && params.id) {
2930
+ whereClause = `id = '${params.id}'`;
2931
+ } else if ("filter" in params && params.filter) {
2932
+ const translator = new LanceFilterTranslator();
2933
+ const processFilterKeys = (filter) => {
2934
+ const processedFilter = {};
2935
+ Object.entries(filter).forEach(([key, value]) => {
2936
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2937
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
2938
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
2939
+ });
2940
+ } else {
2941
+ processedFilter[`metadata_${key}`] = value;
2942
+ }
2943
+ });
2944
+ return processedFilter;
2945
+ };
2946
+ const prefixedFilter = processFilterKeys(params.filter);
2947
+ whereClause = translator.translate(prefixedFilter) || "";
2948
+ if (!whereClause) {
2949
+ throw new Error("Failed to translate filter to SQL");
2950
+ }
2951
+ } else {
2952
+ throw new Error("Either id or filter must be provided");
3171
2953
  }
3172
- const rowData = {
3173
- id
3174
- };
3175
- Object.entries(existingRecord[0]).forEach(([key, value]) => {
3176
- if (key !== "id" && key !== "_distance") {
3177
- if (key === indexName) {
3178
- if (!update.vector) {
3179
- if (Array.isArray(value)) {
3180
- rowData[key] = [...value];
3181
- } else if (typeof value === "object" && value !== null) {
3182
- rowData[key] = Array.from(value);
2954
+ const existingRecords = await table.query().where(whereClause).select(schema.fields.map((field) => field.name)).toArray();
2955
+ if (existingRecords.length === 0) {
2956
+ this.logger.info(`No records found matching criteria in table ${tableName}`);
2957
+ return;
2958
+ }
2959
+ const updatedRecords = existingRecords.map((record) => {
2960
+ const rowData = {};
2961
+ Object.entries(record).forEach(([key, value]) => {
2962
+ if (key !== "_distance") {
2963
+ if (key === indexName) {
2964
+ if (update.vector) {
2965
+ rowData[key] = update.vector;
3183
2966
  } else {
3184
- rowData[key] = value;
2967
+ if (Array.isArray(value)) {
2968
+ rowData[key] = [...value];
2969
+ } else if (typeof value === "object" && value !== null) {
2970
+ rowData[key] = Array.from(value);
2971
+ } else {
2972
+ rowData[key] = value;
2973
+ }
3185
2974
  }
2975
+ } else {
2976
+ rowData[key] = value;
3186
2977
  }
3187
- } else {
3188
- rowData[key] = value;
3189
2978
  }
2979
+ });
2980
+ if (update.metadata) {
2981
+ Object.entries(update.metadata).forEach(([key, value]) => {
2982
+ rowData[`metadata_${key}`] = value;
2983
+ });
3190
2984
  }
2985
+ return rowData;
3191
2986
  });
3192
- if (update.vector) {
3193
- rowData[indexName] = update.vector;
3194
- }
3195
- if (update.metadata) {
3196
- Object.entries(update.metadata).forEach(([key, value]) => {
3197
- rowData[`metadata_${key}`] = value;
3198
- });
3199
- }
3200
- await table.add([rowData], { mode: "overwrite" });
2987
+ await table.add(updatedRecords, { mode: "overwrite" });
3201
2988
  return;
3202
2989
  }
3203
2990
  } catch (err) {
@@ -3207,12 +2994,19 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3207
2994
  }
3208
2995
  throw new Error(`No table found with column/index '${indexName}'`);
3209
2996
  } catch (error) {
2997
+ if (error instanceof MastraError) throw error;
3210
2998
  throw new MastraError(
3211
2999
  {
3212
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
3000
+ id: createVectorErrorId("LANCE", "UPDATE_VECTOR", "FAILED"),
3213
3001
  domain: ErrorDomain.STORAGE,
3214
3002
  category: ErrorCategory.THIRD_PARTY,
3215
- details: { indexName, id, hasVector: !!update.vector, hasMetadata: !!update.metadata }
3003
+ details: {
3004
+ indexName,
3005
+ ..."id" in params && params.id && { id: params.id },
3006
+ ..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) },
3007
+ hasVector: !!update.vector,
3008
+ hasMetadata: !!update.metadata
3009
+ }
3216
3010
  },
3217
3011
  error
3218
3012
  );
@@ -3232,10 +3026,13 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3232
3026
  } catch (err) {
3233
3027
  throw new MastraError(
3234
3028
  {
3235
- id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
3029
+ id: createVectorErrorId("LANCE", "DELETE_VECTOR", "INVALID_ARGS"),
3236
3030
  domain: ErrorDomain.STORAGE,
3237
3031
  category: ErrorCategory.USER,
3238
- details: { indexName, id }
3032
+ details: {
3033
+ indexName,
3034
+ ...id && { id }
3035
+ }
3239
3036
  },
3240
3037
  err
3241
3038
  );
@@ -3262,10 +3059,13 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3262
3059
  } catch (error) {
3263
3060
  throw new MastraError(
3264
3061
  {
3265
- id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
3062
+ id: createVectorErrorId("LANCE", "DELETE_VECTOR", "FAILED"),
3266
3063
  domain: ErrorDomain.STORAGE,
3267
3064
  category: ErrorCategory.THIRD_PARTY,
3268
- details: { indexName, id }
3065
+ details: {
3066
+ indexName,
3067
+ ...id && { id }
3068
+ }
3269
3069
  },
3270
3070
  error
3271
3071
  );
@@ -3296,6 +3096,109 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3296
3096
  });
3297
3097
  return result;
3298
3098
  }
3099
+ async deleteVectors({ indexName, filter, ids }) {
3100
+ if (ids && filter) {
3101
+ throw new MastraError({
3102
+ id: createVectorErrorId("LANCE", "DELETE_VECTORS", "MUTUALLY_EXCLUSIVE"),
3103
+ domain: ErrorDomain.STORAGE,
3104
+ category: ErrorCategory.USER,
3105
+ text: "ids and filter are mutually exclusive",
3106
+ details: { indexName }
3107
+ });
3108
+ }
3109
+ if (!ids && !filter) {
3110
+ throw new MastraError({
3111
+ id: createVectorErrorId("LANCE", "DELETE_VECTORS", "NO_TARGET"),
3112
+ domain: ErrorDomain.STORAGE,
3113
+ category: ErrorCategory.USER,
3114
+ text: "Either filter or ids must be provided",
3115
+ details: { indexName }
3116
+ });
3117
+ }
3118
+ if (ids && ids.length === 0) {
3119
+ throw new MastraError({
3120
+ id: createVectorErrorId("LANCE", "DELETE_VECTORS", "EMPTY_IDS"),
3121
+ domain: ErrorDomain.STORAGE,
3122
+ category: ErrorCategory.USER,
3123
+ text: "Cannot delete with empty ids array",
3124
+ details: { indexName }
3125
+ });
3126
+ }
3127
+ if (filter && Object.keys(filter).length === 0) {
3128
+ throw new MastraError({
3129
+ id: createVectorErrorId("LANCE", "DELETE_VECTORS", "EMPTY_FILTER"),
3130
+ domain: ErrorDomain.STORAGE,
3131
+ category: ErrorCategory.USER,
3132
+ text: "Cannot delete with empty filter",
3133
+ details: { indexName }
3134
+ });
3135
+ }
3136
+ try {
3137
+ if (!this.lanceClient) {
3138
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3139
+ }
3140
+ if (!indexName) {
3141
+ throw new Error("indexName is required");
3142
+ }
3143
+ const tables = await this.lanceClient.tableNames();
3144
+ for (const tableName of tables) {
3145
+ this.logger.debug("Checking table:" + tableName);
3146
+ const table = await this.lanceClient.openTable(tableName);
3147
+ try {
3148
+ const schema = await table.schema();
3149
+ const hasColumn = schema.fields.some((field) => field.name === indexName);
3150
+ if (hasColumn) {
3151
+ this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3152
+ if (ids) {
3153
+ const idsConditions = ids.map((id) => `id = '${id}'`).join(" OR ");
3154
+ await table.delete(idsConditions);
3155
+ } else if (filter) {
3156
+ const translator = new LanceFilterTranslator();
3157
+ const processFilterKeys = (filter2) => {
3158
+ const processedFilter = {};
3159
+ Object.entries(filter2).forEach(([key, value]) => {
3160
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3161
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3162
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3163
+ });
3164
+ } else {
3165
+ processedFilter[`metadata_${key}`] = value;
3166
+ }
3167
+ });
3168
+ return processedFilter;
3169
+ };
3170
+ const prefixedFilter = processFilterKeys(filter);
3171
+ const whereClause = translator.translate(prefixedFilter);
3172
+ if (!whereClause) {
3173
+ throw new Error("Failed to translate filter to SQL");
3174
+ }
3175
+ await table.delete(whereClause);
3176
+ }
3177
+ return;
3178
+ }
3179
+ } catch (err) {
3180
+ this.logger.error(`Error checking schema for table ${tableName}:` + err);
3181
+ continue;
3182
+ }
3183
+ }
3184
+ throw new Error(`No table found with column/index '${indexName}'`);
3185
+ } catch (error) {
3186
+ if (error instanceof MastraError) throw error;
3187
+ throw new MastraError(
3188
+ {
3189
+ id: createVectorErrorId("LANCE", "DELETE_VECTORS", "FAILED"),
3190
+ domain: ErrorDomain.STORAGE,
3191
+ category: ErrorCategory.THIRD_PARTY,
3192
+ details: {
3193
+ indexName,
3194
+ ...filter && { filter: JSON.stringify(filter) },
3195
+ ...ids && { idsCount: ids.length }
3196
+ }
3197
+ },
3198
+ error
3199
+ );
3200
+ }
3201
+ }
3299
3202
  };
3300
3203
 
3301
3204
  export { LanceStorage, LanceVectorStore };