@mastra/lance 0.0.0-working-memory-per-user-20250620161509 → 0.0.0-zod-v4-compat-part-2-20250820135355

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 (50) hide show
  1. package/CHANGELOG.md +170 -2
  2. package/LICENSE.md +11 -42
  3. package/dist/index.cjs +2321 -695
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +3 -2
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +2286 -660
  8. package/dist/index.js.map +1 -0
  9. package/dist/storage/domains/legacy-evals/index.d.ts +25 -0
  10. package/dist/storage/domains/legacy-evals/index.d.ts.map +1 -0
  11. package/dist/storage/domains/memory/index.d.ts +94 -0
  12. package/dist/storage/domains/memory/index.d.ts.map +1 -0
  13. package/dist/storage/domains/operations/index.d.ts +40 -0
  14. package/dist/storage/domains/operations/index.d.ts.map +1 -0
  15. package/dist/storage/domains/scores/index.d.ts +39 -0
  16. package/dist/storage/domains/scores/index.d.ts.map +1 -0
  17. package/dist/storage/domains/traces/index.d.ts +34 -0
  18. package/dist/storage/domains/traces/index.d.ts.map +1 -0
  19. package/dist/storage/domains/utils.d.ts +10 -0
  20. package/dist/storage/domains/utils.d.ts.map +1 -0
  21. package/dist/storage/domains/workflows/index.d.ts +38 -0
  22. package/dist/storage/domains/workflows/index.d.ts.map +1 -0
  23. package/dist/storage/index.d.ts +233 -0
  24. package/dist/storage/index.d.ts.map +1 -0
  25. package/dist/vector/filter.d.ts +41 -0
  26. package/dist/vector/filter.d.ts.map +1 -0
  27. package/dist/vector/index.d.ts +85 -0
  28. package/dist/vector/index.d.ts.map +1 -0
  29. package/dist/vector/types.d.ts +15 -0
  30. package/dist/vector/types.d.ts.map +1 -0
  31. package/package.json +9 -9
  32. package/src/storage/domains/legacy-evals/index.ts +156 -0
  33. package/src/storage/domains/memory/index.ts +947 -0
  34. package/src/storage/domains/operations/index.ts +489 -0
  35. package/src/storage/domains/scores/index.ts +221 -0
  36. package/src/storage/domains/traces/index.ts +212 -0
  37. package/src/storage/domains/utils.ts +158 -0
  38. package/src/storage/domains/workflows/index.ts +207 -0
  39. package/src/storage/index.test.ts +6 -1262
  40. package/src/storage/index.ts +168 -755
  41. package/src/vector/filter.test.ts +3 -3
  42. package/src/vector/filter.ts +24 -4
  43. package/src/vector/index.test.ts +3 -3
  44. package/src/vector/index.ts +320 -79
  45. package/tsconfig.build.json +9 -0
  46. package/tsconfig.json +1 -1
  47. package/tsup.config.ts +22 -0
  48. package/dist/_tsup-dts-rollup.d.cts +0 -395
  49. package/dist/_tsup-dts-rollup.d.ts +0 -395
  50. package/dist/index.d.cts +0 -2
package/dist/index.cjs CHANGED
@@ -1,14 +1,1879 @@
1
1
  'use strict';
2
2
 
3
3
  var lancedb = require('@lancedb/lancedb');
4
- var agent = require('@mastra/core/agent');
4
+ var error = require('@mastra/core/error');
5
5
  var storage = require('@mastra/core/storage');
6
+ var agent = require('@mastra/core/agent');
6
7
  var apacheArrow = require('apache-arrow');
7
8
  var vector = require('@mastra/core/vector');
8
9
  var filter = require('@mastra/core/vector/filter');
9
10
 
11
+ // src/storage/index.ts
12
+ var StoreLegacyEvalsLance = class extends storage.LegacyEvalsStorage {
13
+ client;
14
+ constructor({ client }) {
15
+ super();
16
+ this.client = client;
17
+ }
18
+ async getEvalsByAgentName(agentName, type) {
19
+ try {
20
+ const table = await this.client.openTable(storage.TABLE_EVALS);
21
+ const query = table.query().where(`agent_name = '${agentName}'`);
22
+ const records = await query.toArray();
23
+ let filteredRecords = records;
24
+ if (type === "live") {
25
+ filteredRecords = records.filter((record) => record.test_info === null);
26
+ } else if (type === "test") {
27
+ filteredRecords = records.filter((record) => record.test_info !== null);
28
+ }
29
+ return filteredRecords.map((record) => {
30
+ return {
31
+ id: record.id,
32
+ input: record.input,
33
+ output: record.output,
34
+ agentName: record.agent_name,
35
+ metricName: record.metric_name,
36
+ result: JSON.parse(record.result),
37
+ instructions: record.instructions,
38
+ testInfo: record.test_info ? JSON.parse(record.test_info) : null,
39
+ globalRunId: record.global_run_id,
40
+ runId: record.run_id,
41
+ createdAt: new Date(record.created_at).toString()
42
+ };
43
+ });
44
+ } catch (error$1) {
45
+ throw new error.MastraError(
46
+ {
47
+ id: "LANCE_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
48
+ domain: error.ErrorDomain.STORAGE,
49
+ category: error.ErrorCategory.THIRD_PARTY,
50
+ details: { agentName }
51
+ },
52
+ error$1
53
+ );
54
+ }
55
+ }
56
+ async getEvals(options) {
57
+ try {
58
+ const table = await this.client.openTable(storage.TABLE_EVALS);
59
+ const conditions = [];
60
+ if (options.agentName) {
61
+ conditions.push(`agent_name = '${options.agentName}'`);
62
+ }
63
+ if (options.type === "live") {
64
+ conditions.push("length(test_info) = 0");
65
+ } else if (options.type === "test") {
66
+ conditions.push("length(test_info) > 0");
67
+ }
68
+ const startDate = options.dateRange?.start || options.fromDate;
69
+ const endDate = options.dateRange?.end || options.toDate;
70
+ if (startDate) {
71
+ conditions.push(`\`created_at\` >= ${startDate.getTime()}`);
72
+ }
73
+ if (endDate) {
74
+ conditions.push(`\`created_at\` <= ${endDate.getTime()}`);
75
+ }
76
+ let total = 0;
77
+ if (conditions.length > 0) {
78
+ total = await table.countRows(conditions.join(" AND "));
79
+ } else {
80
+ total = await table.countRows();
81
+ }
82
+ const query = table.query();
83
+ if (conditions.length > 0) {
84
+ const whereClause = conditions.join(" AND ");
85
+ query.where(whereClause);
86
+ }
87
+ const records = await query.toArray();
88
+ const evals = records.sort((a, b) => b.created_at - a.created_at).map((record) => {
89
+ return {
90
+ id: record.id,
91
+ input: record.input,
92
+ output: record.output,
93
+ agentName: record.agent_name,
94
+ metricName: record.metric_name,
95
+ result: JSON.parse(record.result),
96
+ instructions: record.instructions,
97
+ testInfo: record.test_info ? JSON.parse(record.test_info) : null,
98
+ globalRunId: record.global_run_id,
99
+ runId: record.run_id,
100
+ createdAt: new Date(record.created_at).toISOString()
101
+ };
102
+ });
103
+ const page = options.page || 0;
104
+ const perPage = options.perPage || 10;
105
+ const pagedEvals = evals.slice(page * perPage, (page + 1) * perPage);
106
+ return {
107
+ evals: pagedEvals,
108
+ total,
109
+ page,
110
+ perPage,
111
+ hasMore: total > (page + 1) * perPage
112
+ };
113
+ } catch (error$1) {
114
+ throw new error.MastraError(
115
+ {
116
+ id: "LANCE_STORE_GET_EVALS_FAILED",
117
+ domain: error.ErrorDomain.STORAGE,
118
+ category: error.ErrorCategory.THIRD_PARTY,
119
+ details: { agentName: options.agentName ?? "" }
120
+ },
121
+ error$1
122
+ );
123
+ }
124
+ }
125
+ };
126
+ function getPrimaryKeys(tableName) {
127
+ let primaryId = ["id"];
128
+ if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
129
+ primaryId = ["workflow_name", "run_id"];
130
+ } else if (tableName === storage.TABLE_EVALS) {
131
+ primaryId = ["agent_name", "metric_name", "run_id"];
132
+ }
133
+ return primaryId;
134
+ }
135
+ function validateKeyTypes(keys, tableSchema) {
136
+ const fieldTypes = new Map(
137
+ tableSchema.fields.map((field) => [field.name, field.type?.toString().toLowerCase()])
138
+ );
139
+ for (const [key, value] of Object.entries(keys)) {
140
+ const fieldType = fieldTypes.get(key);
141
+ if (!fieldType) {
142
+ throw new Error(`Field '${key}' does not exist in table schema`);
143
+ }
144
+ if (value !== null) {
145
+ if ((fieldType.includes("int") || fieldType.includes("bigint")) && typeof value !== "number") {
146
+ throw new Error(`Expected numeric value for field '${key}', got ${typeof value}`);
147
+ }
148
+ if (fieldType.includes("utf8") && typeof value !== "string") {
149
+ throw new Error(`Expected string value for field '${key}', got ${typeof value}`);
150
+ }
151
+ if (fieldType.includes("timestamp") && !(value instanceof Date) && typeof value !== "string") {
152
+ throw new Error(`Expected Date or string value for field '${key}', got ${typeof value}`);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ function processResultWithTypeConversion(rawResult, tableSchema) {
158
+ const fieldTypeMap = /* @__PURE__ */ new Map();
159
+ tableSchema.fields.forEach((field) => {
160
+ const fieldName = field.name;
161
+ const fieldTypeStr = field.type.toString().toLowerCase();
162
+ fieldTypeMap.set(fieldName, fieldTypeStr);
163
+ });
164
+ if (Array.isArray(rawResult)) {
165
+ return rawResult.map((item) => processResultWithTypeConversion(item, tableSchema));
166
+ }
167
+ const processedResult = { ...rawResult };
168
+ for (const key in processedResult) {
169
+ const fieldTypeStr = fieldTypeMap.get(key);
170
+ if (!fieldTypeStr) continue;
171
+ if (typeof processedResult[key] === "string") {
172
+ if (fieldTypeStr.includes("int32") || fieldTypeStr.includes("float32")) {
173
+ if (!isNaN(Number(processedResult[key]))) {
174
+ processedResult[key] = Number(processedResult[key]);
175
+ }
176
+ } else if (fieldTypeStr.includes("int64")) {
177
+ processedResult[key] = Number(processedResult[key]);
178
+ } else if (fieldTypeStr.includes("utf8") && key !== "id") {
179
+ try {
180
+ const parsed = JSON.parse(processedResult[key]);
181
+ if (typeof parsed === "object") {
182
+ processedResult[key] = JSON.parse(processedResult[key]);
183
+ }
184
+ } catch {
185
+ }
186
+ }
187
+ } else if (typeof processedResult[key] === "bigint") {
188
+ processedResult[key] = Number(processedResult[key]);
189
+ } else if (fieldTypeStr.includes("float64") && ["createdAt", "updatedAt"].includes(key)) {
190
+ processedResult[key] = new Date(processedResult[key]);
191
+ }
192
+ console.log(key, "processedResult", processedResult);
193
+ }
194
+ return processedResult;
195
+ }
196
+ async function getTableSchema({
197
+ tableName,
198
+ client
199
+ }) {
200
+ try {
201
+ if (!client) {
202
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
203
+ }
204
+ if (!tableName) {
205
+ throw new Error("tableName is required for getTableSchema.");
206
+ }
207
+ } catch (validationError) {
208
+ throw new error.MastraError(
209
+ {
210
+ id: "STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_INVALID_ARGS",
211
+ domain: error.ErrorDomain.STORAGE,
212
+ category: error.ErrorCategory.USER,
213
+ text: validationError.message,
214
+ details: { tableName }
215
+ },
216
+ validationError
217
+ );
218
+ }
219
+ try {
220
+ const table = await client.openTable(tableName);
221
+ const rawSchema = await table.schema();
222
+ const fields = rawSchema.fields;
223
+ return {
224
+ fields,
225
+ metadata: /* @__PURE__ */ new Map(),
226
+ get names() {
227
+ return fields.map((field) => field.name);
228
+ }
229
+ };
230
+ } catch (error$1) {
231
+ throw new error.MastraError(
232
+ {
233
+ id: "STORAGE_LANCE_STORAGE_GET_TABLE_SCHEMA_FAILED",
234
+ domain: error.ErrorDomain.STORAGE,
235
+ category: error.ErrorCategory.THIRD_PARTY,
236
+ details: { tableName }
237
+ },
238
+ error$1
239
+ );
240
+ }
241
+ }
242
+
243
+ // src/storage/domains/memory/index.ts
244
+ var StoreMemoryLance = class extends storage.MemoryStorage {
245
+ client;
246
+ operations;
247
+ constructor({ client, operations }) {
248
+ super();
249
+ this.client = client;
250
+ this.operations = operations;
251
+ }
252
+ async getThreadById({ threadId }) {
253
+ try {
254
+ const thread = await this.operations.load({ tableName: storage.TABLE_THREADS, keys: { id: threadId } });
255
+ if (!thread) {
256
+ return null;
257
+ }
258
+ return {
259
+ ...thread,
260
+ createdAt: new Date(thread.createdAt),
261
+ updatedAt: new Date(thread.updatedAt)
262
+ };
263
+ } catch (error$1) {
264
+ throw new error.MastraError(
265
+ {
266
+ id: "LANCE_STORE_GET_THREAD_BY_ID_FAILED",
267
+ domain: error.ErrorDomain.STORAGE,
268
+ category: error.ErrorCategory.THIRD_PARTY
269
+ },
270
+ error$1
271
+ );
272
+ }
273
+ }
274
+ async getThreadsByResourceId({ resourceId }) {
275
+ try {
276
+ const table = await this.client.openTable(storage.TABLE_THREADS);
277
+ const query = table.query().where(`\`resourceId\` = '${resourceId}'`);
278
+ const records = await query.toArray();
279
+ return processResultWithTypeConversion(
280
+ records,
281
+ await getTableSchema({ tableName: storage.TABLE_THREADS, client: this.client })
282
+ );
283
+ } catch (error$1) {
284
+ throw new error.MastraError(
285
+ {
286
+ id: "LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
287
+ domain: error.ErrorDomain.STORAGE,
288
+ category: error.ErrorCategory.THIRD_PARTY
289
+ },
290
+ error$1
291
+ );
292
+ }
293
+ }
294
+ /**
295
+ * Saves a thread to the database. This function doesn't overwrite existing threads.
296
+ * @param thread - The thread to save
297
+ * @returns The saved thread
298
+ */
299
+ async saveThread({ thread }) {
300
+ try {
301
+ const record = { ...thread, metadata: JSON.stringify(thread.metadata) };
302
+ const table = await this.client.openTable(storage.TABLE_THREADS);
303
+ await table.add([record], { mode: "append" });
304
+ return thread;
305
+ } catch (error$1) {
306
+ throw new error.MastraError(
307
+ {
308
+ id: "LANCE_STORE_SAVE_THREAD_FAILED",
309
+ domain: error.ErrorDomain.STORAGE,
310
+ category: error.ErrorCategory.THIRD_PARTY
311
+ },
312
+ error$1
313
+ );
314
+ }
315
+ }
316
+ async updateThread({
317
+ id,
318
+ title,
319
+ metadata
320
+ }) {
321
+ const maxRetries = 5;
322
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
323
+ try {
324
+ const current = await this.getThreadById({ threadId: id });
325
+ if (!current) {
326
+ throw new Error(`Thread with id ${id} not found`);
327
+ }
328
+ const mergedMetadata = { ...current.metadata, ...metadata };
329
+ const record = {
330
+ id,
331
+ title,
332
+ metadata: JSON.stringify(mergedMetadata),
333
+ updatedAt: (/* @__PURE__ */ new Date()).getTime()
334
+ };
335
+ const table = await this.client.openTable(storage.TABLE_THREADS);
336
+ await table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([record]);
337
+ const updatedThread = await this.getThreadById({ threadId: id });
338
+ if (!updatedThread) {
339
+ throw new Error(`Failed to retrieve updated thread ${id}`);
340
+ }
341
+ return updatedThread;
342
+ } catch (error$1) {
343
+ if (error$1.message?.includes("Commit conflict") && attempt < maxRetries - 1) {
344
+ const delay = Math.pow(2, attempt) * 10;
345
+ await new Promise((resolve) => setTimeout(resolve, delay));
346
+ continue;
347
+ }
348
+ throw new error.MastraError(
349
+ {
350
+ id: "LANCE_STORE_UPDATE_THREAD_FAILED",
351
+ domain: error.ErrorDomain.STORAGE,
352
+ category: error.ErrorCategory.THIRD_PARTY
353
+ },
354
+ error$1
355
+ );
356
+ }
357
+ }
358
+ throw new error.MastraError(
359
+ {
360
+ id: "LANCE_STORE_UPDATE_THREAD_FAILED",
361
+ domain: error.ErrorDomain.STORAGE,
362
+ category: error.ErrorCategory.THIRD_PARTY
363
+ },
364
+ new Error("All retries exhausted")
365
+ );
366
+ }
367
+ async deleteThread({ threadId }) {
368
+ try {
369
+ const table = await this.client.openTable(storage.TABLE_THREADS);
370
+ await table.delete(`id = '${threadId}'`);
371
+ const messagesTable = await this.client.openTable(storage.TABLE_MESSAGES);
372
+ await messagesTable.delete(`thread_id = '${threadId}'`);
373
+ } catch (error$1) {
374
+ throw new error.MastraError(
375
+ {
376
+ id: "LANCE_STORE_DELETE_THREAD_FAILED",
377
+ domain: error.ErrorDomain.STORAGE,
378
+ category: error.ErrorCategory.THIRD_PARTY
379
+ },
380
+ error$1
381
+ );
382
+ }
383
+ }
384
+ async getMessages({
385
+ threadId,
386
+ resourceId,
387
+ selectBy,
388
+ format,
389
+ threadConfig
390
+ }) {
391
+ try {
392
+ if (threadConfig) {
393
+ throw new Error("ThreadConfig is not supported by LanceDB storage");
394
+ }
395
+ const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
396
+ const table = await this.client.openTable(storage.TABLE_MESSAGES);
397
+ let allRecords = [];
398
+ if (selectBy?.include && selectBy.include.length > 0) {
399
+ const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
400
+ for (const threadId2 of threadIds) {
401
+ const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
402
+ let threadRecords = await threadQuery.toArray();
403
+ allRecords.push(...threadRecords);
404
+ }
405
+ } else {
406
+ let query = table.query().where(`\`thread_id\` = '${threadId}'`);
407
+ allRecords = await query.toArray();
408
+ }
409
+ allRecords.sort((a, b) => {
410
+ const dateA = new Date(a.createdAt).getTime();
411
+ const dateB = new Date(b.createdAt).getTime();
412
+ return dateA - dateB;
413
+ });
414
+ if (selectBy?.include && selectBy.include.length > 0) {
415
+ allRecords = this.processMessagesWithContext(allRecords, selectBy.include);
416
+ }
417
+ if (limit !== Number.MAX_SAFE_INTEGER) {
418
+ allRecords = allRecords.slice(-limit);
419
+ }
420
+ const messages = processResultWithTypeConversion(
421
+ allRecords,
422
+ await getTableSchema({ tableName: storage.TABLE_MESSAGES, client: this.client })
423
+ );
424
+ const normalized = messages.map((msg) => {
425
+ const { thread_id, ...rest } = msg;
426
+ return {
427
+ ...rest,
428
+ threadId: thread_id,
429
+ content: typeof msg.content === "string" ? (() => {
430
+ try {
431
+ return JSON.parse(msg.content);
432
+ } catch {
433
+ return msg.content;
434
+ }
435
+ })() : msg.content
436
+ };
437
+ });
438
+ const list = new agent.MessageList({ threadId, resourceId }).add(normalized, "memory");
439
+ if (format === "v2") return list.get.all.v2();
440
+ return list.get.all.v1();
441
+ } catch (error$1) {
442
+ throw new error.MastraError(
443
+ {
444
+ id: "LANCE_STORE_GET_MESSAGES_FAILED",
445
+ domain: error.ErrorDomain.STORAGE,
446
+ category: error.ErrorCategory.THIRD_PARTY
447
+ },
448
+ error$1
449
+ );
450
+ }
451
+ }
452
+ async saveMessages(args) {
453
+ try {
454
+ const { messages, format = "v1" } = args;
455
+ if (messages.length === 0) {
456
+ return [];
457
+ }
458
+ const threadId = messages[0]?.threadId;
459
+ if (!threadId) {
460
+ throw new Error("Thread ID is required");
461
+ }
462
+ for (const message of messages) {
463
+ if (!message.id) {
464
+ throw new Error("Message ID is required");
465
+ }
466
+ if (!message.threadId) {
467
+ throw new Error("Thread ID is required for all messages");
468
+ }
469
+ if (message.resourceId === null || message.resourceId === void 0) {
470
+ throw new Error("Resource ID cannot be null or undefined");
471
+ }
472
+ if (!message.content) {
473
+ throw new Error("Message content is required");
474
+ }
475
+ }
476
+ const transformedMessages = messages.map((message) => {
477
+ const { threadId: threadId2, type, ...rest } = message;
478
+ return {
479
+ ...rest,
480
+ thread_id: threadId2,
481
+ type: type ?? "v2",
482
+ content: JSON.stringify(message.content)
483
+ };
484
+ });
485
+ const table = await this.client.openTable(storage.TABLE_MESSAGES);
486
+ await table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(transformedMessages);
487
+ const threadsTable = await this.client.openTable(storage.TABLE_THREADS);
488
+ const currentTime = (/* @__PURE__ */ new Date()).getTime();
489
+ const updateRecord = { id: threadId, updatedAt: currentTime };
490
+ await threadsTable.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([updateRecord]);
491
+ const list = new agent.MessageList().add(messages, "memory");
492
+ if (format === `v2`) return list.get.all.v2();
493
+ return list.get.all.v1();
494
+ } catch (error$1) {
495
+ throw new error.MastraError(
496
+ {
497
+ id: "LANCE_STORE_SAVE_MESSAGES_FAILED",
498
+ domain: error.ErrorDomain.STORAGE,
499
+ category: error.ErrorCategory.THIRD_PARTY
500
+ },
501
+ error$1
502
+ );
503
+ }
504
+ }
505
+ async getThreadsByResourceIdPaginated(args) {
506
+ try {
507
+ const { resourceId, page = 0, perPage = 10 } = args;
508
+ const table = await this.client.openTable(storage.TABLE_THREADS);
509
+ const total = await table.countRows(`\`resourceId\` = '${resourceId}'`);
510
+ const query = table.query().where(`\`resourceId\` = '${resourceId}'`);
511
+ const offset = page * perPage;
512
+ query.limit(perPage);
513
+ if (offset > 0) {
514
+ query.offset(offset);
515
+ }
516
+ const records = await query.toArray();
517
+ records.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
518
+ const schema = await getTableSchema({ tableName: storage.TABLE_THREADS, client: this.client });
519
+ const threads = records.map((record) => processResultWithTypeConversion(record, schema));
520
+ return {
521
+ threads,
522
+ total,
523
+ page,
524
+ perPage,
525
+ hasMore: total > (page + 1) * perPage
526
+ };
527
+ } catch (error$1) {
528
+ throw new error.MastraError(
529
+ {
530
+ id: "LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
531
+ domain: error.ErrorDomain.STORAGE,
532
+ category: error.ErrorCategory.THIRD_PARTY
533
+ },
534
+ error$1
535
+ );
536
+ }
537
+ }
538
+ /**
539
+ * Processes messages to include context messages based on withPreviousMessages and withNextMessages
540
+ * @param records - The sorted array of records to process
541
+ * @param include - The array of include specifications with context parameters
542
+ * @returns The processed array with context messages included
543
+ */
544
+ processMessagesWithContext(records, include) {
545
+ const messagesWithContext = include.filter((item) => item.withPreviousMessages || item.withNextMessages);
546
+ if (messagesWithContext.length === 0) {
547
+ return records;
548
+ }
549
+ const messageIndexMap = /* @__PURE__ */ new Map();
550
+ records.forEach((message, index) => {
551
+ messageIndexMap.set(message.id, index);
552
+ });
553
+ const additionalIndices = /* @__PURE__ */ new Set();
554
+ for (const item of messagesWithContext) {
555
+ const messageIndex = messageIndexMap.get(item.id);
556
+ if (messageIndex !== void 0) {
557
+ if (item.withPreviousMessages) {
558
+ const startIdx = Math.max(0, messageIndex - item.withPreviousMessages);
559
+ for (let i = startIdx; i < messageIndex; i++) {
560
+ additionalIndices.add(i);
561
+ }
562
+ }
563
+ if (item.withNextMessages) {
564
+ const endIdx = Math.min(records.length - 1, messageIndex + item.withNextMessages);
565
+ for (let i = messageIndex + 1; i <= endIdx; i++) {
566
+ additionalIndices.add(i);
567
+ }
568
+ }
569
+ }
570
+ }
571
+ if (additionalIndices.size === 0) {
572
+ return records;
573
+ }
574
+ const originalMatchIds = new Set(include.map((item) => item.id));
575
+ const allIndices = /* @__PURE__ */ new Set();
576
+ records.forEach((record, index) => {
577
+ if (originalMatchIds.has(record.id)) {
578
+ allIndices.add(index);
579
+ }
580
+ });
581
+ additionalIndices.forEach((index) => {
582
+ allIndices.add(index);
583
+ });
584
+ return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
585
+ }
586
+ async getMessagesPaginated(args) {
587
+ try {
588
+ const { threadId, resourceId, selectBy, format = "v1" } = args;
589
+ if (!threadId) {
590
+ throw new Error("Thread ID is required for getMessagesPaginated");
591
+ }
592
+ const page = selectBy?.pagination?.page ?? 0;
593
+ const perPage = selectBy?.pagination?.perPage ?? 10;
594
+ const dateRange = selectBy?.pagination?.dateRange;
595
+ const fromDate = dateRange?.start;
596
+ const toDate = dateRange?.end;
597
+ const table = await this.client.openTable(storage.TABLE_MESSAGES);
598
+ const messages = [];
599
+ if (selectBy?.include && Array.isArray(selectBy.include)) {
600
+ const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
601
+ const allThreadMessages = [];
602
+ for (const threadId2 of threadIds) {
603
+ const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
604
+ let threadRecords = await threadQuery.toArray();
605
+ if (fromDate) threadRecords = threadRecords.filter((m) => m.createdAt >= fromDate.getTime());
606
+ if (toDate) threadRecords = threadRecords.filter((m) => m.createdAt <= toDate.getTime());
607
+ allThreadMessages.push(...threadRecords);
608
+ }
609
+ allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
610
+ const contextMessages = this.processMessagesWithContext(allThreadMessages, selectBy.include);
611
+ messages.push(...contextMessages);
612
+ }
613
+ const conditions = [`thread_id = '${threadId}'`];
614
+ if (resourceId) {
615
+ conditions.push(`\`resourceId\` = '${resourceId}'`);
616
+ }
617
+ if (fromDate) {
618
+ conditions.push(`\`createdAt\` >= ${fromDate.getTime()}`);
619
+ }
620
+ if (toDate) {
621
+ conditions.push(`\`createdAt\` <= ${toDate.getTime()}`);
622
+ }
623
+ let total = 0;
624
+ if (conditions.length > 0) {
625
+ total = await table.countRows(conditions.join(" AND "));
626
+ } else {
627
+ total = await table.countRows();
628
+ }
629
+ if (total === 0 && messages.length === 0) {
630
+ return {
631
+ messages: [],
632
+ total: 0,
633
+ page,
634
+ perPage,
635
+ hasMore: false
636
+ };
637
+ }
638
+ const excludeIds = messages.map((m) => m.id);
639
+ let selectedMessages = [];
640
+ if (selectBy?.last && selectBy.last > 0) {
641
+ const query = table.query();
642
+ if (conditions.length > 0) {
643
+ query.where(conditions.join(" AND "));
644
+ }
645
+ let records = await query.toArray();
646
+ records = records.sort((a, b) => a.createdAt - b.createdAt);
647
+ if (excludeIds.length > 0) {
648
+ records = records.filter((m) => !excludeIds.includes(m.id));
649
+ }
650
+ selectedMessages = records.slice(-selectBy.last);
651
+ } else {
652
+ const query = table.query();
653
+ if (conditions.length > 0) {
654
+ query.where(conditions.join(" AND "));
655
+ }
656
+ let records = await query.toArray();
657
+ records = records.sort((a, b) => a.createdAt - b.createdAt);
658
+ if (excludeIds.length > 0) {
659
+ records = records.filter((m) => !excludeIds.includes(m.id));
660
+ }
661
+ selectedMessages = records.slice(page * perPage, (page + 1) * perPage);
662
+ }
663
+ const allMessages = [...messages, ...selectedMessages];
664
+ const seen = /* @__PURE__ */ new Set();
665
+ const dedupedMessages = allMessages.filter((m) => {
666
+ const key = `${m.id}:${m.thread_id}`;
667
+ if (seen.has(key)) return false;
668
+ seen.add(key);
669
+ return true;
670
+ });
671
+ const formattedMessages = dedupedMessages.map((msg) => {
672
+ const { thread_id, ...rest } = msg;
673
+ return {
674
+ ...rest,
675
+ threadId: thread_id,
676
+ content: typeof msg.content === "string" ? (() => {
677
+ try {
678
+ return JSON.parse(msg.content);
679
+ } catch {
680
+ return msg.content;
681
+ }
682
+ })() : msg.content
683
+ };
684
+ });
685
+ const list = new agent.MessageList().add(formattedMessages, "memory");
686
+ return {
687
+ messages: format === "v2" ? list.get.all.v2() : list.get.all.v1(),
688
+ total,
689
+ // Total should be the count of messages matching the filters
690
+ page,
691
+ perPage,
692
+ hasMore: total > (page + 1) * perPage
693
+ };
694
+ } catch (error$1) {
695
+ throw new error.MastraError(
696
+ {
697
+ id: "LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED",
698
+ domain: error.ErrorDomain.STORAGE,
699
+ category: error.ErrorCategory.THIRD_PARTY
700
+ },
701
+ error$1
702
+ );
703
+ }
704
+ }
705
+ /**
706
+ * Parse message data from LanceDB record format to MastraMessageV2 format
707
+ */
708
+ parseMessageData(data) {
709
+ const { thread_id, ...rest } = data;
710
+ return {
711
+ ...rest,
712
+ threadId: thread_id,
713
+ content: typeof data.content === "string" ? (() => {
714
+ try {
715
+ return JSON.parse(data.content);
716
+ } catch {
717
+ return data.content;
718
+ }
719
+ })() : data.content,
720
+ createdAt: new Date(data.createdAt),
721
+ updatedAt: new Date(data.updatedAt)
722
+ };
723
+ }
724
+ async updateMessages(args) {
725
+ const { messages } = args;
726
+ this.logger.debug("Updating messages", { count: messages.length });
727
+ if (!messages.length) {
728
+ return [];
729
+ }
730
+ const updatedMessages = [];
731
+ const affectedThreadIds = /* @__PURE__ */ new Set();
732
+ try {
733
+ for (const updateData of messages) {
734
+ const { id, ...updates } = updateData;
735
+ const existingMessage = await this.operations.load({ tableName: storage.TABLE_MESSAGES, keys: { id } });
736
+ if (!existingMessage) {
737
+ this.logger.warn("Message not found for update", { id });
738
+ continue;
739
+ }
740
+ const existingMsg = this.parseMessageData(existingMessage);
741
+ const originalThreadId = existingMsg.threadId;
742
+ affectedThreadIds.add(originalThreadId);
743
+ const updatePayload = {};
744
+ if ("role" in updates && updates.role !== void 0) updatePayload.role = updates.role;
745
+ if ("type" in updates && updates.type !== void 0) updatePayload.type = updates.type;
746
+ if ("resourceId" in updates && updates.resourceId !== void 0) updatePayload.resourceId = updates.resourceId;
747
+ if ("threadId" in updates && updates.threadId !== void 0 && updates.threadId !== null) {
748
+ updatePayload.thread_id = updates.threadId;
749
+ affectedThreadIds.add(updates.threadId);
750
+ }
751
+ if (updates.content) {
752
+ const existingContent = existingMsg.content;
753
+ let newContent = { ...existingContent };
754
+ if (updates.content.metadata !== void 0) {
755
+ newContent.metadata = {
756
+ ...existingContent.metadata || {},
757
+ ...updates.content.metadata || {}
758
+ };
759
+ }
760
+ if (updates.content.content !== void 0) {
761
+ newContent.content = updates.content.content;
762
+ }
763
+ if ("parts" in updates.content && updates.content.parts !== void 0) {
764
+ newContent.parts = updates.content.parts;
765
+ }
766
+ updatePayload.content = JSON.stringify(newContent);
767
+ }
768
+ await this.operations.insert({ tableName: storage.TABLE_MESSAGES, record: { id, ...updatePayload } });
769
+ const updatedMessage = await this.operations.load({ tableName: storage.TABLE_MESSAGES, keys: { id } });
770
+ if (updatedMessage) {
771
+ updatedMessages.push(this.parseMessageData(updatedMessage));
772
+ }
773
+ }
774
+ for (const threadId of affectedThreadIds) {
775
+ await this.operations.insert({
776
+ tableName: storage.TABLE_THREADS,
777
+ record: { id: threadId, updatedAt: Date.now() }
778
+ });
779
+ }
780
+ return updatedMessages;
781
+ } catch (error$1) {
782
+ throw new error.MastraError(
783
+ {
784
+ id: "LANCE_STORE_UPDATE_MESSAGES_FAILED",
785
+ domain: error.ErrorDomain.STORAGE,
786
+ category: error.ErrorCategory.THIRD_PARTY,
787
+ details: { count: messages.length }
788
+ },
789
+ error$1
790
+ );
791
+ }
792
+ }
793
+ async getResourceById({ resourceId }) {
794
+ try {
795
+ const resource = await this.operations.load({ tableName: storage.TABLE_RESOURCES, keys: { id: resourceId } });
796
+ if (!resource) {
797
+ return null;
798
+ }
799
+ let createdAt;
800
+ let updatedAt;
801
+ try {
802
+ if (resource.createdAt instanceof Date) {
803
+ createdAt = resource.createdAt;
804
+ } else if (typeof resource.createdAt === "string") {
805
+ createdAt = new Date(resource.createdAt);
806
+ } else if (typeof resource.createdAt === "number") {
807
+ createdAt = new Date(resource.createdAt);
808
+ } else {
809
+ createdAt = /* @__PURE__ */ new Date();
810
+ }
811
+ if (isNaN(createdAt.getTime())) {
812
+ createdAt = /* @__PURE__ */ new Date();
813
+ }
814
+ } catch {
815
+ createdAt = /* @__PURE__ */ new Date();
816
+ }
817
+ try {
818
+ if (resource.updatedAt instanceof Date) {
819
+ updatedAt = resource.updatedAt;
820
+ } else if (typeof resource.updatedAt === "string") {
821
+ updatedAt = new Date(resource.updatedAt);
822
+ } else if (typeof resource.updatedAt === "number") {
823
+ updatedAt = new Date(resource.updatedAt);
824
+ } else {
825
+ updatedAt = /* @__PURE__ */ new Date();
826
+ }
827
+ if (isNaN(updatedAt.getTime())) {
828
+ updatedAt = /* @__PURE__ */ new Date();
829
+ }
830
+ } catch {
831
+ updatedAt = /* @__PURE__ */ new Date();
832
+ }
833
+ let workingMemory = resource.workingMemory;
834
+ if (workingMemory === null || workingMemory === void 0) {
835
+ workingMemory = void 0;
836
+ } else if (workingMemory === "") {
837
+ workingMemory = "";
838
+ } else if (typeof workingMemory === "object") {
839
+ workingMemory = JSON.stringify(workingMemory);
840
+ }
841
+ let metadata = resource.metadata;
842
+ if (metadata === "" || metadata === null || metadata === void 0) {
843
+ metadata = void 0;
844
+ } else if (typeof metadata === "string") {
845
+ try {
846
+ metadata = JSON.parse(metadata);
847
+ } catch {
848
+ metadata = metadata;
849
+ }
850
+ }
851
+ return {
852
+ ...resource,
853
+ createdAt,
854
+ updatedAt,
855
+ workingMemory,
856
+ metadata
857
+ };
858
+ } catch (error$1) {
859
+ throw new error.MastraError(
860
+ {
861
+ id: "LANCE_STORE_GET_RESOURCE_BY_ID_FAILED",
862
+ domain: error.ErrorDomain.STORAGE,
863
+ category: error.ErrorCategory.THIRD_PARTY
864
+ },
865
+ error$1
866
+ );
867
+ }
868
+ }
869
+ async saveResource({ resource }) {
870
+ try {
871
+ const record = {
872
+ ...resource,
873
+ metadata: resource.metadata ? JSON.stringify(resource.metadata) : "",
874
+ createdAt: resource.createdAt.getTime(),
875
+ // Store as timestamp (milliseconds)
876
+ updatedAt: resource.updatedAt.getTime()
877
+ // Store as timestamp (milliseconds)
878
+ };
879
+ const table = await this.client.openTable(storage.TABLE_RESOURCES);
880
+ await table.add([record], { mode: "append" });
881
+ return resource;
882
+ } catch (error$1) {
883
+ throw new error.MastraError(
884
+ {
885
+ id: "LANCE_STORE_SAVE_RESOURCE_FAILED",
886
+ domain: error.ErrorDomain.STORAGE,
887
+ category: error.ErrorCategory.THIRD_PARTY
888
+ },
889
+ error$1
890
+ );
891
+ }
892
+ }
893
+ async updateResource({
894
+ resourceId,
895
+ workingMemory,
896
+ metadata
897
+ }) {
898
+ const maxRetries = 3;
899
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
900
+ try {
901
+ const existingResource = await this.getResourceById({ resourceId });
902
+ if (!existingResource) {
903
+ const newResource = {
904
+ id: resourceId,
905
+ workingMemory,
906
+ metadata: metadata || {},
907
+ createdAt: /* @__PURE__ */ new Date(),
908
+ updatedAt: /* @__PURE__ */ new Date()
909
+ };
910
+ return this.saveResource({ resource: newResource });
911
+ }
912
+ const updatedResource = {
913
+ ...existingResource,
914
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
915
+ metadata: {
916
+ ...existingResource.metadata,
917
+ ...metadata
918
+ },
919
+ updatedAt: /* @__PURE__ */ new Date()
920
+ };
921
+ const record = {
922
+ id: resourceId,
923
+ workingMemory: updatedResource.workingMemory || "",
924
+ metadata: updatedResource.metadata ? JSON.stringify(updatedResource.metadata) : "",
925
+ updatedAt: updatedResource.updatedAt.getTime()
926
+ // Store as timestamp (milliseconds)
927
+ };
928
+ const table = await this.client.openTable(storage.TABLE_RESOURCES);
929
+ await table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([record]);
930
+ return updatedResource;
931
+ } catch (error$1) {
932
+ if (error$1.message?.includes("Commit conflict") && attempt < maxRetries - 1) {
933
+ const delay = Math.pow(2, attempt) * 10;
934
+ await new Promise((resolve) => setTimeout(resolve, delay));
935
+ continue;
936
+ }
937
+ throw new error.MastraError(
938
+ {
939
+ id: "LANCE_STORE_UPDATE_RESOURCE_FAILED",
940
+ domain: error.ErrorDomain.STORAGE,
941
+ category: error.ErrorCategory.THIRD_PARTY
942
+ },
943
+ error$1
944
+ );
945
+ }
946
+ }
947
+ throw new Error("Unexpected end of retry loop");
948
+ }
949
+ };
950
+ var StoreOperationsLance = class extends storage.StoreOperations {
951
+ client;
952
+ constructor({ client }) {
953
+ super();
954
+ this.client = client;
955
+ }
956
+ getDefaultValue(type) {
957
+ switch (type) {
958
+ case "text":
959
+ return "''";
960
+ case "timestamp":
961
+ return "CURRENT_TIMESTAMP";
962
+ case "integer":
963
+ case "bigint":
964
+ return "0";
965
+ case "jsonb":
966
+ return "'{}'";
967
+ case "uuid":
968
+ return "''";
969
+ default:
970
+ return super.getDefaultValue(type);
971
+ }
972
+ }
973
+ async hasColumn(tableName, columnName) {
974
+ const table = await this.client.openTable(tableName);
975
+ const schema = await table.schema();
976
+ return schema.fields.some((field) => field.name === columnName);
977
+ }
978
+ translateSchema(schema) {
979
+ const fields = Object.entries(schema).map(([name, column]) => {
980
+ let arrowType;
981
+ switch (column.type.toLowerCase()) {
982
+ case "text":
983
+ case "uuid":
984
+ arrowType = new apacheArrow.Utf8();
985
+ break;
986
+ case "int":
987
+ case "integer":
988
+ arrowType = new apacheArrow.Int32();
989
+ break;
990
+ case "bigint":
991
+ arrowType = new apacheArrow.Float64();
992
+ break;
993
+ case "float":
994
+ arrowType = new apacheArrow.Float32();
995
+ break;
996
+ case "jsonb":
997
+ case "json":
998
+ arrowType = new apacheArrow.Utf8();
999
+ break;
1000
+ case "binary":
1001
+ arrowType = new apacheArrow.Binary();
1002
+ break;
1003
+ case "timestamp":
1004
+ arrowType = new apacheArrow.Float64();
1005
+ break;
1006
+ default:
1007
+ arrowType = new apacheArrow.Utf8();
1008
+ }
1009
+ return new apacheArrow.Field(name, arrowType, column.nullable ?? true);
1010
+ });
1011
+ return new apacheArrow.Schema(fields);
1012
+ }
1013
+ async createTable({
1014
+ tableName,
1015
+ schema
1016
+ }) {
1017
+ try {
1018
+ if (!this.client) {
1019
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
1020
+ }
1021
+ if (!tableName) {
1022
+ throw new Error("tableName is required for createTable.");
1023
+ }
1024
+ if (!schema) {
1025
+ throw new Error("schema is required for createTable.");
1026
+ }
1027
+ } catch (error$1) {
1028
+ throw new error.MastraError(
1029
+ {
1030
+ id: "STORAGE_LANCE_STORAGE_CREATE_TABLE_INVALID_ARGS",
1031
+ domain: error.ErrorDomain.STORAGE,
1032
+ category: error.ErrorCategory.USER,
1033
+ details: { tableName }
1034
+ },
1035
+ error$1
1036
+ );
1037
+ }
1038
+ try {
1039
+ const arrowSchema = this.translateSchema(schema);
1040
+ await this.client.createEmptyTable(tableName, arrowSchema);
1041
+ } catch (error$1) {
1042
+ if (error$1.message?.includes("already exists")) {
1043
+ this.logger.debug(`Table '${tableName}' already exists, skipping create`);
1044
+ return;
1045
+ }
1046
+ throw new error.MastraError(
1047
+ {
1048
+ id: "STORAGE_LANCE_STORAGE_CREATE_TABLE_FAILED",
1049
+ domain: error.ErrorDomain.STORAGE,
1050
+ category: error.ErrorCategory.THIRD_PARTY,
1051
+ details: { tableName }
1052
+ },
1053
+ error$1
1054
+ );
1055
+ }
1056
+ }
1057
+ async dropTable({ tableName }) {
1058
+ try {
1059
+ if (!this.client) {
1060
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
1061
+ }
1062
+ if (!tableName) {
1063
+ throw new Error("tableName is required for dropTable.");
1064
+ }
1065
+ } catch (validationError) {
1066
+ throw new error.MastraError(
1067
+ {
1068
+ id: "STORAGE_LANCE_STORAGE_DROP_TABLE_INVALID_ARGS",
1069
+ domain: error.ErrorDomain.STORAGE,
1070
+ category: error.ErrorCategory.USER,
1071
+ text: validationError.message,
1072
+ details: { tableName }
1073
+ },
1074
+ validationError
1075
+ );
1076
+ }
1077
+ try {
1078
+ await this.client.dropTable(tableName);
1079
+ } catch (error$1) {
1080
+ if (error$1.toString().includes("was not found") || error$1.message?.includes("Table not found")) {
1081
+ this.logger.debug(`Table '${tableName}' does not exist, skipping drop`);
1082
+ return;
1083
+ }
1084
+ throw new error.MastraError(
1085
+ {
1086
+ id: "STORAGE_LANCE_STORAGE_DROP_TABLE_FAILED",
1087
+ domain: error.ErrorDomain.STORAGE,
1088
+ category: error.ErrorCategory.THIRD_PARTY,
1089
+ details: { tableName }
1090
+ },
1091
+ error$1
1092
+ );
1093
+ }
1094
+ }
1095
+ async alterTable({
1096
+ tableName,
1097
+ schema,
1098
+ ifNotExists
1099
+ }) {
1100
+ try {
1101
+ if (!this.client) {
1102
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
1103
+ }
1104
+ if (!tableName) {
1105
+ throw new Error("tableName is required for alterTable.");
1106
+ }
1107
+ if (!schema) {
1108
+ throw new Error("schema is required for alterTable.");
1109
+ }
1110
+ if (!ifNotExists || ifNotExists.length === 0) {
1111
+ this.logger.debug("No columns specified to add in alterTable, skipping.");
1112
+ return;
1113
+ }
1114
+ } catch (validationError) {
1115
+ throw new error.MastraError(
1116
+ {
1117
+ id: "STORAGE_LANCE_STORAGE_ALTER_TABLE_INVALID_ARGS",
1118
+ domain: error.ErrorDomain.STORAGE,
1119
+ category: error.ErrorCategory.USER,
1120
+ text: validationError.message,
1121
+ details: { tableName }
1122
+ },
1123
+ validationError
1124
+ );
1125
+ }
1126
+ try {
1127
+ const table = await this.client.openTable(tableName);
1128
+ const currentSchema = await table.schema();
1129
+ const existingFields = new Set(currentSchema.fields.map((f) => f.name));
1130
+ const typeMap = {
1131
+ text: "string",
1132
+ integer: "int",
1133
+ bigint: "bigint",
1134
+ timestamp: "timestamp",
1135
+ jsonb: "string",
1136
+ uuid: "string"
1137
+ };
1138
+ const columnsToAdd = ifNotExists.filter((col) => schema[col] && !existingFields.has(col)).map((col) => {
1139
+ const colDef = schema[col];
1140
+ return {
1141
+ name: col,
1142
+ valueSql: colDef?.nullable ? `cast(NULL as ${typeMap[colDef.type ?? "text"]})` : `cast(${this.getDefaultValue(colDef?.type ?? "text")} as ${typeMap[colDef?.type ?? "text"]})`
1143
+ };
1144
+ });
1145
+ if (columnsToAdd.length > 0) {
1146
+ await table.addColumns(columnsToAdd);
1147
+ this.logger?.info?.(`Added columns [${columnsToAdd.map((c) => c.name).join(", ")}] to table ${tableName}`);
1148
+ }
1149
+ } catch (error$1) {
1150
+ throw new error.MastraError(
1151
+ {
1152
+ id: "STORAGE_LANCE_STORAGE_ALTER_TABLE_FAILED",
1153
+ domain: error.ErrorDomain.STORAGE,
1154
+ category: error.ErrorCategory.THIRD_PARTY,
1155
+ details: { tableName }
1156
+ },
1157
+ error$1
1158
+ );
1159
+ }
1160
+ }
1161
+ async clearTable({ tableName }) {
1162
+ try {
1163
+ if (!this.client) {
1164
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
1165
+ }
1166
+ if (!tableName) {
1167
+ throw new Error("tableName is required for clearTable.");
1168
+ }
1169
+ } catch (validationError) {
1170
+ throw new error.MastraError(
1171
+ {
1172
+ id: "STORAGE_LANCE_STORAGE_CLEAR_TABLE_INVALID_ARGS",
1173
+ domain: error.ErrorDomain.STORAGE,
1174
+ category: error.ErrorCategory.USER,
1175
+ text: validationError.message,
1176
+ details: { tableName }
1177
+ },
1178
+ validationError
1179
+ );
1180
+ }
1181
+ try {
1182
+ const table = await this.client.openTable(tableName);
1183
+ await table.delete("1=1");
1184
+ } catch (error$1) {
1185
+ throw new error.MastraError(
1186
+ {
1187
+ id: "STORAGE_LANCE_STORAGE_CLEAR_TABLE_FAILED",
1188
+ domain: error.ErrorDomain.STORAGE,
1189
+ category: error.ErrorCategory.THIRD_PARTY,
1190
+ details: { tableName }
1191
+ },
1192
+ error$1
1193
+ );
1194
+ }
1195
+ }
1196
+ async insert({ tableName, record }) {
1197
+ try {
1198
+ if (!this.client) {
1199
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
1200
+ }
1201
+ if (!tableName) {
1202
+ throw new Error("tableName is required for insert.");
1203
+ }
1204
+ if (!record || Object.keys(record).length === 0) {
1205
+ throw new Error("record is required and cannot be empty for insert.");
1206
+ }
1207
+ } catch (validationError) {
1208
+ throw new error.MastraError(
1209
+ {
1210
+ id: "STORAGE_LANCE_STORAGE_INSERT_INVALID_ARGS",
1211
+ domain: error.ErrorDomain.STORAGE,
1212
+ category: error.ErrorCategory.USER,
1213
+ text: validationError.message,
1214
+ details: { tableName }
1215
+ },
1216
+ validationError
1217
+ );
1218
+ }
1219
+ try {
1220
+ const table = await this.client.openTable(tableName);
1221
+ const primaryId = getPrimaryKeys(tableName);
1222
+ const processedRecord = { ...record };
1223
+ for (const key in processedRecord) {
1224
+ if (processedRecord[key] !== null && typeof processedRecord[key] === "object" && !(processedRecord[key] instanceof Date)) {
1225
+ this.logger.debug("Converting object to JSON string: ", processedRecord[key]);
1226
+ processedRecord[key] = JSON.stringify(processedRecord[key]);
1227
+ }
1228
+ }
1229
+ console.log(await table.schema());
1230
+ await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([processedRecord]);
1231
+ } catch (error$1) {
1232
+ throw new error.MastraError(
1233
+ {
1234
+ id: "STORAGE_LANCE_STORAGE_INSERT_FAILED",
1235
+ domain: error.ErrorDomain.STORAGE,
1236
+ category: error.ErrorCategory.THIRD_PARTY,
1237
+ details: { tableName }
1238
+ },
1239
+ error$1
1240
+ );
1241
+ }
1242
+ }
1243
+ async batchInsert({ tableName, records }) {
1244
+ try {
1245
+ if (!this.client) {
1246
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
1247
+ }
1248
+ if (!tableName) {
1249
+ throw new Error("tableName is required for batchInsert.");
1250
+ }
1251
+ if (!records || records.length === 0) {
1252
+ throw new Error("records array is required and cannot be empty for batchInsert.");
1253
+ }
1254
+ } catch (validationError) {
1255
+ throw new error.MastraError(
1256
+ {
1257
+ id: "STORAGE_LANCE_STORAGE_BATCH_INSERT_INVALID_ARGS",
1258
+ domain: error.ErrorDomain.STORAGE,
1259
+ category: error.ErrorCategory.USER,
1260
+ text: validationError.message,
1261
+ details: { tableName }
1262
+ },
1263
+ validationError
1264
+ );
1265
+ }
1266
+ try {
1267
+ const table = await this.client.openTable(tableName);
1268
+ const primaryId = getPrimaryKeys(tableName);
1269
+ const processedRecords = records.map((record) => {
1270
+ const processedRecord = { ...record };
1271
+ for (const key in processedRecord) {
1272
+ if (processedRecord[key] == null) continue;
1273
+ if (processedRecord[key] !== null && typeof processedRecord[key] === "object" && !(processedRecord[key] instanceof Date)) {
1274
+ processedRecord[key] = JSON.stringify(processedRecord[key]);
1275
+ }
1276
+ }
1277
+ return processedRecord;
1278
+ });
1279
+ console.log(processedRecords);
1280
+ await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(processedRecords);
1281
+ } catch (error$1) {
1282
+ throw new error.MastraError(
1283
+ {
1284
+ id: "STORAGE_LANCE_STORAGE_BATCH_INSERT_FAILED",
1285
+ domain: error.ErrorDomain.STORAGE,
1286
+ category: error.ErrorCategory.THIRD_PARTY,
1287
+ details: { tableName }
1288
+ },
1289
+ error$1
1290
+ );
1291
+ }
1292
+ }
1293
+ async load({ tableName, keys }) {
1294
+ try {
1295
+ if (!this.client) {
1296
+ throw new Error("LanceDB client not initialized. Call LanceStorage.create() first.");
1297
+ }
1298
+ if (!tableName) {
1299
+ throw new Error("tableName is required for load.");
1300
+ }
1301
+ if (!keys || Object.keys(keys).length === 0) {
1302
+ throw new Error("keys are required and cannot be empty for load.");
1303
+ }
1304
+ } catch (validationError) {
1305
+ throw new error.MastraError(
1306
+ {
1307
+ id: "STORAGE_LANCE_STORAGE_LOAD_INVALID_ARGS",
1308
+ domain: error.ErrorDomain.STORAGE,
1309
+ category: error.ErrorCategory.USER,
1310
+ text: validationError.message,
1311
+ details: { tableName }
1312
+ },
1313
+ validationError
1314
+ );
1315
+ }
1316
+ try {
1317
+ const table = await this.client.openTable(tableName);
1318
+ const tableSchema = await getTableSchema({ tableName, client: this.client });
1319
+ const query = table.query();
1320
+ if (Object.keys(keys).length > 0) {
1321
+ validateKeyTypes(keys, tableSchema);
1322
+ const filterConditions = Object.entries(keys).map(([key, value]) => {
1323
+ const isCamelCase = /^[a-z][a-zA-Z]*$/.test(key) && /[A-Z]/.test(key);
1324
+ const quotedKey = isCamelCase ? `\`${key}\`` : key;
1325
+ if (typeof value === "string") {
1326
+ return `${quotedKey} = '${value}'`;
1327
+ } else if (value === null) {
1328
+ return `${quotedKey} IS NULL`;
1329
+ } else {
1330
+ return `${quotedKey} = ${value}`;
1331
+ }
1332
+ }).join(" AND ");
1333
+ this.logger.debug("where clause generated: " + filterConditions);
1334
+ query.where(filterConditions);
1335
+ }
1336
+ const result = await query.limit(1).toArray();
1337
+ if (result.length === 0) {
1338
+ this.logger.debug("No record found");
1339
+ return null;
1340
+ }
1341
+ return processResultWithTypeConversion(result[0], tableSchema);
1342
+ } catch (error$1) {
1343
+ if (error$1 instanceof error.MastraError) throw error$1;
1344
+ throw new error.MastraError(
1345
+ {
1346
+ id: "STORAGE_LANCE_STORAGE_LOAD_FAILED",
1347
+ domain: error.ErrorDomain.STORAGE,
1348
+ category: error.ErrorCategory.THIRD_PARTY,
1349
+ details: { tableName, keyCount: Object.keys(keys).length, firstKey: Object.keys(keys)[0] ?? "" }
1350
+ },
1351
+ error$1
1352
+ );
1353
+ }
1354
+ }
1355
+ };
1356
+ var StoreScoresLance = class extends storage.ScoresStorage {
1357
+ client;
1358
+ constructor({ client }) {
1359
+ super();
1360
+ this.client = client;
1361
+ }
1362
+ async saveScore(score) {
1363
+ try {
1364
+ const table = await this.client.openTable(storage.TABLE_SCORERS);
1365
+ const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1366
+ const allowedFields = new Set(schema.fields.map((f) => f.name));
1367
+ const filteredScore = {};
1368
+ Object.keys(score).forEach((key) => {
1369
+ if (allowedFields.has(key)) {
1370
+ filteredScore[key] = score[key];
1371
+ }
1372
+ });
1373
+ for (const key in filteredScore) {
1374
+ if (filteredScore[key] !== null && typeof filteredScore[key] === "object" && !(filteredScore[key] instanceof Date)) {
1375
+ filteredScore[key] = JSON.stringify(filteredScore[key]);
1376
+ }
1377
+ }
1378
+ console.log("Saving score to LanceStorage:", filteredScore);
1379
+ await table.add([filteredScore], { mode: "append" });
1380
+ return { score };
1381
+ } catch (error$1) {
1382
+ throw new error.MastraError(
1383
+ {
1384
+ id: "LANCE_STORAGE_SAVE_SCORE_FAILED",
1385
+ text: "Failed to save score in LanceStorage",
1386
+ domain: error.ErrorDomain.STORAGE,
1387
+ category: error.ErrorCategory.THIRD_PARTY,
1388
+ details: { error: error$1?.message }
1389
+ },
1390
+ error$1
1391
+ );
1392
+ }
1393
+ }
1394
+ async getScoreById({ id }) {
1395
+ try {
1396
+ const table = await this.client.openTable(storage.TABLE_SCORERS);
1397
+ const query = table.query().where(`id = '${id}'`).limit(1);
1398
+ const records = await query.toArray();
1399
+ if (records.length === 0) return null;
1400
+ const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1401
+ return processResultWithTypeConversion(records[0], schema);
1402
+ } catch (error$1) {
1403
+ throw new error.MastraError(
1404
+ {
1405
+ id: "LANCE_STORAGE_GET_SCORE_BY_ID_FAILED",
1406
+ text: "Failed to get score by id in LanceStorage",
1407
+ domain: error.ErrorDomain.STORAGE,
1408
+ category: error.ErrorCategory.THIRD_PARTY,
1409
+ details: { error: error$1?.message }
1410
+ },
1411
+ error$1
1412
+ );
1413
+ }
1414
+ }
1415
+ async getScoresByScorerId({
1416
+ scorerId,
1417
+ pagination
1418
+ }) {
1419
+ try {
1420
+ const table = await this.client.openTable(storage.TABLE_SCORERS);
1421
+ const { page = 0, perPage = 10 } = pagination || {};
1422
+ const offset = page * perPage;
1423
+ const query = table.query().where(`\`scorerId\` = '${scorerId}'`).limit(perPage);
1424
+ if (offset > 0) query.offset(offset);
1425
+ const records = await query.toArray();
1426
+ const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1427
+ const scores = processResultWithTypeConversion(records, schema);
1428
+ const allRecords = await table.query().where(`\`scorerId\` = '${scorerId}'`).toArray();
1429
+ const total = allRecords.length;
1430
+ return {
1431
+ pagination: {
1432
+ page,
1433
+ perPage,
1434
+ total,
1435
+ hasMore: offset + scores.length < total
1436
+ },
1437
+ scores
1438
+ };
1439
+ } catch (error$1) {
1440
+ throw new error.MastraError(
1441
+ {
1442
+ id: "LANCE_STORAGE_GET_SCORES_BY_SCORER_ID_FAILED",
1443
+ text: "Failed to get scores by scorerId in LanceStorage",
1444
+ domain: error.ErrorDomain.STORAGE,
1445
+ category: error.ErrorCategory.THIRD_PARTY,
1446
+ details: { error: error$1?.message }
1447
+ },
1448
+ error$1
1449
+ );
1450
+ }
1451
+ }
1452
+ async getScoresByRunId({
1453
+ runId,
1454
+ pagination
1455
+ }) {
1456
+ try {
1457
+ const table = await this.client.openTable(storage.TABLE_SCORERS);
1458
+ const { page = 0, perPage = 10 } = pagination || {};
1459
+ const offset = page * perPage;
1460
+ const query = table.query().where(`\`runId\` = '${runId}'`).limit(perPage);
1461
+ if (offset > 0) query.offset(offset);
1462
+ const records = await query.toArray();
1463
+ const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1464
+ const scores = processResultWithTypeConversion(records, schema);
1465
+ const allRecords = await table.query().where(`\`runId\` = '${runId}'`).toArray();
1466
+ const total = allRecords.length;
1467
+ return {
1468
+ pagination: {
1469
+ page,
1470
+ perPage,
1471
+ total,
1472
+ hasMore: offset + scores.length < total
1473
+ },
1474
+ scores
1475
+ };
1476
+ } catch (error$1) {
1477
+ throw new error.MastraError(
1478
+ {
1479
+ id: "LANCE_STORAGE_GET_SCORES_BY_RUN_ID_FAILED",
1480
+ text: "Failed to get scores by runId in LanceStorage",
1481
+ domain: error.ErrorDomain.STORAGE,
1482
+ category: error.ErrorCategory.THIRD_PARTY,
1483
+ details: { error: error$1?.message }
1484
+ },
1485
+ error$1
1486
+ );
1487
+ }
1488
+ }
1489
+ async getScoresByEntityId({
1490
+ entityId,
1491
+ entityType,
1492
+ pagination
1493
+ }) {
1494
+ try {
1495
+ const table = await this.client.openTable(storage.TABLE_SCORERS);
1496
+ const { page = 0, perPage = 10 } = pagination || {};
1497
+ const offset = page * perPage;
1498
+ const query = table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).limit(perPage);
1499
+ if (offset > 0) query.offset(offset);
1500
+ const records = await query.toArray();
1501
+ const schema = await getTableSchema({ tableName: storage.TABLE_SCORERS, client: this.client });
1502
+ const scores = processResultWithTypeConversion(records, schema);
1503
+ const allRecords = await table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).toArray();
1504
+ const total = allRecords.length;
1505
+ return {
1506
+ pagination: {
1507
+ page,
1508
+ perPage,
1509
+ total,
1510
+ hasMore: offset + scores.length < total
1511
+ },
1512
+ scores
1513
+ };
1514
+ } catch (error$1) {
1515
+ throw new error.MastraError(
1516
+ {
1517
+ id: "LANCE_STORAGE_GET_SCORES_BY_ENTITY_ID_FAILED",
1518
+ text: "Failed to get scores by entityId and entityType in LanceStorage",
1519
+ domain: error.ErrorDomain.STORAGE,
1520
+ category: error.ErrorCategory.THIRD_PARTY,
1521
+ details: { error: error$1?.message }
1522
+ },
1523
+ error$1
1524
+ );
1525
+ }
1526
+ }
1527
+ };
1528
+ var StoreTracesLance = class extends storage.TracesStorage {
1529
+ client;
1530
+ operations;
1531
+ constructor({ client, operations }) {
1532
+ super();
1533
+ this.client = client;
1534
+ this.operations = operations;
1535
+ }
1536
+ async saveTrace({ trace }) {
1537
+ try {
1538
+ const table = await this.client.openTable(storage.TABLE_TRACES);
1539
+ const record = {
1540
+ ...trace,
1541
+ attributes: JSON.stringify(trace.attributes),
1542
+ status: JSON.stringify(trace.status),
1543
+ events: JSON.stringify(trace.events),
1544
+ links: JSON.stringify(trace.links),
1545
+ other: JSON.stringify(trace.other)
1546
+ };
1547
+ await table.add([record], { mode: "append" });
1548
+ return trace;
1549
+ } catch (error$1) {
1550
+ throw new error.MastraError(
1551
+ {
1552
+ id: "LANCE_STORE_SAVE_TRACE_FAILED",
1553
+ domain: error.ErrorDomain.STORAGE,
1554
+ category: error.ErrorCategory.THIRD_PARTY
1555
+ },
1556
+ error$1
1557
+ );
1558
+ }
1559
+ }
1560
+ async getTraceById({ traceId }) {
1561
+ try {
1562
+ const table = await this.client.openTable(storage.TABLE_TRACES);
1563
+ const query = table.query().where(`id = '${traceId}'`);
1564
+ const records = await query.toArray();
1565
+ return records[0];
1566
+ } catch (error$1) {
1567
+ throw new error.MastraError(
1568
+ {
1569
+ id: "LANCE_STORE_GET_TRACE_BY_ID_FAILED",
1570
+ domain: error.ErrorDomain.STORAGE,
1571
+ category: error.ErrorCategory.THIRD_PARTY
1572
+ },
1573
+ error$1
1574
+ );
1575
+ }
1576
+ }
1577
+ async getTraces({
1578
+ name,
1579
+ scope,
1580
+ page = 1,
1581
+ perPage = 10,
1582
+ attributes
1583
+ }) {
1584
+ try {
1585
+ const table = await this.client.openTable(storage.TABLE_TRACES);
1586
+ const query = table.query();
1587
+ if (name) {
1588
+ query.where(`name = '${name}'`);
1589
+ }
1590
+ if (scope) {
1591
+ query.where(`scope = '${scope}'`);
1592
+ }
1593
+ if (attributes) {
1594
+ query.where(`attributes = '${JSON.stringify(attributes)}'`);
1595
+ }
1596
+ const offset = (page - 1) * perPage;
1597
+ query.limit(perPage);
1598
+ if (offset > 0) {
1599
+ query.offset(offset);
1600
+ }
1601
+ const records = await query.toArray();
1602
+ return records.map((record) => {
1603
+ const processed = {
1604
+ ...record,
1605
+ attributes: record.attributes ? JSON.parse(record.attributes) : {},
1606
+ status: record.status ? JSON.parse(record.status) : {},
1607
+ events: record.events ? JSON.parse(record.events) : [],
1608
+ links: record.links ? JSON.parse(record.links) : [],
1609
+ other: record.other ? JSON.parse(record.other) : {},
1610
+ startTime: new Date(record.startTime),
1611
+ endTime: new Date(record.endTime),
1612
+ createdAt: new Date(record.createdAt)
1613
+ };
1614
+ if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
1615
+ processed.parentSpanId = "";
1616
+ } else {
1617
+ processed.parentSpanId = String(processed.parentSpanId);
1618
+ }
1619
+ return processed;
1620
+ });
1621
+ } catch (error$1) {
1622
+ throw new error.MastraError(
1623
+ {
1624
+ id: "LANCE_STORE_GET_TRACES_FAILED",
1625
+ domain: error.ErrorDomain.STORAGE,
1626
+ category: error.ErrorCategory.THIRD_PARTY,
1627
+ details: { name: name ?? "", scope: scope ?? "" }
1628
+ },
1629
+ error$1
1630
+ );
1631
+ }
1632
+ }
1633
+ async getTracesPaginated(args) {
1634
+ try {
1635
+ const table = await this.client.openTable(storage.TABLE_TRACES);
1636
+ const query = table.query();
1637
+ const conditions = [];
1638
+ if (args.name) {
1639
+ conditions.push(`name = '${args.name}'`);
1640
+ }
1641
+ if (args.scope) {
1642
+ conditions.push(`scope = '${args.scope}'`);
1643
+ }
1644
+ if (args.attributes) {
1645
+ const attributesStr = JSON.stringify(args.attributes);
1646
+ conditions.push(`attributes LIKE '%${attributesStr.replace(/"/g, '\\"')}%'`);
1647
+ }
1648
+ if (args.dateRange?.start) {
1649
+ conditions.push(`\`createdAt\` >= ${args.dateRange.start.getTime()}`);
1650
+ }
1651
+ if (args.dateRange?.end) {
1652
+ conditions.push(`\`createdAt\` <= ${args.dateRange.end.getTime()}`);
1653
+ }
1654
+ if (conditions.length > 0) {
1655
+ const whereClause = conditions.join(" AND ");
1656
+ query.where(whereClause);
1657
+ }
1658
+ let total = 0;
1659
+ if (conditions.length > 0) {
1660
+ const countQuery = table.query().where(conditions.join(" AND "));
1661
+ const allRecords = await countQuery.toArray();
1662
+ total = allRecords.length;
1663
+ } else {
1664
+ total = await table.countRows();
1665
+ }
1666
+ const page = args.page || 0;
1667
+ const perPage = args.perPage || 10;
1668
+ const offset = page * perPage;
1669
+ query.limit(perPage);
1670
+ if (offset > 0) {
1671
+ query.offset(offset);
1672
+ }
1673
+ const records = await query.toArray();
1674
+ const traces = records.map((record) => {
1675
+ const processed = {
1676
+ ...record,
1677
+ attributes: record.attributes ? JSON.parse(record.attributes) : {},
1678
+ status: record.status ? JSON.parse(record.status) : {},
1679
+ events: record.events ? JSON.parse(record.events) : [],
1680
+ links: record.links ? JSON.parse(record.links) : [],
1681
+ other: record.other ? JSON.parse(record.other) : {},
1682
+ startTime: new Date(record.startTime),
1683
+ endTime: new Date(record.endTime),
1684
+ createdAt: new Date(record.createdAt)
1685
+ };
1686
+ if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
1687
+ processed.parentSpanId = "";
1688
+ } else {
1689
+ processed.parentSpanId = String(processed.parentSpanId);
1690
+ }
1691
+ return processed;
1692
+ });
1693
+ return {
1694
+ traces,
1695
+ total,
1696
+ page,
1697
+ perPage,
1698
+ hasMore: total > (page + 1) * perPage
1699
+ };
1700
+ } catch (error$1) {
1701
+ throw new error.MastraError(
1702
+ {
1703
+ id: "LANCE_STORE_GET_TRACES_PAGINATED_FAILED",
1704
+ domain: error.ErrorDomain.STORAGE,
1705
+ category: error.ErrorCategory.THIRD_PARTY,
1706
+ details: { name: args.name ?? "", scope: args.scope ?? "" }
1707
+ },
1708
+ error$1
1709
+ );
1710
+ }
1711
+ }
1712
+ async batchTraceInsert({ records }) {
1713
+ this.logger.debug("Batch inserting traces", { count: records.length });
1714
+ await this.operations.batchInsert({
1715
+ tableName: storage.TABLE_TRACES,
1716
+ records
1717
+ });
1718
+ }
1719
+ };
1720
+ function parseWorkflowRun(row) {
1721
+ let parsedSnapshot = row.snapshot;
1722
+ if (typeof parsedSnapshot === "string") {
1723
+ try {
1724
+ parsedSnapshot = JSON.parse(row.snapshot);
1725
+ } catch (e) {
1726
+ console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
1727
+ }
1728
+ }
1729
+ return {
1730
+ workflowName: row.workflow_name,
1731
+ runId: row.run_id,
1732
+ snapshot: parsedSnapshot,
1733
+ createdAt: storage.ensureDate(row.createdAt),
1734
+ updatedAt: storage.ensureDate(row.updatedAt),
1735
+ resourceId: row.resourceId
1736
+ };
1737
+ }
1738
+ var StoreWorkflowsLance = class extends storage.WorkflowsStorage {
1739
+ client;
1740
+ constructor({ client }) {
1741
+ super();
1742
+ this.client = client;
1743
+ }
1744
+ async persistWorkflowSnapshot({
1745
+ workflowName,
1746
+ runId,
1747
+ snapshot
1748
+ }) {
1749
+ try {
1750
+ const table = await this.client.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
1751
+ const query = table.query().where(`workflow_name = '${workflowName}' AND run_id = '${runId}'`);
1752
+ const records = await query.toArray();
1753
+ let createdAt;
1754
+ const now = Date.now();
1755
+ if (records.length > 0) {
1756
+ createdAt = records[0].createdAt ?? now;
1757
+ } else {
1758
+ createdAt = now;
1759
+ }
1760
+ const record = {
1761
+ workflow_name: workflowName,
1762
+ run_id: runId,
1763
+ snapshot: JSON.stringify(snapshot),
1764
+ createdAt,
1765
+ updatedAt: now
1766
+ };
1767
+ await table.mergeInsert(["workflow_name", "run_id"]).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([record]);
1768
+ } catch (error$1) {
1769
+ throw new error.MastraError(
1770
+ {
1771
+ id: "LANCE_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
1772
+ domain: error.ErrorDomain.STORAGE,
1773
+ category: error.ErrorCategory.THIRD_PARTY,
1774
+ details: { workflowName, runId }
1775
+ },
1776
+ error$1
1777
+ );
1778
+ }
1779
+ }
1780
+ async loadWorkflowSnapshot({
1781
+ workflowName,
1782
+ runId
1783
+ }) {
1784
+ try {
1785
+ const table = await this.client.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
1786
+ const query = table.query().where(`workflow_name = '${workflowName}' AND run_id = '${runId}'`);
1787
+ const records = await query.toArray();
1788
+ return records.length > 0 ? JSON.parse(records[0].snapshot) : null;
1789
+ } catch (error$1) {
1790
+ throw new error.MastraError(
1791
+ {
1792
+ id: "LANCE_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
1793
+ domain: error.ErrorDomain.STORAGE,
1794
+ category: error.ErrorCategory.THIRD_PARTY,
1795
+ details: { workflowName, runId }
1796
+ },
1797
+ error$1
1798
+ );
1799
+ }
1800
+ }
1801
+ async getWorkflowRunById(args) {
1802
+ try {
1803
+ const table = await this.client.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
1804
+ let whereClause = `run_id = '${args.runId}'`;
1805
+ if (args.workflowName) {
1806
+ whereClause += ` AND workflow_name = '${args.workflowName}'`;
1807
+ }
1808
+ const query = table.query().where(whereClause);
1809
+ const records = await query.toArray();
1810
+ if (records.length === 0) return null;
1811
+ const record = records[0];
1812
+ return parseWorkflowRun(record);
1813
+ } catch (error$1) {
1814
+ throw new error.MastraError(
1815
+ {
1816
+ id: "LANCE_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
1817
+ domain: error.ErrorDomain.STORAGE,
1818
+ category: error.ErrorCategory.THIRD_PARTY,
1819
+ details: { runId: args.runId, workflowName: args.workflowName ?? "" }
1820
+ },
1821
+ error$1
1822
+ );
1823
+ }
1824
+ }
1825
+ async getWorkflowRuns(args) {
1826
+ try {
1827
+ const table = await this.client.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
1828
+ let query = table.query();
1829
+ const conditions = [];
1830
+ if (args?.workflowName) {
1831
+ conditions.push(`workflow_name = '${args.workflowName.replace(/'/g, "''")}'`);
1832
+ }
1833
+ if (args?.resourceId) {
1834
+ conditions.push(`\`resourceId\` = '${args.resourceId}'`);
1835
+ }
1836
+ if (args?.fromDate instanceof Date) {
1837
+ conditions.push(`\`createdAt\` >= ${args.fromDate.getTime()}`);
1838
+ }
1839
+ if (args?.toDate instanceof Date) {
1840
+ conditions.push(`\`createdAt\` <= ${args.toDate.getTime()}`);
1841
+ }
1842
+ let total = 0;
1843
+ if (conditions.length > 0) {
1844
+ query = query.where(conditions.join(" AND "));
1845
+ total = await table.countRows(conditions.join(" AND "));
1846
+ } else {
1847
+ total = await table.countRows();
1848
+ }
1849
+ if (args?.limit) {
1850
+ query.limit(args.limit);
1851
+ }
1852
+ if (args?.offset) {
1853
+ query.offset(args.offset);
1854
+ }
1855
+ const records = await query.toArray();
1856
+ return {
1857
+ runs: records.map((record) => parseWorkflowRun(record)),
1858
+ total: total || records.length
1859
+ };
1860
+ } catch (error$1) {
1861
+ throw new error.MastraError(
1862
+ {
1863
+ id: "LANCE_STORE_GET_WORKFLOW_RUNS_FAILED",
1864
+ domain: error.ErrorDomain.STORAGE,
1865
+ category: error.ErrorCategory.THIRD_PARTY,
1866
+ details: { namespace: args?.namespace ?? "", workflowName: args?.workflowName ?? "" }
1867
+ },
1868
+ error$1
1869
+ );
1870
+ }
1871
+ }
1872
+ };
1873
+
10
1874
  // src/storage/index.ts
11
1875
  var LanceStorage = class _LanceStorage extends storage.MastraStorage {
1876
+ stores;
12
1877
  lanceClient;
13
1878
  /**
14
1879
  * Creates a new instance of LanceStorage
@@ -36,9 +1901,27 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
36
1901
  const instance = new _LanceStorage(name);
37
1902
  try {
38
1903
  instance.lanceClient = await lancedb.connect(uri, options);
1904
+ const operations = new StoreOperationsLance({ client: instance.lanceClient });
1905
+ instance.stores = {
1906
+ operations: new StoreOperationsLance({ client: instance.lanceClient }),
1907
+ workflows: new StoreWorkflowsLance({ client: instance.lanceClient }),
1908
+ traces: new StoreTracesLance({ client: instance.lanceClient, operations }),
1909
+ scores: new StoreScoresLance({ client: instance.lanceClient }),
1910
+ memory: new StoreMemoryLance({ client: instance.lanceClient, operations }),
1911
+ legacyEvals: new StoreLegacyEvalsLance({ client: instance.lanceClient })
1912
+ };
39
1913
  return instance;
40
1914
  } catch (e) {
41
- throw new Error(`Failed to connect to LanceDB: ${e}`);
1915
+ throw new error.MastraError(
1916
+ {
1917
+ id: "STORAGE_LANCE_STORAGE_CONNECT_FAILED",
1918
+ domain: error.ErrorDomain.STORAGE,
1919
+ category: error.ErrorCategory.THIRD_PARTY,
1920
+ text: `Failed to connect to LanceDB: ${e.message || e}`,
1921
+ details: { uri, optionsProvided: !!options }
1922
+ },
1923
+ e
1924
+ );
42
1925
  }
43
1926
  }
44
1927
  /**
@@ -47,312 +1930,49 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
47
1930
  */
48
1931
  constructor(name) {
49
1932
  super({ name });
1933
+ const operations = new StoreOperationsLance({ client: this.lanceClient });
1934
+ this.stores = {
1935
+ operations: new StoreOperationsLance({ client: this.lanceClient }),
1936
+ workflows: new StoreWorkflowsLance({ client: this.lanceClient }),
1937
+ traces: new StoreTracesLance({ client: this.lanceClient, operations }),
1938
+ scores: new StoreScoresLance({ client: this.lanceClient }),
1939
+ legacyEvals: new StoreLegacyEvalsLance({ client: this.lanceClient }),
1940
+ memory: new StoreMemoryLance({ client: this.lanceClient, operations })
1941
+ };
50
1942
  }
51
1943
  async createTable({
52
1944
  tableName,
53
1945
  schema
54
1946
  }) {
55
- try {
56
- const arrowSchema = this.translateSchema(schema);
57
- await this.lanceClient.createEmptyTable(tableName, arrowSchema);
58
- } catch (error) {
59
- throw new Error(`Failed to create table: ${error}`);
60
- }
61
- }
62
- translateSchema(schema) {
63
- const fields = Object.entries(schema).map(([name, column]) => {
64
- let arrowType;
65
- switch (column.type.toLowerCase()) {
66
- case "text":
67
- case "uuid":
68
- arrowType = new apacheArrow.Utf8();
69
- break;
70
- case "int":
71
- case "integer":
72
- arrowType = new apacheArrow.Int32();
73
- break;
74
- case "bigint":
75
- arrowType = new apacheArrow.Float64();
76
- break;
77
- case "float":
78
- arrowType = new apacheArrow.Float32();
79
- break;
80
- case "jsonb":
81
- case "json":
82
- arrowType = new apacheArrow.Utf8();
83
- break;
84
- case "binary":
85
- arrowType = new apacheArrow.Binary();
86
- break;
87
- case "timestamp":
88
- arrowType = new apacheArrow.Float64();
89
- break;
90
- default:
91
- arrowType = new apacheArrow.Utf8();
92
- }
93
- return new apacheArrow.Field(name, arrowType, column.nullable ?? true);
94
- });
95
- return new apacheArrow.Schema(fields);
96
- }
97
- /**
98
- * Drop a table if it exists
99
- * @param tableName Name of the table to drop
100
- */
101
- async dropTable(tableName) {
102
- try {
103
- await this.lanceClient.dropTable(tableName);
104
- } catch (error) {
105
- if (error.toString().includes("was not found")) {
106
- this.logger.debug(`Table '${tableName}' does not exist, skipping drop`);
107
- return;
108
- }
109
- throw new Error(`Failed to drop table: ${error}`);
110
- }
111
- }
112
- /**
113
- * Get table schema
114
- * @param tableName Name of the table
115
- * @returns Table schema
116
- */
117
- async getTableSchema(tableName) {
118
- try {
119
- const table = await this.lanceClient.openTable(tableName);
120
- const rawSchema = await table.schema();
121
- const fields = rawSchema.fields;
122
- return {
123
- fields,
124
- metadata: /* @__PURE__ */ new Map(),
125
- get names() {
126
- return fields.map((field) => field.name);
127
- }
128
- };
129
- } catch (error) {
130
- throw new Error(`Failed to get table schema: ${error}`);
131
- }
1947
+ return this.stores.operations.createTable({ tableName, schema });
132
1948
  }
133
- getDefaultValue(type) {
134
- switch (type) {
135
- case "text":
136
- return "''";
137
- case "timestamp":
138
- return "CURRENT_TIMESTAMP";
139
- case "integer":
140
- case "bigint":
141
- return "0";
142
- case "jsonb":
143
- return "'{}'";
144
- case "uuid":
145
- return "''";
146
- default:
147
- return super.getDefaultValue(type);
148
- }
1949
+ async dropTable({ tableName }) {
1950
+ return this.stores.operations.dropTable({ tableName });
149
1951
  }
150
- /**
151
- * Alters table schema to add columns if they don't exist
152
- * @param tableName Name of the table
153
- * @param schema Schema of the table
154
- * @param ifNotExists Array of column names to add if they don't exist
155
- */
156
1952
  async alterTable({
157
1953
  tableName,
158
1954
  schema,
159
1955
  ifNotExists
160
1956
  }) {
161
- const table = await this.lanceClient.openTable(tableName);
162
- const currentSchema = await table.schema();
163
- const existingFields = new Set(currentSchema.fields.map((f) => f.name));
164
- const typeMap = {
165
- text: "string",
166
- integer: "int",
167
- bigint: "bigint",
168
- timestamp: "timestamp",
169
- jsonb: "string",
170
- uuid: "string"
171
- };
172
- const columnsToAdd = ifNotExists.filter((col) => schema[col] && !existingFields.has(col)).map((col) => {
173
- const colDef = schema[col];
174
- return {
175
- name: col,
176
- valueSql: colDef?.nullable ? `cast(NULL as ${typeMap[colDef.type ?? "text"]})` : `cast(${this.getDefaultValue(colDef?.type ?? "text")} as ${typeMap[colDef?.type ?? "text"]})`
177
- };
178
- });
179
- if (columnsToAdd.length > 0) {
180
- await table.addColumns(columnsToAdd);
181
- this.logger?.info?.(`Added columns [${columnsToAdd.map((c) => c.name).join(", ")}] to table ${tableName}`);
182
- }
1957
+ return this.stores.operations.alterTable({ tableName, schema, ifNotExists });
183
1958
  }
184
1959
  async clearTable({ tableName }) {
185
- const table = await this.lanceClient.openTable(tableName);
186
- await table.delete("1=1");
1960
+ return this.stores.operations.clearTable({ tableName });
187
1961
  }
188
- /**
189
- * Insert a single record into a table. This function overwrites the existing record if it exists. Use this function for inserting records into tables with custom schemas.
190
- * @param tableName The name of the table to insert into.
191
- * @param record The record to insert.
192
- */
193
1962
  async insert({ tableName, record }) {
194
- try {
195
- const table = await this.lanceClient.openTable(tableName);
196
- const processedRecord = { ...record };
197
- for (const key in processedRecord) {
198
- if (processedRecord[key] !== null && typeof processedRecord[key] === "object" && !(processedRecord[key] instanceof Date)) {
199
- this.logger.debug("Converting object to JSON string: ", processedRecord[key]);
200
- processedRecord[key] = JSON.stringify(processedRecord[key]);
201
- }
202
- }
203
- await table.add([processedRecord], { mode: "overwrite" });
204
- } catch (error) {
205
- throw new Error(`Failed to insert record: ${error}`);
206
- }
1963
+ return this.stores.operations.insert({ tableName, record });
207
1964
  }
208
- /**
209
- * Insert multiple records into a table. This function overwrites the existing records if they exist. Use this function for inserting records into tables with custom schemas.
210
- * @param tableName The name of the table to insert into.
211
- * @param records The records to insert.
212
- */
213
1965
  async batchInsert({ tableName, records }) {
214
- try {
215
- const table = await this.lanceClient.openTable(tableName);
216
- const processedRecords = records.map((record) => {
217
- const processedRecord = { ...record };
218
- for (const key in processedRecord) {
219
- if (processedRecord[key] == null) continue;
220
- if (processedRecord[key] !== null && typeof processedRecord[key] === "object" && !(processedRecord[key] instanceof Date)) {
221
- processedRecord[key] = JSON.stringify(processedRecord[key]);
222
- }
223
- }
224
- return processedRecord;
225
- });
226
- await table.add(processedRecords, { mode: "overwrite" });
227
- } catch (error) {
228
- throw new Error(`Failed to batch insert records: ${error}`);
229
- }
1966
+ return this.stores.operations.batchInsert({ tableName, records });
230
1967
  }
231
- /**
232
- * Load a record from the database by its key(s)
233
- * @param tableName The name of the table to query
234
- * @param keys Record of key-value pairs to use for lookup
235
- * @throws Error if invalid types are provided for keys
236
- * @returns The loaded record with proper type conversions, or null if not found
237
- */
238
1968
  async load({ tableName, keys }) {
239
- try {
240
- const table = await this.lanceClient.openTable(tableName);
241
- const tableSchema = await this.getTableSchema(tableName);
242
- const query = table.query();
243
- if (Object.keys(keys).length > 0) {
244
- this.validateKeyTypes(keys, tableSchema);
245
- const filterConditions = Object.entries(keys).map(([key, value]) => {
246
- const isCamelCase = /^[a-z][a-zA-Z]*$/.test(key) && /[A-Z]/.test(key);
247
- const quotedKey = isCamelCase ? `\`${key}\`` : key;
248
- if (typeof value === "string") {
249
- return `${quotedKey} = '${value}'`;
250
- } else if (value === null) {
251
- return `${quotedKey} IS NULL`;
252
- } else {
253
- return `${quotedKey} = ${value}`;
254
- }
255
- }).join(" AND ");
256
- this.logger.debug("where clause generated: " + filterConditions);
257
- query.where(filterConditions);
258
- }
259
- const result = await query.limit(1).toArray();
260
- if (result.length === 0) {
261
- this.logger.debug("No record found");
262
- return null;
263
- }
264
- return this.processResultWithTypeConversion(result[0], tableSchema);
265
- } catch (error) {
266
- throw new Error(`Failed to load record: ${error}`);
267
- }
268
- }
269
- /**
270
- * Validates that key types match the schema definition
271
- * @param keys The keys to validate
272
- * @param tableSchema The table schema to validate against
273
- * @throws Error if a key has an incompatible type
274
- */
275
- validateKeyTypes(keys, tableSchema) {
276
- const fieldTypes = new Map(
277
- tableSchema.fields.map((field) => [field.name, field.type?.toString().toLowerCase()])
278
- );
279
- for (const [key, value] of Object.entries(keys)) {
280
- const fieldType = fieldTypes.get(key);
281
- if (!fieldType) {
282
- throw new Error(`Field '${key}' does not exist in table schema`);
283
- }
284
- if (value !== null) {
285
- if ((fieldType.includes("int") || fieldType.includes("bigint")) && typeof value !== "number") {
286
- throw new Error(`Expected numeric value for field '${key}', got ${typeof value}`);
287
- }
288
- if (fieldType.includes("utf8") && typeof value !== "string") {
289
- throw new Error(`Expected string value for field '${key}', got ${typeof value}`);
290
- }
291
- if (fieldType.includes("timestamp") && !(value instanceof Date) && typeof value !== "string") {
292
- throw new Error(`Expected Date or string value for field '${key}', got ${typeof value}`);
293
- }
294
- }
295
- }
296
- }
297
- /**
298
- * Process a database result with appropriate type conversions based on the table schema
299
- * @param rawResult The raw result object from the database
300
- * @param tableSchema The schema of the table containing type information
301
- * @returns Processed result with correct data types
302
- */
303
- processResultWithTypeConversion(rawResult, tableSchema) {
304
- const fieldTypeMap = /* @__PURE__ */ new Map();
305
- tableSchema.fields.forEach((field) => {
306
- const fieldName = field.name;
307
- const fieldTypeStr = field.type.toString().toLowerCase();
308
- fieldTypeMap.set(fieldName, fieldTypeStr);
309
- });
310
- if (Array.isArray(rawResult)) {
311
- return rawResult.map((item) => this.processResultWithTypeConversion(item, tableSchema));
312
- }
313
- const processedResult = { ...rawResult };
314
- for (const key in processedResult) {
315
- const fieldTypeStr = fieldTypeMap.get(key);
316
- if (!fieldTypeStr) continue;
317
- if (typeof processedResult[key] === "string") {
318
- if (fieldTypeStr.includes("int32") || fieldTypeStr.includes("float32")) {
319
- if (!isNaN(Number(processedResult[key]))) {
320
- processedResult[key] = Number(processedResult[key]);
321
- }
322
- } else if (fieldTypeStr.includes("int64")) {
323
- processedResult[key] = Number(processedResult[key]);
324
- } else if (fieldTypeStr.includes("utf8")) {
325
- try {
326
- processedResult[key] = JSON.parse(processedResult[key]);
327
- } catch (e) {
328
- this.logger.debug(`Failed to parse JSON for key ${key}: ${e}`);
329
- }
330
- }
331
- } else if (typeof processedResult[key] === "bigint") {
332
- processedResult[key] = Number(processedResult[key]);
333
- }
334
- }
335
- return processedResult;
1969
+ return this.stores.operations.load({ tableName, keys });
336
1970
  }
337
- getThreadById({ threadId }) {
338
- try {
339
- return this.load({ tableName: storage.TABLE_THREADS, keys: { id: threadId } });
340
- } catch (error) {
341
- throw new Error(`Failed to get thread by ID: ${error}`);
342
- }
1971
+ async getThreadById({ threadId }) {
1972
+ return this.stores.memory.getThreadById({ threadId });
343
1973
  }
344
1974
  async getThreadsByResourceId({ resourceId }) {
345
- try {
346
- const table = await this.lanceClient.openTable(storage.TABLE_THREADS);
347
- const query = table.query().where(`\`resourceId\` = '${resourceId}'`);
348
- const records = await query.toArray();
349
- return this.processResultWithTypeConversion(
350
- records,
351
- await this.getTableSchema(storage.TABLE_THREADS)
352
- );
353
- } catch (error) {
354
- throw new Error(`Failed to get threads by resource ID: ${error}`);
355
- }
1975
+ return this.stores.memory.getThreadsByResourceId({ resourceId });
356
1976
  }
357
1977
  /**
358
1978
  * Saves a thread to the database. This function doesn't overwrite existing threads.
@@ -360,41 +1980,39 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
360
1980
  * @returns The saved thread
361
1981
  */
362
1982
  async saveThread({ thread }) {
363
- try {
364
- const record = { ...thread, metadata: JSON.stringify(thread.metadata) };
365
- const table = await this.lanceClient.openTable(storage.TABLE_THREADS);
366
- await table.add([record], { mode: "append" });
367
- return thread;
368
- } catch (error) {
369
- throw new Error(`Failed to save thread: ${error}`);
370
- }
1983
+ return this.stores.memory.saveThread({ thread });
371
1984
  }
372
1985
  async updateThread({
373
1986
  id,
374
1987
  title,
375
1988
  metadata
376
1989
  }) {
377
- try {
378
- const record = { id, title, metadata: JSON.stringify(metadata) };
379
- const table = await this.lanceClient.openTable(storage.TABLE_THREADS);
380
- await table.add([record], { mode: "overwrite" });
381
- const query = table.query().where(`id = '${id}'`);
382
- const records = await query.toArray();
383
- return this.processResultWithTypeConversion(
384
- records[0],
385
- await this.getTableSchema(storage.TABLE_THREADS)
386
- );
387
- } catch (error) {
388
- throw new Error(`Failed to update thread: ${error}`);
389
- }
1990
+ return this.stores.memory.updateThread({ id, title, metadata });
390
1991
  }
391
1992
  async deleteThread({ threadId }) {
392
- try {
393
- const table = await this.lanceClient.openTable(storage.TABLE_THREADS);
394
- await table.delete(`id = '${threadId}'`);
395
- } catch (error) {
396
- throw new Error(`Failed to delete thread: ${error}`);
397
- }
1993
+ return this.stores.memory.deleteThread({ threadId });
1994
+ }
1995
+ get supports() {
1996
+ return {
1997
+ selectByIncludeResourceScope: true,
1998
+ resourceWorkingMemory: true,
1999
+ hasColumn: true,
2000
+ createTable: true,
2001
+ deleteMessages: false
2002
+ };
2003
+ }
2004
+ async getResourceById({ resourceId }) {
2005
+ return this.stores.memory.getResourceById({ resourceId });
2006
+ }
2007
+ async saveResource({ resource }) {
2008
+ return this.stores.memory.saveResource({ resource });
2009
+ }
2010
+ async updateResource({
2011
+ resourceId,
2012
+ workingMemory,
2013
+ metadata
2014
+ }) {
2015
+ return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
398
2016
  }
399
2017
  /**
400
2018
  * Processes messages to include context messages based on withPreviousMessages and withNextMessages
@@ -426,337 +2044,103 @@ var LanceStorage = class _LanceStorage extends storage.MastraStorage {
426
2044
  for (let i = messageIndex + 1; i <= endIdx; i++) {
427
2045
  additionalIndices.add(i);
428
2046
  }
429
- }
430
- }
431
- }
432
- if (additionalIndices.size === 0) {
433
- return records;
434
- }
435
- const originalMatchIds = new Set(include.map((item) => item.id));
436
- const allIndices = /* @__PURE__ */ new Set();
437
- records.forEach((record, index) => {
438
- if (originalMatchIds.has(record.id)) {
439
- allIndices.add(index);
440
- }
441
- });
442
- additionalIndices.forEach((index) => {
443
- allIndices.add(index);
444
- });
445
- return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
446
- }
447
- async getMessages({
448
- threadId,
449
- resourceId,
450
- selectBy,
451
- format,
452
- threadConfig
453
- }) {
454
- try {
455
- if (threadConfig) {
456
- throw new Error("ThreadConfig is not supported by LanceDB storage");
457
- }
458
- const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
459
- const table = await this.lanceClient.openTable(storage.TABLE_MESSAGES);
460
- let query = table.query().where(`\`threadId\` = '${threadId}'`);
461
- if (selectBy) {
462
- if (selectBy.include && selectBy.include.length > 0) {
463
- const includeIds = selectBy.include.map((item) => item.id);
464
- const includeClause = includeIds.map((id) => `\`id\` = '${id}'`).join(" OR ");
465
- query = query.where(`(\`threadId\` = '${threadId}' OR (${includeClause}))`);
466
- }
467
- }
468
- let records = await query.toArray();
469
- records.sort((a, b) => {
470
- const dateA = new Date(a.createdAt).getTime();
471
- const dateB = new Date(b.createdAt).getTime();
472
- return dateA - dateB;
473
- });
474
- if (selectBy?.include && selectBy.include.length > 0) {
475
- records = this.processMessagesWithContext(records, selectBy.include);
476
- }
477
- if (limit !== Number.MAX_SAFE_INTEGER) {
478
- records = records.slice(-limit);
479
- }
480
- const messages = this.processResultWithTypeConversion(records, await this.getTableSchema(storage.TABLE_MESSAGES));
481
- const normalized = messages.map((msg) => ({
482
- ...msg,
483
- content: typeof msg.content === "string" ? (() => {
484
- try {
485
- return JSON.parse(msg.content);
486
- } catch {
487
- return msg.content;
488
- }
489
- })() : msg.content
490
- }));
491
- const list = new agent.MessageList({ threadId, resourceId }).add(normalized, "memory");
492
- if (format === "v2") return list.get.all.v2();
493
- return list.get.all.v1();
494
- } catch (error) {
495
- throw new Error(`Failed to get messages: ${error}`);
496
- }
497
- }
498
- async saveMessages(args) {
499
- try {
500
- const { messages, format = "v1" } = args;
501
- if (messages.length === 0) {
502
- return [];
503
- }
504
- const threadId = messages[0]?.threadId;
505
- if (!threadId) {
506
- throw new Error("Thread ID is required");
2047
+ }
507
2048
  }
508
- const transformedMessages = messages.map((message) => ({
509
- ...message,
510
- content: JSON.stringify(message.content)
511
- }));
512
- const table = await this.lanceClient.openTable(storage.TABLE_MESSAGES);
513
- await table.add(transformedMessages, { mode: "overwrite" });
514
- const list = new agent.MessageList().add(messages, "memory");
515
- if (format === `v2`) return list.get.all.v2();
516
- return list.get.all.v1();
517
- } catch (error) {
518
- throw new Error(`Failed to save messages: ${error}`);
519
- }
520
- }
521
- async saveTrace({ trace }) {
522
- try {
523
- const table = await this.lanceClient.openTable(storage.TABLE_TRACES);
524
- const record = {
525
- ...trace,
526
- attributes: JSON.stringify(trace.attributes),
527
- status: JSON.stringify(trace.status),
528
- events: JSON.stringify(trace.events),
529
- links: JSON.stringify(trace.links),
530
- other: JSON.stringify(trace.other)
531
- };
532
- await table.add([record], { mode: "append" });
533
- return trace;
534
- } catch (error) {
535
- throw new Error(`Failed to save trace: ${error}`);
536
2049
  }
537
- }
538
- async getTraceById({ traceId }) {
539
- try {
540
- const table = await this.lanceClient.openTable(storage.TABLE_TRACES);
541
- const query = table.query().where(`id = '${traceId}'`);
542
- const records = await query.toArray();
543
- return this.processResultWithTypeConversion(records[0], await this.getTableSchema(storage.TABLE_TRACES));
544
- } catch (error) {
545
- throw new Error(`Failed to get trace by ID: ${error}`);
2050
+ if (additionalIndices.size === 0) {
2051
+ return records;
546
2052
  }
2053
+ const originalMatchIds = new Set(include.map((item) => item.id));
2054
+ const allIndices = /* @__PURE__ */ new Set();
2055
+ records.forEach((record, index) => {
2056
+ if (originalMatchIds.has(record.id)) {
2057
+ allIndices.add(index);
2058
+ }
2059
+ });
2060
+ additionalIndices.forEach((index) => {
2061
+ allIndices.add(index);
2062
+ });
2063
+ return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
547
2064
  }
548
- async getTraces({
549
- name,
550
- scope,
551
- page = 1,
552
- perPage = 10,
553
- attributes
2065
+ async getMessages({
2066
+ threadId,
2067
+ resourceId,
2068
+ selectBy,
2069
+ format,
2070
+ threadConfig
554
2071
  }) {
555
- try {
556
- const table = await this.lanceClient.openTable(storage.TABLE_TRACES);
557
- const query = table.query();
558
- if (name) {
559
- query.where(`name = '${name}'`);
560
- }
561
- if (scope) {
562
- query.where(`scope = '${scope}'`);
563
- }
564
- if (attributes) {
565
- query.where(`attributes = '${JSON.stringify(attributes)}'`);
566
- }
567
- const offset = (page - 1) * perPage;
568
- query.limit(perPage);
569
- if (offset > 0) {
570
- query.offset(offset);
571
- }
572
- const records = await query.toArray();
573
- return records.map((record) => {
574
- return {
575
- ...record,
576
- attributes: JSON.parse(record.attributes),
577
- status: JSON.parse(record.status),
578
- events: JSON.parse(record.events),
579
- links: JSON.parse(record.links),
580
- other: JSON.parse(record.other),
581
- startTime: new Date(record.startTime),
582
- endTime: new Date(record.endTime),
583
- createdAt: new Date(record.createdAt)
584
- };
585
- });
586
- } catch (error) {
587
- throw new Error(`Failed to get traces: ${error}`);
588
- }
2072
+ return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format, threadConfig });
589
2073
  }
590
- async saveEvals({ evals }) {
591
- try {
592
- const table = await this.lanceClient.openTable(storage.TABLE_EVALS);
593
- const transformedEvals = evals.map((evalRecord) => ({
594
- input: evalRecord.input,
595
- output: evalRecord.output,
596
- agent_name: evalRecord.agentName,
597
- metric_name: evalRecord.metricName,
598
- result: JSON.stringify(evalRecord.result),
599
- instructions: evalRecord.instructions,
600
- test_info: JSON.stringify(evalRecord.testInfo),
601
- global_run_id: evalRecord.globalRunId,
602
- run_id: evalRecord.runId,
603
- created_at: new Date(evalRecord.createdAt).getTime()
604
- }));
605
- await table.add(transformedEvals, { mode: "append" });
606
- return evals;
607
- } catch (error) {
608
- throw new Error(`Failed to save evals: ${error}`);
609
- }
2074
+ async saveMessages(args) {
2075
+ return this.stores.memory.saveMessages(args);
2076
+ }
2077
+ async getThreadsByResourceIdPaginated(args) {
2078
+ return this.stores.memory.getThreadsByResourceIdPaginated(args);
2079
+ }
2080
+ async getMessagesPaginated(args) {
2081
+ return this.stores.memory.getMessagesPaginated(args);
2082
+ }
2083
+ async updateMessages(_args) {
2084
+ return this.stores.memory.updateMessages(_args);
2085
+ }
2086
+ async getTraceById(args) {
2087
+ return this.stores.traces.getTraceById(args);
2088
+ }
2089
+ async getTraces(args) {
2090
+ return this.stores.traces.getTraces(args);
2091
+ }
2092
+ async getTracesPaginated(args) {
2093
+ return this.stores.traces.getTracesPaginated(args);
610
2094
  }
611
2095
  async getEvalsByAgentName(agentName, type) {
612
- try {
613
- if (type) {
614
- this.logger.warn("Type is not implemented yet in LanceDB storage");
615
- }
616
- const table = await this.lanceClient.openTable(storage.TABLE_EVALS);
617
- const query = table.query().where(`agent_name = '${agentName}'`);
618
- const records = await query.toArray();
619
- return records.map((record) => {
620
- return {
621
- id: record.id,
622
- input: record.input,
623
- output: record.output,
624
- agentName: record.agent_name,
625
- metricName: record.metric_name,
626
- result: JSON.parse(record.result),
627
- instructions: record.instructions,
628
- testInfo: JSON.parse(record.test_info),
629
- globalRunId: record.global_run_id,
630
- runId: record.run_id,
631
- createdAt: new Date(record.created_at).toString()
632
- };
633
- });
634
- } catch (error) {
635
- throw new Error(`Failed to get evals by agent name: ${error}`);
636
- }
2096
+ return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
637
2097
  }
638
- parseWorkflowRun(row) {
639
- let parsedSnapshot = row.snapshot;
640
- if (typeof parsedSnapshot === "string") {
641
- try {
642
- parsedSnapshot = JSON.parse(row.snapshot);
643
- } catch (e) {
644
- console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
645
- }
646
- }
647
- return {
648
- workflowName: row.workflow_name,
649
- runId: row.run_id,
650
- snapshot: parsedSnapshot,
651
- createdAt: this.ensureDate(row.createdAt),
652
- updatedAt: this.ensureDate(row.updatedAt),
653
- resourceId: row.resourceId
654
- };
2098
+ async getEvals(options) {
2099
+ return this.stores.legacyEvals.getEvals(options);
655
2100
  }
656
2101
  async getWorkflowRuns(args) {
657
- try {
658
- const table = await this.lanceClient.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
659
- const query = table.query();
660
- if (args?.workflowName) {
661
- query.where(`workflow_name = '${args.workflowName}'`);
662
- }
663
- if (args?.fromDate) {
664
- query.where(`\`createdAt\` >= ${args.fromDate.getTime()}`);
665
- }
666
- if (args?.toDate) {
667
- query.where(`\`createdAt\` <= ${args.toDate.getTime()}`);
668
- }
669
- if (args?.limit) {
670
- query.limit(args.limit);
671
- }
672
- if (args?.offset) {
673
- query.offset(args.offset);
674
- }
675
- const records = await query.toArray();
676
- return {
677
- runs: records.map((record) => this.parseWorkflowRun(record)),
678
- total: records.length
679
- };
680
- } catch (error) {
681
- throw new Error(`Failed to get workflow runs: ${error}`);
682
- }
2102
+ return this.stores.workflows.getWorkflowRuns(args);
683
2103
  }
684
- /**
685
- * Retrieve a single workflow run by its runId.
686
- * @param args The ID of the workflow run to retrieve
687
- * @returns The workflow run object or null if not found
688
- */
689
2104
  async getWorkflowRunById(args) {
690
- try {
691
- const table = await this.lanceClient.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
692
- let whereClause = `run_id = '${args.runId}'`;
693
- if (args.workflowName) {
694
- whereClause += ` AND workflow_name = '${args.workflowName}'`;
695
- }
696
- const query = table.query().where(whereClause);
697
- const records = await query.toArray();
698
- if (records.length === 0) return null;
699
- const record = records[0];
700
- return this.parseWorkflowRun(record);
701
- } catch (error) {
702
- throw new Error(`Failed to get workflow run by id: ${error}`);
703
- }
2105
+ return this.stores.workflows.getWorkflowRunById(args);
704
2106
  }
705
2107
  async persistWorkflowSnapshot({
706
2108
  workflowName,
707
2109
  runId,
708
2110
  snapshot
709
2111
  }) {
710
- try {
711
- const table = await this.lanceClient.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
712
- const query = table.query().where(`workflow_name = '${workflowName}' AND run_id = '${runId}'`);
713
- const records = await query.toArray();
714
- let createdAt;
715
- const now = Date.now();
716
- let mode = "append";
717
- if (records.length > 0) {
718
- createdAt = records[0].createdAt ?? now;
719
- mode = "overwrite";
720
- } else {
721
- createdAt = now;
722
- }
723
- const record = {
724
- workflow_name: workflowName,
725
- run_id: runId,
726
- snapshot: JSON.stringify(snapshot),
727
- createdAt,
728
- updatedAt: now
729
- };
730
- await table.add([record], { mode });
731
- } catch (error) {
732
- throw new Error(`Failed to persist workflow snapshot: ${error}`);
733
- }
2112
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
734
2113
  }
735
2114
  async loadWorkflowSnapshot({
736
2115
  workflowName,
737
2116
  runId
738
2117
  }) {
739
- try {
740
- const table = await this.lanceClient.openTable(storage.TABLE_WORKFLOW_SNAPSHOT);
741
- const query = table.query().where(`workflow_name = '${workflowName}' AND run_id = '${runId}'`);
742
- const records = await query.toArray();
743
- return records.length > 0 ? JSON.parse(records[0].snapshot) : null;
744
- } catch (error) {
745
- throw new Error(`Failed to load workflow snapshot: ${error}`);
746
- }
2118
+ return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
2119
+ }
2120
+ async getScoreById({ id: _id }) {
2121
+ return this.stores.scores.getScoreById({ id: _id });
747
2122
  }
748
- async getTracesPaginated(_args) {
749
- throw new Error("Method not implemented.");
2123
+ async getScoresByScorerId({
2124
+ scorerId,
2125
+ pagination
2126
+ }) {
2127
+ return this.stores.scores.getScoresByScorerId({ scorerId, pagination });
750
2128
  }
751
- async getThreadsByResourceIdPaginated(_args) {
752
- throw new Error("Method not implemented.");
2129
+ async saveScore(_score) {
2130
+ return this.stores.scores.saveScore(_score);
753
2131
  }
754
- async getMessagesPaginated(_args) {
755
- throw new Error("Method not implemented.");
2132
+ async getScoresByRunId({
2133
+ runId,
2134
+ pagination
2135
+ }) {
2136
+ return this.stores.scores.getScoresByRunId({ runId, pagination });
756
2137
  }
757
- async updateMessages(_args) {
758
- this.logger.error("updateMessages is not yet implemented in LanceStore");
759
- throw new Error("Method not implemented");
2138
+ async getScoresByEntityId({
2139
+ entityId,
2140
+ entityType,
2141
+ pagination
2142
+ }) {
2143
+ return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
760
2144
  }
761
2145
  };
762
2146
  var LanceFilterTranslator = class extends filter.BaseFilterTranslator {
@@ -1110,7 +2494,15 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1110
2494
  instance.lanceClient = await lancedb.connect(uri, options);
1111
2495
  return instance;
1112
2496
  } catch (e) {
1113
- throw new Error(`Failed to connect to LanceDB: ${e}`);
2497
+ throw new error.MastraError(
2498
+ {
2499
+ id: "STORAGE_LANCE_VECTOR_CONNECT_FAILED",
2500
+ domain: error.ErrorDomain.STORAGE,
2501
+ category: error.ErrorCategory.THIRD_PARTY,
2502
+ details: { uri }
2503
+ },
2504
+ e
2505
+ );
1114
2506
  }
1115
2507
  }
1116
2508
  /**
@@ -1134,14 +2526,27 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1134
2526
  columns = [],
1135
2527
  includeAllColumns = false
1136
2528
  }) {
1137
- if (!this.lanceClient) {
1138
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
1139
- }
1140
- if (!tableName) {
1141
- throw new Error("tableName is required");
1142
- }
1143
- if (!queryVector) {
1144
- throw new Error("queryVector is required");
2529
+ try {
2530
+ if (!this.lanceClient) {
2531
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2532
+ }
2533
+ if (!tableName) {
2534
+ throw new Error("tableName is required");
2535
+ }
2536
+ if (!queryVector) {
2537
+ throw new Error("queryVector is required");
2538
+ }
2539
+ } catch (error$1) {
2540
+ throw new error.MastraError(
2541
+ {
2542
+ id: "STORAGE_LANCE_VECTOR_QUERY_FAILED_INVALID_ARGS",
2543
+ domain: error.ErrorDomain.STORAGE,
2544
+ category: error.ErrorCategory.USER,
2545
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
2546
+ details: { tableName }
2547
+ },
2548
+ error$1
2549
+ );
1145
2550
  }
1146
2551
  try {
1147
2552
  const table = await this.lanceClient.openTable(tableName);
@@ -1179,8 +2584,16 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1179
2584
  score: result._distance
1180
2585
  };
1181
2586
  });
1182
- } catch (error) {
1183
- throw new Error(`Failed to query vectors: ${error.message}`);
2587
+ } catch (error$1) {
2588
+ throw new error.MastraError(
2589
+ {
2590
+ id: "STORAGE_LANCE_VECTOR_QUERY_FAILED",
2591
+ domain: error.ErrorDomain.STORAGE,
2592
+ category: error.ErrorCategory.THIRD_PARTY,
2593
+ details: { tableName, includeVector, columnsCount: columns?.length, includeAllColumns }
2594
+ },
2595
+ error$1
2596
+ );
1184
2597
  }
1185
2598
  }
1186
2599
  filterTranslator(filter) {
@@ -1213,14 +2626,27 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1213
2626
  return translator.translate(prefixedFilter);
1214
2627
  }
1215
2628
  async upsert({ tableName, vectors, metadata = [], ids = [] }) {
1216
- if (!this.lanceClient) {
1217
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
1218
- }
1219
- if (!tableName) {
1220
- throw new Error("tableName is required");
1221
- }
1222
- if (!vectors || !Array.isArray(vectors) || vectors.length === 0) {
1223
- throw new Error("vectors array is required and must not be empty");
2629
+ try {
2630
+ if (!this.lanceClient) {
2631
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2632
+ }
2633
+ if (!tableName) {
2634
+ throw new Error("tableName is required");
2635
+ }
2636
+ if (!vectors || !Array.isArray(vectors) || vectors.length === 0) {
2637
+ throw new Error("vectors array is required and must not be empty");
2638
+ }
2639
+ } catch (error$1) {
2640
+ throw new error.MastraError(
2641
+ {
2642
+ id: "STORAGE_LANCE_VECTOR_UPSERT_FAILED_INVALID_ARGS",
2643
+ domain: error.ErrorDomain.STORAGE,
2644
+ category: error.ErrorCategory.USER,
2645
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
2646
+ details: { tableName }
2647
+ },
2648
+ error$1
2649
+ );
1224
2650
  }
1225
2651
  try {
1226
2652
  const tables = await this.lanceClient.tableNames();
@@ -1246,8 +2672,16 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1246
2672
  });
1247
2673
  await table.add(data, { mode: "overwrite" });
1248
2674
  return vectorIds;
1249
- } catch (error) {
1250
- throw new Error(`Failed to upsert vectors: ${error.message}`);
2675
+ } catch (error$1) {
2676
+ throw new error.MastraError(
2677
+ {
2678
+ id: "STORAGE_LANCE_VECTOR_UPSERT_FAILED",
2679
+ domain: error.ErrorDomain.STORAGE,
2680
+ category: error.ErrorCategory.THIRD_PARTY,
2681
+ details: { tableName, vectorCount: vectors.length, metadataCount: metadata.length, idsCount: ids.length }
2682
+ },
2683
+ error$1
2684
+ );
1251
2685
  }
1252
2686
  }
1253
2687
  /**
@@ -1267,29 +2701,78 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1267
2701
  }
1268
2702
  async createTable(tableName, data, options) {
1269
2703
  if (!this.lanceClient) {
1270
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2704
+ throw new error.MastraError({
2705
+ id: "STORAGE_LANCE_VECTOR_CREATE_TABLE_FAILED_INVALID_ARGS",
2706
+ domain: error.ErrorDomain.STORAGE,
2707
+ category: error.ErrorCategory.USER,
2708
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
2709
+ details: { tableName }
2710
+ });
2711
+ }
2712
+ if (Array.isArray(data)) {
2713
+ data = data.map((record) => this.flattenObject(record));
1271
2714
  }
1272
2715
  try {
1273
- if (Array.isArray(data)) {
1274
- data = data.map((record) => this.flattenObject(record));
1275
- }
1276
2716
  return await this.lanceClient.createTable(tableName, data, options);
1277
- } catch (error) {
1278
- throw new Error(`Failed to create table: ${error.message}`);
2717
+ } catch (error$1) {
2718
+ throw new error.MastraError(
2719
+ {
2720
+ id: "STORAGE_LANCE_VECTOR_CREATE_TABLE_FAILED",
2721
+ domain: error.ErrorDomain.STORAGE,
2722
+ category: error.ErrorCategory.THIRD_PARTY,
2723
+ details: { tableName }
2724
+ },
2725
+ error$1
2726
+ );
1279
2727
  }
1280
2728
  }
1281
2729
  async listTables() {
1282
2730
  if (!this.lanceClient) {
1283
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2731
+ throw new error.MastraError({
2732
+ id: "STORAGE_LANCE_VECTOR_LIST_TABLES_FAILED_INVALID_ARGS",
2733
+ domain: error.ErrorDomain.STORAGE,
2734
+ category: error.ErrorCategory.USER,
2735
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
2736
+ details: { methodName: "listTables" }
2737
+ });
2738
+ }
2739
+ try {
2740
+ return await this.lanceClient.tableNames();
2741
+ } catch (error$1) {
2742
+ throw new error.MastraError(
2743
+ {
2744
+ id: "STORAGE_LANCE_VECTOR_LIST_TABLES_FAILED",
2745
+ domain: error.ErrorDomain.STORAGE,
2746
+ category: error.ErrorCategory.THIRD_PARTY
2747
+ },
2748
+ error$1
2749
+ );
1284
2750
  }
1285
- return await this.lanceClient.tableNames();
1286
2751
  }
1287
2752
  async getTableSchema(tableName) {
1288
2753
  if (!this.lanceClient) {
1289
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2754
+ throw new error.MastraError({
2755
+ id: "STORAGE_LANCE_VECTOR_GET_TABLE_SCHEMA_FAILED_INVALID_ARGS",
2756
+ domain: error.ErrorDomain.STORAGE,
2757
+ category: error.ErrorCategory.USER,
2758
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
2759
+ details: { tableName }
2760
+ });
2761
+ }
2762
+ try {
2763
+ const table = await this.lanceClient.openTable(tableName);
2764
+ return await table.schema();
2765
+ } catch (error$1) {
2766
+ throw new error.MastraError(
2767
+ {
2768
+ id: "STORAGE_LANCE_VECTOR_GET_TABLE_SCHEMA_FAILED",
2769
+ domain: error.ErrorDomain.STORAGE,
2770
+ category: error.ErrorCategory.THIRD_PARTY,
2771
+ details: { tableName }
2772
+ },
2773
+ error$1
2774
+ );
1290
2775
  }
1291
- const table = await this.lanceClient.openTable(tableName);
1292
- return await table.schema();
1293
2776
  }
1294
2777
  /**
1295
2778
  * indexName is actually a column name in a table in lanceDB
@@ -1301,10 +2784,10 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1301
2784
  metric = "cosine",
1302
2785
  indexConfig = {}
1303
2786
  }) {
1304
- if (!this.lanceClient) {
1305
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
1306
- }
1307
2787
  try {
2788
+ if (!this.lanceClient) {
2789
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2790
+ }
1308
2791
  if (!tableName) {
1309
2792
  throw new Error("tableName is required");
1310
2793
  }
@@ -1314,6 +2797,18 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1314
2797
  if (typeof dimension !== "number" || dimension <= 0) {
1315
2798
  throw new Error("dimension must be a positive number");
1316
2799
  }
2800
+ } catch (err) {
2801
+ throw new error.MastraError(
2802
+ {
2803
+ id: "STORAGE_LANCE_VECTOR_CREATE_INDEX_FAILED_INVALID_ARGS",
2804
+ domain: error.ErrorDomain.STORAGE,
2805
+ category: error.ErrorCategory.USER,
2806
+ details: { tableName: tableName || "", indexName, dimension, metric }
2807
+ },
2808
+ err
2809
+ );
2810
+ }
2811
+ try {
1317
2812
  const tables = await this.lanceClient.tableNames();
1318
2813
  if (!tables.includes(tableName)) {
1319
2814
  throw new Error(
@@ -1347,13 +2842,27 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1347
2842
  })
1348
2843
  });
1349
2844
  }
1350
- } catch (error) {
1351
- throw new Error(`Failed to create index: ${error.message}`);
2845
+ } catch (error$1) {
2846
+ throw new error.MastraError(
2847
+ {
2848
+ id: "STORAGE_LANCE_VECTOR_CREATE_INDEX_FAILED",
2849
+ domain: error.ErrorDomain.STORAGE,
2850
+ category: error.ErrorCategory.THIRD_PARTY,
2851
+ details: { tableName: tableName || "", indexName, dimension }
2852
+ },
2853
+ error$1
2854
+ );
1352
2855
  }
1353
2856
  }
1354
2857
  async listIndexes() {
1355
2858
  if (!this.lanceClient) {
1356
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2859
+ throw new error.MastraError({
2860
+ id: "STORAGE_LANCE_VECTOR_LIST_INDEXES_FAILED_INVALID_ARGS",
2861
+ domain: error.ErrorDomain.STORAGE,
2862
+ category: error.ErrorCategory.USER,
2863
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance",
2864
+ details: { methodName: "listIndexes" }
2865
+ });
1357
2866
  }
1358
2867
  try {
1359
2868
  const tables = await this.lanceClient.tableNames();
@@ -1364,16 +2873,35 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1364
2873
  allIndices.push(...tableIndices.map((index) => index.name));
1365
2874
  }
1366
2875
  return allIndices;
1367
- } catch (error) {
1368
- throw new Error(`Failed to list indexes: ${error.message}`);
2876
+ } catch (error$1) {
2877
+ throw new error.MastraError(
2878
+ {
2879
+ id: "STORAGE_LANCE_VECTOR_LIST_INDEXES_FAILED",
2880
+ domain: error.ErrorDomain.STORAGE,
2881
+ category: error.ErrorCategory.THIRD_PARTY
2882
+ },
2883
+ error$1
2884
+ );
1369
2885
  }
1370
2886
  }
1371
2887
  async describeIndex({ indexName }) {
1372
- if (!this.lanceClient) {
1373
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
1374
- }
1375
- if (!indexName) {
1376
- throw new Error("indexName is required");
2888
+ try {
2889
+ if (!this.lanceClient) {
2890
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2891
+ }
2892
+ if (!indexName) {
2893
+ throw new Error("indexName is required");
2894
+ }
2895
+ } catch (err) {
2896
+ throw new error.MastraError(
2897
+ {
2898
+ id: "STORAGE_LANCE_VECTOR_DESCRIBE_INDEX_FAILED_INVALID_ARGS",
2899
+ domain: error.ErrorDomain.STORAGE,
2900
+ category: error.ErrorCategory.USER,
2901
+ details: { indexName }
2902
+ },
2903
+ err
2904
+ );
1377
2905
  }
1378
2906
  try {
1379
2907
  const tables = await this.lanceClient.tableNames();
@@ -1399,16 +2927,36 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1399
2927
  }
1400
2928
  }
1401
2929
  throw new Error(`IndexName: ${indexName} not found`);
1402
- } catch (error) {
1403
- throw new Error(`Failed to describe index: ${error.message}`);
2930
+ } catch (error$1) {
2931
+ throw new error.MastraError(
2932
+ {
2933
+ id: "STORAGE_LANCE_VECTOR_DESCRIBE_INDEX_FAILED",
2934
+ domain: error.ErrorDomain.STORAGE,
2935
+ category: error.ErrorCategory.THIRD_PARTY,
2936
+ details: { indexName }
2937
+ },
2938
+ error$1
2939
+ );
1404
2940
  }
1405
2941
  }
1406
2942
  async deleteIndex({ indexName }) {
1407
- if (!this.lanceClient) {
1408
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
1409
- }
1410
- if (!indexName) {
1411
- throw new Error("indexName is required");
2943
+ try {
2944
+ if (!this.lanceClient) {
2945
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2946
+ }
2947
+ if (!indexName) {
2948
+ throw new Error("indexName is required");
2949
+ }
2950
+ } catch (err) {
2951
+ throw new error.MastraError(
2952
+ {
2953
+ id: "STORAGE_LANCE_VECTOR_DELETE_INDEX_FAILED_INVALID_ARGS",
2954
+ domain: error.ErrorDomain.STORAGE,
2955
+ category: error.ErrorCategory.USER,
2956
+ details: { indexName }
2957
+ },
2958
+ err
2959
+ );
1412
2960
  }
1413
2961
  try {
1414
2962
  const tables = await this.lanceClient.tableNames();
@@ -1422,8 +2970,16 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1422
2970
  }
1423
2971
  }
1424
2972
  throw new Error(`Index ${indexName} not found`);
1425
- } catch (error) {
1426
- throw new Error(`Failed to delete index: ${error.message}`);
2973
+ } catch (error$1) {
2974
+ throw new error.MastraError(
2975
+ {
2976
+ id: "STORAGE_LANCE_VECTOR_DELETE_INDEX_FAILED",
2977
+ domain: error.ErrorDomain.STORAGE,
2978
+ category: error.ErrorCategory.THIRD_PARTY,
2979
+ details: { indexName }
2980
+ },
2981
+ error$1
2982
+ );
1427
2983
  }
1428
2984
  }
1429
2985
  /**
@@ -1431,33 +2987,73 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1431
2987
  */
1432
2988
  async deleteAllTables() {
1433
2989
  if (!this.lanceClient) {
1434
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
2990
+ throw new error.MastraError({
2991
+ id: "STORAGE_LANCE_VECTOR_DELETE_ALL_TABLES_FAILED_INVALID_ARGS",
2992
+ domain: error.ErrorDomain.STORAGE,
2993
+ category: error.ErrorCategory.USER,
2994
+ details: { methodName: "deleteAllTables" },
2995
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance"
2996
+ });
1435
2997
  }
1436
2998
  try {
1437
2999
  await this.lanceClient.dropAllTables();
1438
- } catch (error) {
1439
- throw new Error(`Failed to delete tables: ${error.message}`);
3000
+ } catch (error$1) {
3001
+ throw new error.MastraError(
3002
+ {
3003
+ id: "STORAGE_LANCE_VECTOR_DELETE_ALL_TABLES_FAILED",
3004
+ domain: error.ErrorDomain.STORAGE,
3005
+ category: error.ErrorCategory.THIRD_PARTY,
3006
+ details: { methodName: "deleteAllTables" }
3007
+ },
3008
+ error$1
3009
+ );
1440
3010
  }
1441
3011
  }
1442
3012
  async deleteTable(tableName) {
1443
3013
  if (!this.lanceClient) {
1444
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3014
+ throw new error.MastraError({
3015
+ id: "STORAGE_LANCE_VECTOR_DELETE_TABLE_FAILED_INVALID_ARGS",
3016
+ domain: error.ErrorDomain.STORAGE,
3017
+ category: error.ErrorCategory.USER,
3018
+ details: { tableName },
3019
+ text: "LanceDB client not initialized. Use LanceVectorStore.create() to create an instance"
3020
+ });
1445
3021
  }
1446
3022
  try {
1447
3023
  await this.lanceClient.dropTable(tableName);
1448
- } catch (error) {
1449
- throw new Error(`Failed to delete tables: ${error.message}`);
3024
+ } catch (error$1) {
3025
+ throw new error.MastraError(
3026
+ {
3027
+ id: "STORAGE_LANCE_VECTOR_DELETE_TABLE_FAILED",
3028
+ domain: error.ErrorDomain.STORAGE,
3029
+ category: error.ErrorCategory.THIRD_PARTY,
3030
+ details: { tableName }
3031
+ },
3032
+ error$1
3033
+ );
1450
3034
  }
1451
3035
  }
1452
3036
  async updateVector({ indexName, id, update }) {
1453
- if (!this.lanceClient) {
1454
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
1455
- }
1456
- if (!indexName) {
1457
- throw new Error("indexName is required");
1458
- }
1459
- if (!id) {
1460
- throw new Error("id is required");
3037
+ try {
3038
+ if (!this.lanceClient) {
3039
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3040
+ }
3041
+ if (!indexName) {
3042
+ throw new Error("indexName is required");
3043
+ }
3044
+ if (!id) {
3045
+ throw new Error("id is required");
3046
+ }
3047
+ } catch (err) {
3048
+ throw new error.MastraError(
3049
+ {
3050
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
3051
+ domain: error.ErrorDomain.STORAGE,
3052
+ category: error.ErrorCategory.USER,
3053
+ details: { indexName, id }
3054
+ },
3055
+ err
3056
+ );
1461
3057
  }
1462
3058
  try {
1463
3059
  const tables = await this.lanceClient.tableNames();
@@ -1510,19 +3106,39 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1510
3106
  }
1511
3107
  }
1512
3108
  throw new Error(`No table found with column/index '${indexName}'`);
1513
- } catch (error) {
1514
- throw new Error(`Failed to update index: ${error.message}`);
3109
+ } catch (error$1) {
3110
+ throw new error.MastraError(
3111
+ {
3112
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
3113
+ domain: error.ErrorDomain.STORAGE,
3114
+ category: error.ErrorCategory.THIRD_PARTY,
3115
+ details: { indexName, id, hasVector: !!update.vector, hasMetadata: !!update.metadata }
3116
+ },
3117
+ error$1
3118
+ );
1515
3119
  }
1516
3120
  }
1517
3121
  async deleteVector({ indexName, id }) {
1518
- if (!this.lanceClient) {
1519
- throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
1520
- }
1521
- if (!indexName) {
1522
- throw new Error("indexName is required");
1523
- }
1524
- if (!id) {
1525
- throw new Error("id is required");
3122
+ try {
3123
+ if (!this.lanceClient) {
3124
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3125
+ }
3126
+ if (!indexName) {
3127
+ throw new Error("indexName is required");
3128
+ }
3129
+ if (!id) {
3130
+ throw new Error("id is required");
3131
+ }
3132
+ } catch (err) {
3133
+ throw new error.MastraError(
3134
+ {
3135
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
3136
+ domain: error.ErrorDomain.STORAGE,
3137
+ category: error.ErrorCategory.USER,
3138
+ details: { indexName, id }
3139
+ },
3140
+ err
3141
+ );
1526
3142
  }
1527
3143
  try {
1528
3144
  const tables = await this.lanceClient.tableNames();
@@ -1543,8 +3159,16 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1543
3159
  }
1544
3160
  }
1545
3161
  throw new Error(`No table found with column/index '${indexName}'`);
1546
- } catch (error) {
1547
- throw new Error(`Failed to delete index: ${error.message}`);
3162
+ } catch (error$1) {
3163
+ throw new error.MastraError(
3164
+ {
3165
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
3166
+ domain: error.ErrorDomain.STORAGE,
3167
+ category: error.ErrorCategory.THIRD_PARTY,
3168
+ details: { indexName, id }
3169
+ },
3170
+ error$1
3171
+ );
1548
3172
  }
1549
3173
  }
1550
3174
  /**
@@ -1576,3 +3200,5 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
1576
3200
 
1577
3201
  exports.LanceStorage = LanceStorage;
1578
3202
  exports.LanceVectorStore = LanceVectorStore;
3203
+ //# sourceMappingURL=index.cjs.map
3204
+ //# sourceMappingURL=index.cjs.map