@mastra/lance 0.1.2 → 0.1.3-alpha.1

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.
@@ -1,6 +1,8 @@
1
1
  import { connect } from '@lancedb/lancedb';
2
2
  import type { Connection, ConnectionOptions, SchemaLike, FieldLike } from '@lancedb/lancedb';
3
+ import type { MastraMessageContentV2 } from '@mastra/core/agent';
3
4
  import { MessageList } from '@mastra/core/agent';
5
+ import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
4
6
  import type { MastraMessageV1, MastraMessageV2, StorageThreadType, TraceType } from '@mastra/core/memory';
5
7
  import {
6
8
  MastraStorage,
@@ -56,7 +58,16 @@ export class LanceStorage extends MastraStorage {
56
58
  instance.lanceClient = await connect(uri, options);
57
59
  return instance;
58
60
  } catch (e: any) {
59
- throw new Error(`Failed to connect to LanceDB: ${e}`);
61
+ throw new MastraError(
62
+ {
63
+ id: 'STORAGE_LANCE_STORAGE_CONNECT_FAILED',
64
+ domain: ErrorDomain.STORAGE,
65
+ category: ErrorCategory.THIRD_PARTY,
66
+ text: `Failed to connect to LanceDB: ${e.message || e}`,
67
+ details: { uri, optionsProvided: !!options },
68
+ },
69
+ e,
70
+ );
60
71
  }
61
72
  }
62
73
 
@@ -75,11 +86,41 @@ export class LanceStorage extends MastraStorage {
75
86
  tableName: TABLE_NAMES;
76
87
  schema: Record<string, StorageColumn>;
77
88
  }): Promise<void> {
89
+ try {
90
+ if (!this.lanceClient) {
91
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
92
+ }
93
+ if (!tableName) {
94
+ throw new Error('tableName is required for createTable.');
95
+ }
96
+ if (!schema) {
97
+ throw new Error('schema is required for createTable.');
98
+ }
99
+ } catch (error) {
100
+ throw new MastraError(
101
+ {
102
+ id: 'STORAGE_LANCE_STORAGE_CREATE_TABLE_INVALID_ARGS',
103
+ domain: ErrorDomain.STORAGE,
104
+ category: ErrorCategory.USER,
105
+ details: { tableName },
106
+ },
107
+ error,
108
+ );
109
+ }
110
+
78
111
  try {
79
112
  const arrowSchema = this.translateSchema(schema);
80
113
  await this.lanceClient.createEmptyTable(tableName, arrowSchema);
81
114
  } catch (error: any) {
82
- throw new Error(`Failed to create table: ${error}`);
115
+ throw new MastraError(
116
+ {
117
+ id: 'STORAGE_LANCE_STORAGE_CREATE_TABLE_FAILED',
118
+ domain: ErrorDomain.STORAGE,
119
+ category: ErrorCategory.THIRD_PARTY,
120
+ details: { tableName },
121
+ },
122
+ error,
123
+ );
83
124
  }
84
125
  }
85
126
 
@@ -129,15 +170,42 @@ export class LanceStorage extends MastraStorage {
129
170
  * @param tableName Name of the table to drop
130
171
  */
131
172
  async dropTable(tableName: TABLE_NAMES): Promise<void> {
173
+ try {
174
+ if (!this.lanceClient) {
175
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
176
+ }
177
+ if (!tableName) {
178
+ throw new Error('tableName is required for dropTable.');
179
+ }
180
+ } catch (validationError: any) {
181
+ throw new MastraError(
182
+ {
183
+ id: 'STORAGE_LANCE_STORAGE_DROP_TABLE_INVALID_ARGS',
184
+ domain: ErrorDomain.STORAGE,
185
+ category: ErrorCategory.USER,
186
+ text: validationError.message,
187
+ details: { tableName },
188
+ },
189
+ validationError,
190
+ );
191
+ }
192
+
132
193
  try {
133
194
  await this.lanceClient.dropTable(tableName);
134
195
  } catch (error: any) {
135
- // Don't throw if the table doesn't exist
136
- if (error.toString().includes('was not found')) {
196
+ if (error.toString().includes('was not found') || error.message?.includes('Table not found')) {
137
197
  this.logger.debug(`Table '${tableName}' does not exist, skipping drop`);
138
198
  return;
139
199
  }
140
- throw new Error(`Failed to drop table: ${error}`);
200
+ throw new MastraError(
201
+ {
202
+ id: 'STORAGE_LANCE_STORAGE_DROP_TABLE_FAILED',
203
+ domain: ErrorDomain.STORAGE,
204
+ category: ErrorCategory.THIRD_PARTY,
205
+ details: { tableName },
206
+ },
207
+ error,
208
+ );
141
209
  }
142
210
  }
143
211
 
@@ -147,6 +215,26 @@ export class LanceStorage extends MastraStorage {
147
215
  * @returns Table schema
148
216
  */
149
217
  async getTableSchema(tableName: TABLE_NAMES): Promise<SchemaLike> {
218
+ try {
219
+ if (!this.lanceClient) {
220
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
221
+ }
222
+ if (!tableName) {
223
+ throw new Error('tableName is required for getTableSchema.');
224
+ }
225
+ } catch (validationError: any) {
226
+ throw new MastraError(
227
+ {
228
+ id: 'STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_INVALID_ARGS',
229
+ domain: ErrorDomain.STORAGE,
230
+ category: ErrorCategory.USER,
231
+ text: validationError.message,
232
+ details: { tableName },
233
+ },
234
+ validationError,
235
+ );
236
+ }
237
+
150
238
  try {
151
239
  const table = await this.lanceClient.openTable(tableName);
152
240
  const rawSchema = await table.schema();
@@ -161,7 +249,15 @@ export class LanceStorage extends MastraStorage {
161
249
  },
162
250
  };
163
251
  } catch (error: any) {
164
- throw new Error(`Failed to get table schema: ${error}`);
252
+ throw new MastraError(
253
+ {
254
+ id: 'STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_FAILED',
255
+ domain: ErrorDomain.STORAGE,
256
+ category: ErrorCategory.THIRD_PARTY,
257
+ details: { tableName },
258
+ },
259
+ error,
260
+ );
165
261
  }
166
262
  }
167
263
 
@@ -198,43 +294,114 @@ export class LanceStorage extends MastraStorage {
198
294
  schema: Record<string, StorageColumn>;
199
295
  ifNotExists: string[];
200
296
  }): Promise<void> {
201
- const table = await this.lanceClient.openTable(tableName);
202
- const currentSchema = await table.schema();
203
- const existingFields = new Set(currentSchema.fields.map((f: any) => f.name));
204
-
205
- const typeMap: Record<string, string> = {
206
- text: 'string',
207
- integer: 'int',
208
- bigint: 'bigint',
209
- timestamp: 'timestamp',
210
- jsonb: 'string',
211
- uuid: 'string',
212
- };
297
+ try {
298
+ if (!this.lanceClient) {
299
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
300
+ }
301
+ if (!tableName) {
302
+ throw new Error('tableName is required for alterTable.');
303
+ }
304
+ if (!schema) {
305
+ throw new Error('schema is required for alterTable.');
306
+ }
307
+ if (!ifNotExists || ifNotExists.length === 0) {
308
+ this.logger.debug('No columns specified to add in alterTable, skipping.');
309
+ return;
310
+ }
311
+ } catch (validationError: any) {
312
+ throw new MastraError(
313
+ {
314
+ id: 'STORAGE_LANCE_STORAGE_ALTER_TABLE_INVALID_ARGS',
315
+ domain: ErrorDomain.STORAGE,
316
+ category: ErrorCategory.USER,
317
+ text: validationError.message,
318
+ details: { tableName },
319
+ },
320
+ validationError,
321
+ );
322
+ }
213
323
 
214
- // Find columns to add
215
- const columnsToAdd = ifNotExists
216
- .filter(col => schema[col] && !existingFields.has(col))
217
- .map(col => {
218
- const colDef = schema[col];
219
- return {
220
- name: col,
221
- valueSql: colDef?.nullable
222
- ? `cast(NULL as ${typeMap[colDef.type ?? 'text']})`
223
- : `cast(${this.getDefaultValue(colDef?.type ?? 'text')} as ${typeMap[colDef?.type ?? 'text']})`,
224
- };
225
- });
324
+ try {
325
+ const table = await this.lanceClient.openTable(tableName);
326
+ const currentSchema = await table.schema();
327
+ const existingFields = new Set(currentSchema.fields.map((f: any) => f.name));
328
+
329
+ const typeMap: Record<string, string> = {
330
+ text: 'string',
331
+ integer: 'int',
332
+ bigint: 'bigint',
333
+ timestamp: 'timestamp',
334
+ jsonb: 'string',
335
+ uuid: 'string',
336
+ };
226
337
 
227
- if (columnsToAdd.length > 0) {
228
- await table.addColumns(columnsToAdd);
229
- this.logger?.info?.(`Added columns [${columnsToAdd.map(c => c.name).join(', ')}] to table ${tableName}`);
338
+ // Find columns to add
339
+ const columnsToAdd = ifNotExists
340
+ .filter(col => schema[col] && !existingFields.has(col))
341
+ .map(col => {
342
+ const colDef = schema[col];
343
+ return {
344
+ name: col,
345
+ valueSql: colDef?.nullable
346
+ ? `cast(NULL as ${typeMap[colDef.type ?? 'text']})`
347
+ : `cast(${this.getDefaultValue(colDef?.type ?? 'text')} as ${typeMap[colDef?.type ?? 'text']})`,
348
+ };
349
+ });
350
+
351
+ if (columnsToAdd.length > 0) {
352
+ await table.addColumns(columnsToAdd);
353
+ this.logger?.info?.(`Added columns [${columnsToAdd.map(c => c.name).join(', ')}] to table ${tableName}`);
354
+ }
355
+ } catch (error: any) {
356
+ throw new MastraError(
357
+ {
358
+ id: 'STORAGE_LANCE_STORAGE_ALTER_TABLE_FAILED',
359
+ domain: ErrorDomain.STORAGE,
360
+ category: ErrorCategory.THIRD_PARTY,
361
+ details: { tableName },
362
+ },
363
+ error,
364
+ );
230
365
  }
231
366
  }
232
367
 
233
368
  async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
234
- const table = await this.lanceClient.openTable(tableName);
369
+ try {
370
+ if (!this.lanceClient) {
371
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
372
+ }
373
+ if (!tableName) {
374
+ throw new Error('tableName is required for clearTable.');
375
+ }
376
+ } catch (validationError: any) {
377
+ throw new MastraError(
378
+ {
379
+ id: 'STORAGE_LANCE_STORAGE_CLEAR_TABLE_INVALID_ARGS',
380
+ domain: ErrorDomain.STORAGE,
381
+ category: ErrorCategory.USER,
382
+ text: validationError.message,
383
+ details: { tableName },
384
+ },
385
+ validationError,
386
+ );
387
+ }
388
+
389
+ try {
390
+ const table = await this.lanceClient.openTable(tableName);
235
391
 
236
- // delete function always takes a predicate as an argument, so we use '1=1' to delete all records because it is always true.
237
- await table.delete('1=1');
392
+ // delete function always takes a predicate as an argument, so we use '1=1' to delete all records because it is always true.
393
+ await table.delete('1=1');
394
+ } catch (error: any) {
395
+ throw new MastraError(
396
+ {
397
+ id: 'STORAGE_LANCE_STORAGE_CLEAR_TABLE_FAILED',
398
+ domain: ErrorDomain.STORAGE,
399
+ category: ErrorCategory.THIRD_PARTY,
400
+ details: { tableName },
401
+ },
402
+ error,
403
+ );
404
+ }
238
405
  }
239
406
 
240
407
  /**
@@ -243,6 +410,29 @@ export class LanceStorage extends MastraStorage {
243
410
  * @param record The record to insert.
244
411
  */
245
412
  async insert({ tableName, record }: { tableName: string; record: Record<string, any> }): Promise<void> {
413
+ try {
414
+ if (!this.lanceClient) {
415
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
416
+ }
417
+ if (!tableName) {
418
+ throw new Error('tableName is required for insert.');
419
+ }
420
+ if (!record || Object.keys(record).length === 0) {
421
+ throw new Error('record is required and cannot be empty for insert.');
422
+ }
423
+ } catch (validationError: any) {
424
+ throw new MastraError(
425
+ {
426
+ id: 'STORAGE_LANCE_STORAGE_INSERT_INVALID_ARGS',
427
+ domain: ErrorDomain.STORAGE,
428
+ category: ErrorCategory.USER,
429
+ text: validationError.message,
430
+ details: { tableName },
431
+ },
432
+ validationError,
433
+ );
434
+ }
435
+
246
436
  try {
247
437
  const table = await this.lanceClient.openTable(tableName);
248
438
 
@@ -261,7 +451,15 @@ export class LanceStorage extends MastraStorage {
261
451
 
262
452
  await table.add([processedRecord], { mode: 'overwrite' });
263
453
  } catch (error: any) {
264
- throw new Error(`Failed to insert record: ${error}`);
454
+ throw new MastraError(
455
+ {
456
+ id: 'STORAGE_LANCE_STORAGE_INSERT_FAILED',
457
+ domain: ErrorDomain.STORAGE,
458
+ category: ErrorCategory.THIRD_PARTY,
459
+ details: { tableName },
460
+ },
461
+ error,
462
+ );
265
463
  }
266
464
  }
267
465
 
@@ -271,6 +469,29 @@ export class LanceStorage extends MastraStorage {
271
469
  * @param records The records to insert.
272
470
  */
273
471
  async batchInsert({ tableName, records }: { tableName: string; records: Record<string, any>[] }): Promise<void> {
472
+ try {
473
+ if (!this.lanceClient) {
474
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
475
+ }
476
+ if (!tableName) {
477
+ throw new Error('tableName is required for batchInsert.');
478
+ }
479
+ if (!records || records.length === 0) {
480
+ throw new Error('records array is required and cannot be empty for batchInsert.');
481
+ }
482
+ } catch (validationError: any) {
483
+ throw new MastraError(
484
+ {
485
+ id: 'STORAGE_LANCE_STORAGE_BATCH_INSERT_INVALID_ARGS',
486
+ domain: ErrorDomain.STORAGE,
487
+ category: ErrorCategory.USER,
488
+ text: validationError.message,
489
+ details: { tableName },
490
+ },
491
+ validationError,
492
+ );
493
+ }
494
+
274
495
  try {
275
496
  const table = await this.lanceClient.openTable(tableName);
276
497
 
@@ -296,7 +517,15 @@ export class LanceStorage extends MastraStorage {
296
517
 
297
518
  await table.add(processedRecords, { mode: 'overwrite' });
298
519
  } catch (error: any) {
299
- throw new Error(`Failed to batch insert records: ${error}`);
520
+ throw new MastraError(
521
+ {
522
+ id: 'STORAGE_LANCE_STORAGE_BATCH_INSERT_FAILED',
523
+ domain: ErrorDomain.STORAGE,
524
+ category: ErrorCategory.THIRD_PARTY,
525
+ details: { tableName },
526
+ },
527
+ error,
528
+ );
300
529
  }
301
530
  }
302
531
 
@@ -308,6 +537,29 @@ export class LanceStorage extends MastraStorage {
308
537
  * @returns The loaded record with proper type conversions, or null if not found
309
538
  */
310
539
  async load({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, any> }): Promise<any> {
540
+ try {
541
+ if (!this.lanceClient) {
542
+ throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
543
+ }
544
+ if (!tableName) {
545
+ throw new Error('tableName is required for load.');
546
+ }
547
+ if (!keys || Object.keys(keys).length === 0) {
548
+ throw new Error('keys are required and cannot be empty for load.');
549
+ }
550
+ } catch (validationError: any) {
551
+ throw new MastraError(
552
+ {
553
+ id: 'STORAGE_LANCE_STORAGE_LOAD_INVALID_ARGS',
554
+ domain: ErrorDomain.STORAGE,
555
+ category: ErrorCategory.USER,
556
+ text: validationError.message,
557
+ details: { tableName },
558
+ },
559
+ validationError,
560
+ );
561
+ }
562
+
311
563
  try {
312
564
  const table = await this.lanceClient.openTable(tableName);
313
565
  const tableSchema = await this.getTableSchema(tableName);
@@ -350,7 +602,17 @@ export class LanceStorage extends MastraStorage {
350
602
  // Process the result with type conversions
351
603
  return this.processResultWithTypeConversion(result[0], tableSchema);
352
604
  } catch (error: any) {
353
- throw new Error(`Failed to load record: ${error}`);
605
+ // If it's already a MastraError (e.g. from validateKeyTypes if we change it later), rethrow
606
+ if (error instanceof MastraError) throw error;
607
+ throw new MastraError(
608
+ {
609
+ id: 'STORAGE_LANCE_STORAGE_LOAD_FAILED',
610
+ domain: ErrorDomain.STORAGE,
611
+ category: ErrorCategory.THIRD_PARTY,
612
+ details: { tableName, keyCount: Object.keys(keys).length, firstKey: Object.keys(keys)[0] ?? '' },
613
+ },
614
+ error,
615
+ );
354
616
  }
355
617
  }
356
618
 
@@ -456,7 +718,14 @@ export class LanceStorage extends MastraStorage {
456
718
  try {
457
719
  return this.load({ tableName: TABLE_THREADS, keys: { id: threadId } });
458
720
  } catch (error: any) {
459
- throw new Error(`Failed to get thread by ID: ${error}`);
721
+ throw new MastraError(
722
+ {
723
+ id: 'LANCE_STORE_GET_THREAD_BY_ID_FAILED',
724
+ domain: ErrorDomain.STORAGE,
725
+ category: ErrorCategory.THIRD_PARTY,
726
+ },
727
+ error,
728
+ );
460
729
  }
461
730
  }
462
731
 
@@ -472,7 +741,14 @@ export class LanceStorage extends MastraStorage {
472
741
  await this.getTableSchema(TABLE_THREADS),
473
742
  ) as StorageThreadType[];
474
743
  } catch (error: any) {
475
- throw new Error(`Failed to get threads by resource ID: ${error}`);
744
+ throw new MastraError(
745
+ {
746
+ id: 'LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
747
+ domain: ErrorDomain.STORAGE,
748
+ category: ErrorCategory.THIRD_PARTY,
749
+ },
750
+ error,
751
+ );
476
752
  }
477
753
  }
478
754
 
@@ -489,7 +765,14 @@ export class LanceStorage extends MastraStorage {
489
765
 
490
766
  return thread;
491
767
  } catch (error: any) {
492
- throw new Error(`Failed to save thread: ${error}`);
768
+ throw new MastraError(
769
+ {
770
+ id: 'LANCE_STORE_SAVE_THREAD_FAILED',
771
+ domain: ErrorDomain.STORAGE,
772
+ category: ErrorCategory.THIRD_PARTY,
773
+ },
774
+ error,
775
+ );
493
776
  }
494
777
  }
495
778
 
@@ -515,7 +798,14 @@ export class LanceStorage extends MastraStorage {
515
798
  await this.getTableSchema(TABLE_THREADS),
516
799
  ) as StorageThreadType;
517
800
  } catch (error: any) {
518
- throw new Error(`Failed to update thread: ${error}`);
801
+ throw new MastraError(
802
+ {
803
+ id: 'LANCE_STORE_UPDATE_THREAD_FAILED',
804
+ domain: ErrorDomain.STORAGE,
805
+ category: ErrorCategory.THIRD_PARTY,
806
+ },
807
+ error,
808
+ );
519
809
  }
520
810
  }
521
811
 
@@ -524,7 +814,14 @@ export class LanceStorage extends MastraStorage {
524
814
  const table = await this.lanceClient.openTable(TABLE_THREADS);
525
815
  await table.delete(`id = '${threadId}'`);
526
816
  } catch (error: any) {
527
- throw new Error(`Failed to delete thread: ${error}`);
817
+ throw new MastraError(
818
+ {
819
+ id: 'LANCE_STORE_DELETE_THREAD_FAILED',
820
+ domain: ErrorDomain.STORAGE,
821
+ category: ErrorCategory.THIRD_PARTY,
822
+ },
823
+ error,
824
+ );
528
825
  }
529
826
  }
530
827
 
@@ -617,7 +914,7 @@ export class LanceStorage extends MastraStorage {
617
914
  if (threadConfig) {
618
915
  throw new Error('ThreadConfig is not supported by LanceDB storage');
619
916
  }
620
-
917
+ const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
621
918
  const table = await this.lanceClient.openTable(TABLE_MESSAGES);
622
919
  let query = table.query().where(`\`threadId\` = '${threadId}'`);
623
920
 
@@ -652,8 +949,8 @@ export class LanceStorage extends MastraStorage {
652
949
  }
653
950
 
654
951
  // If we're fetching the last N messages, take only the last N after sorting
655
- if (selectBy?.last !== undefined && selectBy.last !== false) {
656
- records = records.slice(-selectBy.last);
952
+ if (limit !== Number.MAX_SAFE_INTEGER) {
953
+ records = records.slice(-limit);
657
954
  }
658
955
 
659
956
  const messages = this.processResultWithTypeConversion(records, await this.getTableSchema(TABLE_MESSAGES));
@@ -674,7 +971,14 @@ export class LanceStorage extends MastraStorage {
674
971
  if (format === 'v2') return list.get.all.v2();
675
972
  return list.get.all.v1();
676
973
  } catch (error: any) {
677
- throw new Error(`Failed to get messages: ${error}`);
974
+ throw new MastraError(
975
+ {
976
+ id: 'LANCE_STORE_GET_MESSAGES_FAILED',
977
+ domain: ErrorDomain.STORAGE,
978
+ category: ErrorCategory.THIRD_PARTY,
979
+ },
980
+ error,
981
+ );
678
982
  }
679
983
  }
680
984
 
@@ -706,7 +1010,14 @@ export class LanceStorage extends MastraStorage {
706
1010
  if (format === `v2`) return list.get.all.v2();
707
1011
  return list.get.all.v1();
708
1012
  } catch (error: any) {
709
- throw new Error(`Failed to save messages: ${error}`);
1013
+ throw new MastraError(
1014
+ {
1015
+ id: 'LANCE_STORE_SAVE_MESSAGES_FAILED',
1016
+ domain: ErrorDomain.STORAGE,
1017
+ category: ErrorCategory.THIRD_PARTY,
1018
+ },
1019
+ error,
1020
+ );
710
1021
  }
711
1022
  }
712
1023
 
@@ -725,7 +1036,14 @@ export class LanceStorage extends MastraStorage {
725
1036
 
726
1037
  return trace;
727
1038
  } catch (error: any) {
728
- throw new Error(`Failed to save trace: ${error}`);
1039
+ throw new MastraError(
1040
+ {
1041
+ id: 'LANCE_STORE_SAVE_TRACE_FAILED',
1042
+ domain: ErrorDomain.STORAGE,
1043
+ category: ErrorCategory.THIRD_PARTY,
1044
+ },
1045
+ error,
1046
+ );
729
1047
  }
730
1048
  }
731
1049
 
@@ -736,7 +1054,14 @@ export class LanceStorage extends MastraStorage {
736
1054
  const records = await query.toArray();
737
1055
  return this.processResultWithTypeConversion(records[0], await this.getTableSchema(TABLE_TRACES)) as TraceType;
738
1056
  } catch (error: any) {
739
- throw new Error(`Failed to get trace by ID: ${error}`);
1057
+ throw new MastraError(
1058
+ {
1059
+ id: 'LANCE_STORE_GET_TRACE_BY_ID_FAILED',
1060
+ domain: ErrorDomain.STORAGE,
1061
+ category: ErrorCategory.THIRD_PARTY,
1062
+ },
1063
+ error,
1064
+ );
740
1065
  }
741
1066
  }
742
1067
 
@@ -795,7 +1120,15 @@ export class LanceStorage extends MastraStorage {
795
1120
  };
796
1121
  }) as TraceType[];
797
1122
  } catch (error: any) {
798
- throw new Error(`Failed to get traces: ${error}`);
1123
+ throw new MastraError(
1124
+ {
1125
+ id: 'LANCE_STORE_GET_TRACES_FAILED',
1126
+ domain: ErrorDomain.STORAGE,
1127
+ category: ErrorCategory.THIRD_PARTY,
1128
+ details: { name: name ?? '', scope: scope ?? '' },
1129
+ },
1130
+ error,
1131
+ );
799
1132
  }
800
1133
  }
801
1134
 
@@ -818,7 +1151,14 @@ export class LanceStorage extends MastraStorage {
818
1151
  await table.add(transformedEvals, { mode: 'append' });
819
1152
  return evals;
820
1153
  } catch (error: any) {
821
- throw new Error(`Failed to save evals: ${error}`);
1154
+ throw new MastraError(
1155
+ {
1156
+ id: 'LANCE_STORE_SAVE_EVALS_FAILED',
1157
+ domain: ErrorDomain.STORAGE,
1158
+ category: ErrorCategory.THIRD_PARTY,
1159
+ },
1160
+ error,
1161
+ );
822
1162
  }
823
1163
  }
824
1164
 
@@ -846,7 +1186,15 @@ export class LanceStorage extends MastraStorage {
846
1186
  };
847
1187
  }) as EvalRow[];
848
1188
  } catch (error: any) {
849
- throw new Error(`Failed to get evals by agent name: ${error}`);
1189
+ throw new MastraError(
1190
+ {
1191
+ id: 'LANCE_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',
1192
+ domain: ErrorDomain.STORAGE,
1193
+ category: ErrorCategory.THIRD_PARTY,
1194
+ details: { agentName },
1195
+ },
1196
+ error,
1197
+ );
850
1198
  }
851
1199
  }
852
1200
 
@@ -909,7 +1257,15 @@ export class LanceStorage extends MastraStorage {
909
1257
  total: records.length,
910
1258
  };
911
1259
  } catch (error: any) {
912
- throw new Error(`Failed to get workflow runs: ${error}`);
1260
+ throw new MastraError(
1261
+ {
1262
+ id: 'LANCE_STORE_GET_WORKFLOW_RUNS_FAILED',
1263
+ domain: ErrorDomain.STORAGE,
1264
+ category: ErrorCategory.THIRD_PARTY,
1265
+ details: { namespace: args?.namespace ?? '', workflowName: args?.workflowName ?? '' },
1266
+ },
1267
+ error,
1268
+ );
913
1269
  }
914
1270
  }
915
1271
 
@@ -937,7 +1293,15 @@ export class LanceStorage extends MastraStorage {
937
1293
  const record = records[0];
938
1294
  return this.parseWorkflowRun(record);
939
1295
  } catch (error: any) {
940
- throw new Error(`Failed to get workflow run by id: ${error}`);
1296
+ throw new MastraError(
1297
+ {
1298
+ id: 'LANCE_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED',
1299
+ domain: ErrorDomain.STORAGE,
1300
+ category: ErrorCategory.THIRD_PARTY,
1301
+ details: { runId: args.runId, workflowName: args.workflowName ?? '' },
1302
+ },
1303
+ error,
1304
+ );
941
1305
  }
942
1306
  }
943
1307
 
@@ -977,7 +1341,15 @@ export class LanceStorage extends MastraStorage {
977
1341
 
978
1342
  await table.add([record], { mode });
979
1343
  } catch (error: any) {
980
- throw new Error(`Failed to persist workflow snapshot: ${error}`);
1344
+ throw new MastraError(
1345
+ {
1346
+ id: 'LANCE_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED',
1347
+ domain: ErrorDomain.STORAGE,
1348
+ category: ErrorCategory.THIRD_PARTY,
1349
+ details: { workflowName, runId },
1350
+ },
1351
+ error,
1352
+ );
981
1353
  }
982
1354
  }
983
1355
  async loadWorkflowSnapshot({
@@ -993,12 +1365,27 @@ export class LanceStorage extends MastraStorage {
993
1365
  const records = await query.toArray();
994
1366
  return records.length > 0 ? JSON.parse(records[0].snapshot) : null;
995
1367
  } catch (error: any) {
996
- throw new Error(`Failed to load workflow snapshot: ${error}`);
1368
+ throw new MastraError(
1369
+ {
1370
+ id: 'LANCE_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED',
1371
+ domain: ErrorDomain.STORAGE,
1372
+ category: ErrorCategory.THIRD_PARTY,
1373
+ details: { workflowName, runId },
1374
+ },
1375
+ error,
1376
+ );
997
1377
  }
998
1378
  }
999
1379
 
1000
1380
  async getTracesPaginated(_args: StorageGetTracesArg): Promise<PaginationInfo & { traces: Trace[] }> {
1001
- throw new Error('Method not implemented.');
1381
+ throw new MastraError(
1382
+ {
1383
+ id: 'LANCE_STORE_GET_TRACES_PAGINATED_FAILED',
1384
+ domain: ErrorDomain.STORAGE,
1385
+ category: ErrorCategory.THIRD_PARTY,
1386
+ },
1387
+ 'Method not implemented.',
1388
+ );
1002
1389
  }
1003
1390
 
1004
1391
  async getThreadsByResourceIdPaginated(_args: {
@@ -1006,12 +1393,37 @@ export class LanceStorage extends MastraStorage {
1006
1393
  page?: number;
1007
1394
  perPage?: number;
1008
1395
  }): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
1009
- throw new Error('Method not implemented.');
1396
+ throw new MastraError(
1397
+ {
1398
+ id: 'LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED',
1399
+ domain: ErrorDomain.STORAGE,
1400
+ category: ErrorCategory.THIRD_PARTY,
1401
+ },
1402
+ 'Method not implemented.',
1403
+ );
1010
1404
  }
1011
1405
 
1012
1406
  async getMessagesPaginated(
1013
1407
  _args: StorageGetMessagesArg,
1014
1408
  ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
1015
- throw new Error('Method not implemented.');
1409
+ throw new MastraError(
1410
+ {
1411
+ id: 'LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED',
1412
+ domain: ErrorDomain.STORAGE,
1413
+ category: ErrorCategory.THIRD_PARTY,
1414
+ },
1415
+ 'Method not implemented.',
1416
+ );
1417
+ }
1418
+
1419
+ async updateMessages(_args: {
1420
+ messages: Partial<Omit<MastraMessageV2, 'createdAt'>> &
1421
+ {
1422
+ id: string;
1423
+ content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
1424
+ }[];
1425
+ }): Promise<MastraMessageV2[]> {
1426
+ this.logger.error('updateMessages is not yet implemented in LanceStore');
1427
+ throw new Error('Method not implemented');
1016
1428
  }
1017
1429
  }