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