@mastra/lance 0.0.0-fix-generate-title-20250616171351 → 0.0.0-fix-fetching-workflow-snapshots-20250625000954
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +90 -3
- package/dist/_tsup-dts-rollup.d.cts +28 -4
- package/dist/_tsup-dts-rollup.d.ts +28 -4
- package/dist/index.cjs +806 -160
- package/dist/index.js +773 -127
- package/package.json +6 -6
- package/src/storage/index.test.ts +72 -2
- package/src/storage/index.ts +498 -68
- package/src/vector/filter.test.ts +3 -3
- package/src/vector/filter.ts +24 -4
- package/src/vector/index.test.ts +3 -3
- package/src/vector/index.ts +320 -79
package/src/storage/index.ts
CHANGED
|
@@ -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,10 +58,30 @@ 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
|
|
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
|
|
|
74
|
+
private getPrimaryKeys(tableName: TABLE_NAMES): string[] {
|
|
75
|
+
let primaryId: string[] = ['id'];
|
|
76
|
+
if (tableName === TABLE_WORKFLOW_SNAPSHOT) {
|
|
77
|
+
primaryId = ['workflow_name', 'run_id'];
|
|
78
|
+
} else if (tableName === TABLE_EVALS) {
|
|
79
|
+
primaryId = ['agent_name', 'metric_name', 'run_id'];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return primaryId;
|
|
83
|
+
}
|
|
84
|
+
|
|
63
85
|
/**
|
|
64
86
|
* @internal
|
|
65
87
|
* Private constructor to enforce using the create factory method
|
|
@@ -75,11 +97,41 @@ export class LanceStorage extends MastraStorage {
|
|
|
75
97
|
tableName: TABLE_NAMES;
|
|
76
98
|
schema: Record<string, StorageColumn>;
|
|
77
99
|
}): Promise<void> {
|
|
100
|
+
try {
|
|
101
|
+
if (!this.lanceClient) {
|
|
102
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
103
|
+
}
|
|
104
|
+
if (!tableName) {
|
|
105
|
+
throw new Error('tableName is required for createTable.');
|
|
106
|
+
}
|
|
107
|
+
if (!schema) {
|
|
108
|
+
throw new Error('schema is required for createTable.');
|
|
109
|
+
}
|
|
110
|
+
} catch (error) {
|
|
111
|
+
throw new MastraError(
|
|
112
|
+
{
|
|
113
|
+
id: 'STORAGE_LANCE_STORAGE_CREATE_TABLE_INVALID_ARGS',
|
|
114
|
+
domain: ErrorDomain.STORAGE,
|
|
115
|
+
category: ErrorCategory.USER,
|
|
116
|
+
details: { tableName },
|
|
117
|
+
},
|
|
118
|
+
error,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
78
122
|
try {
|
|
79
123
|
const arrowSchema = this.translateSchema(schema);
|
|
80
124
|
await this.lanceClient.createEmptyTable(tableName, arrowSchema);
|
|
81
125
|
} catch (error: any) {
|
|
82
|
-
throw new
|
|
126
|
+
throw new MastraError(
|
|
127
|
+
{
|
|
128
|
+
id: 'STORAGE_LANCE_STORAGE_CREATE_TABLE_FAILED',
|
|
129
|
+
domain: ErrorDomain.STORAGE,
|
|
130
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
131
|
+
details: { tableName },
|
|
132
|
+
},
|
|
133
|
+
error,
|
|
134
|
+
);
|
|
83
135
|
}
|
|
84
136
|
}
|
|
85
137
|
|
|
@@ -129,15 +181,42 @@ export class LanceStorage extends MastraStorage {
|
|
|
129
181
|
* @param tableName Name of the table to drop
|
|
130
182
|
*/
|
|
131
183
|
async dropTable(tableName: TABLE_NAMES): Promise<void> {
|
|
184
|
+
try {
|
|
185
|
+
if (!this.lanceClient) {
|
|
186
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
187
|
+
}
|
|
188
|
+
if (!tableName) {
|
|
189
|
+
throw new Error('tableName is required for dropTable.');
|
|
190
|
+
}
|
|
191
|
+
} catch (validationError: any) {
|
|
192
|
+
throw new MastraError(
|
|
193
|
+
{
|
|
194
|
+
id: 'STORAGE_LANCE_STORAGE_DROP_TABLE_INVALID_ARGS',
|
|
195
|
+
domain: ErrorDomain.STORAGE,
|
|
196
|
+
category: ErrorCategory.USER,
|
|
197
|
+
text: validationError.message,
|
|
198
|
+
details: { tableName },
|
|
199
|
+
},
|
|
200
|
+
validationError,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
132
204
|
try {
|
|
133
205
|
await this.lanceClient.dropTable(tableName);
|
|
134
206
|
} catch (error: any) {
|
|
135
|
-
|
|
136
|
-
if (error.toString().includes('was not found')) {
|
|
207
|
+
if (error.toString().includes('was not found') || error.message?.includes('Table not found')) {
|
|
137
208
|
this.logger.debug(`Table '${tableName}' does not exist, skipping drop`);
|
|
138
209
|
return;
|
|
139
210
|
}
|
|
140
|
-
throw new
|
|
211
|
+
throw new MastraError(
|
|
212
|
+
{
|
|
213
|
+
id: 'STORAGE_LANCE_STORAGE_DROP_TABLE_FAILED',
|
|
214
|
+
domain: ErrorDomain.STORAGE,
|
|
215
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
216
|
+
details: { tableName },
|
|
217
|
+
},
|
|
218
|
+
error,
|
|
219
|
+
);
|
|
141
220
|
}
|
|
142
221
|
}
|
|
143
222
|
|
|
@@ -147,6 +226,26 @@ export class LanceStorage extends MastraStorage {
|
|
|
147
226
|
* @returns Table schema
|
|
148
227
|
*/
|
|
149
228
|
async getTableSchema(tableName: TABLE_NAMES): Promise<SchemaLike> {
|
|
229
|
+
try {
|
|
230
|
+
if (!this.lanceClient) {
|
|
231
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
232
|
+
}
|
|
233
|
+
if (!tableName) {
|
|
234
|
+
throw new Error('tableName is required for getTableSchema.');
|
|
235
|
+
}
|
|
236
|
+
} catch (validationError: any) {
|
|
237
|
+
throw new MastraError(
|
|
238
|
+
{
|
|
239
|
+
id: 'STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_INVALID_ARGS',
|
|
240
|
+
domain: ErrorDomain.STORAGE,
|
|
241
|
+
category: ErrorCategory.USER,
|
|
242
|
+
text: validationError.message,
|
|
243
|
+
details: { tableName },
|
|
244
|
+
},
|
|
245
|
+
validationError,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
150
249
|
try {
|
|
151
250
|
const table = await this.lanceClient.openTable(tableName);
|
|
152
251
|
const rawSchema = await table.schema();
|
|
@@ -161,7 +260,15 @@ export class LanceStorage extends MastraStorage {
|
|
|
161
260
|
},
|
|
162
261
|
};
|
|
163
262
|
} catch (error: any) {
|
|
164
|
-
throw new
|
|
263
|
+
throw new MastraError(
|
|
264
|
+
{
|
|
265
|
+
id: 'STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_FAILED',
|
|
266
|
+
domain: ErrorDomain.STORAGE,
|
|
267
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
268
|
+
details: { tableName },
|
|
269
|
+
},
|
|
270
|
+
error,
|
|
271
|
+
);
|
|
165
272
|
}
|
|
166
273
|
}
|
|
167
274
|
|
|
@@ -198,43 +305,114 @@ export class LanceStorage extends MastraStorage {
|
|
|
198
305
|
schema: Record<string, StorageColumn>;
|
|
199
306
|
ifNotExists: string[];
|
|
200
307
|
}): Promise<void> {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
308
|
+
try {
|
|
309
|
+
if (!this.lanceClient) {
|
|
310
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
311
|
+
}
|
|
312
|
+
if (!tableName) {
|
|
313
|
+
throw new Error('tableName is required for alterTable.');
|
|
314
|
+
}
|
|
315
|
+
if (!schema) {
|
|
316
|
+
throw new Error('schema is required for alterTable.');
|
|
317
|
+
}
|
|
318
|
+
if (!ifNotExists || ifNotExists.length === 0) {
|
|
319
|
+
this.logger.debug('No columns specified to add in alterTable, skipping.');
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
} catch (validationError: any) {
|
|
323
|
+
throw new MastraError(
|
|
324
|
+
{
|
|
325
|
+
id: 'STORAGE_LANCE_STORAGE_ALTER_TABLE_INVALID_ARGS',
|
|
326
|
+
domain: ErrorDomain.STORAGE,
|
|
327
|
+
category: ErrorCategory.USER,
|
|
328
|
+
text: validationError.message,
|
|
329
|
+
details: { tableName },
|
|
330
|
+
},
|
|
331
|
+
validationError,
|
|
332
|
+
);
|
|
333
|
+
}
|
|
213
334
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
.map(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
335
|
+
try {
|
|
336
|
+
const table = await this.lanceClient.openTable(tableName);
|
|
337
|
+
const currentSchema = await table.schema();
|
|
338
|
+
const existingFields = new Set(currentSchema.fields.map((f: any) => f.name));
|
|
339
|
+
|
|
340
|
+
const typeMap: Record<string, string> = {
|
|
341
|
+
text: 'string',
|
|
342
|
+
integer: 'int',
|
|
343
|
+
bigint: 'bigint',
|
|
344
|
+
timestamp: 'timestamp',
|
|
345
|
+
jsonb: 'string',
|
|
346
|
+
uuid: 'string',
|
|
347
|
+
};
|
|
226
348
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
349
|
+
// Find columns to add
|
|
350
|
+
const columnsToAdd = ifNotExists
|
|
351
|
+
.filter(col => schema[col] && !existingFields.has(col))
|
|
352
|
+
.map(col => {
|
|
353
|
+
const colDef = schema[col];
|
|
354
|
+
return {
|
|
355
|
+
name: col,
|
|
356
|
+
valueSql: colDef?.nullable
|
|
357
|
+
? `cast(NULL as ${typeMap[colDef.type ?? 'text']})`
|
|
358
|
+
: `cast(${this.getDefaultValue(colDef?.type ?? 'text')} as ${typeMap[colDef?.type ?? 'text']})`,
|
|
359
|
+
};
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
if (columnsToAdd.length > 0) {
|
|
363
|
+
await table.addColumns(columnsToAdd);
|
|
364
|
+
this.logger?.info?.(`Added columns [${columnsToAdd.map(c => c.name).join(', ')}] to table ${tableName}`);
|
|
365
|
+
}
|
|
366
|
+
} catch (error: any) {
|
|
367
|
+
throw new MastraError(
|
|
368
|
+
{
|
|
369
|
+
id: 'STORAGE_LANCE_STORAGE_ALTER_TABLE_FAILED',
|
|
370
|
+
domain: ErrorDomain.STORAGE,
|
|
371
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
372
|
+
details: { tableName },
|
|
373
|
+
},
|
|
374
|
+
error,
|
|
375
|
+
);
|
|
230
376
|
}
|
|
231
377
|
}
|
|
232
378
|
|
|
233
379
|
async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
|
|
234
|
-
|
|
380
|
+
try {
|
|
381
|
+
if (!this.lanceClient) {
|
|
382
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
383
|
+
}
|
|
384
|
+
if (!tableName) {
|
|
385
|
+
throw new Error('tableName is required for clearTable.');
|
|
386
|
+
}
|
|
387
|
+
} catch (validationError: any) {
|
|
388
|
+
throw new MastraError(
|
|
389
|
+
{
|
|
390
|
+
id: 'STORAGE_LANCE_STORAGE_CLEAR_TABLE_INVALID_ARGS',
|
|
391
|
+
domain: ErrorDomain.STORAGE,
|
|
392
|
+
category: ErrorCategory.USER,
|
|
393
|
+
text: validationError.message,
|
|
394
|
+
details: { tableName },
|
|
395
|
+
},
|
|
396
|
+
validationError,
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
try {
|
|
401
|
+
const table = await this.lanceClient.openTable(tableName);
|
|
235
402
|
|
|
236
|
-
|
|
237
|
-
|
|
403
|
+
// delete function always takes a predicate as an argument, so we use '1=1' to delete all records because it is always true.
|
|
404
|
+
await table.delete('1=1');
|
|
405
|
+
} catch (error: any) {
|
|
406
|
+
throw new MastraError(
|
|
407
|
+
{
|
|
408
|
+
id: 'STORAGE_LANCE_STORAGE_CLEAR_TABLE_FAILED',
|
|
409
|
+
domain: ErrorDomain.STORAGE,
|
|
410
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
411
|
+
details: { tableName },
|
|
412
|
+
},
|
|
413
|
+
error,
|
|
414
|
+
);
|
|
415
|
+
}
|
|
238
416
|
}
|
|
239
417
|
|
|
240
418
|
/**
|
|
@@ -243,9 +421,34 @@ export class LanceStorage extends MastraStorage {
|
|
|
243
421
|
* @param record The record to insert.
|
|
244
422
|
*/
|
|
245
423
|
async insert({ tableName, record }: { tableName: string; record: Record<string, any> }): Promise<void> {
|
|
424
|
+
try {
|
|
425
|
+
if (!this.lanceClient) {
|
|
426
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
427
|
+
}
|
|
428
|
+
if (!tableName) {
|
|
429
|
+
throw new Error('tableName is required for insert.');
|
|
430
|
+
}
|
|
431
|
+
if (!record || Object.keys(record).length === 0) {
|
|
432
|
+
throw new Error('record is required and cannot be empty for insert.');
|
|
433
|
+
}
|
|
434
|
+
} catch (validationError: any) {
|
|
435
|
+
throw new MastraError(
|
|
436
|
+
{
|
|
437
|
+
id: 'STORAGE_LANCE_STORAGE_INSERT_INVALID_ARGS',
|
|
438
|
+
domain: ErrorDomain.STORAGE,
|
|
439
|
+
category: ErrorCategory.USER,
|
|
440
|
+
text: validationError.message,
|
|
441
|
+
details: { tableName },
|
|
442
|
+
},
|
|
443
|
+
validationError,
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
246
447
|
try {
|
|
247
448
|
const table = await this.lanceClient.openTable(tableName);
|
|
248
449
|
|
|
450
|
+
const primaryId = this.getPrimaryKeys(tableName as TABLE_NAMES);
|
|
451
|
+
|
|
249
452
|
const processedRecord = { ...record };
|
|
250
453
|
|
|
251
454
|
for (const key in processedRecord) {
|
|
@@ -259,9 +462,17 @@ export class LanceStorage extends MastraStorage {
|
|
|
259
462
|
}
|
|
260
463
|
}
|
|
261
464
|
|
|
262
|
-
await table.
|
|
465
|
+
await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([processedRecord]);
|
|
263
466
|
} catch (error: any) {
|
|
264
|
-
throw new
|
|
467
|
+
throw new MastraError(
|
|
468
|
+
{
|
|
469
|
+
id: 'STORAGE_LANCE_STORAGE_INSERT_FAILED',
|
|
470
|
+
domain: ErrorDomain.STORAGE,
|
|
471
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
472
|
+
details: { tableName },
|
|
473
|
+
},
|
|
474
|
+
error,
|
|
475
|
+
);
|
|
265
476
|
}
|
|
266
477
|
}
|
|
267
478
|
|
|
@@ -271,9 +482,34 @@ export class LanceStorage extends MastraStorage {
|
|
|
271
482
|
* @param records The records to insert.
|
|
272
483
|
*/
|
|
273
484
|
async batchInsert({ tableName, records }: { tableName: string; records: Record<string, any>[] }): Promise<void> {
|
|
485
|
+
try {
|
|
486
|
+
if (!this.lanceClient) {
|
|
487
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
488
|
+
}
|
|
489
|
+
if (!tableName) {
|
|
490
|
+
throw new Error('tableName is required for batchInsert.');
|
|
491
|
+
}
|
|
492
|
+
if (!records || records.length === 0) {
|
|
493
|
+
throw new Error('records array is required and cannot be empty for batchInsert.');
|
|
494
|
+
}
|
|
495
|
+
} catch (validationError: any) {
|
|
496
|
+
throw new MastraError(
|
|
497
|
+
{
|
|
498
|
+
id: 'STORAGE_LANCE_STORAGE_BATCH_INSERT_INVALID_ARGS',
|
|
499
|
+
domain: ErrorDomain.STORAGE,
|
|
500
|
+
category: ErrorCategory.USER,
|
|
501
|
+
text: validationError.message,
|
|
502
|
+
details: { tableName },
|
|
503
|
+
},
|
|
504
|
+
validationError,
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
|
|
274
508
|
try {
|
|
275
509
|
const table = await this.lanceClient.openTable(tableName);
|
|
276
510
|
|
|
511
|
+
const primaryId = this.getPrimaryKeys(tableName as TABLE_NAMES);
|
|
512
|
+
|
|
277
513
|
const processedRecords = records.map(record => {
|
|
278
514
|
const processedRecord = { ...record };
|
|
279
515
|
|
|
@@ -294,9 +530,17 @@ export class LanceStorage extends MastraStorage {
|
|
|
294
530
|
return processedRecord;
|
|
295
531
|
});
|
|
296
532
|
|
|
297
|
-
await table.
|
|
533
|
+
await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(processedRecords);
|
|
298
534
|
} catch (error: any) {
|
|
299
|
-
throw new
|
|
535
|
+
throw new MastraError(
|
|
536
|
+
{
|
|
537
|
+
id: 'STORAGE_LANCE_STORAGE_BATCH_INSERT_FAILED',
|
|
538
|
+
domain: ErrorDomain.STORAGE,
|
|
539
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
540
|
+
details: { tableName },
|
|
541
|
+
},
|
|
542
|
+
error,
|
|
543
|
+
);
|
|
300
544
|
}
|
|
301
545
|
}
|
|
302
546
|
|
|
@@ -308,6 +552,29 @@ export class LanceStorage extends MastraStorage {
|
|
|
308
552
|
* @returns The loaded record with proper type conversions, or null if not found
|
|
309
553
|
*/
|
|
310
554
|
async load({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, any> }): Promise<any> {
|
|
555
|
+
try {
|
|
556
|
+
if (!this.lanceClient) {
|
|
557
|
+
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
558
|
+
}
|
|
559
|
+
if (!tableName) {
|
|
560
|
+
throw new Error('tableName is required for load.');
|
|
561
|
+
}
|
|
562
|
+
if (!keys || Object.keys(keys).length === 0) {
|
|
563
|
+
throw new Error('keys are required and cannot be empty for load.');
|
|
564
|
+
}
|
|
565
|
+
} catch (validationError: any) {
|
|
566
|
+
throw new MastraError(
|
|
567
|
+
{
|
|
568
|
+
id: 'STORAGE_LANCE_STORAGE_LOAD_INVALID_ARGS',
|
|
569
|
+
domain: ErrorDomain.STORAGE,
|
|
570
|
+
category: ErrorCategory.USER,
|
|
571
|
+
text: validationError.message,
|
|
572
|
+
details: { tableName },
|
|
573
|
+
},
|
|
574
|
+
validationError,
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
|
|
311
578
|
try {
|
|
312
579
|
const table = await this.lanceClient.openTable(tableName);
|
|
313
580
|
const tableSchema = await this.getTableSchema(tableName);
|
|
@@ -350,7 +617,17 @@ export class LanceStorage extends MastraStorage {
|
|
|
350
617
|
// Process the result with type conversions
|
|
351
618
|
return this.processResultWithTypeConversion(result[0], tableSchema);
|
|
352
619
|
} catch (error: any) {
|
|
353
|
-
|
|
620
|
+
// If it's already a MastraError (e.g. from validateKeyTypes if we change it later), rethrow
|
|
621
|
+
if (error instanceof MastraError) throw error;
|
|
622
|
+
throw new MastraError(
|
|
623
|
+
{
|
|
624
|
+
id: 'STORAGE_LANCE_STORAGE_LOAD_FAILED',
|
|
625
|
+
domain: ErrorDomain.STORAGE,
|
|
626
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
627
|
+
details: { tableName, keyCount: Object.keys(keys).length, firstKey: Object.keys(keys)[0] ?? '' },
|
|
628
|
+
},
|
|
629
|
+
error,
|
|
630
|
+
);
|
|
354
631
|
}
|
|
355
632
|
}
|
|
356
633
|
|
|
@@ -456,7 +733,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
456
733
|
try {
|
|
457
734
|
return this.load({ tableName: TABLE_THREADS, keys: { id: threadId } });
|
|
458
735
|
} catch (error: any) {
|
|
459
|
-
throw new
|
|
736
|
+
throw new MastraError(
|
|
737
|
+
{
|
|
738
|
+
id: 'LANCE_STORE_GET_THREAD_BY_ID_FAILED',
|
|
739
|
+
domain: ErrorDomain.STORAGE,
|
|
740
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
741
|
+
},
|
|
742
|
+
error,
|
|
743
|
+
);
|
|
460
744
|
}
|
|
461
745
|
}
|
|
462
746
|
|
|
@@ -472,7 +756,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
472
756
|
await this.getTableSchema(TABLE_THREADS),
|
|
473
757
|
) as StorageThreadType[];
|
|
474
758
|
} catch (error: any) {
|
|
475
|
-
throw new
|
|
759
|
+
throw new MastraError(
|
|
760
|
+
{
|
|
761
|
+
id: 'LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
|
|
762
|
+
domain: ErrorDomain.STORAGE,
|
|
763
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
764
|
+
},
|
|
765
|
+
error,
|
|
766
|
+
);
|
|
476
767
|
}
|
|
477
768
|
}
|
|
478
769
|
|
|
@@ -489,7 +780,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
489
780
|
|
|
490
781
|
return thread;
|
|
491
782
|
} catch (error: any) {
|
|
492
|
-
throw new
|
|
783
|
+
throw new MastraError(
|
|
784
|
+
{
|
|
785
|
+
id: 'LANCE_STORE_SAVE_THREAD_FAILED',
|
|
786
|
+
domain: ErrorDomain.STORAGE,
|
|
787
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
788
|
+
},
|
|
789
|
+
error,
|
|
790
|
+
);
|
|
493
791
|
}
|
|
494
792
|
}
|
|
495
793
|
|
|
@@ -505,7 +803,7 @@ export class LanceStorage extends MastraStorage {
|
|
|
505
803
|
try {
|
|
506
804
|
const record = { id, title, metadata: JSON.stringify(metadata) };
|
|
507
805
|
const table = await this.lanceClient.openTable(TABLE_THREADS);
|
|
508
|
-
await table.
|
|
806
|
+
await table.mergeInsert('id').whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([record]);
|
|
509
807
|
|
|
510
808
|
const query = table.query().where(`id = '${id}'`);
|
|
511
809
|
|
|
@@ -515,7 +813,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
515
813
|
await this.getTableSchema(TABLE_THREADS),
|
|
516
814
|
) as StorageThreadType;
|
|
517
815
|
} catch (error: any) {
|
|
518
|
-
throw new
|
|
816
|
+
throw new MastraError(
|
|
817
|
+
{
|
|
818
|
+
id: 'LANCE_STORE_UPDATE_THREAD_FAILED',
|
|
819
|
+
domain: ErrorDomain.STORAGE,
|
|
820
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
821
|
+
},
|
|
822
|
+
error,
|
|
823
|
+
);
|
|
519
824
|
}
|
|
520
825
|
}
|
|
521
826
|
|
|
@@ -524,7 +829,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
524
829
|
const table = await this.lanceClient.openTable(TABLE_THREADS);
|
|
525
830
|
await table.delete(`id = '${threadId}'`);
|
|
526
831
|
} catch (error: any) {
|
|
527
|
-
throw new
|
|
832
|
+
throw new MastraError(
|
|
833
|
+
{
|
|
834
|
+
id: 'LANCE_STORE_DELETE_THREAD_FAILED',
|
|
835
|
+
domain: ErrorDomain.STORAGE,
|
|
836
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
837
|
+
},
|
|
838
|
+
error,
|
|
839
|
+
);
|
|
528
840
|
}
|
|
529
841
|
}
|
|
530
842
|
|
|
@@ -617,7 +929,7 @@ export class LanceStorage extends MastraStorage {
|
|
|
617
929
|
if (threadConfig) {
|
|
618
930
|
throw new Error('ThreadConfig is not supported by LanceDB storage');
|
|
619
931
|
}
|
|
620
|
-
|
|
932
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
|
|
621
933
|
const table = await this.lanceClient.openTable(TABLE_MESSAGES);
|
|
622
934
|
let query = table.query().where(`\`threadId\` = '${threadId}'`);
|
|
623
935
|
|
|
@@ -652,8 +964,8 @@ export class LanceStorage extends MastraStorage {
|
|
|
652
964
|
}
|
|
653
965
|
|
|
654
966
|
// If we're fetching the last N messages, take only the last N after sorting
|
|
655
|
-
if (
|
|
656
|
-
records = records.slice(-
|
|
967
|
+
if (limit !== Number.MAX_SAFE_INTEGER) {
|
|
968
|
+
records = records.slice(-limit);
|
|
657
969
|
}
|
|
658
970
|
|
|
659
971
|
const messages = this.processResultWithTypeConversion(records, await this.getTableSchema(TABLE_MESSAGES));
|
|
@@ -674,7 +986,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
674
986
|
if (format === 'v2') return list.get.all.v2();
|
|
675
987
|
return list.get.all.v1();
|
|
676
988
|
} catch (error: any) {
|
|
677
|
-
throw new
|
|
989
|
+
throw new MastraError(
|
|
990
|
+
{
|
|
991
|
+
id: 'LANCE_STORE_GET_MESSAGES_FAILED',
|
|
992
|
+
domain: ErrorDomain.STORAGE,
|
|
993
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
994
|
+
},
|
|
995
|
+
error,
|
|
996
|
+
);
|
|
678
997
|
}
|
|
679
998
|
}
|
|
680
999
|
|
|
@@ -701,12 +1020,20 @@ export class LanceStorage extends MastraStorage {
|
|
|
701
1020
|
}));
|
|
702
1021
|
|
|
703
1022
|
const table = await this.lanceClient.openTable(TABLE_MESSAGES);
|
|
704
|
-
await table.
|
|
1023
|
+
await table.mergeInsert('id').whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(transformedMessages);
|
|
1024
|
+
|
|
705
1025
|
const list = new MessageList().add(messages, 'memory');
|
|
706
1026
|
if (format === `v2`) return list.get.all.v2();
|
|
707
1027
|
return list.get.all.v1();
|
|
708
1028
|
} catch (error: any) {
|
|
709
|
-
throw new
|
|
1029
|
+
throw new MastraError(
|
|
1030
|
+
{
|
|
1031
|
+
id: 'LANCE_STORE_SAVE_MESSAGES_FAILED',
|
|
1032
|
+
domain: ErrorDomain.STORAGE,
|
|
1033
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1034
|
+
},
|
|
1035
|
+
error,
|
|
1036
|
+
);
|
|
710
1037
|
}
|
|
711
1038
|
}
|
|
712
1039
|
|
|
@@ -725,7 +1052,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
725
1052
|
|
|
726
1053
|
return trace;
|
|
727
1054
|
} catch (error: any) {
|
|
728
|
-
throw new
|
|
1055
|
+
throw new MastraError(
|
|
1056
|
+
{
|
|
1057
|
+
id: 'LANCE_STORE_SAVE_TRACE_FAILED',
|
|
1058
|
+
domain: ErrorDomain.STORAGE,
|
|
1059
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1060
|
+
},
|
|
1061
|
+
error,
|
|
1062
|
+
);
|
|
729
1063
|
}
|
|
730
1064
|
}
|
|
731
1065
|
|
|
@@ -736,7 +1070,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
736
1070
|
const records = await query.toArray();
|
|
737
1071
|
return this.processResultWithTypeConversion(records[0], await this.getTableSchema(TABLE_TRACES)) as TraceType;
|
|
738
1072
|
} catch (error: any) {
|
|
739
|
-
throw new
|
|
1073
|
+
throw new MastraError(
|
|
1074
|
+
{
|
|
1075
|
+
id: 'LANCE_STORE_GET_TRACE_BY_ID_FAILED',
|
|
1076
|
+
domain: ErrorDomain.STORAGE,
|
|
1077
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1078
|
+
},
|
|
1079
|
+
error,
|
|
1080
|
+
);
|
|
740
1081
|
}
|
|
741
1082
|
}
|
|
742
1083
|
|
|
@@ -795,7 +1136,15 @@ export class LanceStorage extends MastraStorage {
|
|
|
795
1136
|
};
|
|
796
1137
|
}) as TraceType[];
|
|
797
1138
|
} catch (error: any) {
|
|
798
|
-
throw new
|
|
1139
|
+
throw new MastraError(
|
|
1140
|
+
{
|
|
1141
|
+
id: 'LANCE_STORE_GET_TRACES_FAILED',
|
|
1142
|
+
domain: ErrorDomain.STORAGE,
|
|
1143
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1144
|
+
details: { name: name ?? '', scope: scope ?? '' },
|
|
1145
|
+
},
|
|
1146
|
+
error,
|
|
1147
|
+
);
|
|
799
1148
|
}
|
|
800
1149
|
}
|
|
801
1150
|
|
|
@@ -818,7 +1167,14 @@ export class LanceStorage extends MastraStorage {
|
|
|
818
1167
|
await table.add(transformedEvals, { mode: 'append' });
|
|
819
1168
|
return evals;
|
|
820
1169
|
} catch (error: any) {
|
|
821
|
-
throw new
|
|
1170
|
+
throw new MastraError(
|
|
1171
|
+
{
|
|
1172
|
+
id: 'LANCE_STORE_SAVE_EVALS_FAILED',
|
|
1173
|
+
domain: ErrorDomain.STORAGE,
|
|
1174
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1175
|
+
},
|
|
1176
|
+
error,
|
|
1177
|
+
);
|
|
822
1178
|
}
|
|
823
1179
|
}
|
|
824
1180
|
|
|
@@ -846,7 +1202,15 @@ export class LanceStorage extends MastraStorage {
|
|
|
846
1202
|
};
|
|
847
1203
|
}) as EvalRow[];
|
|
848
1204
|
} catch (error: any) {
|
|
849
|
-
throw new
|
|
1205
|
+
throw new MastraError(
|
|
1206
|
+
{
|
|
1207
|
+
id: 'LANCE_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',
|
|
1208
|
+
domain: ErrorDomain.STORAGE,
|
|
1209
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1210
|
+
details: { agentName },
|
|
1211
|
+
},
|
|
1212
|
+
error,
|
|
1213
|
+
);
|
|
850
1214
|
}
|
|
851
1215
|
}
|
|
852
1216
|
|
|
@@ -909,7 +1273,15 @@ export class LanceStorage extends MastraStorage {
|
|
|
909
1273
|
total: records.length,
|
|
910
1274
|
};
|
|
911
1275
|
} catch (error: any) {
|
|
912
|
-
throw new
|
|
1276
|
+
throw new MastraError(
|
|
1277
|
+
{
|
|
1278
|
+
id: 'LANCE_STORE_GET_WORKFLOW_RUNS_FAILED',
|
|
1279
|
+
domain: ErrorDomain.STORAGE,
|
|
1280
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1281
|
+
details: { namespace: args?.namespace ?? '', workflowName: args?.workflowName ?? '' },
|
|
1282
|
+
},
|
|
1283
|
+
error,
|
|
1284
|
+
);
|
|
913
1285
|
}
|
|
914
1286
|
}
|
|
915
1287
|
|
|
@@ -937,7 +1309,15 @@ export class LanceStorage extends MastraStorage {
|
|
|
937
1309
|
const record = records[0];
|
|
938
1310
|
return this.parseWorkflowRun(record);
|
|
939
1311
|
} catch (error: any) {
|
|
940
|
-
throw new
|
|
1312
|
+
throw new MastraError(
|
|
1313
|
+
{
|
|
1314
|
+
id: 'LANCE_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED',
|
|
1315
|
+
domain: ErrorDomain.STORAGE,
|
|
1316
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1317
|
+
details: { runId: args.runId, workflowName: args.workflowName ?? '' },
|
|
1318
|
+
},
|
|
1319
|
+
error,
|
|
1320
|
+
);
|
|
941
1321
|
}
|
|
942
1322
|
}
|
|
943
1323
|
|
|
@@ -958,11 +1338,9 @@ export class LanceStorage extends MastraStorage {
|
|
|
958
1338
|
const records = await query.toArray();
|
|
959
1339
|
let createdAt: number;
|
|
960
1340
|
const now = Date.now();
|
|
961
|
-
let mode: 'append' | 'overwrite' = 'append';
|
|
962
1341
|
|
|
963
1342
|
if (records.length > 0) {
|
|
964
1343
|
createdAt = records[0].createdAt ?? now;
|
|
965
|
-
mode = 'overwrite';
|
|
966
1344
|
} else {
|
|
967
1345
|
createdAt = now;
|
|
968
1346
|
}
|
|
@@ -975,9 +1353,21 @@ export class LanceStorage extends MastraStorage {
|
|
|
975
1353
|
updatedAt: now,
|
|
976
1354
|
};
|
|
977
1355
|
|
|
978
|
-
await table
|
|
1356
|
+
await table
|
|
1357
|
+
.mergeInsert(['workflow_name', 'run_id'])
|
|
1358
|
+
.whenMatchedUpdateAll()
|
|
1359
|
+
.whenNotMatchedInsertAll()
|
|
1360
|
+
.execute([record]);
|
|
979
1361
|
} catch (error: any) {
|
|
980
|
-
throw new
|
|
1362
|
+
throw new MastraError(
|
|
1363
|
+
{
|
|
1364
|
+
id: 'LANCE_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED',
|
|
1365
|
+
domain: ErrorDomain.STORAGE,
|
|
1366
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1367
|
+
details: { workflowName, runId },
|
|
1368
|
+
},
|
|
1369
|
+
error,
|
|
1370
|
+
);
|
|
981
1371
|
}
|
|
982
1372
|
}
|
|
983
1373
|
async loadWorkflowSnapshot({
|
|
@@ -993,12 +1383,27 @@ export class LanceStorage extends MastraStorage {
|
|
|
993
1383
|
const records = await query.toArray();
|
|
994
1384
|
return records.length > 0 ? JSON.parse(records[0].snapshot) : null;
|
|
995
1385
|
} catch (error: any) {
|
|
996
|
-
throw new
|
|
1386
|
+
throw new MastraError(
|
|
1387
|
+
{
|
|
1388
|
+
id: 'LANCE_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED',
|
|
1389
|
+
domain: ErrorDomain.STORAGE,
|
|
1390
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1391
|
+
details: { workflowName, runId },
|
|
1392
|
+
},
|
|
1393
|
+
error,
|
|
1394
|
+
);
|
|
997
1395
|
}
|
|
998
1396
|
}
|
|
999
1397
|
|
|
1000
1398
|
async getTracesPaginated(_args: StorageGetTracesArg): Promise<PaginationInfo & { traces: Trace[] }> {
|
|
1001
|
-
throw new
|
|
1399
|
+
throw new MastraError(
|
|
1400
|
+
{
|
|
1401
|
+
id: 'LANCE_STORE_GET_TRACES_PAGINATED_FAILED',
|
|
1402
|
+
domain: ErrorDomain.STORAGE,
|
|
1403
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1404
|
+
},
|
|
1405
|
+
'Method not implemented.',
|
|
1406
|
+
);
|
|
1002
1407
|
}
|
|
1003
1408
|
|
|
1004
1409
|
async getThreadsByResourceIdPaginated(_args: {
|
|
@@ -1006,12 +1411,37 @@ export class LanceStorage extends MastraStorage {
|
|
|
1006
1411
|
page?: number;
|
|
1007
1412
|
perPage?: number;
|
|
1008
1413
|
}): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
|
|
1009
|
-
throw new
|
|
1414
|
+
throw new MastraError(
|
|
1415
|
+
{
|
|
1416
|
+
id: 'LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED',
|
|
1417
|
+
domain: ErrorDomain.STORAGE,
|
|
1418
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1419
|
+
},
|
|
1420
|
+
'Method not implemented.',
|
|
1421
|
+
);
|
|
1010
1422
|
}
|
|
1011
1423
|
|
|
1012
1424
|
async getMessagesPaginated(
|
|
1013
1425
|
_args: StorageGetMessagesArg,
|
|
1014
1426
|
): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
|
|
1015
|
-
throw new
|
|
1427
|
+
throw new MastraError(
|
|
1428
|
+
{
|
|
1429
|
+
id: 'LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED',
|
|
1430
|
+
domain: ErrorDomain.STORAGE,
|
|
1431
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1432
|
+
},
|
|
1433
|
+
'Method not implemented.',
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
async updateMessages(_args: {
|
|
1438
|
+
messages: Partial<Omit<MastraMessageV2, 'createdAt'>> &
|
|
1439
|
+
{
|
|
1440
|
+
id: string;
|
|
1441
|
+
content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
|
|
1442
|
+
}[];
|
|
1443
|
+
}): Promise<MastraMessageV2[]> {
|
|
1444
|
+
this.logger.error('updateMessages is not yet implemented in LanceStore');
|
|
1445
|
+
throw new Error('Method not implemented');
|
|
1016
1446
|
}
|
|
1017
1447
|
}
|