@mastra/lance 0.0.0-mssql-store-20250804200341 → 0.0.0-netlify-no-bundle-20251127120354
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 +857 -2
- package/README.md +64 -7
- package/dist/index.cjs +635 -651
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +636 -652
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +18 -33
- 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 +16 -4
- 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 +23 -11
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +57 -79
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/vector/filter.d.ts +5 -5
- package/dist/vector/index.d.ts +8 -5
- package/dist/vector/index.d.ts.map +1 -1
- package/package.json +29 -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/eslint.config.js +0 -6
- package/src/index.ts +0 -2
- package/src/storage/domains/legacy-evals/index.ts +0 -156
- package/src/storage/domains/memory/index.ts +0 -947
- package/src/storage/domains/operations/index.ts +0 -489
- package/src/storage/domains/scores/index.ts +0 -221
- package/src/storage/domains/traces/index.ts +0 -212
- package/src/storage/domains/utils.ts +0 -158
- package/src/storage/domains/workflows/index.ts +0 -207
- package/src/storage/index.test.ts +0 -10
- package/src/storage/index.ts +0 -442
- package/src/vector/filter.test.ts +0 -295
- package/src/vector/filter.ts +0 -443
- package/src/vector/index.test.ts +0 -1493
- package/src/vector/index.ts +0 -941
- package/src/vector/types.ts +0 -16
- package/tsconfig.build.json +0 -9
- package/tsconfig.json +0 -5
- package/tsup.config.ts +0 -22
- package/vitest.config.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -1,132 +1,17 @@
|
|
|
1
1
|
import { connect, Index } from '@lancedb/lancedb';
|
|
2
2
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
3
|
-
import { MastraStorage, StoreOperations,
|
|
3
|
+
import { MastraStorage, 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
|
}
|
|
@@ -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 } });
|
|
@@ -269,26 +157,6 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
269
157
|
);
|
|
270
158
|
}
|
|
271
159
|
}
|
|
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",
|
|
285
|
-
domain: ErrorDomain.STORAGE,
|
|
286
|
-
category: ErrorCategory.THIRD_PARTY
|
|
287
|
-
},
|
|
288
|
-
error
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
160
|
/**
|
|
293
161
|
* Saves a thread to the database. This function doesn't overwrite existing threads.
|
|
294
162
|
* @param thread - The thread to save
|
|
@@ -379,79 +247,188 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
379
247
|
);
|
|
380
248
|
}
|
|
381
249
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
250
|
+
normalizeMessage(message) {
|
|
251
|
+
const { thread_id, ...rest } = message;
|
|
252
|
+
return {
|
|
253
|
+
...rest,
|
|
254
|
+
threadId: thread_id,
|
|
255
|
+
content: typeof message.content === "string" ? (() => {
|
|
256
|
+
try {
|
|
257
|
+
return JSON.parse(message.content);
|
|
258
|
+
} catch {
|
|
259
|
+
return message.content;
|
|
260
|
+
}
|
|
261
|
+
})() : message.content
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
async listMessagesById({ messageIds }) {
|
|
265
|
+
if (messageIds.length === 0) return { messages: [] };
|
|
389
266
|
try {
|
|
390
|
-
if (threadConfig) {
|
|
391
|
-
throw new Error("ThreadConfig is not supported by LanceDB storage");
|
|
392
|
-
}
|
|
393
|
-
const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
|
|
394
267
|
const table = await this.client.openTable(TABLE_MESSAGES);
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
|
|
398
|
-
for (const threadId2 of threadIds) {
|
|
399
|
-
const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
|
|
400
|
-
let threadRecords = await threadQuery.toArray();
|
|
401
|
-
allRecords.push(...threadRecords);
|
|
402
|
-
}
|
|
403
|
-
} else {
|
|
404
|
-
let query = table.query().where(`\`thread_id\` = '${threadId}'`);
|
|
405
|
-
allRecords = await query.toArray();
|
|
406
|
-
}
|
|
407
|
-
allRecords.sort((a, b) => {
|
|
408
|
-
const dateA = new Date(a.createdAt).getTime();
|
|
409
|
-
const dateB = new Date(b.createdAt).getTime();
|
|
410
|
-
return dateA - dateB;
|
|
411
|
-
});
|
|
412
|
-
if (selectBy?.include && selectBy.include.length > 0) {
|
|
413
|
-
allRecords = this.processMessagesWithContext(allRecords, selectBy.include);
|
|
414
|
-
}
|
|
415
|
-
if (limit !== Number.MAX_SAFE_INTEGER) {
|
|
416
|
-
allRecords = allRecords.slice(-limit);
|
|
417
|
-
}
|
|
268
|
+
const quotedIds = messageIds.map((id) => `'${id}'`).join(", ");
|
|
269
|
+
const allRecords = await table.query().where(`id IN (${quotedIds})`).toArray();
|
|
418
270
|
const messages = processResultWithTypeConversion(
|
|
419
271
|
allRecords,
|
|
420
272
|
await getTableSchema({ tableName: TABLE_MESSAGES, client: this.client })
|
|
421
273
|
);
|
|
422
|
-
const
|
|
423
|
-
|
|
274
|
+
const list = new MessageList().add(
|
|
275
|
+
messages.map(this.normalizeMessage),
|
|
276
|
+
"memory"
|
|
277
|
+
);
|
|
278
|
+
return { messages: list.get.all.db() };
|
|
279
|
+
} catch (error) {
|
|
280
|
+
throw new MastraError(
|
|
281
|
+
{
|
|
282
|
+
id: "LANCE_STORE_LIST_MESSAGES_BY_ID_FAILED",
|
|
283
|
+
domain: ErrorDomain.STORAGE,
|
|
284
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
285
|
+
details: {
|
|
286
|
+
messageIds: JSON.stringify(messageIds)
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
error
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async listMessages(args) {
|
|
294
|
+
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
295
|
+
if (!threadId.trim()) {
|
|
296
|
+
throw new MastraError(
|
|
297
|
+
{
|
|
298
|
+
id: "STORAGE_LANCE_LIST_MESSAGES_INVALID_THREAD_ID",
|
|
299
|
+
domain: ErrorDomain.STORAGE,
|
|
300
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
301
|
+
details: { threadId }
|
|
302
|
+
},
|
|
303
|
+
new Error("threadId must be a non-empty string")
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
const perPage = normalizePerPage(perPageInput, 40);
|
|
307
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
308
|
+
try {
|
|
309
|
+
if (page < 0) {
|
|
310
|
+
throw new MastraError(
|
|
311
|
+
{
|
|
312
|
+
id: "STORAGE_LANCE_LIST_MESSAGES_INVALID_PAGE",
|
|
313
|
+
domain: ErrorDomain.STORAGE,
|
|
314
|
+
category: ErrorCategory.USER,
|
|
315
|
+
details: { page }
|
|
316
|
+
},
|
|
317
|
+
new Error("page must be >= 0")
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
321
|
+
const table = await this.client.openTable(TABLE_MESSAGES);
|
|
322
|
+
const conditions = [`thread_id = '${this.escapeSql(threadId)}'`];
|
|
323
|
+
if (resourceId) {
|
|
324
|
+
conditions.push(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
|
|
325
|
+
}
|
|
326
|
+
if (filter?.dateRange?.start) {
|
|
327
|
+
const startTime = filter.dateRange.start instanceof Date ? filter.dateRange.start.getTime() : new Date(filter.dateRange.start).getTime();
|
|
328
|
+
conditions.push(`\`createdAt\` >= ${startTime}`);
|
|
329
|
+
}
|
|
330
|
+
if (filter?.dateRange?.end) {
|
|
331
|
+
const endTime = filter.dateRange.end instanceof Date ? filter.dateRange.end.getTime() : new Date(filter.dateRange.end).getTime();
|
|
332
|
+
conditions.push(`\`createdAt\` <= ${endTime}`);
|
|
333
|
+
}
|
|
334
|
+
const whereClause = conditions.join(" AND ");
|
|
335
|
+
const total = await table.countRows(whereClause);
|
|
336
|
+
const query = table.query().where(whereClause);
|
|
337
|
+
let allRecords = await query.toArray();
|
|
338
|
+
allRecords.sort((a, b) => {
|
|
339
|
+
const aValue = field === "createdAt" ? a.createdAt : a[field];
|
|
340
|
+
const bValue = field === "createdAt" ? b.createdAt : b[field];
|
|
341
|
+
if (aValue == null && bValue == null) return 0;
|
|
342
|
+
if (aValue == null) return direction === "ASC" ? -1 : 1;
|
|
343
|
+
if (bValue == null) return direction === "ASC" ? 1 : -1;
|
|
344
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
345
|
+
return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
|
346
|
+
}
|
|
347
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
348
|
+
});
|
|
349
|
+
const paginatedRecords = allRecords.slice(offset, offset + perPage);
|
|
350
|
+
const messages = paginatedRecords.map((row) => this.normalizeMessage(row));
|
|
351
|
+
if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
|
|
424
352
|
return {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
} catch {
|
|
431
|
-
return msg.content;
|
|
432
|
-
}
|
|
433
|
-
})() : msg.content
|
|
353
|
+
messages: [],
|
|
354
|
+
total: 0,
|
|
355
|
+
page,
|
|
356
|
+
perPage: perPageForResponse,
|
|
357
|
+
hasMore: false
|
|
434
358
|
};
|
|
359
|
+
}
|
|
360
|
+
const messageIds = new Set(messages.map((m) => m.id));
|
|
361
|
+
if (include && include.length > 0) {
|
|
362
|
+
const threadIds = [...new Set(include.map((item) => item.threadId || threadId))];
|
|
363
|
+
const allThreadMessages = [];
|
|
364
|
+
for (const tid of threadIds) {
|
|
365
|
+
const threadQuery = table.query().where(`thread_id = '${tid}'`);
|
|
366
|
+
let threadRecords = await threadQuery.toArray();
|
|
367
|
+
allThreadMessages.push(...threadRecords);
|
|
368
|
+
}
|
|
369
|
+
allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
|
|
370
|
+
const contextMessages = this.processMessagesWithContext(allThreadMessages, include);
|
|
371
|
+
const includedMessages = contextMessages.map((row) => this.normalizeMessage(row));
|
|
372
|
+
for (const includeMsg of includedMessages) {
|
|
373
|
+
if (!messageIds.has(includeMsg.id)) {
|
|
374
|
+
messages.push(includeMsg);
|
|
375
|
+
messageIds.add(includeMsg.id);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const list = new MessageList().add(messages, "memory");
|
|
380
|
+
let finalMessages = list.get.all.db();
|
|
381
|
+
finalMessages = finalMessages.sort((a, b) => {
|
|
382
|
+
const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
|
|
383
|
+
const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
|
|
384
|
+
if (aValue == null && bValue == null) return 0;
|
|
385
|
+
if (aValue == null) return direction === "ASC" ? -1 : 1;
|
|
386
|
+
if (bValue == null) return direction === "ASC" ? 1 : -1;
|
|
387
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
388
|
+
return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
|
389
|
+
}
|
|
390
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
435
391
|
});
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
392
|
+
const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
|
|
393
|
+
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
394
|
+
const fetchedAll = perPageInput === false || allThreadMessagesReturned;
|
|
395
|
+
const hasMore = !fetchedAll && offset + perPage < total;
|
|
396
|
+
return {
|
|
397
|
+
messages: finalMessages,
|
|
398
|
+
total,
|
|
399
|
+
page,
|
|
400
|
+
perPage: perPageForResponse,
|
|
401
|
+
hasMore
|
|
402
|
+
};
|
|
439
403
|
} catch (error) {
|
|
440
|
-
|
|
404
|
+
const mastraError = new MastraError(
|
|
441
405
|
{
|
|
442
|
-
id: "
|
|
406
|
+
id: "LANCE_STORE_LIST_MESSAGES_FAILED",
|
|
443
407
|
domain: ErrorDomain.STORAGE,
|
|
444
|
-
category: ErrorCategory.THIRD_PARTY
|
|
408
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
409
|
+
details: {
|
|
410
|
+
threadId,
|
|
411
|
+
resourceId: resourceId ?? ""
|
|
412
|
+
}
|
|
445
413
|
},
|
|
446
414
|
error
|
|
447
415
|
);
|
|
416
|
+
this.logger?.error?.(mastraError.toString());
|
|
417
|
+
this.logger?.trackException?.(mastraError);
|
|
418
|
+
return {
|
|
419
|
+
messages: [],
|
|
420
|
+
total: 0,
|
|
421
|
+
page,
|
|
422
|
+
perPage: perPageForResponse,
|
|
423
|
+
hasMore: false
|
|
424
|
+
};
|
|
448
425
|
}
|
|
449
426
|
}
|
|
450
427
|
async saveMessages(args) {
|
|
451
428
|
try {
|
|
452
|
-
const { messages
|
|
429
|
+
const { messages } = args;
|
|
453
430
|
if (messages.length === 0) {
|
|
454
|
-
return [];
|
|
431
|
+
return { messages: [] };
|
|
455
432
|
}
|
|
456
433
|
const threadId = messages[0]?.threadId;
|
|
457
434
|
if (!threadId) {
|
|
@@ -487,8 +464,7 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
487
464
|
const updateRecord = { id: threadId, updatedAt: currentTime };
|
|
488
465
|
await threadsTable.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([updateRecord]);
|
|
489
466
|
const list = new MessageList().add(messages, "memory");
|
|
490
|
-
|
|
491
|
-
return list.get.all.v1();
|
|
467
|
+
return { messages: list.get.all.db() };
|
|
492
468
|
} catch (error) {
|
|
493
469
|
throw new MastraError(
|
|
494
470
|
{
|
|
@@ -500,32 +476,54 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
500
476
|
);
|
|
501
477
|
}
|
|
502
478
|
}
|
|
503
|
-
async
|
|
479
|
+
async listThreadsByResourceId(args) {
|
|
504
480
|
try {
|
|
505
|
-
const { resourceId, page = 0, perPage
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
481
|
+
const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
|
|
482
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
483
|
+
if (page < 0) {
|
|
484
|
+
throw new MastraError(
|
|
485
|
+
{
|
|
486
|
+
id: "STORAGE_LANCE_LIST_THREADS_BY_RESOURCE_ID_INVALID_PAGE",
|
|
487
|
+
domain: ErrorDomain.STORAGE,
|
|
488
|
+
category: ErrorCategory.USER,
|
|
489
|
+
details: { page }
|
|
490
|
+
},
|
|
491
|
+
new Error("page must be >= 0")
|
|
492
|
+
);
|
|
513
493
|
}
|
|
494
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
495
|
+
const { field, direction } = this.parseOrderBy(orderBy);
|
|
496
|
+
const table = await this.client.openTable(TABLE_THREADS);
|
|
497
|
+
const total = await table.countRows(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
|
|
498
|
+
const query = table.query().where(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
|
|
514
499
|
const records = await query.toArray();
|
|
515
|
-
records.sort((a, b) =>
|
|
500
|
+
records.sort((a, b) => {
|
|
501
|
+
const aValue = ["createdAt", "updatedAt"].includes(field) ? new Date(a[field]).getTime() : a[field];
|
|
502
|
+
const bValue = ["createdAt", "updatedAt"].includes(field) ? new Date(b[field]).getTime() : b[field];
|
|
503
|
+
if (aValue == null && bValue == null) return 0;
|
|
504
|
+
if (aValue == null) return direction === "ASC" ? -1 : 1;
|
|
505
|
+
if (bValue == null) return direction === "ASC" ? 1 : -1;
|
|
506
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
507
|
+
return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
|
508
|
+
}
|
|
509
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
510
|
+
});
|
|
511
|
+
const paginatedRecords = records.slice(offset, offset + perPage);
|
|
516
512
|
const schema = await getTableSchema({ tableName: TABLE_THREADS, client: this.client });
|
|
517
|
-
const threads =
|
|
513
|
+
const threads = paginatedRecords.map(
|
|
514
|
+
(record) => processResultWithTypeConversion(record, schema)
|
|
515
|
+
);
|
|
518
516
|
return {
|
|
519
517
|
threads,
|
|
520
518
|
total,
|
|
521
519
|
page,
|
|
522
|
-
perPage,
|
|
523
|
-
hasMore:
|
|
520
|
+
perPage: perPageForResponse,
|
|
521
|
+
hasMore: offset + perPage < total
|
|
524
522
|
};
|
|
525
523
|
} catch (error) {
|
|
526
524
|
throw new MastraError(
|
|
527
525
|
{
|
|
528
|
-
id: "
|
|
526
|
+
id: "LANCE_STORE_LIST_THREADS_BY_RESOURCE_ID_FAILED",
|
|
529
527
|
domain: ErrorDomain.STORAGE,
|
|
530
528
|
category: ErrorCategory.THIRD_PARTY
|
|
531
529
|
},
|
|
@@ -581,127 +579,8 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
581
579
|
});
|
|
582
580
|
return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
|
|
583
581
|
}
|
|
584
|
-
async getMessagesPaginated(args) {
|
|
585
|
-
try {
|
|
586
|
-
const { threadId, resourceId, selectBy, format = "v1" } = args;
|
|
587
|
-
if (!threadId) {
|
|
588
|
-
throw new Error("Thread ID is required for getMessagesPaginated");
|
|
589
|
-
}
|
|
590
|
-
const page = selectBy?.pagination?.page ?? 0;
|
|
591
|
-
const perPage = selectBy?.pagination?.perPage ?? 10;
|
|
592
|
-
const dateRange = selectBy?.pagination?.dateRange;
|
|
593
|
-
const fromDate = dateRange?.start;
|
|
594
|
-
const toDate = dateRange?.end;
|
|
595
|
-
const table = await this.client.openTable(TABLE_MESSAGES);
|
|
596
|
-
const messages = [];
|
|
597
|
-
if (selectBy?.include && Array.isArray(selectBy.include)) {
|
|
598
|
-
const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
|
|
599
|
-
const allThreadMessages = [];
|
|
600
|
-
for (const threadId2 of threadIds) {
|
|
601
|
-
const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
|
|
602
|
-
let threadRecords = await threadQuery.toArray();
|
|
603
|
-
if (fromDate) threadRecords = threadRecords.filter((m) => m.createdAt >= fromDate.getTime());
|
|
604
|
-
if (toDate) threadRecords = threadRecords.filter((m) => m.createdAt <= toDate.getTime());
|
|
605
|
-
allThreadMessages.push(...threadRecords);
|
|
606
|
-
}
|
|
607
|
-
allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
|
|
608
|
-
const contextMessages = this.processMessagesWithContext(allThreadMessages, selectBy.include);
|
|
609
|
-
messages.push(...contextMessages);
|
|
610
|
-
}
|
|
611
|
-
const conditions = [`thread_id = '${threadId}'`];
|
|
612
|
-
if (resourceId) {
|
|
613
|
-
conditions.push(`\`resourceId\` = '${resourceId}'`);
|
|
614
|
-
}
|
|
615
|
-
if (fromDate) {
|
|
616
|
-
conditions.push(`\`createdAt\` >= ${fromDate.getTime()}`);
|
|
617
|
-
}
|
|
618
|
-
if (toDate) {
|
|
619
|
-
conditions.push(`\`createdAt\` <= ${toDate.getTime()}`);
|
|
620
|
-
}
|
|
621
|
-
let total = 0;
|
|
622
|
-
if (conditions.length > 0) {
|
|
623
|
-
total = await table.countRows(conditions.join(" AND "));
|
|
624
|
-
} else {
|
|
625
|
-
total = await table.countRows();
|
|
626
|
-
}
|
|
627
|
-
if (total === 0 && messages.length === 0) {
|
|
628
|
-
return {
|
|
629
|
-
messages: [],
|
|
630
|
-
total: 0,
|
|
631
|
-
page,
|
|
632
|
-
perPage,
|
|
633
|
-
hasMore: false
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
const excludeIds = messages.map((m) => m.id);
|
|
637
|
-
let selectedMessages = [];
|
|
638
|
-
if (selectBy?.last && selectBy.last > 0) {
|
|
639
|
-
const query = table.query();
|
|
640
|
-
if (conditions.length > 0) {
|
|
641
|
-
query.where(conditions.join(" AND "));
|
|
642
|
-
}
|
|
643
|
-
let records = await query.toArray();
|
|
644
|
-
records = records.sort((a, b) => a.createdAt - b.createdAt);
|
|
645
|
-
if (excludeIds.length > 0) {
|
|
646
|
-
records = records.filter((m) => !excludeIds.includes(m.id));
|
|
647
|
-
}
|
|
648
|
-
selectedMessages = records.slice(-selectBy.last);
|
|
649
|
-
} else {
|
|
650
|
-
const query = table.query();
|
|
651
|
-
if (conditions.length > 0) {
|
|
652
|
-
query.where(conditions.join(" AND "));
|
|
653
|
-
}
|
|
654
|
-
let records = await query.toArray();
|
|
655
|
-
records = records.sort((a, b) => a.createdAt - b.createdAt);
|
|
656
|
-
if (excludeIds.length > 0) {
|
|
657
|
-
records = records.filter((m) => !excludeIds.includes(m.id));
|
|
658
|
-
}
|
|
659
|
-
selectedMessages = records.slice(page * perPage, (page + 1) * perPage);
|
|
660
|
-
}
|
|
661
|
-
const allMessages = [...messages, ...selectedMessages];
|
|
662
|
-
const seen = /* @__PURE__ */ new Set();
|
|
663
|
-
const dedupedMessages = allMessages.filter((m) => {
|
|
664
|
-
const key = `${m.id}:${m.thread_id}`;
|
|
665
|
-
if (seen.has(key)) return false;
|
|
666
|
-
seen.add(key);
|
|
667
|
-
return true;
|
|
668
|
-
});
|
|
669
|
-
const formattedMessages = dedupedMessages.map((msg) => {
|
|
670
|
-
const { thread_id, ...rest } = msg;
|
|
671
|
-
return {
|
|
672
|
-
...rest,
|
|
673
|
-
threadId: thread_id,
|
|
674
|
-
content: typeof msg.content === "string" ? (() => {
|
|
675
|
-
try {
|
|
676
|
-
return JSON.parse(msg.content);
|
|
677
|
-
} catch {
|
|
678
|
-
return msg.content;
|
|
679
|
-
}
|
|
680
|
-
})() : msg.content
|
|
681
|
-
};
|
|
682
|
-
});
|
|
683
|
-
const list = new MessageList().add(formattedMessages, "memory");
|
|
684
|
-
return {
|
|
685
|
-
messages: format === "v2" ? list.get.all.v2() : list.get.all.v1(),
|
|
686
|
-
total,
|
|
687
|
-
// Total should be the count of messages matching the filters
|
|
688
|
-
page,
|
|
689
|
-
perPage,
|
|
690
|
-
hasMore: total > (page + 1) * perPage
|
|
691
|
-
};
|
|
692
|
-
} catch (error) {
|
|
693
|
-
throw new MastraError(
|
|
694
|
-
{
|
|
695
|
-
id: "LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED",
|
|
696
|
-
domain: ErrorDomain.STORAGE,
|
|
697
|
-
category: ErrorCategory.THIRD_PARTY
|
|
698
|
-
},
|
|
699
|
-
error
|
|
700
|
-
);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
582
|
/**
|
|
704
|
-
* Parse message data from LanceDB record format to
|
|
583
|
+
* Parse message data from LanceDB record format to MastraDBMessage format
|
|
705
584
|
*/
|
|
706
585
|
parseMessageData(data) {
|
|
707
586
|
const { thread_id, ...rest } = data;
|
|
@@ -1224,7 +1103,7 @@ var StoreOperationsLance = class extends StoreOperations {
|
|
|
1224
1103
|
processedRecord[key] = JSON.stringify(processedRecord[key]);
|
|
1225
1104
|
}
|
|
1226
1105
|
}
|
|
1227
|
-
console.
|
|
1106
|
+
console.info(await table.schema());
|
|
1228
1107
|
await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([processedRecord]);
|
|
1229
1108
|
} catch (error) {
|
|
1230
1109
|
throw new MastraError(
|
|
@@ -1274,7 +1153,6 @@ var StoreOperationsLance = class extends StoreOperations {
|
|
|
1274
1153
|
}
|
|
1275
1154
|
return processedRecord;
|
|
1276
1155
|
});
|
|
1277
|
-
console.log(processedRecords);
|
|
1278
1156
|
await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(processedRecords);
|
|
1279
1157
|
} catch (error) {
|
|
1280
1158
|
throw new MastraError(
|
|
@@ -1358,12 +1236,27 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1358
1236
|
this.client = client;
|
|
1359
1237
|
}
|
|
1360
1238
|
async saveScore(score) {
|
|
1239
|
+
let validatedScore;
|
|
1361
1240
|
try {
|
|
1241
|
+
validatedScore = saveScorePayloadSchema.parse(score);
|
|
1242
|
+
} catch (error) {
|
|
1243
|
+
throw new MastraError(
|
|
1244
|
+
{
|
|
1245
|
+
id: "LANCE_STORAGE_SAVE_SCORE_FAILED",
|
|
1246
|
+
text: "Failed to save score in LanceStorage",
|
|
1247
|
+
domain: ErrorDomain.STORAGE,
|
|
1248
|
+
category: ErrorCategory.THIRD_PARTY
|
|
1249
|
+
},
|
|
1250
|
+
error
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
try {
|
|
1254
|
+
const id = crypto.randomUUID();
|
|
1362
1255
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1363
1256
|
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1364
1257
|
const allowedFields = new Set(schema.fields.map((f) => f.name));
|
|
1365
1258
|
const filteredScore = {};
|
|
1366
|
-
Object.keys(
|
|
1259
|
+
Object.keys(validatedScore).forEach((key) => {
|
|
1367
1260
|
if (allowedFields.has(key)) {
|
|
1368
1261
|
filteredScore[key] = score[key];
|
|
1369
1262
|
}
|
|
@@ -1373,7 +1266,9 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1373
1266
|
filteredScore[key] = JSON.stringify(filteredScore[key]);
|
|
1374
1267
|
}
|
|
1375
1268
|
}
|
|
1376
|
-
|
|
1269
|
+
filteredScore.createdAt = /* @__PURE__ */ new Date();
|
|
1270
|
+
filteredScore.updatedAt = /* @__PURE__ */ new Date();
|
|
1271
|
+
filteredScore.id = id;
|
|
1377
1272
|
await table.add([filteredScore], { mode: "append" });
|
|
1378
1273
|
return { score };
|
|
1379
1274
|
} catch (error) {
|
|
@@ -1395,8 +1290,7 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1395
1290
|
const query = table.query().where(`id = '${id}'`).limit(1);
|
|
1396
1291
|
const records = await query.toArray();
|
|
1397
1292
|
if (records.length === 0) return null;
|
|
1398
|
-
|
|
1399
|
-
return processResultWithTypeConversion(records[0], schema);
|
|
1293
|
+
return await this.transformScoreRow(records[0]);
|
|
1400
1294
|
} catch (error) {
|
|
1401
1295
|
throw new MastraError(
|
|
1402
1296
|
{
|
|
@@ -1410,27 +1304,63 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1410
1304
|
);
|
|
1411
1305
|
}
|
|
1412
1306
|
}
|
|
1413
|
-
async
|
|
1307
|
+
async transformScoreRow(row) {
|
|
1308
|
+
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1309
|
+
const transformed = processResultWithTypeConversion(row, schema);
|
|
1310
|
+
const result = {
|
|
1311
|
+
...transformed,
|
|
1312
|
+
createdAt: row.createdAt,
|
|
1313
|
+
updatedAt: row.updatedAt
|
|
1314
|
+
};
|
|
1315
|
+
return result;
|
|
1316
|
+
}
|
|
1317
|
+
async listScoresByScorerId({
|
|
1414
1318
|
scorerId,
|
|
1415
|
-
pagination
|
|
1319
|
+
pagination,
|
|
1320
|
+
entityId,
|
|
1321
|
+
entityType,
|
|
1322
|
+
source
|
|
1416
1323
|
}) {
|
|
1417
1324
|
try {
|
|
1325
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1326
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1327
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1418
1328
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1329
|
+
let query = table.query().where(`\`scorerId\` = '${scorerId}'`);
|
|
1330
|
+
if (source) {
|
|
1331
|
+
query = query.where(`\`source\` = '${source}'`);
|
|
1332
|
+
}
|
|
1333
|
+
if (entityId) {
|
|
1334
|
+
query = query.where(`\`entityId\` = '${entityId}'`);
|
|
1335
|
+
}
|
|
1336
|
+
if (entityType) {
|
|
1337
|
+
query = query.where(`\`entityType\` = '${entityType}'`);
|
|
1338
|
+
}
|
|
1339
|
+
let totalQuery = table.query().where(`\`scorerId\` = '${scorerId}'`);
|
|
1340
|
+
if (source) {
|
|
1341
|
+
totalQuery = totalQuery.where(`\`source\` = '${source}'`);
|
|
1342
|
+
}
|
|
1343
|
+
if (entityId) {
|
|
1344
|
+
totalQuery = totalQuery.where(`\`entityId\` = '${entityId}'`);
|
|
1345
|
+
}
|
|
1346
|
+
if (entityType) {
|
|
1347
|
+
totalQuery = totalQuery.where(`\`entityType\` = '${entityType}'`);
|
|
1348
|
+
}
|
|
1349
|
+
const allRecords = await totalQuery.toArray();
|
|
1427
1350
|
const total = allRecords.length;
|
|
1351
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1352
|
+
if (perPageInput !== false) {
|
|
1353
|
+
query = query.limit(perPage);
|
|
1354
|
+
if (start > 0) query = query.offset(start);
|
|
1355
|
+
}
|
|
1356
|
+
const records = await query.toArray();
|
|
1357
|
+
const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
|
|
1428
1358
|
return {
|
|
1429
1359
|
pagination: {
|
|
1430
1360
|
page,
|
|
1431
|
-
perPage,
|
|
1361
|
+
perPage: perPageForResponse,
|
|
1432
1362
|
total,
|
|
1433
|
-
hasMore:
|
|
1363
|
+
hasMore: end < total
|
|
1434
1364
|
},
|
|
1435
1365
|
scores
|
|
1436
1366
|
};
|
|
@@ -1447,27 +1377,31 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1447
1377
|
);
|
|
1448
1378
|
}
|
|
1449
1379
|
}
|
|
1450
|
-
async
|
|
1380
|
+
async listScoresByRunId({
|
|
1451
1381
|
runId,
|
|
1452
1382
|
pagination
|
|
1453
1383
|
}) {
|
|
1454
1384
|
try {
|
|
1385
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1386
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1387
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1455
1388
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1456
|
-
const { page = 0, perPage = 10 } = pagination || {};
|
|
1457
|
-
const offset = page * perPage;
|
|
1458
|
-
const query = table.query().where(`\`runId\` = '${runId}'`).limit(perPage);
|
|
1459
|
-
if (offset > 0) query.offset(offset);
|
|
1460
|
-
const records = await query.toArray();
|
|
1461
|
-
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1462
|
-
const scores = processResultWithTypeConversion(records, schema);
|
|
1463
1389
|
const allRecords = await table.query().where(`\`runId\` = '${runId}'`).toArray();
|
|
1464
1390
|
const total = allRecords.length;
|
|
1391
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1392
|
+
let query = table.query().where(`\`runId\` = '${runId}'`);
|
|
1393
|
+
if (perPageInput !== false) {
|
|
1394
|
+
query = query.limit(perPage);
|
|
1395
|
+
if (start > 0) query = query.offset(start);
|
|
1396
|
+
}
|
|
1397
|
+
const records = await query.toArray();
|
|
1398
|
+
const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
|
|
1465
1399
|
return {
|
|
1466
1400
|
pagination: {
|
|
1467
1401
|
page,
|
|
1468
|
-
perPage,
|
|
1402
|
+
perPage: perPageForResponse,
|
|
1469
1403
|
total,
|
|
1470
|
-
hasMore:
|
|
1404
|
+
hasMore: end < total
|
|
1471
1405
|
},
|
|
1472
1406
|
scores
|
|
1473
1407
|
};
|
|
@@ -1484,28 +1418,32 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1484
1418
|
);
|
|
1485
1419
|
}
|
|
1486
1420
|
}
|
|
1487
|
-
async
|
|
1421
|
+
async listScoresByEntityId({
|
|
1488
1422
|
entityId,
|
|
1489
1423
|
entityType,
|
|
1490
1424
|
pagination
|
|
1491
1425
|
}) {
|
|
1492
1426
|
try {
|
|
1427
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1428
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1429
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1493
1430
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1494
|
-
const { page = 0, perPage = 10 } = pagination || {};
|
|
1495
|
-
const offset = page * perPage;
|
|
1496
|
-
const query = table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).limit(perPage);
|
|
1497
|
-
if (offset > 0) query.offset(offset);
|
|
1498
|
-
const records = await query.toArray();
|
|
1499
|
-
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1500
|
-
const scores = processResultWithTypeConversion(records, schema);
|
|
1501
1431
|
const allRecords = await table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).toArray();
|
|
1502
1432
|
const total = allRecords.length;
|
|
1433
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1434
|
+
let query = table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`);
|
|
1435
|
+
if (perPageInput !== false) {
|
|
1436
|
+
query = query.limit(perPage);
|
|
1437
|
+
if (start > 0) query = query.offset(start);
|
|
1438
|
+
}
|
|
1439
|
+
const records = await query.toArray();
|
|
1440
|
+
const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
|
|
1503
1441
|
return {
|
|
1504
1442
|
pagination: {
|
|
1505
1443
|
page,
|
|
1506
|
-
perPage,
|
|
1444
|
+
perPage: perPageForResponse,
|
|
1507
1445
|
total,
|
|
1508
|
-
hasMore:
|
|
1446
|
+
hasMore: end < total
|
|
1509
1447
|
},
|
|
1510
1448
|
scores
|
|
1511
1449
|
};
|
|
@@ -1522,198 +1460,48 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1522
1460
|
);
|
|
1523
1461
|
}
|
|
1524
1462
|
}
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
constructor({ client, operations }) {
|
|
1530
|
-
super();
|
|
1531
|
-
this.client = client;
|
|
1532
|
-
this.operations = operations;
|
|
1533
|
-
}
|
|
1534
|
-
async saveTrace({ trace }) {
|
|
1535
|
-
try {
|
|
1536
|
-
const table = await this.client.openTable(TABLE_TRACES);
|
|
1537
|
-
const record = {
|
|
1538
|
-
...trace,
|
|
1539
|
-
attributes: JSON.stringify(trace.attributes),
|
|
1540
|
-
status: JSON.stringify(trace.status),
|
|
1541
|
-
events: JSON.stringify(trace.events),
|
|
1542
|
-
links: JSON.stringify(trace.links),
|
|
1543
|
-
other: JSON.stringify(trace.other)
|
|
1544
|
-
};
|
|
1545
|
-
await table.add([record], { mode: "append" });
|
|
1546
|
-
return trace;
|
|
1547
|
-
} catch (error) {
|
|
1548
|
-
throw new MastraError(
|
|
1549
|
-
{
|
|
1550
|
-
id: "LANCE_STORE_SAVE_TRACE_FAILED",
|
|
1551
|
-
domain: ErrorDomain.STORAGE,
|
|
1552
|
-
category: ErrorCategory.THIRD_PARTY
|
|
1553
|
-
},
|
|
1554
|
-
error
|
|
1555
|
-
);
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
async getTraceById({ traceId }) {
|
|
1559
|
-
try {
|
|
1560
|
-
const table = await this.client.openTable(TABLE_TRACES);
|
|
1561
|
-
const query = table.query().where(`id = '${traceId}'`);
|
|
1562
|
-
const records = await query.toArray();
|
|
1563
|
-
return records[0];
|
|
1564
|
-
} catch (error) {
|
|
1565
|
-
throw new MastraError(
|
|
1566
|
-
{
|
|
1567
|
-
id: "LANCE_STORE_GET_TRACE_BY_ID_FAILED",
|
|
1568
|
-
domain: ErrorDomain.STORAGE,
|
|
1569
|
-
category: ErrorCategory.THIRD_PARTY
|
|
1570
|
-
},
|
|
1571
|
-
error
|
|
1572
|
-
);
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
async getTraces({
|
|
1576
|
-
name,
|
|
1577
|
-
scope,
|
|
1578
|
-
page = 1,
|
|
1579
|
-
perPage = 10,
|
|
1580
|
-
attributes
|
|
1463
|
+
async listScoresBySpan({
|
|
1464
|
+
traceId,
|
|
1465
|
+
spanId,
|
|
1466
|
+
pagination
|
|
1581
1467
|
}) {
|
|
1582
1468
|
try {
|
|
1583
|
-
const
|
|
1584
|
-
const
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
}
|
|
1591
|
-
if (
|
|
1592
|
-
query
|
|
1593
|
-
|
|
1594
|
-
const offset = (page - 1) * perPage;
|
|
1595
|
-
query.limit(perPage);
|
|
1596
|
-
if (offset > 0) {
|
|
1597
|
-
query.offset(offset);
|
|
1598
|
-
}
|
|
1599
|
-
const records = await query.toArray();
|
|
1600
|
-
return records.map((record) => {
|
|
1601
|
-
const processed = {
|
|
1602
|
-
...record,
|
|
1603
|
-
attributes: record.attributes ? JSON.parse(record.attributes) : {},
|
|
1604
|
-
status: record.status ? JSON.parse(record.status) : {},
|
|
1605
|
-
events: record.events ? JSON.parse(record.events) : [],
|
|
1606
|
-
links: record.links ? JSON.parse(record.links) : [],
|
|
1607
|
-
other: record.other ? JSON.parse(record.other) : {},
|
|
1608
|
-
startTime: new Date(record.startTime),
|
|
1609
|
-
endTime: new Date(record.endTime),
|
|
1610
|
-
createdAt: new Date(record.createdAt)
|
|
1611
|
-
};
|
|
1612
|
-
if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
|
|
1613
|
-
processed.parentSpanId = "";
|
|
1614
|
-
} else {
|
|
1615
|
-
processed.parentSpanId = String(processed.parentSpanId);
|
|
1616
|
-
}
|
|
1617
|
-
return processed;
|
|
1618
|
-
});
|
|
1619
|
-
} catch (error) {
|
|
1620
|
-
throw new MastraError(
|
|
1621
|
-
{
|
|
1622
|
-
id: "LANCE_STORE_GET_TRACES_FAILED",
|
|
1623
|
-
domain: ErrorDomain.STORAGE,
|
|
1624
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
1625
|
-
details: { name: name ?? "", scope: scope ?? "" }
|
|
1626
|
-
},
|
|
1627
|
-
error
|
|
1628
|
-
);
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
async getTracesPaginated(args) {
|
|
1632
|
-
try {
|
|
1633
|
-
const table = await this.client.openTable(TABLE_TRACES);
|
|
1634
|
-
const query = table.query();
|
|
1635
|
-
const conditions = [];
|
|
1636
|
-
if (args.name) {
|
|
1637
|
-
conditions.push(`name = '${args.name}'`);
|
|
1638
|
-
}
|
|
1639
|
-
if (args.scope) {
|
|
1640
|
-
conditions.push(`scope = '${args.scope}'`);
|
|
1641
|
-
}
|
|
1642
|
-
if (args.attributes) {
|
|
1643
|
-
const attributesStr = JSON.stringify(args.attributes);
|
|
1644
|
-
conditions.push(`attributes LIKE '%${attributesStr.replace(/"/g, '\\"')}%'`);
|
|
1645
|
-
}
|
|
1646
|
-
if (args.dateRange?.start) {
|
|
1647
|
-
conditions.push(`\`createdAt\` >= ${args.dateRange.start.getTime()}`);
|
|
1648
|
-
}
|
|
1649
|
-
if (args.dateRange?.end) {
|
|
1650
|
-
conditions.push(`\`createdAt\` <= ${args.dateRange.end.getTime()}`);
|
|
1651
|
-
}
|
|
1652
|
-
if (conditions.length > 0) {
|
|
1653
|
-
const whereClause = conditions.join(" AND ");
|
|
1654
|
-
query.where(whereClause);
|
|
1655
|
-
}
|
|
1656
|
-
let total = 0;
|
|
1657
|
-
if (conditions.length > 0) {
|
|
1658
|
-
const countQuery = table.query().where(conditions.join(" AND "));
|
|
1659
|
-
const allRecords = await countQuery.toArray();
|
|
1660
|
-
total = allRecords.length;
|
|
1661
|
-
} else {
|
|
1662
|
-
total = await table.countRows();
|
|
1663
|
-
}
|
|
1664
|
-
const page = args.page || 0;
|
|
1665
|
-
const perPage = args.perPage || 10;
|
|
1666
|
-
const offset = page * perPage;
|
|
1667
|
-
query.limit(perPage);
|
|
1668
|
-
if (offset > 0) {
|
|
1669
|
-
query.offset(offset);
|
|
1469
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1470
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1471
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1472
|
+
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1473
|
+
const allRecords = await table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`).toArray();
|
|
1474
|
+
const total = allRecords.length;
|
|
1475
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1476
|
+
let query = table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`);
|
|
1477
|
+
if (perPageInput !== false) {
|
|
1478
|
+
query = query.limit(perPage);
|
|
1479
|
+
if (start > 0) query = query.offset(start);
|
|
1670
1480
|
}
|
|
1671
1481
|
const records = await query.toArray();
|
|
1672
|
-
const
|
|
1673
|
-
const processed = {
|
|
1674
|
-
...record,
|
|
1675
|
-
attributes: record.attributes ? JSON.parse(record.attributes) : {},
|
|
1676
|
-
status: record.status ? JSON.parse(record.status) : {},
|
|
1677
|
-
events: record.events ? JSON.parse(record.events) : [],
|
|
1678
|
-
links: record.links ? JSON.parse(record.links) : [],
|
|
1679
|
-
other: record.other ? JSON.parse(record.other) : {},
|
|
1680
|
-
startTime: new Date(record.startTime),
|
|
1681
|
-
endTime: new Date(record.endTime),
|
|
1682
|
-
createdAt: new Date(record.createdAt)
|
|
1683
|
-
};
|
|
1684
|
-
if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
|
|
1685
|
-
processed.parentSpanId = "";
|
|
1686
|
-
} else {
|
|
1687
|
-
processed.parentSpanId = String(processed.parentSpanId);
|
|
1688
|
-
}
|
|
1689
|
-
return processed;
|
|
1690
|
-
});
|
|
1482
|
+
const scores = await Promise.all(records.map(async (record) => await this.transformScoreRow(record)));
|
|
1691
1483
|
return {
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1484
|
+
pagination: {
|
|
1485
|
+
page,
|
|
1486
|
+
perPage: perPageForResponse,
|
|
1487
|
+
total,
|
|
1488
|
+
hasMore: end < total
|
|
1489
|
+
},
|
|
1490
|
+
scores
|
|
1697
1491
|
};
|
|
1698
1492
|
} catch (error) {
|
|
1699
1493
|
throw new MastraError(
|
|
1700
1494
|
{
|
|
1701
|
-
id: "
|
|
1495
|
+
id: "LANCE_STORAGE_GET_SCORES_BY_SPAN_FAILED",
|
|
1496
|
+
text: "Failed to get scores by traceId and spanId in LanceStorage",
|
|
1702
1497
|
domain: ErrorDomain.STORAGE,
|
|
1703
1498
|
category: ErrorCategory.THIRD_PARTY,
|
|
1704
|
-
details: {
|
|
1499
|
+
details: { error: error?.message }
|
|
1705
1500
|
},
|
|
1706
1501
|
error
|
|
1707
1502
|
);
|
|
1708
1503
|
}
|
|
1709
1504
|
}
|
|
1710
|
-
async batchTraceInsert({ records }) {
|
|
1711
|
-
this.logger.debug("Batch inserting traces", { count: records.length });
|
|
1712
|
-
await this.operations.batchInsert({
|
|
1713
|
-
tableName: TABLE_TRACES,
|
|
1714
|
-
records
|
|
1715
|
-
});
|
|
1716
|
-
}
|
|
1717
1505
|
};
|
|
1718
1506
|
function parseWorkflowRun(row) {
|
|
1719
1507
|
let parsedSnapshot = row.snapshot;
|
|
@@ -1739,9 +1527,26 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1739
1527
|
super();
|
|
1740
1528
|
this.client = client;
|
|
1741
1529
|
}
|
|
1530
|
+
updateWorkflowResults({
|
|
1531
|
+
// workflowName,
|
|
1532
|
+
// runId,
|
|
1533
|
+
// stepId,
|
|
1534
|
+
// result,
|
|
1535
|
+
// requestContext,
|
|
1536
|
+
}) {
|
|
1537
|
+
throw new Error("Method not implemented.");
|
|
1538
|
+
}
|
|
1539
|
+
updateWorkflowState({
|
|
1540
|
+
// workflowName,
|
|
1541
|
+
// runId,
|
|
1542
|
+
// opts,
|
|
1543
|
+
}) {
|
|
1544
|
+
throw new Error("Method not implemented.");
|
|
1545
|
+
}
|
|
1742
1546
|
async persistWorkflowSnapshot({
|
|
1743
1547
|
workflowName,
|
|
1744
1548
|
runId,
|
|
1549
|
+
resourceId,
|
|
1745
1550
|
snapshot
|
|
1746
1551
|
}) {
|
|
1747
1552
|
try {
|
|
@@ -1755,10 +1560,13 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1755
1560
|
} else {
|
|
1756
1561
|
createdAt = now;
|
|
1757
1562
|
}
|
|
1563
|
+
const { status, value, ...rest } = snapshot;
|
|
1758
1564
|
const record = {
|
|
1759
1565
|
workflow_name: workflowName,
|
|
1760
1566
|
run_id: runId,
|
|
1761
|
-
|
|
1567
|
+
resourceId,
|
|
1568
|
+
snapshot: JSON.stringify({ status, value, ...rest }),
|
|
1569
|
+
// this is to ensure status is always just before value, for when querying the db by status
|
|
1762
1570
|
createdAt,
|
|
1763
1571
|
updatedAt: now
|
|
1764
1572
|
};
|
|
@@ -1820,7 +1628,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1820
1628
|
);
|
|
1821
1629
|
}
|
|
1822
1630
|
}
|
|
1823
|
-
async
|
|
1631
|
+
async listWorkflowRuns(args) {
|
|
1824
1632
|
try {
|
|
1825
1633
|
const table = await this.client.openTable(TABLE_WORKFLOW_SNAPSHOT);
|
|
1826
1634
|
let query = table.query();
|
|
@@ -1828,6 +1636,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1828
1636
|
if (args?.workflowName) {
|
|
1829
1637
|
conditions.push(`workflow_name = '${args.workflowName.replace(/'/g, "''")}'`);
|
|
1830
1638
|
}
|
|
1639
|
+
if (args?.status) {
|
|
1640
|
+
const escapedStatus = args.status.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
1641
|
+
conditions.push(`\`snapshot\` LIKE '%"status":"${escapedStatus}","value"%'`);
|
|
1642
|
+
}
|
|
1831
1643
|
if (args?.resourceId) {
|
|
1832
1644
|
conditions.push(`\`resourceId\` = '${args.resourceId}'`);
|
|
1833
1645
|
}
|
|
@@ -1844,11 +1656,22 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1844
1656
|
} else {
|
|
1845
1657
|
total = await table.countRows();
|
|
1846
1658
|
}
|
|
1847
|
-
if (args?.
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1659
|
+
if (args?.perPage !== void 0 && args?.page !== void 0) {
|
|
1660
|
+
const normalizedPerPage = normalizePerPage(args.perPage, Number.MAX_SAFE_INTEGER);
|
|
1661
|
+
if (args.page < 0 || !Number.isInteger(args.page)) {
|
|
1662
|
+
throw new MastraError(
|
|
1663
|
+
{
|
|
1664
|
+
id: "LANCE_STORE_INVALID_PAGINATION_PARAMS",
|
|
1665
|
+
domain: ErrorDomain.STORAGE,
|
|
1666
|
+
category: ErrorCategory.USER,
|
|
1667
|
+
details: { page: args.page, perPage: args.perPage }
|
|
1668
|
+
},
|
|
1669
|
+
new Error(`Invalid pagination parameters: page=${args.page}, perPage=${args.perPage}`)
|
|
1670
|
+
);
|
|
1671
|
+
}
|
|
1672
|
+
const offset = args.page * normalizedPerPage;
|
|
1673
|
+
query.limit(normalizedPerPage);
|
|
1674
|
+
query.offset(offset);
|
|
1852
1675
|
}
|
|
1853
1676
|
const records = await query.toArray();
|
|
1854
1677
|
return {
|
|
@@ -1858,10 +1681,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1858
1681
|
} catch (error) {
|
|
1859
1682
|
throw new MastraError(
|
|
1860
1683
|
{
|
|
1861
|
-
id: "
|
|
1684
|
+
id: "LANCE_STORE_LIST_WORKFLOW_RUNS_FAILED",
|
|
1862
1685
|
domain: ErrorDomain.STORAGE,
|
|
1863
1686
|
category: ErrorCategory.THIRD_PARTY,
|
|
1864
|
-
details: {
|
|
1687
|
+
details: { resourceId: args?.resourceId ?? "", workflowName: args?.workflowName ?? "" }
|
|
1865
1688
|
},
|
|
1866
1689
|
error
|
|
1867
1690
|
);
|
|
@@ -1875,6 +1698,8 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
1875
1698
|
lanceClient;
|
|
1876
1699
|
/**
|
|
1877
1700
|
* Creates a new instance of LanceStorage
|
|
1701
|
+
* @param id The unique identifier for this storage instance
|
|
1702
|
+
* @param name The name for this storage instance
|
|
1878
1703
|
* @param uri The URI to connect to LanceDB
|
|
1879
1704
|
* @param options connection options
|
|
1880
1705
|
*
|
|
@@ -1882,31 +1707,29 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
1882
1707
|
*
|
|
1883
1708
|
* Connect to a local database
|
|
1884
1709
|
* ```ts
|
|
1885
|
-
* const store = await LanceStorage.create('/path/to/db');
|
|
1710
|
+
* const store = await LanceStorage.create('my-storage-id', 'MyStorage', '/path/to/db');
|
|
1886
1711
|
* ```
|
|
1887
1712
|
*
|
|
1888
1713
|
* Connect to a LanceDB cloud database
|
|
1889
1714
|
* ```ts
|
|
1890
|
-
* const store = await LanceStorage.create('db://host:port');
|
|
1715
|
+
* const store = await LanceStorage.create('my-storage-id', 'MyStorage', 'db://host:port');
|
|
1891
1716
|
* ```
|
|
1892
1717
|
*
|
|
1893
1718
|
* Connect to a cloud database
|
|
1894
1719
|
* ```ts
|
|
1895
|
-
* const store = await LanceStorage.create('s3://bucket/db', { storageOptions: { timeout: '60s' } });
|
|
1720
|
+
* const store = await LanceStorage.create('my-storage-id', 'MyStorage', 's3://bucket/db', { storageOptions: { timeout: '60s' } });
|
|
1896
1721
|
* ```
|
|
1897
1722
|
*/
|
|
1898
|
-
static async create(name, uri, options) {
|
|
1899
|
-
const instance = new _LanceStorage(name);
|
|
1723
|
+
static async create(id, name, uri, options) {
|
|
1724
|
+
const instance = new _LanceStorage(id, name);
|
|
1900
1725
|
try {
|
|
1901
1726
|
instance.lanceClient = await connect(uri, options);
|
|
1902
1727
|
const operations = new StoreOperationsLance({ client: instance.lanceClient });
|
|
1903
1728
|
instance.stores = {
|
|
1904
1729
|
operations: new StoreOperationsLance({ client: instance.lanceClient }),
|
|
1905
1730
|
workflows: new StoreWorkflowsLance({ client: instance.lanceClient }),
|
|
1906
|
-
traces: new StoreTracesLance({ client: instance.lanceClient, operations }),
|
|
1907
1731
|
scores: new StoreScoresLance({ client: instance.lanceClient }),
|
|
1908
|
-
memory: new StoreMemoryLance({ client: instance.lanceClient, operations })
|
|
1909
|
-
legacyEvals: new StoreLegacyEvalsLance({ client: instance.lanceClient })
|
|
1732
|
+
memory: new StoreMemoryLance({ client: instance.lanceClient, operations })
|
|
1910
1733
|
};
|
|
1911
1734
|
return instance;
|
|
1912
1735
|
} catch (e) {
|
|
@@ -1926,15 +1749,13 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
1926
1749
|
* @internal
|
|
1927
1750
|
* Private constructor to enforce using the create factory method
|
|
1928
1751
|
*/
|
|
1929
|
-
constructor(name) {
|
|
1930
|
-
super({ name });
|
|
1752
|
+
constructor(id, name) {
|
|
1753
|
+
super({ id, name });
|
|
1931
1754
|
const operations = new StoreOperationsLance({ client: this.lanceClient });
|
|
1932
1755
|
this.stores = {
|
|
1933
1756
|
operations: new StoreOperationsLance({ client: this.lanceClient }),
|
|
1934
1757
|
workflows: new StoreWorkflowsLance({ client: this.lanceClient }),
|
|
1935
|
-
traces: new StoreTracesLance({ client: this.lanceClient, operations }),
|
|
1936
1758
|
scores: new StoreScoresLance({ client: this.lanceClient }),
|
|
1937
|
-
legacyEvals: new StoreLegacyEvalsLance({ client: this.lanceClient }),
|
|
1938
1759
|
memory: new StoreMemoryLance({ client: this.lanceClient, operations })
|
|
1939
1760
|
};
|
|
1940
1761
|
}
|
|
@@ -1969,9 +1790,6 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
1969
1790
|
async getThreadById({ threadId }) {
|
|
1970
1791
|
return this.stores.memory.getThreadById({ threadId });
|
|
1971
1792
|
}
|
|
1972
|
-
async getThreadsByResourceId({ resourceId }) {
|
|
1973
|
-
return this.stores.memory.getThreadsByResourceId({ resourceId });
|
|
1974
|
-
}
|
|
1975
1793
|
/**
|
|
1976
1794
|
* Saves a thread to the database. This function doesn't overwrite existing threads.
|
|
1977
1795
|
* @param thread - The thread to save
|
|
@@ -1996,7 +1814,8 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
1996
1814
|
resourceWorkingMemory: true,
|
|
1997
1815
|
hasColumn: true,
|
|
1998
1816
|
createTable: true,
|
|
1999
|
-
deleteMessages: false
|
|
1817
|
+
deleteMessages: false,
|
|
1818
|
+
listScoresBySpan: true
|
|
2000
1819
|
};
|
|
2001
1820
|
}
|
|
2002
1821
|
async getResourceById({ resourceId }) {
|
|
@@ -2060,54 +1879,44 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2060
1879
|
});
|
|
2061
1880
|
return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
|
|
2062
1881
|
}
|
|
2063
|
-
async
|
|
2064
|
-
|
|
2065
|
-
resourceId,
|
|
2066
|
-
selectBy,
|
|
2067
|
-
format,
|
|
2068
|
-
threadConfig
|
|
2069
|
-
}) {
|
|
2070
|
-
return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format, threadConfig });
|
|
1882
|
+
async listMessagesById({ messageIds }) {
|
|
1883
|
+
return this.stores.memory.listMessagesById({ messageIds });
|
|
2071
1884
|
}
|
|
2072
1885
|
async saveMessages(args) {
|
|
2073
1886
|
return this.stores.memory.saveMessages(args);
|
|
2074
1887
|
}
|
|
2075
|
-
async getThreadsByResourceIdPaginated(args) {
|
|
2076
|
-
return this.stores.memory.getThreadsByResourceIdPaginated(args);
|
|
2077
|
-
}
|
|
2078
|
-
async getMessagesPaginated(args) {
|
|
2079
|
-
return this.stores.memory.getMessagesPaginated(args);
|
|
2080
|
-
}
|
|
2081
1888
|
async updateMessages(_args) {
|
|
2082
1889
|
return this.stores.memory.updateMessages(_args);
|
|
2083
1890
|
}
|
|
2084
|
-
async
|
|
2085
|
-
return this.stores.
|
|
2086
|
-
}
|
|
2087
|
-
async getTraces(args) {
|
|
2088
|
-
return this.stores.traces.getTraces(args);
|
|
2089
|
-
}
|
|
2090
|
-
async getTracesPaginated(args) {
|
|
2091
|
-
return this.stores.traces.getTracesPaginated(args);
|
|
2092
|
-
}
|
|
2093
|
-
async getEvalsByAgentName(agentName, type) {
|
|
2094
|
-
return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
|
|
2095
|
-
}
|
|
2096
|
-
async getEvals(options) {
|
|
2097
|
-
return this.stores.legacyEvals.getEvals(options);
|
|
2098
|
-
}
|
|
2099
|
-
async getWorkflowRuns(args) {
|
|
2100
|
-
return this.stores.workflows.getWorkflowRuns(args);
|
|
1891
|
+
async listWorkflowRuns(args) {
|
|
1892
|
+
return this.stores.workflows.listWorkflowRuns(args);
|
|
2101
1893
|
}
|
|
2102
1894
|
async getWorkflowRunById(args) {
|
|
2103
1895
|
return this.stores.workflows.getWorkflowRunById(args);
|
|
2104
1896
|
}
|
|
1897
|
+
async updateWorkflowResults({
|
|
1898
|
+
workflowName,
|
|
1899
|
+
runId,
|
|
1900
|
+
stepId,
|
|
1901
|
+
result,
|
|
1902
|
+
requestContext
|
|
1903
|
+
}) {
|
|
1904
|
+
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
|
|
1905
|
+
}
|
|
1906
|
+
async updateWorkflowState({
|
|
1907
|
+
workflowName,
|
|
1908
|
+
runId,
|
|
1909
|
+
opts
|
|
1910
|
+
}) {
|
|
1911
|
+
return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
|
|
1912
|
+
}
|
|
2105
1913
|
async persistWorkflowSnapshot({
|
|
2106
1914
|
workflowName,
|
|
2107
1915
|
runId,
|
|
1916
|
+
resourceId,
|
|
2108
1917
|
snapshot
|
|
2109
1918
|
}) {
|
|
2110
|
-
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
|
|
1919
|
+
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
2111
1920
|
}
|
|
2112
1921
|
async loadWorkflowSnapshot({
|
|
2113
1922
|
workflowName,
|
|
@@ -2118,27 +1927,37 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2118
1927
|
async getScoreById({ id: _id }) {
|
|
2119
1928
|
return this.stores.scores.getScoreById({ id: _id });
|
|
2120
1929
|
}
|
|
2121
|
-
async
|
|
1930
|
+
async listScoresByScorerId({
|
|
2122
1931
|
scorerId,
|
|
1932
|
+
source,
|
|
1933
|
+
entityId,
|
|
1934
|
+
entityType,
|
|
2123
1935
|
pagination
|
|
2124
1936
|
}) {
|
|
2125
|
-
return this.stores.scores.
|
|
1937
|
+
return this.stores.scores.listScoresByScorerId({ scorerId, source, pagination, entityId, entityType });
|
|
2126
1938
|
}
|
|
2127
1939
|
async saveScore(_score) {
|
|
2128
1940
|
return this.stores.scores.saveScore(_score);
|
|
2129
1941
|
}
|
|
2130
|
-
async
|
|
1942
|
+
async listScoresByRunId({
|
|
2131
1943
|
runId,
|
|
2132
1944
|
pagination
|
|
2133
1945
|
}) {
|
|
2134
|
-
return this.stores.scores.
|
|
1946
|
+
return this.stores.scores.listScoresByRunId({ runId, pagination });
|
|
2135
1947
|
}
|
|
2136
|
-
async
|
|
1948
|
+
async listScoresByEntityId({
|
|
2137
1949
|
entityId,
|
|
2138
1950
|
entityType,
|
|
2139
1951
|
pagination
|
|
2140
1952
|
}) {
|
|
2141
|
-
return this.stores.scores.
|
|
1953
|
+
return this.stores.scores.listScoresByEntityId({ entityId, entityType, pagination });
|
|
1954
|
+
}
|
|
1955
|
+
async listScoresBySpan({
|
|
1956
|
+
traceId,
|
|
1957
|
+
spanId,
|
|
1958
|
+
pagination
|
|
1959
|
+
}) {
|
|
1960
|
+
return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
|
|
2142
1961
|
}
|
|
2143
1962
|
};
|
|
2144
1963
|
var LanceFilterTranslator = class extends BaseFilterTranslator {
|
|
@@ -2487,7 +2306,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2487
2306
|
* ```
|
|
2488
2307
|
*/
|
|
2489
2308
|
static async create(uri, options) {
|
|
2490
|
-
const instance = new _LanceVectorStore();
|
|
2309
|
+
const instance = new _LanceVectorStore(options?.id || crypto.randomUUID());
|
|
2491
2310
|
try {
|
|
2492
2311
|
instance.lanceClient = await connect(uri, options);
|
|
2493
2312
|
return instance;
|
|
@@ -2507,8 +2326,8 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2507
2326
|
* @internal
|
|
2508
2327
|
* Private constructor to enforce using the create factory method
|
|
2509
2328
|
*/
|
|
2510
|
-
constructor() {
|
|
2511
|
-
super();
|
|
2329
|
+
constructor(id) {
|
|
2330
|
+
super({ id });
|
|
2512
2331
|
}
|
|
2513
2332
|
close() {
|
|
2514
2333
|
if (this.lanceClient) {
|
|
@@ -3031,7 +2850,44 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3031
2850
|
);
|
|
3032
2851
|
}
|
|
3033
2852
|
}
|
|
3034
|
-
async updateVector(
|
|
2853
|
+
async updateVector(params) {
|
|
2854
|
+
const { indexName, update } = params;
|
|
2855
|
+
if ("id" in params && "filter" in params && params.id && params.filter) {
|
|
2856
|
+
throw new MastraError({
|
|
2857
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2858
|
+
domain: ErrorDomain.STORAGE,
|
|
2859
|
+
category: ErrorCategory.USER,
|
|
2860
|
+
text: "id and filter are mutually exclusive",
|
|
2861
|
+
details: { indexName }
|
|
2862
|
+
});
|
|
2863
|
+
}
|
|
2864
|
+
if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
|
|
2865
|
+
throw new MastraError({
|
|
2866
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2867
|
+
domain: ErrorDomain.STORAGE,
|
|
2868
|
+
category: ErrorCategory.USER,
|
|
2869
|
+
text: "Either id or filter must be provided",
|
|
2870
|
+
details: { indexName }
|
|
2871
|
+
});
|
|
2872
|
+
}
|
|
2873
|
+
if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
|
|
2874
|
+
throw new MastraError({
|
|
2875
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2876
|
+
domain: ErrorDomain.STORAGE,
|
|
2877
|
+
category: ErrorCategory.USER,
|
|
2878
|
+
text: "Cannot update with empty filter",
|
|
2879
|
+
details: { indexName }
|
|
2880
|
+
});
|
|
2881
|
+
}
|
|
2882
|
+
if (!update.vector && !update.metadata) {
|
|
2883
|
+
throw new MastraError({
|
|
2884
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2885
|
+
domain: ErrorDomain.STORAGE,
|
|
2886
|
+
category: ErrorCategory.USER,
|
|
2887
|
+
text: "No updates provided",
|
|
2888
|
+
details: { indexName }
|
|
2889
|
+
});
|
|
2890
|
+
}
|
|
3035
2891
|
try {
|
|
3036
2892
|
if (!this.lanceClient) {
|
|
3037
2893
|
throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
|
|
@@ -3039,21 +2895,6 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3039
2895
|
if (!indexName) {
|
|
3040
2896
|
throw new Error("indexName is required");
|
|
3041
2897
|
}
|
|
3042
|
-
if (!id) {
|
|
3043
|
-
throw new Error("id is required");
|
|
3044
|
-
}
|
|
3045
|
-
} catch (err) {
|
|
3046
|
-
throw new MastraError(
|
|
3047
|
-
{
|
|
3048
|
-
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
|
|
3049
|
-
domain: ErrorDomain.STORAGE,
|
|
3050
|
-
category: ErrorCategory.USER,
|
|
3051
|
-
details: { indexName, id }
|
|
3052
|
-
},
|
|
3053
|
-
err
|
|
3054
|
-
);
|
|
3055
|
-
}
|
|
3056
|
-
try {
|
|
3057
2898
|
const tables = await this.lanceClient.tableNames();
|
|
3058
2899
|
for (const tableName of tables) {
|
|
3059
2900
|
this.logger.debug("Checking table:" + tableName);
|
|
@@ -3063,39 +2904,66 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3063
2904
|
const hasColumn = schema.fields.some((field) => field.name === indexName);
|
|
3064
2905
|
if (hasColumn) {
|
|
3065
2906
|
this.logger.debug(`Found column ${indexName} in table ${tableName}`);
|
|
3066
|
-
|
|
3067
|
-
if (
|
|
3068
|
-
|
|
2907
|
+
let whereClause;
|
|
2908
|
+
if ("id" in params && params.id) {
|
|
2909
|
+
whereClause = `id = '${params.id}'`;
|
|
2910
|
+
} else if ("filter" in params && params.filter) {
|
|
2911
|
+
const translator = new LanceFilterTranslator();
|
|
2912
|
+
const processFilterKeys = (filter) => {
|
|
2913
|
+
const processedFilter = {};
|
|
2914
|
+
Object.entries(filter).forEach(([key, value]) => {
|
|
2915
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
2916
|
+
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
|
|
2917
|
+
processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
|
|
2918
|
+
});
|
|
2919
|
+
} else {
|
|
2920
|
+
processedFilter[`metadata_${key}`] = value;
|
|
2921
|
+
}
|
|
2922
|
+
});
|
|
2923
|
+
return processedFilter;
|
|
2924
|
+
};
|
|
2925
|
+
const prefixedFilter = processFilterKeys(params.filter);
|
|
2926
|
+
whereClause = translator.translate(prefixedFilter) || "";
|
|
2927
|
+
if (!whereClause) {
|
|
2928
|
+
throw new Error("Failed to translate filter to SQL");
|
|
2929
|
+
}
|
|
2930
|
+
} else {
|
|
2931
|
+
throw new Error("Either id or filter must be provided");
|
|
3069
2932
|
}
|
|
3070
|
-
const
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
2933
|
+
const existingRecords = await table.query().where(whereClause).select(schema.fields.map((field) => field.name)).toArray();
|
|
2934
|
+
if (existingRecords.length === 0) {
|
|
2935
|
+
this.logger.info(`No records found matching criteria in table ${tableName}`);
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
const updatedRecords = existingRecords.map((record) => {
|
|
2939
|
+
const rowData = {};
|
|
2940
|
+
Object.entries(record).forEach(([key, value]) => {
|
|
2941
|
+
if (key !== "_distance") {
|
|
2942
|
+
if (key === indexName) {
|
|
2943
|
+
if (update.vector) {
|
|
2944
|
+
rowData[key] = update.vector;
|
|
3081
2945
|
} else {
|
|
3082
|
-
|
|
2946
|
+
if (Array.isArray(value)) {
|
|
2947
|
+
rowData[key] = [...value];
|
|
2948
|
+
} else if (typeof value === "object" && value !== null) {
|
|
2949
|
+
rowData[key] = Array.from(value);
|
|
2950
|
+
} else {
|
|
2951
|
+
rowData[key] = value;
|
|
2952
|
+
}
|
|
3083
2953
|
}
|
|
2954
|
+
} else {
|
|
2955
|
+
rowData[key] = value;
|
|
3084
2956
|
}
|
|
3085
|
-
} else {
|
|
3086
|
-
rowData[key] = value;
|
|
3087
2957
|
}
|
|
2958
|
+
});
|
|
2959
|
+
if (update.metadata) {
|
|
2960
|
+
Object.entries(update.metadata).forEach(([key, value]) => {
|
|
2961
|
+
rowData[`metadata_${key}`] = value;
|
|
2962
|
+
});
|
|
3088
2963
|
}
|
|
2964
|
+
return rowData;
|
|
3089
2965
|
});
|
|
3090
|
-
|
|
3091
|
-
rowData[indexName] = update.vector;
|
|
3092
|
-
}
|
|
3093
|
-
if (update.metadata) {
|
|
3094
|
-
Object.entries(update.metadata).forEach(([key, value]) => {
|
|
3095
|
-
rowData[`metadata_${key}`] = value;
|
|
3096
|
-
});
|
|
3097
|
-
}
|
|
3098
|
-
await table.add([rowData], { mode: "overwrite" });
|
|
2966
|
+
await table.add(updatedRecords, { mode: "overwrite" });
|
|
3099
2967
|
return;
|
|
3100
2968
|
}
|
|
3101
2969
|
} catch (err) {
|
|
@@ -3105,12 +2973,19 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3105
2973
|
}
|
|
3106
2974
|
throw new Error(`No table found with column/index '${indexName}'`);
|
|
3107
2975
|
} catch (error) {
|
|
2976
|
+
if (error instanceof MastraError) throw error;
|
|
3108
2977
|
throw new MastraError(
|
|
3109
2978
|
{
|
|
3110
2979
|
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
|
|
3111
2980
|
domain: ErrorDomain.STORAGE,
|
|
3112
2981
|
category: ErrorCategory.THIRD_PARTY,
|
|
3113
|
-
details: {
|
|
2982
|
+
details: {
|
|
2983
|
+
indexName,
|
|
2984
|
+
..."id" in params && params.id && { id: params.id },
|
|
2985
|
+
..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) },
|
|
2986
|
+
hasVector: !!update.vector,
|
|
2987
|
+
hasMetadata: !!update.metadata
|
|
2988
|
+
}
|
|
3114
2989
|
},
|
|
3115
2990
|
error
|
|
3116
2991
|
);
|
|
@@ -3133,7 +3008,10 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3133
3008
|
id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
|
|
3134
3009
|
domain: ErrorDomain.STORAGE,
|
|
3135
3010
|
category: ErrorCategory.USER,
|
|
3136
|
-
details: {
|
|
3011
|
+
details: {
|
|
3012
|
+
indexName,
|
|
3013
|
+
...id && { id }
|
|
3014
|
+
}
|
|
3137
3015
|
},
|
|
3138
3016
|
err
|
|
3139
3017
|
);
|
|
@@ -3163,7 +3041,10 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3163
3041
|
id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
|
|
3164
3042
|
domain: ErrorDomain.STORAGE,
|
|
3165
3043
|
category: ErrorCategory.THIRD_PARTY,
|
|
3166
|
-
details: {
|
|
3044
|
+
details: {
|
|
3045
|
+
indexName,
|
|
3046
|
+
...id && { id }
|
|
3047
|
+
}
|
|
3167
3048
|
},
|
|
3168
3049
|
error
|
|
3169
3050
|
);
|
|
@@ -3194,6 +3075,109 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3194
3075
|
});
|
|
3195
3076
|
return result;
|
|
3196
3077
|
}
|
|
3078
|
+
async deleteVectors({ indexName, filter, ids }) {
|
|
3079
|
+
if (ids && filter) {
|
|
3080
|
+
throw new MastraError({
|
|
3081
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3082
|
+
domain: ErrorDomain.STORAGE,
|
|
3083
|
+
category: ErrorCategory.USER,
|
|
3084
|
+
text: "ids and filter are mutually exclusive",
|
|
3085
|
+
details: { indexName }
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
if (!ids && !filter) {
|
|
3089
|
+
throw new MastraError({
|
|
3090
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3091
|
+
domain: ErrorDomain.STORAGE,
|
|
3092
|
+
category: ErrorCategory.USER,
|
|
3093
|
+
text: "Either filter or ids must be provided",
|
|
3094
|
+
details: { indexName }
|
|
3095
|
+
});
|
|
3096
|
+
}
|
|
3097
|
+
if (ids && ids.length === 0) {
|
|
3098
|
+
throw new MastraError({
|
|
3099
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3100
|
+
domain: ErrorDomain.STORAGE,
|
|
3101
|
+
category: ErrorCategory.USER,
|
|
3102
|
+
text: "Cannot delete with empty ids array",
|
|
3103
|
+
details: { indexName }
|
|
3104
|
+
});
|
|
3105
|
+
}
|
|
3106
|
+
if (filter && Object.keys(filter).length === 0) {
|
|
3107
|
+
throw new MastraError({
|
|
3108
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3109
|
+
domain: ErrorDomain.STORAGE,
|
|
3110
|
+
category: ErrorCategory.USER,
|
|
3111
|
+
text: "Cannot delete with empty filter",
|
|
3112
|
+
details: { indexName }
|
|
3113
|
+
});
|
|
3114
|
+
}
|
|
3115
|
+
try {
|
|
3116
|
+
if (!this.lanceClient) {
|
|
3117
|
+
throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
|
|
3118
|
+
}
|
|
3119
|
+
if (!indexName) {
|
|
3120
|
+
throw new Error("indexName is required");
|
|
3121
|
+
}
|
|
3122
|
+
const tables = await this.lanceClient.tableNames();
|
|
3123
|
+
for (const tableName of tables) {
|
|
3124
|
+
this.logger.debug("Checking table:" + tableName);
|
|
3125
|
+
const table = await this.lanceClient.openTable(tableName);
|
|
3126
|
+
try {
|
|
3127
|
+
const schema = await table.schema();
|
|
3128
|
+
const hasColumn = schema.fields.some((field) => field.name === indexName);
|
|
3129
|
+
if (hasColumn) {
|
|
3130
|
+
this.logger.debug(`Found column ${indexName} in table ${tableName}`);
|
|
3131
|
+
if (ids) {
|
|
3132
|
+
const idsConditions = ids.map((id) => `id = '${id}'`).join(" OR ");
|
|
3133
|
+
await table.delete(idsConditions);
|
|
3134
|
+
} else if (filter) {
|
|
3135
|
+
const translator = new LanceFilterTranslator();
|
|
3136
|
+
const processFilterKeys = (filter2) => {
|
|
3137
|
+
const processedFilter = {};
|
|
3138
|
+
Object.entries(filter2).forEach(([key, value]) => {
|
|
3139
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
3140
|
+
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
|
|
3141
|
+
processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
|
|
3142
|
+
});
|
|
3143
|
+
} else {
|
|
3144
|
+
processedFilter[`metadata_${key}`] = value;
|
|
3145
|
+
}
|
|
3146
|
+
});
|
|
3147
|
+
return processedFilter;
|
|
3148
|
+
};
|
|
3149
|
+
const prefixedFilter = processFilterKeys(filter);
|
|
3150
|
+
const whereClause = translator.translate(prefixedFilter);
|
|
3151
|
+
if (!whereClause) {
|
|
3152
|
+
throw new Error("Failed to translate filter to SQL");
|
|
3153
|
+
}
|
|
3154
|
+
await table.delete(whereClause);
|
|
3155
|
+
}
|
|
3156
|
+
return;
|
|
3157
|
+
}
|
|
3158
|
+
} catch (err) {
|
|
3159
|
+
this.logger.error(`Error checking schema for table ${tableName}:` + err);
|
|
3160
|
+
continue;
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
throw new Error(`No table found with column/index '${indexName}'`);
|
|
3164
|
+
} catch (error) {
|
|
3165
|
+
if (error instanceof MastraError) throw error;
|
|
3166
|
+
throw new MastraError(
|
|
3167
|
+
{
|
|
3168
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_FAILED",
|
|
3169
|
+
domain: ErrorDomain.STORAGE,
|
|
3170
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3171
|
+
details: {
|
|
3172
|
+
indexName,
|
|
3173
|
+
...filter && { filter: JSON.stringify(filter) },
|
|
3174
|
+
...ids && { idsCount: ids.length }
|
|
3175
|
+
}
|
|
3176
|
+
},
|
|
3177
|
+
error
|
|
3178
|
+
);
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3197
3181
|
};
|
|
3198
3182
|
|
|
3199
3183
|
export { LanceStorage, LanceVectorStore };
|