@mastra/lance 0.0.0-scorers-api-v2-20250801171841 → 0.0.0-scorers-logs-20251208093427

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +982 -3
  2. package/README.md +64 -7
  3. package/dist/index.cjs +725 -720
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +726 -721
  7. package/dist/index.js.map +1 -1
  8. package/dist/storage/domains/memory/index.d.ts +18 -33
  9. package/dist/storage/domains/memory/index.d.ts.map +1 -1
  10. package/dist/storage/domains/operations/index.d.ts.map +1 -1
  11. package/dist/storage/domains/scores/index.d.ts +24 -5
  12. package/dist/storage/domains/scores/index.d.ts.map +1 -1
  13. package/dist/storage/domains/utils.d.ts.map +1 -1
  14. package/dist/storage/domains/workflows/index.d.ts +23 -11
  15. package/dist/storage/domains/workflows/index.d.ts.map +1 -1
  16. package/dist/storage/index.d.ts +87 -81
  17. package/dist/storage/index.d.ts.map +1 -1
  18. package/dist/vector/filter.d.ts +5 -5
  19. package/dist/vector/index.d.ts +8 -5
  20. package/dist/vector/index.d.ts.map +1 -1
  21. package/package.json +29 -10
  22. package/dist/storage/domains/legacy-evals/index.d.ts +0 -25
  23. package/dist/storage/domains/legacy-evals/index.d.ts.map +0 -1
  24. package/dist/storage/domains/traces/index.d.ts +0 -34
  25. package/dist/storage/domains/traces/index.d.ts.map +0 -1
  26. package/eslint.config.js +0 -6
  27. package/src/index.ts +0 -2
  28. package/src/storage/domains/legacy-evals/index.ts +0 -156
  29. package/src/storage/domains/memory/index.ts +0 -947
  30. package/src/storage/domains/operations/index.ts +0 -489
  31. package/src/storage/domains/scores/index.ts +0 -221
  32. package/src/storage/domains/traces/index.ts +0 -212
  33. package/src/storage/domains/utils.ts +0 -158
  34. package/src/storage/domains/workflows/index.ts +0 -207
  35. package/src/storage/index.test.ts +0 -10
  36. package/src/storage/index.ts +0 -442
  37. package/src/vector/filter.test.ts +0 -295
  38. package/src/vector/filter.ts +0 -443
  39. package/src/vector/index.test.ts +0 -1493
  40. package/src/vector/index.ts +0 -941
  41. package/src/vector/types.ts +0 -16
  42. package/tsconfig.build.json +0 -9
  43. package/tsconfig.json +0 -5
  44. package/tsup.config.ts +0 -22
  45. package/vitest.config.ts +0 -11
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
  },
@@ -379,79 +247,190 @@ var StoreMemoryLance = class extends MemoryStorage {
379
247
  );
380
248
  }
381
249
  }
382
- async getMessages({
383
- threadId,
384
- resourceId,
385
- selectBy,
386
- format,
387
- threadConfig
388
- }) {
250
+ normalizeMessage(message) {
251
+ const { thread_id, ...rest } = message;
252
+ return {
253
+ ...rest,
254
+ threadId: thread_id,
255
+ content: typeof message.content === "string" ? (() => {
256
+ try {
257
+ return JSON.parse(message.content);
258
+ } catch {
259
+ return message.content;
260
+ }
261
+ })() : message.content
262
+ };
263
+ }
264
+ async listMessagesById({ messageIds }) {
265
+ if (messageIds.length === 0) return { messages: [] };
389
266
  try {
390
- if (threadConfig) {
391
- throw new Error("ThreadConfig is not supported by LanceDB storage");
392
- }
393
- const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
394
267
  const table = await this.client.openTable(TABLE_MESSAGES);
395
- let allRecords = [];
396
- if (selectBy?.include && selectBy.include.length > 0) {
397
- const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
398
- for (const threadId2 of threadIds) {
399
- const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
400
- let threadRecords = await threadQuery.toArray();
401
- allRecords.push(...threadRecords);
402
- }
403
- } else {
404
- let query = table.query().where(`\`thread_id\` = '${threadId}'`);
405
- allRecords = await query.toArray();
406
- }
407
- allRecords.sort((a, b) => {
408
- const dateA = new Date(a.createdAt).getTime();
409
- const dateB = new Date(b.createdAt).getTime();
410
- return dateA - dateB;
411
- });
412
- if (selectBy?.include && selectBy.include.length > 0) {
413
- allRecords = this.processMessagesWithContext(allRecords, selectBy.include);
414
- }
415
- if (limit !== Number.MAX_SAFE_INTEGER) {
416
- allRecords = allRecords.slice(-limit);
417
- }
268
+ const quotedIds = messageIds.map((id) => `'${id}'`).join(", ");
269
+ const allRecords = await table.query().where(`id IN (${quotedIds})`).toArray();
418
270
  const messages = processResultWithTypeConversion(
419
271
  allRecords,
420
272
  await getTableSchema({ tableName: TABLE_MESSAGES, client: this.client })
421
273
  );
422
- const normalized = messages.map((msg) => {
423
- const { thread_id, ...rest } = msg;
274
+ const list = new MessageList().add(
275
+ messages.map(this.normalizeMessage),
276
+ "memory"
277
+ );
278
+ return { messages: list.get.all.db() };
279
+ } catch (error) {
280
+ throw new MastraError(
281
+ {
282
+ id: createStorageErrorId("LANCE", "LIST_MESSAGES_BY_ID", "FAILED"),
283
+ domain: ErrorDomain.STORAGE,
284
+ category: ErrorCategory.THIRD_PARTY,
285
+ details: {
286
+ messageIds: JSON.stringify(messageIds)
287
+ }
288
+ },
289
+ error
290
+ );
291
+ }
292
+ }
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);
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");
322
+ const table = await this.client.openTable(TABLE_MESSAGES);
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)) {
424
354
  return {
425
- ...rest,
426
- threadId: thread_id,
427
- content: typeof msg.content === "string" ? (() => {
428
- try {
429
- return JSON.parse(msg.content);
430
- } catch {
431
- return msg.content;
432
- }
433
- })() : msg.content
355
+ messages: [],
356
+ total: 0,
357
+ page,
358
+ perPage: perPageForResponse,
359
+ hasMore: false
434
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;
435
393
  });
436
- const list = new MessageList({ threadId, resourceId }).add(normalized, "memory");
437
- if (format === "v2") return list.get.all.v2();
438
- return list.get.all.v1();
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
+ };
439
405
  } catch (error) {
440
- throw new MastraError(
406
+ const mastraError = new MastraError(
441
407
  {
442
- id: "LANCE_STORE_GET_MESSAGES_FAILED",
408
+ id: createStorageErrorId("LANCE", "LIST_MESSAGES", "FAILED"),
443
409
  domain: ErrorDomain.STORAGE,
444
- category: ErrorCategory.THIRD_PARTY
410
+ category: ErrorCategory.THIRD_PARTY,
411
+ details: {
412
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
413
+ resourceId: resourceId ?? ""
414
+ }
445
415
  },
446
416
  error
447
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
+ };
448
427
  }
449
428
  }
450
429
  async saveMessages(args) {
451
430
  try {
452
- const { messages, format = "v1" } = args;
431
+ const { messages } = args;
453
432
  if (messages.length === 0) {
454
- return [];
433
+ return { messages: [] };
455
434
  }
456
435
  const threadId = messages[0]?.threadId;
457
436
  if (!threadId) {
@@ -487,12 +466,11 @@ var StoreMemoryLance = class extends MemoryStorage {
487
466
  const updateRecord = { id: threadId, updatedAt: currentTime };
488
467
  await threadsTable.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([updateRecord]);
489
468
  const list = new MessageList().add(messages, "memory");
490
- if (format === `v2`) return list.get.all.v2();
491
- return list.get.all.v1();
469
+ return { messages: list.get.all.db() };
492
470
  } catch (error) {
493
471
  throw new MastraError(
494
472
  {
495
- id: "LANCE_STORE_SAVE_MESSAGES_FAILED",
473
+ id: createStorageErrorId("LANCE", "SAVE_MESSAGES", "FAILED"),
496
474
  domain: ErrorDomain.STORAGE,
497
475
  category: ErrorCategory.THIRD_PARTY
498
476
  },
@@ -500,32 +478,54 @@ var StoreMemoryLance = class extends MemoryStorage {
500
478
  );
501
479
  }
502
480
  }
503
- async getThreadsByResourceIdPaginated(args) {
481
+ async listThreadsByResourceId(args) {
504
482
  try {
505
- const { resourceId, page = 0, perPage = 10 } = args;
506
- const table = await this.client.openTable(TABLE_THREADS);
507
- const total = await table.countRows(`\`resourceId\` = '${resourceId}'`);
508
- const query = table.query().where(`\`resourceId\` = '${resourceId}'`);
509
- const offset = page * perPage;
510
- query.limit(perPage);
511
- if (offset > 0) {
512
- 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
+ );
513
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)}'`);
514
501
  const records = await query.toArray();
515
- 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);
516
514
  const schema = await getTableSchema({ tableName: TABLE_THREADS, client: this.client });
517
- const threads = records.map((record) => processResultWithTypeConversion(record, schema));
515
+ const threads = paginatedRecords.map(
516
+ (record) => processResultWithTypeConversion(record, schema)
517
+ );
518
518
  return {
519
519
  threads,
520
520
  total,
521
521
  page,
522
- perPage,
523
- hasMore: total > (page + 1) * perPage
522
+ perPage: perPageForResponse,
523
+ hasMore: offset + perPage < total
524
524
  };
525
525
  } catch (error) {
526
526
  throw new MastraError(
527
527
  {
528
- id: "LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
528
+ id: createStorageErrorId("LANCE", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
529
529
  domain: ErrorDomain.STORAGE,
530
530
  category: ErrorCategory.THIRD_PARTY
531
531
  },
@@ -581,127 +581,8 @@ var StoreMemoryLance = class extends MemoryStorage {
581
581
  });
582
582
  return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
583
583
  }
584
- async getMessagesPaginated(args) {
585
- try {
586
- const { threadId, resourceId, selectBy, format = "v1" } = args;
587
- if (!threadId) {
588
- throw new Error("Thread ID is required for getMessagesPaginated");
589
- }
590
- const page = selectBy?.pagination?.page ?? 0;
591
- const perPage = selectBy?.pagination?.perPage ?? 10;
592
- const dateRange = selectBy?.pagination?.dateRange;
593
- const fromDate = dateRange?.start;
594
- const toDate = dateRange?.end;
595
- const table = await this.client.openTable(TABLE_MESSAGES);
596
- const messages = [];
597
- if (selectBy?.include && Array.isArray(selectBy.include)) {
598
- const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
599
- const allThreadMessages = [];
600
- for (const threadId2 of threadIds) {
601
- const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
602
- let threadRecords = await threadQuery.toArray();
603
- if (fromDate) threadRecords = threadRecords.filter((m) => m.createdAt >= fromDate.getTime());
604
- if (toDate) threadRecords = threadRecords.filter((m) => m.createdAt <= toDate.getTime());
605
- allThreadMessages.push(...threadRecords);
606
- }
607
- allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
608
- const contextMessages = this.processMessagesWithContext(allThreadMessages, selectBy.include);
609
- messages.push(...contextMessages);
610
- }
611
- const conditions = [`thread_id = '${threadId}'`];
612
- if (resourceId) {
613
- conditions.push(`\`resourceId\` = '${resourceId}'`);
614
- }
615
- if (fromDate) {
616
- conditions.push(`\`createdAt\` >= ${fromDate.getTime()}`);
617
- }
618
- if (toDate) {
619
- conditions.push(`\`createdAt\` <= ${toDate.getTime()}`);
620
- }
621
- let total = 0;
622
- if (conditions.length > 0) {
623
- total = await table.countRows(conditions.join(" AND "));
624
- } else {
625
- total = await table.countRows();
626
- }
627
- if (total === 0 && messages.length === 0) {
628
- return {
629
- messages: [],
630
- total: 0,
631
- page,
632
- perPage,
633
- hasMore: false
634
- };
635
- }
636
- const excludeIds = messages.map((m) => m.id);
637
- let selectedMessages = [];
638
- if (selectBy?.last && selectBy.last > 0) {
639
- const query = table.query();
640
- if (conditions.length > 0) {
641
- query.where(conditions.join(" AND "));
642
- }
643
- let records = await query.toArray();
644
- records = records.sort((a, b) => a.createdAt - b.createdAt);
645
- if (excludeIds.length > 0) {
646
- records = records.filter((m) => !excludeIds.includes(m.id));
647
- }
648
- selectedMessages = records.slice(-selectBy.last);
649
- } else {
650
- const query = table.query();
651
- if (conditions.length > 0) {
652
- query.where(conditions.join(" AND "));
653
- }
654
- let records = await query.toArray();
655
- records = records.sort((a, b) => a.createdAt - b.createdAt);
656
- if (excludeIds.length > 0) {
657
- records = records.filter((m) => !excludeIds.includes(m.id));
658
- }
659
- selectedMessages = records.slice(page * perPage, (page + 1) * perPage);
660
- }
661
- const allMessages = [...messages, ...selectedMessages];
662
- const seen = /* @__PURE__ */ new Set();
663
- const dedupedMessages = allMessages.filter((m) => {
664
- const key = `${m.id}:${m.thread_id}`;
665
- if (seen.has(key)) return false;
666
- seen.add(key);
667
- return true;
668
- });
669
- const formattedMessages = dedupedMessages.map((msg) => {
670
- const { thread_id, ...rest } = msg;
671
- return {
672
- ...rest,
673
- threadId: thread_id,
674
- content: typeof msg.content === "string" ? (() => {
675
- try {
676
- return JSON.parse(msg.content);
677
- } catch {
678
- return msg.content;
679
- }
680
- })() : msg.content
681
- };
682
- });
683
- const list = new MessageList().add(formattedMessages, "memory");
684
- return {
685
- messages: format === "v2" ? list.get.all.v2() : list.get.all.v1(),
686
- total,
687
- // Total should be the count of messages matching the filters
688
- page,
689
- perPage,
690
- hasMore: total > (page + 1) * perPage
691
- };
692
- } catch (error) {
693
- throw new MastraError(
694
- {
695
- id: "LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED",
696
- domain: ErrorDomain.STORAGE,
697
- category: ErrorCategory.THIRD_PARTY
698
- },
699
- error
700
- );
701
- }
702
- }
703
584
  /**
704
- * Parse message data from LanceDB record format to MastraMessageV2 format
585
+ * Parse message data from LanceDB record format to MastraDBMessage format
705
586
  */
706
587
  parseMessageData(data) {
707
588
  const { thread_id, ...rest } = data;
@@ -779,7 +660,7 @@ var StoreMemoryLance = class extends MemoryStorage {
779
660
  } catch (error) {
780
661
  throw new MastraError(
781
662
  {
782
- id: "LANCE_STORE_UPDATE_MESSAGES_FAILED",
663
+ id: createStorageErrorId("LANCE", "UPDATE_MESSAGES", "FAILED"),
783
664
  domain: ErrorDomain.STORAGE,
784
665
  category: ErrorCategory.THIRD_PARTY,
785
666
  details: { count: messages.length }
@@ -856,7 +737,7 @@ var StoreMemoryLance = class extends MemoryStorage {
856
737
  } catch (error) {
857
738
  throw new MastraError(
858
739
  {
859
- id: "LANCE_STORE_GET_RESOURCE_BY_ID_FAILED",
740
+ id: createStorageErrorId("LANCE", "GET_RESOURCE_BY_ID", "FAILED"),
860
741
  domain: ErrorDomain.STORAGE,
861
742
  category: ErrorCategory.THIRD_PARTY
862
743
  },
@@ -880,7 +761,7 @@ var StoreMemoryLance = class extends MemoryStorage {
880
761
  } catch (error) {
881
762
  throw new MastraError(
882
763
  {
883
- id: "LANCE_STORE_SAVE_RESOURCE_FAILED",
764
+ id: createStorageErrorId("LANCE", "SAVE_RESOURCE", "FAILED"),
884
765
  domain: ErrorDomain.STORAGE,
885
766
  category: ErrorCategory.THIRD_PARTY
886
767
  },
@@ -934,7 +815,7 @@ var StoreMemoryLance = class extends MemoryStorage {
934
815
  }
935
816
  throw new MastraError(
936
817
  {
937
- id: "LANCE_STORE_UPDATE_RESOURCE_FAILED",
818
+ id: createStorageErrorId("LANCE", "UPDATE_RESOURCE", "FAILED"),
938
819
  domain: ErrorDomain.STORAGE,
939
820
  category: ErrorCategory.THIRD_PARTY
940
821
  },
@@ -1025,7 +906,7 @@ var StoreOperationsLance = class extends StoreOperations {
1025
906
  } catch (error) {
1026
907
  throw new MastraError(
1027
908
  {
1028
- id: "STORAGE_LANCE_STORAGE_CREATE_TABLE_INVALID_ARGS",
909
+ id: createStorageErrorId("LANCE", "CREATE_TABLE", "INVALID_ARGS"),
1029
910
  domain: ErrorDomain.STORAGE,
1030
911
  category: ErrorCategory.USER,
1031
912
  details: { tableName }
@@ -1043,7 +924,7 @@ var StoreOperationsLance = class extends StoreOperations {
1043
924
  }
1044
925
  throw new MastraError(
1045
926
  {
1046
- id: "STORAGE_LANCE_STORAGE_CREATE_TABLE_FAILED",
927
+ id: createStorageErrorId("LANCE", "CREATE_TABLE", "FAILED"),
1047
928
  domain: ErrorDomain.STORAGE,
1048
929
  category: ErrorCategory.THIRD_PARTY,
1049
930
  details: { tableName }
@@ -1063,7 +944,7 @@ var StoreOperationsLance = class extends StoreOperations {
1063
944
  } catch (validationError) {
1064
945
  throw new MastraError(
1065
946
  {
1066
- id: "STORAGE_LANCE_STORAGE_DROP_TABLE_INVALID_ARGS",
947
+ id: createStorageErrorId("LANCE", "DROP_TABLE", "INVALID_ARGS"),
1067
948
  domain: ErrorDomain.STORAGE,
1068
949
  category: ErrorCategory.USER,
1069
950
  text: validationError.message,
@@ -1081,7 +962,7 @@ var StoreOperationsLance = class extends StoreOperations {
1081
962
  }
1082
963
  throw new MastraError(
1083
964
  {
1084
- id: "STORAGE_LANCE_STORAGE_DROP_TABLE_FAILED",
965
+ id: createStorageErrorId("LANCE", "DROP_TABLE", "FAILED"),
1085
966
  domain: ErrorDomain.STORAGE,
1086
967
  category: ErrorCategory.THIRD_PARTY,
1087
968
  details: { tableName }
@@ -1112,7 +993,7 @@ var StoreOperationsLance = class extends StoreOperations {
1112
993
  } catch (validationError) {
1113
994
  throw new MastraError(
1114
995
  {
1115
- id: "STORAGE_LANCE_STORAGE_ALTER_TABLE_INVALID_ARGS",
996
+ id: createStorageErrorId("LANCE", "ALTER_TABLE", "INVALID_ARGS"),
1116
997
  domain: ErrorDomain.STORAGE,
1117
998
  category: ErrorCategory.USER,
1118
999
  text: validationError.message,
@@ -1147,7 +1028,7 @@ var StoreOperationsLance = class extends StoreOperations {
1147
1028
  } catch (error) {
1148
1029
  throw new MastraError(
1149
1030
  {
1150
- id: "STORAGE_LANCE_STORAGE_ALTER_TABLE_FAILED",
1031
+ id: createStorageErrorId("LANCE", "ALTER_TABLE", "FAILED"),
1151
1032
  domain: ErrorDomain.STORAGE,
1152
1033
  category: ErrorCategory.THIRD_PARTY,
1153
1034
  details: { tableName }
@@ -1167,7 +1048,7 @@ var StoreOperationsLance = class extends StoreOperations {
1167
1048
  } catch (validationError) {
1168
1049
  throw new MastraError(
1169
1050
  {
1170
- id: "STORAGE_LANCE_STORAGE_CLEAR_TABLE_INVALID_ARGS",
1051
+ id: createStorageErrorId("LANCE", "CLEAR_TABLE", "INVALID_ARGS"),
1171
1052
  domain: ErrorDomain.STORAGE,
1172
1053
  category: ErrorCategory.USER,
1173
1054
  text: validationError.message,
@@ -1182,7 +1063,7 @@ var StoreOperationsLance = class extends StoreOperations {
1182
1063
  } catch (error) {
1183
1064
  throw new MastraError(
1184
1065
  {
1185
- id: "STORAGE_LANCE_STORAGE_CLEAR_TABLE_FAILED",
1066
+ id: createStorageErrorId("LANCE", "CLEAR_TABLE", "FAILED"),
1186
1067
  domain: ErrorDomain.STORAGE,
1187
1068
  category: ErrorCategory.THIRD_PARTY,
1188
1069
  details: { tableName }
@@ -1205,7 +1086,7 @@ var StoreOperationsLance = class extends StoreOperations {
1205
1086
  } catch (validationError) {
1206
1087
  throw new MastraError(
1207
1088
  {
1208
- id: "STORAGE_LANCE_STORAGE_INSERT_INVALID_ARGS",
1089
+ id: createStorageErrorId("LANCE", "INSERT", "INVALID_ARGS"),
1209
1090
  domain: ErrorDomain.STORAGE,
1210
1091
  category: ErrorCategory.USER,
1211
1092
  text: validationError.message,
@@ -1224,12 +1105,11 @@ var StoreOperationsLance = class extends StoreOperations {
1224
1105
  processedRecord[key] = JSON.stringify(processedRecord[key]);
1225
1106
  }
1226
1107
  }
1227
- console.log(await table.schema());
1228
1108
  await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([processedRecord]);
1229
1109
  } catch (error) {
1230
1110
  throw new MastraError(
1231
1111
  {
1232
- id: "STORAGE_LANCE_STORAGE_INSERT_FAILED",
1112
+ id: createStorageErrorId("LANCE", "INSERT", "FAILED"),
1233
1113
  domain: ErrorDomain.STORAGE,
1234
1114
  category: ErrorCategory.THIRD_PARTY,
1235
1115
  details: { tableName }
@@ -1252,7 +1132,7 @@ var StoreOperationsLance = class extends StoreOperations {
1252
1132
  } catch (validationError) {
1253
1133
  throw new MastraError(
1254
1134
  {
1255
- id: "STORAGE_LANCE_STORAGE_BATCH_INSERT_INVALID_ARGS",
1135
+ id: createStorageErrorId("LANCE", "BATCH_INSERT", "INVALID_ARGS"),
1256
1136
  domain: ErrorDomain.STORAGE,
1257
1137
  category: ErrorCategory.USER,
1258
1138
  text: validationError.message,
@@ -1274,12 +1154,11 @@ var StoreOperationsLance = class extends StoreOperations {
1274
1154
  }
1275
1155
  return processedRecord;
1276
1156
  });
1277
- console.log(processedRecords);
1278
1157
  await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(processedRecords);
1279
1158
  } catch (error) {
1280
1159
  throw new MastraError(
1281
1160
  {
1282
- id: "STORAGE_LANCE_STORAGE_BATCH_INSERT_FAILED",
1161
+ id: createStorageErrorId("LANCE", "BATCH_INSERT", "FAILED"),
1283
1162
  domain: ErrorDomain.STORAGE,
1284
1163
  category: ErrorCategory.THIRD_PARTY,
1285
1164
  details: { tableName }
@@ -1302,7 +1181,7 @@ var StoreOperationsLance = class extends StoreOperations {
1302
1181
  } catch (validationError) {
1303
1182
  throw new MastraError(
1304
1183
  {
1305
- id: "STORAGE_LANCE_STORAGE_LOAD_INVALID_ARGS",
1184
+ id: createStorageErrorId("LANCE", "LOAD", "INVALID_ARGS"),
1306
1185
  domain: ErrorDomain.STORAGE,
1307
1186
  category: ErrorCategory.USER,
1308
1187
  text: validationError.message,
@@ -1341,7 +1220,7 @@ var StoreOperationsLance = class extends StoreOperations {
1341
1220
  if (error instanceof MastraError) throw error;
1342
1221
  throw new MastraError(
1343
1222
  {
1344
- id: "STORAGE_LANCE_STORAGE_LOAD_FAILED",
1223
+ id: createStorageErrorId("LANCE", "LOAD", "FAILED"),
1345
1224
  domain: ErrorDomain.STORAGE,
1346
1225
  category: ErrorCategory.THIRD_PARTY,
1347
1226
  details: { tableName, keyCount: Object.keys(keys).length, firstKey: Object.keys(keys)[0] ?? "" }
@@ -1358,28 +1237,53 @@ var StoreScoresLance = class extends ScoresStorage {
1358
1237
  this.client = client;
1359
1238
  }
1360
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();
1361
1263
  try {
1362
1264
  const table = await this.client.openTable(TABLE_SCORERS);
1363
1265
  const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1364
1266
  const allowedFields = new Set(schema.fields.map((f) => f.name));
1365
1267
  const filteredScore = {};
1366
- Object.keys(score).forEach((key) => {
1268
+ for (const key of Object.keys(validatedScore)) {
1367
1269
  if (allowedFields.has(key)) {
1368
- filteredScore[key] = score[key];
1270
+ filteredScore[key] = validatedScore[key];
1369
1271
  }
1370
- });
1272
+ }
1371
1273
  for (const key in filteredScore) {
1372
1274
  if (filteredScore[key] !== null && typeof filteredScore[key] === "object" && !(filteredScore[key] instanceof Date)) {
1373
1275
  filteredScore[key] = JSON.stringify(filteredScore[key]);
1374
1276
  }
1375
1277
  }
1376
- console.log("Saving score to LanceStorage:", filteredScore);
1278
+ filteredScore.id = id;
1279
+ filteredScore.createdAt = now;
1280
+ filteredScore.updatedAt = now;
1377
1281
  await table.add([filteredScore], { mode: "append" });
1378
- return { score };
1282
+ return { score: { ...validatedScore, id, createdAt: now, updatedAt: now } };
1379
1283
  } catch (error) {
1380
1284
  throw new MastraError(
1381
1285
  {
1382
- id: "LANCE_STORAGE_SAVE_SCORE_FAILED",
1286
+ id: createStorageErrorId("LANCE", "SAVE_SCORE", "FAILED"),
1383
1287
  text: "Failed to save score in LanceStorage",
1384
1288
  domain: ErrorDomain.STORAGE,
1385
1289
  category: ErrorCategory.THIRD_PARTY,
@@ -1395,12 +1299,11 @@ var StoreScoresLance = class extends ScoresStorage {
1395
1299
  const query = table.query().where(`id = '${id}'`).limit(1);
1396
1300
  const records = await query.toArray();
1397
1301
  if (records.length === 0) return null;
1398
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1399
- return processResultWithTypeConversion(records[0], schema);
1302
+ return await this.transformScoreRow(records[0]);
1400
1303
  } catch (error) {
1401
1304
  throw new MastraError(
1402
1305
  {
1403
- id: "LANCE_STORAGE_GET_SCORE_BY_ID_FAILED",
1306
+ id: createStorageErrorId("LANCE", "GET_SCORE_BY_ID", "FAILED"),
1404
1307
  text: "Failed to get score by id in LanceStorage",
1405
1308
  domain: ErrorDomain.STORAGE,
1406
1309
  category: ErrorCategory.THIRD_PARTY,
@@ -1410,34 +1313,76 @@ var StoreScoresLance = class extends ScoresStorage {
1410
1313
  );
1411
1314
  }
1412
1315
  }
1413
- 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({
1414
1333
  scorerId,
1415
- pagination
1334
+ pagination,
1335
+ entityId,
1336
+ entityType,
1337
+ source
1416
1338
  }) {
1417
1339
  try {
1340
+ const { page, perPage: perPageInput } = pagination;
1341
+ const perPage = normalizePerPage(perPageInput, 100);
1342
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1418
1343
  const table = await this.client.openTable(TABLE_SCORERS);
1419
- const { page = 0, perPage = 10 } = pagination || {};
1420
- const offset = page * perPage;
1421
- const query = table.query().where(`\`scorerId\` = '${scorerId}'`).limit(perPage);
1422
- if (offset > 0) query.offset(offset);
1423
- const records = await query.toArray();
1424
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1425
- const scores = processResultWithTypeConversion(records, schema);
1426
- const allRecords = await table.query().where(`\`scorerId\` = '${scorerId}'`).toArray();
1344
+ let query = table.query().where(`\`scorerId\` = '${scorerId}'`);
1345
+ if (source) {
1346
+ query = query.where(`\`source\` = '${source}'`);
1347
+ }
1348
+ if (entityId) {
1349
+ query = query.where(`\`entityId\` = '${entityId}'`);
1350
+ }
1351
+ if (entityType) {
1352
+ query = query.where(`\`entityType\` = '${entityType}'`);
1353
+ }
1354
+ let totalQuery = table.query().where(`\`scorerId\` = '${scorerId}'`);
1355
+ if (source) {
1356
+ totalQuery = totalQuery.where(`\`source\` = '${source}'`);
1357
+ }
1358
+ if (entityId) {
1359
+ totalQuery = totalQuery.where(`\`entityId\` = '${entityId}'`);
1360
+ }
1361
+ if (entityType) {
1362
+ totalQuery = totalQuery.where(`\`entityType\` = '${entityType}'`);
1363
+ }
1364
+ const allRecords = await totalQuery.toArray();
1427
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)));
1428
1373
  return {
1429
1374
  pagination: {
1430
1375
  page,
1431
- perPage,
1376
+ perPage: perPageForResponse,
1432
1377
  total,
1433
- hasMore: offset + scores.length < total
1378
+ hasMore: end < total
1434
1379
  },
1435
1380
  scores
1436
1381
  };
1437
1382
  } catch (error) {
1438
1383
  throw new MastraError(
1439
1384
  {
1440
- id: "LANCE_STORAGE_GET_SCORES_BY_SCORER_ID_FAILED",
1385
+ id: createStorageErrorId("LANCE", "LIST_SCORES_BY_SCORER_ID", "FAILED"),
1441
1386
  text: "Failed to get scores by scorerId in LanceStorage",
1442
1387
  domain: ErrorDomain.STORAGE,
1443
1388
  category: ErrorCategory.THIRD_PARTY,
@@ -1447,34 +1392,38 @@ var StoreScoresLance = class extends ScoresStorage {
1447
1392
  );
1448
1393
  }
1449
1394
  }
1450
- async getScoresByRunId({
1395
+ async listScoresByRunId({
1451
1396
  runId,
1452
1397
  pagination
1453
1398
  }) {
1454
1399
  try {
1400
+ const { page, perPage: perPageInput } = pagination;
1401
+ const perPage = normalizePerPage(perPageInput, 100);
1402
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1455
1403
  const table = await this.client.openTable(TABLE_SCORERS);
1456
- const { page = 0, perPage = 10 } = pagination || {};
1457
- const offset = page * perPage;
1458
- const query = table.query().where(`\`runId\` = '${runId}'`).limit(perPage);
1459
- if (offset > 0) query.offset(offset);
1460
- const records = await query.toArray();
1461
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1462
- const scores = processResultWithTypeConversion(records, schema);
1463
1404
  const allRecords = await table.query().where(`\`runId\` = '${runId}'`).toArray();
1464
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)));
1465
1414
  return {
1466
1415
  pagination: {
1467
1416
  page,
1468
- perPage,
1417
+ perPage: perPageForResponse,
1469
1418
  total,
1470
- hasMore: offset + scores.length < total
1419
+ hasMore: end < total
1471
1420
  },
1472
1421
  scores
1473
1422
  };
1474
1423
  } catch (error) {
1475
1424
  throw new MastraError(
1476
1425
  {
1477
- id: "LANCE_STORAGE_GET_SCORES_BY_RUN_ID_FAILED",
1426
+ id: createStorageErrorId("LANCE", "LIST_SCORES_BY_RUN_ID", "FAILED"),
1478
1427
  text: "Failed to get scores by runId in LanceStorage",
1479
1428
  domain: ErrorDomain.STORAGE,
1480
1429
  category: ErrorCategory.THIRD_PARTY,
@@ -1484,35 +1433,39 @@ var StoreScoresLance = class extends ScoresStorage {
1484
1433
  );
1485
1434
  }
1486
1435
  }
1487
- async getScoresByEntityId({
1436
+ async listScoresByEntityId({
1488
1437
  entityId,
1489
1438
  entityType,
1490
1439
  pagination
1491
1440
  }) {
1492
1441
  try {
1442
+ const { page, perPage: perPageInput } = pagination;
1443
+ const perPage = normalizePerPage(perPageInput, 100);
1444
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1493
1445
  const table = await this.client.openTable(TABLE_SCORERS);
1494
- const { page = 0, perPage = 10 } = pagination || {};
1495
- const offset = page * perPage;
1496
- const query = table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).limit(perPage);
1497
- if (offset > 0) query.offset(offset);
1498
- const records = await query.toArray();
1499
- const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1500
- const scores = processResultWithTypeConversion(records, schema);
1501
1446
  const allRecords = await table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).toArray();
1502
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)));
1503
1456
  return {
1504
1457
  pagination: {
1505
1458
  page,
1506
- perPage,
1459
+ perPage: perPageForResponse,
1507
1460
  total,
1508
- hasMore: offset + scores.length < total
1461
+ hasMore: end < total
1509
1462
  },
1510
1463
  scores
1511
1464
  };
1512
1465
  } catch (error) {
1513
1466
  throw new MastraError(
1514
1467
  {
1515
- id: "LANCE_STORAGE_GET_SCORES_BY_ENTITY_ID_FAILED",
1468
+ id: createStorageErrorId("LANCE", "LIST_SCORES_BY_ENTITY_ID", "FAILED"),
1516
1469
  text: "Failed to get scores by entityId and entityType in LanceStorage",
1517
1470
  domain: ErrorDomain.STORAGE,
1518
1471
  category: ErrorCategory.THIRD_PARTY,
@@ -1522,198 +1475,48 @@ var StoreScoresLance = class extends ScoresStorage {
1522
1475
  );
1523
1476
  }
1524
1477
  }
1525
- };
1526
- var StoreTracesLance = class extends TracesStorage {
1527
- client;
1528
- operations;
1529
- constructor({ client, operations }) {
1530
- super();
1531
- this.client = client;
1532
- this.operations = operations;
1533
- }
1534
- async saveTrace({ trace }) {
1535
- try {
1536
- const table = await this.client.openTable(TABLE_TRACES);
1537
- const record = {
1538
- ...trace,
1539
- attributes: JSON.stringify(trace.attributes),
1540
- status: JSON.stringify(trace.status),
1541
- events: JSON.stringify(trace.events),
1542
- links: JSON.stringify(trace.links),
1543
- other: JSON.stringify(trace.other)
1544
- };
1545
- await table.add([record], { mode: "append" });
1546
- return trace;
1547
- } catch (error) {
1548
- throw new MastraError(
1549
- {
1550
- id: "LANCE_STORE_SAVE_TRACE_FAILED",
1551
- domain: ErrorDomain.STORAGE,
1552
- category: ErrorCategory.THIRD_PARTY
1553
- },
1554
- error
1555
- );
1556
- }
1557
- }
1558
- async getTraceById({ traceId }) {
1559
- try {
1560
- const table = await this.client.openTable(TABLE_TRACES);
1561
- const query = table.query().where(`id = '${traceId}'`);
1562
- const records = await query.toArray();
1563
- return records[0];
1564
- } catch (error) {
1565
- throw new MastraError(
1566
- {
1567
- id: "LANCE_STORE_GET_TRACE_BY_ID_FAILED",
1568
- domain: ErrorDomain.STORAGE,
1569
- category: ErrorCategory.THIRD_PARTY
1570
- },
1571
- error
1572
- );
1573
- }
1574
- }
1575
- async getTraces({
1576
- name,
1577
- scope,
1578
- page = 1,
1579
- perPage = 10,
1580
- attributes
1478
+ async listScoresBySpan({
1479
+ traceId,
1480
+ spanId,
1481
+ pagination
1581
1482
  }) {
1582
1483
  try {
1583
- const table = await this.client.openTable(TABLE_TRACES);
1584
- const query = table.query();
1585
- if (name) {
1586
- query.where(`name = '${name}'`);
1587
- }
1588
- if (scope) {
1589
- query.where(`scope = '${scope}'`);
1590
- }
1591
- if (attributes) {
1592
- query.where(`attributes = '${JSON.stringify(attributes)}'`);
1593
- }
1594
- const offset = (page - 1) * perPage;
1595
- query.limit(perPage);
1596
- if (offset > 0) {
1597
- query.offset(offset);
1598
- }
1599
- const records = await query.toArray();
1600
- return records.map((record) => {
1601
- const processed = {
1602
- ...record,
1603
- attributes: record.attributes ? JSON.parse(record.attributes) : {},
1604
- status: record.status ? JSON.parse(record.status) : {},
1605
- events: record.events ? JSON.parse(record.events) : [],
1606
- links: record.links ? JSON.parse(record.links) : [],
1607
- other: record.other ? JSON.parse(record.other) : {},
1608
- startTime: new Date(record.startTime),
1609
- endTime: new Date(record.endTime),
1610
- createdAt: new Date(record.createdAt)
1611
- };
1612
- if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
1613
- processed.parentSpanId = "";
1614
- } else {
1615
- processed.parentSpanId = String(processed.parentSpanId);
1616
- }
1617
- return processed;
1618
- });
1619
- } catch (error) {
1620
- throw new MastraError(
1621
- {
1622
- id: "LANCE_STORE_GET_TRACES_FAILED",
1623
- domain: ErrorDomain.STORAGE,
1624
- category: ErrorCategory.THIRD_PARTY,
1625
- details: { name: name ?? "", scope: scope ?? "" }
1626
- },
1627
- error
1628
- );
1629
- }
1630
- }
1631
- async getTracesPaginated(args) {
1632
- try {
1633
- const table = await this.client.openTable(TABLE_TRACES);
1634
- const query = table.query();
1635
- const conditions = [];
1636
- if (args.name) {
1637
- conditions.push(`name = '${args.name}'`);
1638
- }
1639
- if (args.scope) {
1640
- conditions.push(`scope = '${args.scope}'`);
1641
- }
1642
- if (args.attributes) {
1643
- const attributesStr = JSON.stringify(args.attributes);
1644
- conditions.push(`attributes LIKE '%${attributesStr.replace(/"/g, '\\"')}%'`);
1645
- }
1646
- if (args.dateRange?.start) {
1647
- conditions.push(`\`createdAt\` >= ${args.dateRange.start.getTime()}`);
1648
- }
1649
- if (args.dateRange?.end) {
1650
- conditions.push(`\`createdAt\` <= ${args.dateRange.end.getTime()}`);
1651
- }
1652
- if (conditions.length > 0) {
1653
- const whereClause = conditions.join(" AND ");
1654
- query.where(whereClause);
1655
- }
1656
- let total = 0;
1657
- if (conditions.length > 0) {
1658
- const countQuery = table.query().where(conditions.join(" AND "));
1659
- const allRecords = await countQuery.toArray();
1660
- total = allRecords.length;
1661
- } else {
1662
- total = await table.countRows();
1663
- }
1664
- const page = args.page || 0;
1665
- const perPage = args.perPage || 10;
1666
- const offset = page * perPage;
1667
- query.limit(perPage);
1668
- if (offset > 0) {
1669
- 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);
1670
1495
  }
1671
1496
  const records = await query.toArray();
1672
- const traces = records.map((record) => {
1673
- const processed = {
1674
- ...record,
1675
- attributes: record.attributes ? JSON.parse(record.attributes) : {},
1676
- status: record.status ? JSON.parse(record.status) : {},
1677
- events: record.events ? JSON.parse(record.events) : [],
1678
- links: record.links ? JSON.parse(record.links) : [],
1679
- other: record.other ? JSON.parse(record.other) : {},
1680
- startTime: new Date(record.startTime),
1681
- endTime: new Date(record.endTime),
1682
- createdAt: new Date(record.createdAt)
1683
- };
1684
- if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
1685
- processed.parentSpanId = "";
1686
- } else {
1687
- processed.parentSpanId = String(processed.parentSpanId);
1688
- }
1689
- return processed;
1690
- });
1497
+ const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
1691
1498
  return {
1692
- traces,
1693
- total,
1694
- page,
1695
- perPage,
1696
- hasMore: total > (page + 1) * perPage
1499
+ pagination: {
1500
+ page,
1501
+ perPage: perPageForResponse,
1502
+ total,
1503
+ hasMore: end < total
1504
+ },
1505
+ scores
1697
1506
  };
1698
1507
  } catch (error) {
1699
1508
  throw new MastraError(
1700
1509
  {
1701
- 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",
1702
1512
  domain: ErrorDomain.STORAGE,
1703
1513
  category: ErrorCategory.THIRD_PARTY,
1704
- details: { name: args.name ?? "", scope: args.scope ?? "" }
1514
+ details: { error: error?.message }
1705
1515
  },
1706
1516
  error
1707
1517
  );
1708
1518
  }
1709
1519
  }
1710
- async batchTraceInsert({ records }) {
1711
- this.logger.debug("Batch inserting traces", { count: records.length });
1712
- await this.operations.batchInsert({
1713
- tableName: TABLE_TRACES,
1714
- records
1715
- });
1716
- }
1717
1520
  };
1718
1521
  function parseWorkflowRun(row) {
1719
1522
  let parsedSnapshot = row.snapshot;
@@ -1739,9 +1542,26 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1739
1542
  super();
1740
1543
  this.client = client;
1741
1544
  }
1545
+ updateWorkflowResults({
1546
+ // workflowName,
1547
+ // runId,
1548
+ // stepId,
1549
+ // result,
1550
+ // requestContext,
1551
+ }) {
1552
+ throw new Error("Method not implemented.");
1553
+ }
1554
+ updateWorkflowState({
1555
+ // workflowName,
1556
+ // runId,
1557
+ // opts,
1558
+ }) {
1559
+ throw new Error("Method not implemented.");
1560
+ }
1742
1561
  async persistWorkflowSnapshot({
1743
1562
  workflowName,
1744
1563
  runId,
1564
+ resourceId,
1745
1565
  snapshot
1746
1566
  }) {
1747
1567
  try {
@@ -1755,10 +1575,13 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1755
1575
  } else {
1756
1576
  createdAt = now;
1757
1577
  }
1578
+ const { status, value, ...rest } = snapshot;
1758
1579
  const record = {
1759
1580
  workflow_name: workflowName,
1760
1581
  run_id: runId,
1761
- snapshot: JSON.stringify(snapshot),
1582
+ resourceId,
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
1762
1585
  createdAt,
1763
1586
  updatedAt: now
1764
1587
  };
@@ -1766,7 +1589,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1766
1589
  } catch (error) {
1767
1590
  throw new MastraError(
1768
1591
  {
1769
- id: "LANCE_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
1592
+ id: createStorageErrorId("LANCE", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
1770
1593
  domain: ErrorDomain.STORAGE,
1771
1594
  category: ErrorCategory.THIRD_PARTY,
1772
1595
  details: { workflowName, runId }
@@ -1787,7 +1610,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1787
1610
  } catch (error) {
1788
1611
  throw new MastraError(
1789
1612
  {
1790
- id: "LANCE_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
1613
+ id: createStorageErrorId("LANCE", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
1791
1614
  domain: ErrorDomain.STORAGE,
1792
1615
  category: ErrorCategory.THIRD_PARTY,
1793
1616
  details: { workflowName, runId }
@@ -1811,7 +1634,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1811
1634
  } catch (error) {
1812
1635
  throw new MastraError(
1813
1636
  {
1814
- id: "LANCE_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
1637
+ id: createStorageErrorId("LANCE", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
1815
1638
  domain: ErrorDomain.STORAGE,
1816
1639
  category: ErrorCategory.THIRD_PARTY,
1817
1640
  details: { runId: args.runId, workflowName: args.workflowName ?? "" }
@@ -1820,7 +1643,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1820
1643
  );
1821
1644
  }
1822
1645
  }
1823
- async getWorkflowRuns(args) {
1646
+ async listWorkflowRuns(args) {
1824
1647
  try {
1825
1648
  const table = await this.client.openTable(TABLE_WORKFLOW_SNAPSHOT);
1826
1649
  let query = table.query();
@@ -1828,6 +1651,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1828
1651
  if (args?.workflowName) {
1829
1652
  conditions.push(`workflow_name = '${args.workflowName.replace(/'/g, "''")}'`);
1830
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
+ }
1831
1658
  if (args?.resourceId) {
1832
1659
  conditions.push(`\`resourceId\` = '${args.resourceId}'`);
1833
1660
  }
@@ -1844,11 +1671,22 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1844
1671
  } else {
1845
1672
  total = await table.countRows();
1846
1673
  }
1847
- if (args?.limit) {
1848
- query.limit(args.limit);
1849
- }
1850
- if (args?.offset) {
1851
- 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);
1852
1690
  }
1853
1691
  const records = await query.toArray();
1854
1692
  return {
@@ -1858,10 +1696,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1858
1696
  } catch (error) {
1859
1697
  throw new MastraError(
1860
1698
  {
1861
- id: "LANCE_STORE_GET_WORKFLOW_RUNS_FAILED",
1699
+ id: createStorageErrorId("LANCE", "LIST_WORKFLOW_RUNS", "FAILED"),
1862
1700
  domain: ErrorDomain.STORAGE,
1863
1701
  category: ErrorCategory.THIRD_PARTY,
1864
- details: { namespace: args?.namespace ?? "", workflowName: args?.workflowName ?? "" }
1702
+ details: { resourceId: args?.resourceId ?? "", workflowName: args?.workflowName ?? "" }
1865
1703
  },
1866
1704
  error
1867
1705
  );
@@ -1875,48 +1713,54 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
1875
1713
  lanceClient;
1876
1714
  /**
1877
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
1878
1718
  * @param uri The URI to connect to LanceDB
1879
- * @param options connection options
1719
+ * @param connectionOptions connection options for LanceDB
1720
+ * @param storageOptions storage options including disableInit
1880
1721
  *
1881
1722
  * Usage:
1882
1723
  *
1883
1724
  * Connect to a local database
1884
1725
  * ```ts
1885
- * const store = await LanceStorage.create('/path/to/db');
1726
+ * const store = await LanceStorage.create('my-storage-id', 'MyStorage', '/path/to/db');
1886
1727
  * ```
1887
1728
  *
1888
1729
  * Connect to a LanceDB cloud database
1889
1730
  * ```ts
1890
- * const store = await LanceStorage.create('db://host:port');
1731
+ * const store = await LanceStorage.create('my-storage-id', 'MyStorage', 'db://host:port');
1891
1732
  * ```
1892
1733
  *
1893
1734
  * Connect to a cloud database
1894
1735
  * ```ts
1895
- * 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 });
1896
1742
  * ```
1897
1743
  */
1898
- static async create(name, uri, options) {
1899
- const instance = new _LanceStorage(name);
1744
+ static async create(id, name, uri, connectionOptions, storageOptions) {
1745
+ const instance = new _LanceStorage(id, name, storageOptions?.disableInit);
1900
1746
  try {
1901
- instance.lanceClient = await connect(uri, options);
1747
+ instance.lanceClient = await connect(uri, connectionOptions);
1902
1748
  const operations = new StoreOperationsLance({ client: instance.lanceClient });
1903
1749
  instance.stores = {
1904
1750
  operations: new StoreOperationsLance({ client: instance.lanceClient }),
1905
1751
  workflows: new StoreWorkflowsLance({ client: instance.lanceClient }),
1906
- traces: new StoreTracesLance({ client: instance.lanceClient, operations }),
1907
1752
  scores: new StoreScoresLance({ client: instance.lanceClient }),
1908
- memory: new StoreMemoryLance({ client: instance.lanceClient, operations }),
1909
- legacyEvals: new StoreLegacyEvalsLance({ client: instance.lanceClient })
1753
+ memory: new StoreMemoryLance({ client: instance.lanceClient, operations })
1910
1754
  };
1911
1755
  return instance;
1912
1756
  } catch (e) {
1913
1757
  throw new MastraError(
1914
1758
  {
1915
- id: "STORAGE_LANCE_STORAGE_CONNECT_FAILED",
1759
+ id: createStorageErrorId("LANCE", "CONNECT", "FAILED"),
1916
1760
  domain: ErrorDomain.STORAGE,
1917
1761
  category: ErrorCategory.THIRD_PARTY,
1918
1762
  text: `Failed to connect to LanceDB: ${e.message || e}`,
1919
- details: { uri, optionsProvided: !!options }
1763
+ details: { uri, optionsProvided: !!connectionOptions }
1920
1764
  },
1921
1765
  e
1922
1766
  );
@@ -1926,15 +1770,13 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
1926
1770
  * @internal
1927
1771
  * Private constructor to enforce using the create factory method
1928
1772
  */
1929
- constructor(name) {
1930
- super({ name });
1773
+ constructor(id, name, disableInit) {
1774
+ super({ id, name, disableInit });
1931
1775
  const operations = new StoreOperationsLance({ client: this.lanceClient });
1932
1776
  this.stores = {
1933
1777
  operations: new StoreOperationsLance({ client: this.lanceClient }),
1934
1778
  workflows: new StoreWorkflowsLance({ client: this.lanceClient }),
1935
- traces: new StoreTracesLance({ client: this.lanceClient, operations }),
1936
1779
  scores: new StoreScoresLance({ client: this.lanceClient }),
1937
- legacyEvals: new StoreLegacyEvalsLance({ client: this.lanceClient }),
1938
1780
  memory: new StoreMemoryLance({ client: this.lanceClient, operations })
1939
1781
  };
1940
1782
  }
@@ -1969,9 +1811,6 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
1969
1811
  async getThreadById({ threadId }) {
1970
1812
  return this.stores.memory.getThreadById({ threadId });
1971
1813
  }
1972
- async getThreadsByResourceId({ resourceId }) {
1973
- return this.stores.memory.getThreadsByResourceId({ resourceId });
1974
- }
1975
1814
  /**
1976
1815
  * Saves a thread to the database. This function doesn't overwrite existing threads.
1977
1816
  * @param thread - The thread to save
@@ -1996,7 +1835,8 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
1996
1835
  resourceWorkingMemory: true,
1997
1836
  hasColumn: true,
1998
1837
  createTable: true,
1999
- deleteMessages: false
1838
+ deleteMessages: false,
1839
+ listScoresBySpan: true
2000
1840
  };
2001
1841
  }
2002
1842
  async getResourceById({ resourceId }) {
@@ -2060,54 +1900,44 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2060
1900
  });
2061
1901
  return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
2062
1902
  }
2063
- async getMessages({
2064
- threadId,
2065
- resourceId,
2066
- selectBy,
2067
- format,
2068
- threadConfig
2069
- }) {
2070
- return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format, threadConfig });
1903
+ async listMessagesById({ messageIds }) {
1904
+ return this.stores.memory.listMessagesById({ messageIds });
2071
1905
  }
2072
1906
  async saveMessages(args) {
2073
1907
  return this.stores.memory.saveMessages(args);
2074
1908
  }
2075
- async getThreadsByResourceIdPaginated(args) {
2076
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
2077
- }
2078
- async getMessagesPaginated(args) {
2079
- return this.stores.memory.getMessagesPaginated(args);
2080
- }
2081
1909
  async updateMessages(_args) {
2082
1910
  return this.stores.memory.updateMessages(_args);
2083
1911
  }
2084
- async getTraceById(args) {
2085
- return this.stores.traces.getTraceById(args);
2086
- }
2087
- async getTraces(args) {
2088
- return this.stores.traces.getTraces(args);
2089
- }
2090
- async getTracesPaginated(args) {
2091
- return this.stores.traces.getTracesPaginated(args);
2092
- }
2093
- async getEvalsByAgentName(agentName, type) {
2094
- return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
2095
- }
2096
- async getEvals(options) {
2097
- return this.stores.legacyEvals.getEvals(options);
2098
- }
2099
- async getWorkflowRuns(args) {
2100
- return this.stores.workflows.getWorkflowRuns(args);
1912
+ async listWorkflowRuns(args) {
1913
+ return this.stores.workflows.listWorkflowRuns(args);
2101
1914
  }
2102
1915
  async getWorkflowRunById(args) {
2103
1916
  return this.stores.workflows.getWorkflowRunById(args);
2104
1917
  }
1918
+ async updateWorkflowResults({
1919
+ workflowName,
1920
+ runId,
1921
+ stepId,
1922
+ result,
1923
+ requestContext
1924
+ }) {
1925
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
1926
+ }
1927
+ async updateWorkflowState({
1928
+ workflowName,
1929
+ runId,
1930
+ opts
1931
+ }) {
1932
+ return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
1933
+ }
2105
1934
  async persistWorkflowSnapshot({
2106
1935
  workflowName,
2107
1936
  runId,
1937
+ resourceId,
2108
1938
  snapshot
2109
1939
  }) {
2110
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
1940
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
2111
1941
  }
2112
1942
  async loadWorkflowSnapshot({
2113
1943
  workflowName,
@@ -2118,27 +1948,37 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2118
1948
  async getScoreById({ id: _id }) {
2119
1949
  return this.stores.scores.getScoreById({ id: _id });
2120
1950
  }
2121
- async getScoresByScorerId({
1951
+ async listScoresByScorerId({
2122
1952
  scorerId,
1953
+ source,
1954
+ entityId,
1955
+ entityType,
2123
1956
  pagination
2124
1957
  }) {
2125
- return this.stores.scores.getScoresByScorerId({ scorerId, pagination });
1958
+ return this.stores.scores.listScoresByScorerId({ scorerId, source, pagination, entityId, entityType });
2126
1959
  }
2127
- async saveScore(_score) {
2128
- return this.stores.scores.saveScore(_score);
1960
+ async saveScore(score) {
1961
+ return this.stores.scores.saveScore(score);
2129
1962
  }
2130
- async getScoresByRunId({
1963
+ async listScoresByRunId({
2131
1964
  runId,
2132
1965
  pagination
2133
1966
  }) {
2134
- return this.stores.scores.getScoresByRunId({ runId, pagination });
1967
+ return this.stores.scores.listScoresByRunId({ runId, pagination });
2135
1968
  }
2136
- async getScoresByEntityId({
1969
+ async listScoresByEntityId({
2137
1970
  entityId,
2138
1971
  entityType,
2139
1972
  pagination
2140
1973
  }) {
2141
- 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 });
2142
1982
  }
2143
1983
  };
2144
1984
  var LanceFilterTranslator = class extends BaseFilterTranslator {
@@ -2487,14 +2327,14 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2487
2327
  * ```
2488
2328
  */
2489
2329
  static async create(uri, options) {
2490
- const instance = new _LanceVectorStore();
2330
+ const instance = new _LanceVectorStore(options?.id || crypto.randomUUID());
2491
2331
  try {
2492
2332
  instance.lanceClient = await connect(uri, options);
2493
2333
  return instance;
2494
2334
  } catch (e) {
2495
2335
  throw new MastraError(
2496
2336
  {
2497
- id: "STORAGE_LANCE_VECTOR_CONNECT_FAILED",
2337
+ id: createVectorErrorId("LANCE", "CONNECT", "FAILED"),
2498
2338
  domain: ErrorDomain.STORAGE,
2499
2339
  category: ErrorCategory.THIRD_PARTY,
2500
2340
  details: { uri }
@@ -2507,8 +2347,8 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2507
2347
  * @internal
2508
2348
  * Private constructor to enforce using the create factory method
2509
2349
  */
2510
- constructor() {
2511
- super();
2350
+ constructor(id) {
2351
+ super({ id });
2512
2352
  }
2513
2353
  close() {
2514
2354
  if (this.lanceClient) {
@@ -2537,7 +2377,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2537
2377
  } catch (error) {
2538
2378
  throw new MastraError(
2539
2379
  {
2540
- id: "STORAGE_LANCE_VECTOR_QUERY_FAILED_INVALID_ARGS",
2380
+ id: createVectorErrorId("LANCE", "QUERY", "INVALID_ARGS"),
2541
2381
  domain: ErrorDomain.STORAGE,
2542
2382
  category: ErrorCategory.USER,
2543
2383
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2585,7 +2425,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2585
2425
  } catch (error) {
2586
2426
  throw new MastraError(
2587
2427
  {
2588
- id: "STORAGE_LANCE_VECTOR_QUERY_FAILED",
2428
+ id: createVectorErrorId("LANCE", "QUERY", "FAILED"),
2589
2429
  domain: ErrorDomain.STORAGE,
2590
2430
  category: ErrorCategory.THIRD_PARTY,
2591
2431
  details: { tableName, includeVector, columnsCount: columns?.length, includeAllColumns }
@@ -2637,7 +2477,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2637
2477
  } catch (error) {
2638
2478
  throw new MastraError(
2639
2479
  {
2640
- id: "STORAGE_LANCE_VECTOR_UPSERT_FAILED_INVALID_ARGS",
2480
+ id: createVectorErrorId("LANCE", "UPSERT", "INVALID_ARGS"),
2641
2481
  domain: ErrorDomain.STORAGE,
2642
2482
  category: ErrorCategory.USER,
2643
2483
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2673,7 +2513,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2673
2513
  } catch (error) {
2674
2514
  throw new MastraError(
2675
2515
  {
2676
- id: "STORAGE_LANCE_VECTOR_UPSERT_FAILED",
2516
+ id: createVectorErrorId("LANCE", "UPSERT", "FAILED"),
2677
2517
  domain: ErrorDomain.STORAGE,
2678
2518
  category: ErrorCategory.THIRD_PARTY,
2679
2519
  details: { tableName, vectorCount: vectors.length, metadataCount: metadata.length, idsCount: ids.length }
@@ -2700,7 +2540,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2700
2540
  async createTable(tableName, data, options) {
2701
2541
  if (!this.lanceClient) {
2702
2542
  throw new MastraError({
2703
- id: "STORAGE_LANCE_VECTOR_CREATE_TABLE_FAILED_INVALID_ARGS",
2543
+ id: createVectorErrorId("LANCE", "CREATE_TABLE", "INVALID_ARGS"),
2704
2544
  domain: ErrorDomain.STORAGE,
2705
2545
  category: ErrorCategory.USER,
2706
2546
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2715,7 +2555,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2715
2555
  } catch (error) {
2716
2556
  throw new MastraError(
2717
2557
  {
2718
- id: "STORAGE_LANCE_VECTOR_CREATE_TABLE_FAILED",
2558
+ id: createVectorErrorId("LANCE", "CREATE_TABLE", "FAILED"),
2719
2559
  domain: ErrorDomain.STORAGE,
2720
2560
  category: ErrorCategory.THIRD_PARTY,
2721
2561
  details: { tableName }
@@ -2727,7 +2567,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2727
2567
  async listTables() {
2728
2568
  if (!this.lanceClient) {
2729
2569
  throw new MastraError({
2730
- id: "STORAGE_LANCE_VECTOR_LIST_TABLES_FAILED_INVALID_ARGS",
2570
+ id: createVectorErrorId("LANCE", "LIST_TABLES", "INVALID_ARGS"),
2731
2571
  domain: ErrorDomain.STORAGE,
2732
2572
  category: ErrorCategory.USER,
2733
2573
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2739,7 +2579,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2739
2579
  } catch (error) {
2740
2580
  throw new MastraError(
2741
2581
  {
2742
- id: "STORAGE_LANCE_VECTOR_LIST_TABLES_FAILED",
2582
+ id: createVectorErrorId("LANCE", "LIST_TABLES", "FAILED"),
2743
2583
  domain: ErrorDomain.STORAGE,
2744
2584
  category: ErrorCategory.THIRD_PARTY
2745
2585
  },
@@ -2750,7 +2590,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2750
2590
  async getTableSchema(tableName) {
2751
2591
  if (!this.lanceClient) {
2752
2592
  throw new MastraError({
2753
- id: "STORAGE_LANCE_VECTOR_GET_TABLE_SCHEMA_FAILED_INVALID_ARGS",
2593
+ id: createVectorErrorId("LANCE", "GET_TABLE_SCHEMA", "INVALID_ARGS"),
2754
2594
  domain: ErrorDomain.STORAGE,
2755
2595
  category: ErrorCategory.USER,
2756
2596
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2763,7 +2603,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2763
2603
  } catch (error) {
2764
2604
  throw new MastraError(
2765
2605
  {
2766
- id: "STORAGE_LANCE_VECTOR_GET_TABLE_SCHEMA_FAILED",
2606
+ id: createVectorErrorId("LANCE", "GET_TABLE_SCHEMA", "FAILED"),
2767
2607
  domain: ErrorDomain.STORAGE,
2768
2608
  category: ErrorCategory.THIRD_PARTY,
2769
2609
  details: { tableName }
@@ -2798,7 +2638,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2798
2638
  } catch (err) {
2799
2639
  throw new MastraError(
2800
2640
  {
2801
- id: "STORAGE_LANCE_VECTOR_CREATE_INDEX_FAILED_INVALID_ARGS",
2641
+ id: createVectorErrorId("LANCE", "CREATE_INDEX", "INVALID_ARGS"),
2802
2642
  domain: ErrorDomain.STORAGE,
2803
2643
  category: ErrorCategory.USER,
2804
2644
  details: { tableName: tableName || "", indexName, dimension, metric }
@@ -2843,7 +2683,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2843
2683
  } catch (error) {
2844
2684
  throw new MastraError(
2845
2685
  {
2846
- id: "STORAGE_LANCE_VECTOR_CREATE_INDEX_FAILED",
2686
+ id: createVectorErrorId("LANCE", "CREATE_INDEX", "FAILED"),
2847
2687
  domain: ErrorDomain.STORAGE,
2848
2688
  category: ErrorCategory.THIRD_PARTY,
2849
2689
  details: { tableName: tableName || "", indexName, dimension }
@@ -2855,7 +2695,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2855
2695
  async listIndexes() {
2856
2696
  if (!this.lanceClient) {
2857
2697
  throw new MastraError({
2858
- id: "STORAGE_LANCE_VECTOR_LIST_INDEXES_FAILED_INVALID_ARGS",
2698
+ id: createVectorErrorId("LANCE", "LIST_INDEXES", "INVALID_ARGS"),
2859
2699
  domain: ErrorDomain.STORAGE,
2860
2700
  category: ErrorCategory.USER,
2861
2701
  text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
@@ -2874,7 +2714,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2874
2714
  } catch (error) {
2875
2715
  throw new MastraError(
2876
2716
  {
2877
- id: "STORAGE_LANCE_VECTOR_LIST_INDEXES_FAILED",
2717
+ id: createVectorErrorId("LANCE", "LIST_INDEXES", "FAILED"),
2878
2718
  domain: ErrorDomain.STORAGE,
2879
2719
  category: ErrorCategory.THIRD_PARTY
2880
2720
  },
@@ -2893,7 +2733,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2893
2733
  } catch (err) {
2894
2734
  throw new MastraError(
2895
2735
  {
2896
- id: "STORAGE_LANCE_VECTOR_DESCRIBE_INDEX_FAILED_INVALID_ARGS",
2736
+ id: createVectorErrorId("LANCE", "DESCRIBE_INDEX", "INVALID_ARGS"),
2897
2737
  domain: ErrorDomain.STORAGE,
2898
2738
  category: ErrorCategory.USER,
2899
2739
  details: { indexName }
@@ -2928,7 +2768,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2928
2768
  } catch (error) {
2929
2769
  throw new MastraError(
2930
2770
  {
2931
- id: "STORAGE_LANCE_VECTOR_DESCRIBE_INDEX_FAILED",
2771
+ id: createVectorErrorId("LANCE", "DESCRIBE_INDEX", "FAILED"),
2932
2772
  domain: ErrorDomain.STORAGE,
2933
2773
  category: ErrorCategory.THIRD_PARTY,
2934
2774
  details: { indexName }
@@ -2948,7 +2788,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2948
2788
  } catch (err) {
2949
2789
  throw new MastraError(
2950
2790
  {
2951
- id: "STORAGE_LANCE_VECTOR_DELETE_INDEX_FAILED_INVALID_ARGS",
2791
+ id: createVectorErrorId("LANCE", "DELETE_INDEX", "INVALID_ARGS"),
2952
2792
  domain: ErrorDomain.STORAGE,
2953
2793
  category: ErrorCategory.USER,
2954
2794
  details: { indexName }
@@ -2971,7 +2811,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2971
2811
  } catch (error) {
2972
2812
  throw new MastraError(
2973
2813
  {
2974
- id: "STORAGE_LANCE_VECTOR_DELETE_INDEX_FAILED",
2814
+ id: createVectorErrorId("LANCE", "DELETE_INDEX", "FAILED"),
2975
2815
  domain: ErrorDomain.STORAGE,
2976
2816
  category: ErrorCategory.THIRD_PARTY,
2977
2817
  details: { indexName }
@@ -2986,7 +2826,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2986
2826
  async deleteAllTables() {
2987
2827
  if (!this.lanceClient) {
2988
2828
  throw new MastraError({
2989
- id: "STORAGE_LANCE_VECTOR_DELETE_ALL_TABLES_FAILED_INVALID_ARGS",
2829
+ id: createVectorErrorId("LANCE", "DELETE_ALL_TABLES", "INVALID_ARGS"),
2990
2830
  domain: ErrorDomain.STORAGE,
2991
2831
  category: ErrorCategory.USER,
2992
2832
  details: { methodName: "deleteAllTables" },
@@ -2998,7 +2838,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
2998
2838
  } catch (error) {
2999
2839
  throw new MastraError(
3000
2840
  {
3001
- id: "STORAGE_LANCE_VECTOR_DELETE_ALL_TABLES_FAILED",
2841
+ id: createVectorErrorId("LANCE", "DELETE_ALL_TABLES", "FAILED"),
3002
2842
  domain: ErrorDomain.STORAGE,
3003
2843
  category: ErrorCategory.THIRD_PARTY,
3004
2844
  details: { methodName: "deleteAllTables" }
@@ -3010,7 +2850,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3010
2850
  async deleteTable(tableName) {
3011
2851
  if (!this.lanceClient) {
3012
2852
  throw new MastraError({
3013
- id: "STORAGE_LANCE_VECTOR_DELETE_TABLE_FAILED_INVALID_ARGS",
2853
+ id: createVectorErrorId("LANCE", "DELETE_TABLE", "INVALID_ARGS"),
3014
2854
  domain: ErrorDomain.STORAGE,
3015
2855
  category: ErrorCategory.USER,
3016
2856
  details: { tableName },
@@ -3022,7 +2862,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3022
2862
  } catch (error) {
3023
2863
  throw new MastraError(
3024
2864
  {
3025
- id: "STORAGE_LANCE_VECTOR_DELETE_TABLE_FAILED",
2865
+ id: createVectorErrorId("LANCE", "DELETE_TABLE", "FAILED"),
3026
2866
  domain: ErrorDomain.STORAGE,
3027
2867
  category: ErrorCategory.THIRD_PARTY,
3028
2868
  details: { tableName }
@@ -3031,7 +2871,44 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3031
2871
  );
3032
2872
  }
3033
2873
  }
3034
- 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
+ }
3035
2912
  try {
3036
2913
  if (!this.lanceClient) {
3037
2914
  throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
@@ -3039,21 +2916,6 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3039
2916
  if (!indexName) {
3040
2917
  throw new Error("indexName is required");
3041
2918
  }
3042
- if (!id) {
3043
- throw new Error("id is required");
3044
- }
3045
- } catch (err) {
3046
- throw new MastraError(
3047
- {
3048
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
3049
- domain: ErrorDomain.STORAGE,
3050
- category: ErrorCategory.USER,
3051
- details: { indexName, id }
3052
- },
3053
- err
3054
- );
3055
- }
3056
- try {
3057
2919
  const tables = await this.lanceClient.tableNames();
3058
2920
  for (const tableName of tables) {
3059
2921
  this.logger.debug("Checking table:" + tableName);
@@ -3063,39 +2925,66 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3063
2925
  const hasColumn = schema.fields.some((field) => field.name === indexName);
3064
2926
  if (hasColumn) {
3065
2927
  this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3066
- const existingRecord = await table.query().where(`id = '${id}'`).select(schema.fields.map((field) => field.name)).limit(1).toArray();
3067
- if (existingRecord.length === 0) {
3068
- 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");
3069
2953
  }
3070
- const rowData = {
3071
- id
3072
- };
3073
- Object.entries(existingRecord[0]).forEach(([key, value]) => {
3074
- if (key !== "id" && key !== "_distance") {
3075
- if (key === indexName) {
3076
- if (!update.vector) {
3077
- if (Array.isArray(value)) {
3078
- rowData[key] = [...value];
3079
- } else if (typeof value === "object" && value !== null) {
3080
- 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;
3081
2966
  } else {
3082
- 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
+ }
3083
2974
  }
2975
+ } else {
2976
+ rowData[key] = value;
3084
2977
  }
3085
- } else {
3086
- rowData[key] = value;
3087
2978
  }
2979
+ });
2980
+ if (update.metadata) {
2981
+ Object.entries(update.metadata).forEach(([key, value]) => {
2982
+ rowData[`metadata_${key}`] = value;
2983
+ });
3088
2984
  }
2985
+ return rowData;
3089
2986
  });
3090
- if (update.vector) {
3091
- rowData[indexName] = update.vector;
3092
- }
3093
- if (update.metadata) {
3094
- Object.entries(update.metadata).forEach(([key, value]) => {
3095
- rowData[`metadata_${key}`] = value;
3096
- });
3097
- }
3098
- await table.add([rowData], { mode: "overwrite" });
2987
+ await table.add(updatedRecords, { mode: "overwrite" });
3099
2988
  return;
3100
2989
  }
3101
2990
  } catch (err) {
@@ -3105,12 +2994,19 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3105
2994
  }
3106
2995
  throw new Error(`No table found with column/index '${indexName}'`);
3107
2996
  } catch (error) {
2997
+ if (error instanceof MastraError) throw error;
3108
2998
  throw new MastraError(
3109
2999
  {
3110
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
3000
+ id: createVectorErrorId("LANCE", "UPDATE_VECTOR", "FAILED"),
3111
3001
  domain: ErrorDomain.STORAGE,
3112
3002
  category: ErrorCategory.THIRD_PARTY,
3113
- 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
+ }
3114
3010
  },
3115
3011
  error
3116
3012
  );
@@ -3130,10 +3026,13 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3130
3026
  } catch (err) {
3131
3027
  throw new MastraError(
3132
3028
  {
3133
- id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
3029
+ id: createVectorErrorId("LANCE", "DELETE_VECTOR", "INVALID_ARGS"),
3134
3030
  domain: ErrorDomain.STORAGE,
3135
3031
  category: ErrorCategory.USER,
3136
- details: { indexName, id }
3032
+ details: {
3033
+ indexName,
3034
+ ...id && { id }
3035
+ }
3137
3036
  },
3138
3037
  err
3139
3038
  );
@@ -3160,10 +3059,13 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3160
3059
  } catch (error) {
3161
3060
  throw new MastraError(
3162
3061
  {
3163
- id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
3062
+ id: createVectorErrorId("LANCE", "DELETE_VECTOR", "FAILED"),
3164
3063
  domain: ErrorDomain.STORAGE,
3165
3064
  category: ErrorCategory.THIRD_PARTY,
3166
- details: { indexName, id }
3065
+ details: {
3066
+ indexName,
3067
+ ...id && { id }
3068
+ }
3167
3069
  },
3168
3070
  error
3169
3071
  );
@@ -3194,6 +3096,109 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3194
3096
  });
3195
3097
  return result;
3196
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
+ }
3197
3202
  };
3198
3203
 
3199
3204
  export { LanceStorage, LanceVectorStore };