@mastra/lance 0.0.0-vector-extension-schema-20250922130418 → 0.0.0-vnext-20251104230439
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 +236 -3
- package/dist/index.cjs +325 -553
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +326 -554
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +18 -39
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +12 -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 +4 -11
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +31 -82
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +8 -8
- 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, StoreOperations,
|
|
3
|
+
import { MastraStorage, StoreOperations, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, resolveMessageLimit, 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
|
}
|
|
@@ -246,6 +131,10 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
246
131
|
this.client = client;
|
|
247
132
|
this.operations = operations;
|
|
248
133
|
}
|
|
134
|
+
// Utility to escape single quotes in SQL strings
|
|
135
|
+
escapeSql(str) {
|
|
136
|
+
return str.replace(/'/g, "''");
|
|
137
|
+
}
|
|
249
138
|
async getThreadById({ threadId }) {
|
|
250
139
|
try {
|
|
251
140
|
const thread = await this.operations.load({ tableName: TABLE_THREADS, keys: { id: threadId } });
|
|
@@ -268,26 +157,6 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
268
157
|
);
|
|
269
158
|
}
|
|
270
159
|
}
|
|
271
|
-
async getThreadsByResourceId({ resourceId }) {
|
|
272
|
-
try {
|
|
273
|
-
const table = await this.client.openTable(TABLE_THREADS);
|
|
274
|
-
const query = table.query().where(`\`resourceId\` = '${resourceId}'`);
|
|
275
|
-
const records = await query.toArray();
|
|
276
|
-
return processResultWithTypeConversion(
|
|
277
|
-
records,
|
|
278
|
-
await getTableSchema({ tableName: TABLE_THREADS, client: this.client })
|
|
279
|
-
);
|
|
280
|
-
} catch (error) {
|
|
281
|
-
throw new MastraError(
|
|
282
|
-
{
|
|
283
|
-
id: "LANCE_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
|
|
284
|
-
domain: ErrorDomain.STORAGE,
|
|
285
|
-
category: ErrorCategory.THIRD_PARTY
|
|
286
|
-
},
|
|
287
|
-
error
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
160
|
/**
|
|
292
161
|
* Saves a thread to the database. This function doesn't overwrite existing threads.
|
|
293
162
|
* @param thread - The thread to save
|
|
@@ -396,7 +265,6 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
396
265
|
threadId,
|
|
397
266
|
resourceId,
|
|
398
267
|
selectBy,
|
|
399
|
-
format,
|
|
400
268
|
threadConfig
|
|
401
269
|
}) {
|
|
402
270
|
try {
|
|
@@ -433,9 +301,11 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
433
301
|
allRecords,
|
|
434
302
|
await getTableSchema({ tableName: TABLE_MESSAGES, client: this.client })
|
|
435
303
|
);
|
|
436
|
-
const list = new MessageList({ threadId, resourceId }).add(
|
|
437
|
-
|
|
438
|
-
|
|
304
|
+
const list = new MessageList({ threadId, resourceId }).add(
|
|
305
|
+
messages.map(this.normalizeMessage),
|
|
306
|
+
"memory"
|
|
307
|
+
);
|
|
308
|
+
return { messages: list.get.all.db() };
|
|
439
309
|
} catch (error) {
|
|
440
310
|
throw new MastraError(
|
|
441
311
|
{
|
|
@@ -451,11 +321,8 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
451
321
|
);
|
|
452
322
|
}
|
|
453
323
|
}
|
|
454
|
-
async
|
|
455
|
-
messageIds
|
|
456
|
-
format
|
|
457
|
-
}) {
|
|
458
|
-
if (messageIds.length === 0) return [];
|
|
324
|
+
async listMessagesById({ messageIds }) {
|
|
325
|
+
if (messageIds.length === 0) return { messages: [] };
|
|
459
326
|
try {
|
|
460
327
|
const table = await this.client.openTable(TABLE_MESSAGES);
|
|
461
328
|
const quotedIds = messageIds.map((id) => `'${id}'`).join(", ");
|
|
@@ -464,13 +331,15 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
464
331
|
allRecords,
|
|
465
332
|
await getTableSchema({ tableName: TABLE_MESSAGES, client: this.client })
|
|
466
333
|
);
|
|
467
|
-
const list = new MessageList().add(
|
|
468
|
-
|
|
469
|
-
|
|
334
|
+
const list = new MessageList().add(
|
|
335
|
+
messages.map(this.normalizeMessage),
|
|
336
|
+
"memory"
|
|
337
|
+
);
|
|
338
|
+
return { messages: list.get.all.db() };
|
|
470
339
|
} catch (error) {
|
|
471
340
|
throw new MastraError(
|
|
472
341
|
{
|
|
473
|
-
id: "
|
|
342
|
+
id: "LANCE_STORE_LIST_MESSAGES_BY_ID_FAILED",
|
|
474
343
|
domain: ErrorDomain.STORAGE,
|
|
475
344
|
category: ErrorCategory.THIRD_PARTY,
|
|
476
345
|
details: {
|
|
@@ -481,11 +350,145 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
481
350
|
);
|
|
482
351
|
}
|
|
483
352
|
}
|
|
353
|
+
async listMessages(args) {
|
|
354
|
+
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
355
|
+
if (!threadId.trim()) {
|
|
356
|
+
throw new MastraError(
|
|
357
|
+
{
|
|
358
|
+
id: "STORAGE_LANCE_LIST_MESSAGES_INVALID_THREAD_ID",
|
|
359
|
+
domain: ErrorDomain.STORAGE,
|
|
360
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
361
|
+
details: { threadId }
|
|
362
|
+
},
|
|
363
|
+
new Error("threadId must be a non-empty string")
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
const perPage = normalizePerPage(perPageInput, 40);
|
|
367
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
368
|
+
try {
|
|
369
|
+
if (page < 0) {
|
|
370
|
+
throw new MastraError(
|
|
371
|
+
{
|
|
372
|
+
id: "STORAGE_LANCE_LIST_MESSAGES_INVALID_PAGE",
|
|
373
|
+
domain: ErrorDomain.STORAGE,
|
|
374
|
+
category: ErrorCategory.USER,
|
|
375
|
+
details: { page }
|
|
376
|
+
},
|
|
377
|
+
new Error("page must be >= 0")
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
const { field, direction } = this.parseOrderBy(orderBy);
|
|
381
|
+
const table = await this.client.openTable(TABLE_MESSAGES);
|
|
382
|
+
const conditions = [`thread_id = '${this.escapeSql(threadId)}'`];
|
|
383
|
+
if (resourceId) {
|
|
384
|
+
conditions.push(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
|
|
385
|
+
}
|
|
386
|
+
if (filter?.dateRange?.start) {
|
|
387
|
+
const startTime = filter.dateRange.start instanceof Date ? filter.dateRange.start.getTime() : new Date(filter.dateRange.start).getTime();
|
|
388
|
+
conditions.push(`\`createdAt\` >= ${startTime}`);
|
|
389
|
+
}
|
|
390
|
+
if (filter?.dateRange?.end) {
|
|
391
|
+
const endTime = filter.dateRange.end instanceof Date ? filter.dateRange.end.getTime() : new Date(filter.dateRange.end).getTime();
|
|
392
|
+
conditions.push(`\`createdAt\` <= ${endTime}`);
|
|
393
|
+
}
|
|
394
|
+
const whereClause = conditions.join(" AND ");
|
|
395
|
+
const total = await table.countRows(whereClause);
|
|
396
|
+
const query = table.query().where(whereClause);
|
|
397
|
+
let allRecords = await query.toArray();
|
|
398
|
+
allRecords.sort((a, b) => {
|
|
399
|
+
const aValue = field === "createdAt" ? a.createdAt : a[field];
|
|
400
|
+
const bValue = field === "createdAt" ? b.createdAt : b[field];
|
|
401
|
+
if (aValue == null && bValue == null) return 0;
|
|
402
|
+
if (aValue == null) return direction === "ASC" ? -1 : 1;
|
|
403
|
+
if (bValue == null) return direction === "ASC" ? 1 : -1;
|
|
404
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
405
|
+
return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
|
406
|
+
}
|
|
407
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
408
|
+
});
|
|
409
|
+
const paginatedRecords = allRecords.slice(offset, offset + perPage);
|
|
410
|
+
const messages = paginatedRecords.map((row) => this.normalizeMessage(row));
|
|
411
|
+
if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
|
|
412
|
+
return {
|
|
413
|
+
messages: [],
|
|
414
|
+
total: 0,
|
|
415
|
+
page,
|
|
416
|
+
perPage: perPageForResponse,
|
|
417
|
+
hasMore: false
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
const messageIds = new Set(messages.map((m) => m.id));
|
|
421
|
+
if (include && include.length > 0) {
|
|
422
|
+
const threadIds = [...new Set(include.map((item) => item.threadId || threadId))];
|
|
423
|
+
const allThreadMessages = [];
|
|
424
|
+
for (const tid of threadIds) {
|
|
425
|
+
const threadQuery = table.query().where(`thread_id = '${tid}'`);
|
|
426
|
+
let threadRecords = await threadQuery.toArray();
|
|
427
|
+
allThreadMessages.push(...threadRecords);
|
|
428
|
+
}
|
|
429
|
+
allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
|
|
430
|
+
const contextMessages = this.processMessagesWithContext(allThreadMessages, include);
|
|
431
|
+
const includedMessages = contextMessages.map((row) => this.normalizeMessage(row));
|
|
432
|
+
for (const includeMsg of includedMessages) {
|
|
433
|
+
if (!messageIds.has(includeMsg.id)) {
|
|
434
|
+
messages.push(includeMsg);
|
|
435
|
+
messageIds.add(includeMsg.id);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
const list = new MessageList().add(messages, "memory");
|
|
440
|
+
let finalMessages = list.get.all.db();
|
|
441
|
+
finalMessages = finalMessages.sort((a, b) => {
|
|
442
|
+
const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
|
|
443
|
+
const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
|
|
444
|
+
if (aValue == null && bValue == null) return 0;
|
|
445
|
+
if (aValue == null) return direction === "ASC" ? -1 : 1;
|
|
446
|
+
if (bValue == null) return direction === "ASC" ? 1 : -1;
|
|
447
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
448
|
+
return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
|
449
|
+
}
|
|
450
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
451
|
+
});
|
|
452
|
+
const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
|
|
453
|
+
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
454
|
+
const fetchedAll = perPageInput === false || allThreadMessagesReturned;
|
|
455
|
+
const hasMore = !fetchedAll && offset + perPage < total;
|
|
456
|
+
return {
|
|
457
|
+
messages: finalMessages,
|
|
458
|
+
total,
|
|
459
|
+
page,
|
|
460
|
+
perPage: perPageForResponse,
|
|
461
|
+
hasMore
|
|
462
|
+
};
|
|
463
|
+
} catch (error) {
|
|
464
|
+
const mastraError = new MastraError(
|
|
465
|
+
{
|
|
466
|
+
id: "LANCE_STORE_LIST_MESSAGES_FAILED",
|
|
467
|
+
domain: ErrorDomain.STORAGE,
|
|
468
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
469
|
+
details: {
|
|
470
|
+
threadId,
|
|
471
|
+
resourceId: resourceId ?? ""
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
error
|
|
475
|
+
);
|
|
476
|
+
this.logger?.error?.(mastraError.toString());
|
|
477
|
+
this.logger?.trackException?.(mastraError);
|
|
478
|
+
return {
|
|
479
|
+
messages: [],
|
|
480
|
+
total: 0,
|
|
481
|
+
page,
|
|
482
|
+
perPage: perPageForResponse,
|
|
483
|
+
hasMore: false
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
}
|
|
484
487
|
async saveMessages(args) {
|
|
485
488
|
try {
|
|
486
|
-
const { messages
|
|
489
|
+
const { messages } = args;
|
|
487
490
|
if (messages.length === 0) {
|
|
488
|
-
return [];
|
|
491
|
+
return { messages: [] };
|
|
489
492
|
}
|
|
490
493
|
const threadId = messages[0]?.threadId;
|
|
491
494
|
if (!threadId) {
|
|
@@ -521,8 +524,7 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
521
524
|
const updateRecord = { id: threadId, updatedAt: currentTime };
|
|
522
525
|
await threadsTable.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([updateRecord]);
|
|
523
526
|
const list = new MessageList().add(messages, "memory");
|
|
524
|
-
|
|
525
|
-
return list.get.all.v1();
|
|
527
|
+
return { messages: list.get.all.db() };
|
|
526
528
|
} catch (error) {
|
|
527
529
|
throw new MastraError(
|
|
528
530
|
{
|
|
@@ -534,32 +536,54 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
534
536
|
);
|
|
535
537
|
}
|
|
536
538
|
}
|
|
537
|
-
async
|
|
539
|
+
async listThreadsByResourceId(args) {
|
|
538
540
|
try {
|
|
539
|
-
const { resourceId, page = 0, perPage
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
541
|
+
const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
|
|
542
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
543
|
+
if (page < 0) {
|
|
544
|
+
throw new MastraError(
|
|
545
|
+
{
|
|
546
|
+
id: "STORAGE_LANCE_LIST_THREADS_BY_RESOURCE_ID_INVALID_PAGE",
|
|
547
|
+
domain: ErrorDomain.STORAGE,
|
|
548
|
+
category: ErrorCategory.USER,
|
|
549
|
+
details: { page }
|
|
550
|
+
},
|
|
551
|
+
new Error("page must be >= 0")
|
|
552
|
+
);
|
|
547
553
|
}
|
|
554
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
555
|
+
const { field, direction } = this.parseOrderBy(orderBy);
|
|
556
|
+
const table = await this.client.openTable(TABLE_THREADS);
|
|
557
|
+
const total = await table.countRows(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
|
|
558
|
+
const query = table.query().where(`\`resourceId\` = '${this.escapeSql(resourceId)}'`);
|
|
548
559
|
const records = await query.toArray();
|
|
549
|
-
records.sort((a, b) =>
|
|
560
|
+
records.sort((a, b) => {
|
|
561
|
+
const aValue = ["createdAt", "updatedAt"].includes(field) ? new Date(a[field]).getTime() : a[field];
|
|
562
|
+
const bValue = ["createdAt", "updatedAt"].includes(field) ? new Date(b[field]).getTime() : b[field];
|
|
563
|
+
if (aValue == null && bValue == null) return 0;
|
|
564
|
+
if (aValue == null) return direction === "ASC" ? -1 : 1;
|
|
565
|
+
if (bValue == null) return direction === "ASC" ? 1 : -1;
|
|
566
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
567
|
+
return direction === "ASC" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
|
568
|
+
}
|
|
569
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
570
|
+
});
|
|
571
|
+
const paginatedRecords = records.slice(offset, offset + perPage);
|
|
550
572
|
const schema = await getTableSchema({ tableName: TABLE_THREADS, client: this.client });
|
|
551
|
-
const threads =
|
|
573
|
+
const threads = paginatedRecords.map(
|
|
574
|
+
(record) => processResultWithTypeConversion(record, schema)
|
|
575
|
+
);
|
|
552
576
|
return {
|
|
553
577
|
threads,
|
|
554
578
|
total,
|
|
555
579
|
page,
|
|
556
|
-
perPage,
|
|
557
|
-
hasMore:
|
|
580
|
+
perPage: perPageForResponse,
|
|
581
|
+
hasMore: offset + perPage < total
|
|
558
582
|
};
|
|
559
583
|
} catch (error) {
|
|
560
584
|
throw new MastraError(
|
|
561
585
|
{
|
|
562
|
-
id: "
|
|
586
|
+
id: "LANCE_STORE_LIST_THREADS_BY_RESOURCE_ID_FAILED",
|
|
563
587
|
domain: ErrorDomain.STORAGE,
|
|
564
588
|
category: ErrorCategory.THIRD_PARTY
|
|
565
589
|
},
|
|
@@ -615,132 +639,8 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
615
639
|
});
|
|
616
640
|
return Array.from(allIndices).sort((a, b) => a - b).map((index) => records[index]);
|
|
617
641
|
}
|
|
618
|
-
async getMessagesPaginated(args) {
|
|
619
|
-
const { threadId, resourceId, selectBy, format = "v1" } = args;
|
|
620
|
-
const page = selectBy?.pagination?.page ?? 0;
|
|
621
|
-
const perPage = selectBy?.pagination?.perPage ?? 10;
|
|
622
|
-
try {
|
|
623
|
-
if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
|
|
624
|
-
const dateRange = selectBy?.pagination?.dateRange;
|
|
625
|
-
const fromDate = dateRange?.start;
|
|
626
|
-
const toDate = dateRange?.end;
|
|
627
|
-
const table = await this.client.openTable(TABLE_MESSAGES);
|
|
628
|
-
const messages = [];
|
|
629
|
-
if (selectBy?.include && Array.isArray(selectBy.include)) {
|
|
630
|
-
const threadIds = [...new Set(selectBy.include.map((item) => item.threadId))];
|
|
631
|
-
const allThreadMessages = [];
|
|
632
|
-
for (const threadId2 of threadIds) {
|
|
633
|
-
const threadQuery = table.query().where(`thread_id = '${threadId2}'`);
|
|
634
|
-
let threadRecords = await threadQuery.toArray();
|
|
635
|
-
if (fromDate) threadRecords = threadRecords.filter((m) => m.createdAt >= fromDate.getTime());
|
|
636
|
-
if (toDate) threadRecords = threadRecords.filter((m) => m.createdAt <= toDate.getTime());
|
|
637
|
-
allThreadMessages.push(...threadRecords);
|
|
638
|
-
}
|
|
639
|
-
allThreadMessages.sort((a, b) => a.createdAt - b.createdAt);
|
|
640
|
-
const contextMessages = this.processMessagesWithContext(allThreadMessages, selectBy.include);
|
|
641
|
-
messages.push(...contextMessages);
|
|
642
|
-
}
|
|
643
|
-
const conditions = [`thread_id = '${threadId}'`];
|
|
644
|
-
if (resourceId) {
|
|
645
|
-
conditions.push(`\`resourceId\` = '${resourceId}'`);
|
|
646
|
-
}
|
|
647
|
-
if (fromDate) {
|
|
648
|
-
conditions.push(`\`createdAt\` >= ${fromDate.getTime()}`);
|
|
649
|
-
}
|
|
650
|
-
if (toDate) {
|
|
651
|
-
conditions.push(`\`createdAt\` <= ${toDate.getTime()}`);
|
|
652
|
-
}
|
|
653
|
-
let total = 0;
|
|
654
|
-
if (conditions.length > 0) {
|
|
655
|
-
total = await table.countRows(conditions.join(" AND "));
|
|
656
|
-
} else {
|
|
657
|
-
total = await table.countRows();
|
|
658
|
-
}
|
|
659
|
-
if (total === 0 && messages.length === 0) {
|
|
660
|
-
return {
|
|
661
|
-
messages: [],
|
|
662
|
-
total: 0,
|
|
663
|
-
page,
|
|
664
|
-
perPage,
|
|
665
|
-
hasMore: false
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
const excludeIds = messages.map((m) => m.id);
|
|
669
|
-
let selectedMessages = [];
|
|
670
|
-
if (selectBy?.last && selectBy.last > 0) {
|
|
671
|
-
const query = table.query();
|
|
672
|
-
if (conditions.length > 0) {
|
|
673
|
-
query.where(conditions.join(" AND "));
|
|
674
|
-
}
|
|
675
|
-
let records = await query.toArray();
|
|
676
|
-
records = records.sort((a, b) => a.createdAt - b.createdAt);
|
|
677
|
-
if (excludeIds.length > 0) {
|
|
678
|
-
records = records.filter((m) => !excludeIds.includes(m.id));
|
|
679
|
-
}
|
|
680
|
-
selectedMessages = records.slice(-selectBy.last);
|
|
681
|
-
} else {
|
|
682
|
-
const query = table.query();
|
|
683
|
-
if (conditions.length > 0) {
|
|
684
|
-
query.where(conditions.join(" AND "));
|
|
685
|
-
}
|
|
686
|
-
let records = await query.toArray();
|
|
687
|
-
records = records.sort((a, b) => a.createdAt - b.createdAt);
|
|
688
|
-
if (excludeIds.length > 0) {
|
|
689
|
-
records = records.filter((m) => !excludeIds.includes(m.id));
|
|
690
|
-
}
|
|
691
|
-
selectedMessages = records.slice(page * perPage, (page + 1) * perPage);
|
|
692
|
-
}
|
|
693
|
-
const allMessages = [...messages, ...selectedMessages];
|
|
694
|
-
const seen = /* @__PURE__ */ new Set();
|
|
695
|
-
const dedupedMessages = allMessages.filter((m) => {
|
|
696
|
-
const key = `${m.id}:${m.thread_id}`;
|
|
697
|
-
if (seen.has(key)) return false;
|
|
698
|
-
seen.add(key);
|
|
699
|
-
return true;
|
|
700
|
-
});
|
|
701
|
-
const formattedMessages = dedupedMessages.map((msg) => {
|
|
702
|
-
const { thread_id, ...rest } = msg;
|
|
703
|
-
return {
|
|
704
|
-
...rest,
|
|
705
|
-
threadId: thread_id,
|
|
706
|
-
content: typeof msg.content === "string" ? (() => {
|
|
707
|
-
try {
|
|
708
|
-
return JSON.parse(msg.content);
|
|
709
|
-
} catch {
|
|
710
|
-
return msg.content;
|
|
711
|
-
}
|
|
712
|
-
})() : msg.content
|
|
713
|
-
};
|
|
714
|
-
});
|
|
715
|
-
const list = new MessageList().add(formattedMessages, "memory");
|
|
716
|
-
return {
|
|
717
|
-
messages: format === "v2" ? list.get.all.v2() : list.get.all.v1(),
|
|
718
|
-
total,
|
|
719
|
-
// Total should be the count of messages matching the filters
|
|
720
|
-
page,
|
|
721
|
-
perPage,
|
|
722
|
-
hasMore: total > (page + 1) * perPage
|
|
723
|
-
};
|
|
724
|
-
} catch (error) {
|
|
725
|
-
const mastraError = new MastraError(
|
|
726
|
-
{
|
|
727
|
-
id: "LANCE_STORE_GET_MESSAGES_PAGINATED_FAILED",
|
|
728
|
-
domain: ErrorDomain.STORAGE,
|
|
729
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
730
|
-
details: {
|
|
731
|
-
threadId,
|
|
732
|
-
resourceId: resourceId ?? ""
|
|
733
|
-
}
|
|
734
|
-
},
|
|
735
|
-
error
|
|
736
|
-
);
|
|
737
|
-
this.logger?.trackException?.(mastraError);
|
|
738
|
-
this.logger?.error?.(mastraError.toString());
|
|
739
|
-
return { messages: [], total: 0, page, perPage, hasMore: false };
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
642
|
/**
|
|
743
|
-
* Parse message data from LanceDB record format to
|
|
643
|
+
* Parse message data from LanceDB record format to MastraDBMessage format
|
|
744
644
|
*/
|
|
745
645
|
parseMessageData(data) {
|
|
746
646
|
const { thread_id, ...rest } = data;
|
|
@@ -1396,13 +1296,27 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1396
1296
|
this.client = client;
|
|
1397
1297
|
}
|
|
1398
1298
|
async saveScore(score) {
|
|
1299
|
+
let validatedScore;
|
|
1300
|
+
try {
|
|
1301
|
+
validatedScore = saveScorePayloadSchema.parse(score);
|
|
1302
|
+
} catch (error) {
|
|
1303
|
+
throw new MastraError(
|
|
1304
|
+
{
|
|
1305
|
+
id: "LANCE_STORAGE_SAVE_SCORE_FAILED",
|
|
1306
|
+
text: "Failed to save score in LanceStorage",
|
|
1307
|
+
domain: ErrorDomain.STORAGE,
|
|
1308
|
+
category: ErrorCategory.THIRD_PARTY
|
|
1309
|
+
},
|
|
1310
|
+
error
|
|
1311
|
+
);
|
|
1312
|
+
}
|
|
1399
1313
|
try {
|
|
1400
1314
|
const id = crypto.randomUUID();
|
|
1401
1315
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1402
1316
|
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1403
1317
|
const allowedFields = new Set(schema.fields.map((f) => f.name));
|
|
1404
1318
|
const filteredScore = {};
|
|
1405
|
-
Object.keys(
|
|
1319
|
+
Object.keys(validatedScore).forEach((key) => {
|
|
1406
1320
|
if (allowedFields.has(key)) {
|
|
1407
1321
|
filteredScore[key] = score[key];
|
|
1408
1322
|
}
|
|
@@ -1449,7 +1363,7 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1449
1363
|
);
|
|
1450
1364
|
}
|
|
1451
1365
|
}
|
|
1452
|
-
async
|
|
1366
|
+
async listScoresByScorerId({
|
|
1453
1367
|
scorerId,
|
|
1454
1368
|
pagination,
|
|
1455
1369
|
entityId,
|
|
@@ -1457,9 +1371,10 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1457
1371
|
source
|
|
1458
1372
|
}) {
|
|
1459
1373
|
try {
|
|
1374
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1375
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1376
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1460
1377
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1461
|
-
const { page = 0, perPage = 10 } = pagination || {};
|
|
1462
|
-
const offset = page * perPage;
|
|
1463
1378
|
let query = table.query().where(`\`scorerId\` = '${scorerId}'`);
|
|
1464
1379
|
if (source) {
|
|
1465
1380
|
query = query.where(`\`source\` = '${source}'`);
|
|
@@ -1470,23 +1385,32 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1470
1385
|
if (entityType) {
|
|
1471
1386
|
query = query.where(`\`entityType\` = '${entityType}'`);
|
|
1472
1387
|
}
|
|
1473
|
-
query = query.limit(perPage);
|
|
1474
|
-
if (offset > 0) query.offset(offset);
|
|
1475
|
-
const records = await query.toArray();
|
|
1476
|
-
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1477
|
-
const scores = processResultWithTypeConversion(records, schema);
|
|
1478
1388
|
let totalQuery = table.query().where(`\`scorerId\` = '${scorerId}'`);
|
|
1479
1389
|
if (source) {
|
|
1480
1390
|
totalQuery = totalQuery.where(`\`source\` = '${source}'`);
|
|
1481
1391
|
}
|
|
1392
|
+
if (entityId) {
|
|
1393
|
+
totalQuery = totalQuery.where(`\`entityId\` = '${entityId}'`);
|
|
1394
|
+
}
|
|
1395
|
+
if (entityType) {
|
|
1396
|
+
totalQuery = totalQuery.where(`\`entityType\` = '${entityType}'`);
|
|
1397
|
+
}
|
|
1482
1398
|
const allRecords = await totalQuery.toArray();
|
|
1483
1399
|
const total = allRecords.length;
|
|
1400
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1401
|
+
if (perPageInput !== false) {
|
|
1402
|
+
query = query.limit(perPage);
|
|
1403
|
+
if (start > 0) query = query.offset(start);
|
|
1404
|
+
}
|
|
1405
|
+
const records = await query.toArray();
|
|
1406
|
+
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1407
|
+
const scores = processResultWithTypeConversion(records, schema);
|
|
1484
1408
|
return {
|
|
1485
1409
|
pagination: {
|
|
1486
1410
|
page,
|
|
1487
|
-
perPage,
|
|
1411
|
+
perPage: perPageForResponse,
|
|
1488
1412
|
total,
|
|
1489
|
-
hasMore:
|
|
1413
|
+
hasMore: end < total
|
|
1490
1414
|
},
|
|
1491
1415
|
scores
|
|
1492
1416
|
};
|
|
@@ -1503,27 +1427,32 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1503
1427
|
);
|
|
1504
1428
|
}
|
|
1505
1429
|
}
|
|
1506
|
-
async
|
|
1430
|
+
async listScoresByRunId({
|
|
1507
1431
|
runId,
|
|
1508
1432
|
pagination
|
|
1509
1433
|
}) {
|
|
1510
1434
|
try {
|
|
1435
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1436
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1437
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1511
1438
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1512
|
-
const
|
|
1513
|
-
const
|
|
1514
|
-
const
|
|
1515
|
-
|
|
1439
|
+
const allRecords = await table.query().where(`\`runId\` = '${runId}'`).toArray();
|
|
1440
|
+
const total = allRecords.length;
|
|
1441
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1442
|
+
let query = table.query().where(`\`runId\` = '${runId}'`);
|
|
1443
|
+
if (perPageInput !== false) {
|
|
1444
|
+
query = query.limit(perPage);
|
|
1445
|
+
if (start > 0) query = query.offset(start);
|
|
1446
|
+
}
|
|
1516
1447
|
const records = await query.toArray();
|
|
1517
1448
|
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1518
1449
|
const scores = processResultWithTypeConversion(records, schema);
|
|
1519
|
-
const allRecords = await table.query().where(`\`runId\` = '${runId}'`).toArray();
|
|
1520
|
-
const total = allRecords.length;
|
|
1521
1450
|
return {
|
|
1522
1451
|
pagination: {
|
|
1523
1452
|
page,
|
|
1524
|
-
perPage,
|
|
1453
|
+
perPage: perPageForResponse,
|
|
1525
1454
|
total,
|
|
1526
|
-
hasMore:
|
|
1455
|
+
hasMore: end < total
|
|
1527
1456
|
},
|
|
1528
1457
|
scores
|
|
1529
1458
|
};
|
|
@@ -1540,28 +1469,33 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1540
1469
|
);
|
|
1541
1470
|
}
|
|
1542
1471
|
}
|
|
1543
|
-
async
|
|
1472
|
+
async listScoresByEntityId({
|
|
1544
1473
|
entityId,
|
|
1545
1474
|
entityType,
|
|
1546
1475
|
pagination
|
|
1547
1476
|
}) {
|
|
1548
1477
|
try {
|
|
1478
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1479
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1480
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1549
1481
|
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1550
|
-
const
|
|
1551
|
-
const
|
|
1552
|
-
const
|
|
1553
|
-
|
|
1482
|
+
const allRecords = await table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).toArray();
|
|
1483
|
+
const total = allRecords.length;
|
|
1484
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1485
|
+
let query = table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`);
|
|
1486
|
+
if (perPageInput !== false) {
|
|
1487
|
+
query = query.limit(perPage);
|
|
1488
|
+
if (start > 0) query = query.offset(start);
|
|
1489
|
+
}
|
|
1554
1490
|
const records = await query.toArray();
|
|
1555
1491
|
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1556
1492
|
const scores = processResultWithTypeConversion(records, schema);
|
|
1557
|
-
const allRecords = await table.query().where(`\`entityId\` = '${entityId}' AND \`entityType\` = '${entityType}'`).toArray();
|
|
1558
|
-
const total = allRecords.length;
|
|
1559
1493
|
return {
|
|
1560
1494
|
pagination: {
|
|
1561
1495
|
page,
|
|
1562
|
-
perPage,
|
|
1496
|
+
perPage: perPageForResponse,
|
|
1563
1497
|
total,
|
|
1564
|
-
hasMore:
|
|
1498
|
+
hasMore: end < total
|
|
1565
1499
|
},
|
|
1566
1500
|
scores
|
|
1567
1501
|
};
|
|
@@ -1578,198 +1512,49 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1578
1512
|
);
|
|
1579
1513
|
}
|
|
1580
1514
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
constructor({ client, operations }) {
|
|
1586
|
-
super();
|
|
1587
|
-
this.client = client;
|
|
1588
|
-
this.operations = operations;
|
|
1589
|
-
}
|
|
1590
|
-
async saveTrace({ trace }) {
|
|
1591
|
-
try {
|
|
1592
|
-
const table = await this.client.openTable(TABLE_TRACES);
|
|
1593
|
-
const record = {
|
|
1594
|
-
...trace,
|
|
1595
|
-
attributes: JSON.stringify(trace.attributes),
|
|
1596
|
-
status: JSON.stringify(trace.status),
|
|
1597
|
-
events: JSON.stringify(trace.events),
|
|
1598
|
-
links: JSON.stringify(trace.links),
|
|
1599
|
-
other: JSON.stringify(trace.other)
|
|
1600
|
-
};
|
|
1601
|
-
await table.add([record], { mode: "append" });
|
|
1602
|
-
return trace;
|
|
1603
|
-
} catch (error) {
|
|
1604
|
-
throw new MastraError(
|
|
1605
|
-
{
|
|
1606
|
-
id: "LANCE_STORE_SAVE_TRACE_FAILED",
|
|
1607
|
-
domain: ErrorDomain.STORAGE,
|
|
1608
|
-
category: ErrorCategory.THIRD_PARTY
|
|
1609
|
-
},
|
|
1610
|
-
error
|
|
1611
|
-
);
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
async getTraceById({ traceId }) {
|
|
1615
|
-
try {
|
|
1616
|
-
const table = await this.client.openTable(TABLE_TRACES);
|
|
1617
|
-
const query = table.query().where(`id = '${traceId}'`);
|
|
1618
|
-
const records = await query.toArray();
|
|
1619
|
-
return records[0];
|
|
1620
|
-
} catch (error) {
|
|
1621
|
-
throw new MastraError(
|
|
1622
|
-
{
|
|
1623
|
-
id: "LANCE_STORE_GET_TRACE_BY_ID_FAILED",
|
|
1624
|
-
domain: ErrorDomain.STORAGE,
|
|
1625
|
-
category: ErrorCategory.THIRD_PARTY
|
|
1626
|
-
},
|
|
1627
|
-
error
|
|
1628
|
-
);
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
async getTraces({
|
|
1632
|
-
name,
|
|
1633
|
-
scope,
|
|
1634
|
-
page = 1,
|
|
1635
|
-
perPage = 10,
|
|
1636
|
-
attributes
|
|
1515
|
+
async listScoresBySpan({
|
|
1516
|
+
traceId,
|
|
1517
|
+
spanId,
|
|
1518
|
+
pagination
|
|
1637
1519
|
}) {
|
|
1638
1520
|
try {
|
|
1639
|
-
const
|
|
1640
|
-
const
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
}
|
|
1647
|
-
if (
|
|
1648
|
-
query
|
|
1649
|
-
|
|
1650
|
-
const offset = (page - 1) * perPage;
|
|
1651
|
-
query.limit(perPage);
|
|
1652
|
-
if (offset > 0) {
|
|
1653
|
-
query.offset(offset);
|
|
1654
|
-
}
|
|
1655
|
-
const records = await query.toArray();
|
|
1656
|
-
return records.map((record) => {
|
|
1657
|
-
const processed = {
|
|
1658
|
-
...record,
|
|
1659
|
-
attributes: record.attributes ? JSON.parse(record.attributes) : {},
|
|
1660
|
-
status: record.status ? JSON.parse(record.status) : {},
|
|
1661
|
-
events: record.events ? JSON.parse(record.events) : [],
|
|
1662
|
-
links: record.links ? JSON.parse(record.links) : [],
|
|
1663
|
-
other: record.other ? JSON.parse(record.other) : {},
|
|
1664
|
-
startTime: new Date(record.startTime),
|
|
1665
|
-
endTime: new Date(record.endTime),
|
|
1666
|
-
createdAt: new Date(record.createdAt)
|
|
1667
|
-
};
|
|
1668
|
-
if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
|
|
1669
|
-
processed.parentSpanId = "";
|
|
1670
|
-
} else {
|
|
1671
|
-
processed.parentSpanId = String(processed.parentSpanId);
|
|
1672
|
-
}
|
|
1673
|
-
return processed;
|
|
1674
|
-
});
|
|
1675
|
-
} catch (error) {
|
|
1676
|
-
throw new MastraError(
|
|
1677
|
-
{
|
|
1678
|
-
id: "LANCE_STORE_GET_TRACES_FAILED",
|
|
1679
|
-
domain: ErrorDomain.STORAGE,
|
|
1680
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
1681
|
-
details: { name: name ?? "", scope: scope ?? "" }
|
|
1682
|
-
},
|
|
1683
|
-
error
|
|
1684
|
-
);
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
async getTracesPaginated(args) {
|
|
1688
|
-
try {
|
|
1689
|
-
const table = await this.client.openTable(TABLE_TRACES);
|
|
1690
|
-
const query = table.query();
|
|
1691
|
-
const conditions = [];
|
|
1692
|
-
if (args.name) {
|
|
1693
|
-
conditions.push(`name = '${args.name}'`);
|
|
1694
|
-
}
|
|
1695
|
-
if (args.scope) {
|
|
1696
|
-
conditions.push(`scope = '${args.scope}'`);
|
|
1697
|
-
}
|
|
1698
|
-
if (args.attributes) {
|
|
1699
|
-
const attributesStr = JSON.stringify(args.attributes);
|
|
1700
|
-
conditions.push(`attributes LIKE '%${attributesStr.replace(/"/g, '\\"')}%'`);
|
|
1701
|
-
}
|
|
1702
|
-
if (args.dateRange?.start) {
|
|
1703
|
-
conditions.push(`\`createdAt\` >= ${args.dateRange.start.getTime()}`);
|
|
1704
|
-
}
|
|
1705
|
-
if (args.dateRange?.end) {
|
|
1706
|
-
conditions.push(`\`createdAt\` <= ${args.dateRange.end.getTime()}`);
|
|
1707
|
-
}
|
|
1708
|
-
if (conditions.length > 0) {
|
|
1709
|
-
const whereClause = conditions.join(" AND ");
|
|
1710
|
-
query.where(whereClause);
|
|
1711
|
-
}
|
|
1712
|
-
let total = 0;
|
|
1713
|
-
if (conditions.length > 0) {
|
|
1714
|
-
const countQuery = table.query().where(conditions.join(" AND "));
|
|
1715
|
-
const allRecords = await countQuery.toArray();
|
|
1716
|
-
total = allRecords.length;
|
|
1717
|
-
} else {
|
|
1718
|
-
total = await table.countRows();
|
|
1719
|
-
}
|
|
1720
|
-
const page = args.page || 0;
|
|
1721
|
-
const perPage = args.perPage || 10;
|
|
1722
|
-
const offset = page * perPage;
|
|
1723
|
-
query.limit(perPage);
|
|
1724
|
-
if (offset > 0) {
|
|
1725
|
-
query.offset(offset);
|
|
1521
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1522
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1523
|
+
const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1524
|
+
const table = await this.client.openTable(TABLE_SCORERS);
|
|
1525
|
+
const allRecords = await table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`).toArray();
|
|
1526
|
+
const total = allRecords.length;
|
|
1527
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1528
|
+
let query = table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`);
|
|
1529
|
+
if (perPageInput !== false) {
|
|
1530
|
+
query = query.limit(perPage);
|
|
1531
|
+
if (start > 0) query = query.offset(start);
|
|
1726
1532
|
}
|
|
1727
1533
|
const records = await query.toArray();
|
|
1728
|
-
const
|
|
1729
|
-
|
|
1730
|
-
...record,
|
|
1731
|
-
attributes: record.attributes ? JSON.parse(record.attributes) : {},
|
|
1732
|
-
status: record.status ? JSON.parse(record.status) : {},
|
|
1733
|
-
events: record.events ? JSON.parse(record.events) : [],
|
|
1734
|
-
links: record.links ? JSON.parse(record.links) : [],
|
|
1735
|
-
other: record.other ? JSON.parse(record.other) : {},
|
|
1736
|
-
startTime: new Date(record.startTime),
|
|
1737
|
-
endTime: new Date(record.endTime),
|
|
1738
|
-
createdAt: new Date(record.createdAt)
|
|
1739
|
-
};
|
|
1740
|
-
if (processed.parentSpanId === null || processed.parentSpanId === void 0) {
|
|
1741
|
-
processed.parentSpanId = "";
|
|
1742
|
-
} else {
|
|
1743
|
-
processed.parentSpanId = String(processed.parentSpanId);
|
|
1744
|
-
}
|
|
1745
|
-
return processed;
|
|
1746
|
-
});
|
|
1534
|
+
const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
|
|
1535
|
+
const scores = processResultWithTypeConversion(records, schema);
|
|
1747
1536
|
return {
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1537
|
+
pagination: {
|
|
1538
|
+
page,
|
|
1539
|
+
perPage: perPageForResponse,
|
|
1540
|
+
total,
|
|
1541
|
+
hasMore: end < total
|
|
1542
|
+
},
|
|
1543
|
+
scores
|
|
1753
1544
|
};
|
|
1754
1545
|
} catch (error) {
|
|
1755
1546
|
throw new MastraError(
|
|
1756
1547
|
{
|
|
1757
|
-
id: "
|
|
1548
|
+
id: "LANCE_STORAGE_GET_SCORES_BY_SPAN_FAILED",
|
|
1549
|
+
text: "Failed to get scores by traceId and spanId in LanceStorage",
|
|
1758
1550
|
domain: ErrorDomain.STORAGE,
|
|
1759
1551
|
category: ErrorCategory.THIRD_PARTY,
|
|
1760
|
-
details: {
|
|
1552
|
+
details: { error: error?.message }
|
|
1761
1553
|
},
|
|
1762
1554
|
error
|
|
1763
1555
|
);
|
|
1764
1556
|
}
|
|
1765
1557
|
}
|
|
1766
|
-
async batchTraceInsert({ records }) {
|
|
1767
|
-
this.logger.debug("Batch inserting traces", { count: records.length });
|
|
1768
|
-
await this.operations.batchInsert({
|
|
1769
|
-
tableName: TABLE_TRACES,
|
|
1770
|
-
records
|
|
1771
|
-
});
|
|
1772
|
-
}
|
|
1773
1558
|
};
|
|
1774
1559
|
function parseWorkflowRun(row) {
|
|
1775
1560
|
let parsedSnapshot = row.snapshot;
|
|
@@ -1800,7 +1585,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1800
1585
|
// runId,
|
|
1801
1586
|
// stepId,
|
|
1802
1587
|
// result,
|
|
1803
|
-
//
|
|
1588
|
+
// requestContext,
|
|
1804
1589
|
}) {
|
|
1805
1590
|
throw new Error("Method not implemented.");
|
|
1806
1591
|
}
|
|
@@ -1894,7 +1679,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1894
1679
|
);
|
|
1895
1680
|
}
|
|
1896
1681
|
}
|
|
1897
|
-
async
|
|
1682
|
+
async listWorkflowRuns(args) {
|
|
1898
1683
|
try {
|
|
1899
1684
|
const table = await this.client.openTable(TABLE_WORKFLOW_SNAPSHOT);
|
|
1900
1685
|
let query = table.query();
|
|
@@ -1918,11 +1703,22 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1918
1703
|
} else {
|
|
1919
1704
|
total = await table.countRows();
|
|
1920
1705
|
}
|
|
1921
|
-
if (args?.
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1706
|
+
if (args?.perPage !== void 0 && args?.page !== void 0) {
|
|
1707
|
+
const normalizedPerPage = normalizePerPage(args.perPage, Number.MAX_SAFE_INTEGER);
|
|
1708
|
+
if (args.page < 0 || !Number.isInteger(args.page)) {
|
|
1709
|
+
throw new MastraError(
|
|
1710
|
+
{
|
|
1711
|
+
id: "LANCE_STORE_INVALID_PAGINATION_PARAMS",
|
|
1712
|
+
domain: ErrorDomain.STORAGE,
|
|
1713
|
+
category: ErrorCategory.USER,
|
|
1714
|
+
details: { page: args.page, perPage: args.perPage }
|
|
1715
|
+
},
|
|
1716
|
+
new Error(`Invalid pagination parameters: page=${args.page}, perPage=${args.perPage}`)
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
const offset = args.page * normalizedPerPage;
|
|
1720
|
+
query.limit(normalizedPerPage);
|
|
1721
|
+
query.offset(offset);
|
|
1926
1722
|
}
|
|
1927
1723
|
const records = await query.toArray();
|
|
1928
1724
|
return {
|
|
@@ -1932,10 +1728,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1932
1728
|
} catch (error) {
|
|
1933
1729
|
throw new MastraError(
|
|
1934
1730
|
{
|
|
1935
|
-
id: "
|
|
1731
|
+
id: "LANCE_STORE_LIST_WORKFLOW_RUNS_FAILED",
|
|
1936
1732
|
domain: ErrorDomain.STORAGE,
|
|
1937
1733
|
category: ErrorCategory.THIRD_PARTY,
|
|
1938
|
-
details: {
|
|
1734
|
+
details: { resourceId: args?.resourceId ?? "", workflowName: args?.workflowName ?? "" }
|
|
1939
1735
|
},
|
|
1940
1736
|
error
|
|
1941
1737
|
);
|
|
@@ -1977,10 +1773,8 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
1977
1773
|
instance.stores = {
|
|
1978
1774
|
operations: new StoreOperationsLance({ client: instance.lanceClient }),
|
|
1979
1775
|
workflows: new StoreWorkflowsLance({ client: instance.lanceClient }),
|
|
1980
|
-
traces: new StoreTracesLance({ client: instance.lanceClient, operations }),
|
|
1981
1776
|
scores: new StoreScoresLance({ client: instance.lanceClient }),
|
|
1982
|
-
memory: new StoreMemoryLance({ client: instance.lanceClient, operations })
|
|
1983
|
-
legacyEvals: new StoreLegacyEvalsLance({ client: instance.lanceClient })
|
|
1777
|
+
memory: new StoreMemoryLance({ client: instance.lanceClient, operations })
|
|
1984
1778
|
};
|
|
1985
1779
|
return instance;
|
|
1986
1780
|
} catch (e) {
|
|
@@ -2006,9 +1800,7 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2006
1800
|
this.stores = {
|
|
2007
1801
|
operations: new StoreOperationsLance({ client: this.lanceClient }),
|
|
2008
1802
|
workflows: new StoreWorkflowsLance({ client: this.lanceClient }),
|
|
2009
|
-
traces: new StoreTracesLance({ client: this.lanceClient, operations }),
|
|
2010
1803
|
scores: new StoreScoresLance({ client: this.lanceClient }),
|
|
2011
|
-
legacyEvals: new StoreLegacyEvalsLance({ client: this.lanceClient }),
|
|
2012
1804
|
memory: new StoreMemoryLance({ client: this.lanceClient, operations })
|
|
2013
1805
|
};
|
|
2014
1806
|
}
|
|
@@ -2043,9 +1835,6 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2043
1835
|
async getThreadById({ threadId }) {
|
|
2044
1836
|
return this.stores.memory.getThreadById({ threadId });
|
|
2045
1837
|
}
|
|
2046
|
-
async getThreadsByResourceId({ resourceId }) {
|
|
2047
|
-
return this.stores.memory.getThreadsByResourceId({ resourceId });
|
|
2048
|
-
}
|
|
2049
1838
|
/**
|
|
2050
1839
|
* Saves a thread to the database. This function doesn't overwrite existing threads.
|
|
2051
1840
|
* @param thread - The thread to save
|
|
@@ -2070,7 +1859,8 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2070
1859
|
resourceWorkingMemory: true,
|
|
2071
1860
|
hasColumn: true,
|
|
2072
1861
|
createTable: true,
|
|
2073
|
-
deleteMessages: false
|
|
1862
|
+
deleteMessages: false,
|
|
1863
|
+
listScoresBySpan: true
|
|
2074
1864
|
};
|
|
2075
1865
|
}
|
|
2076
1866
|
async getResourceById({ resourceId }) {
|
|
@@ -2138,46 +1928,21 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2138
1928
|
threadId,
|
|
2139
1929
|
resourceId,
|
|
2140
1930
|
selectBy,
|
|
2141
|
-
format,
|
|
2142
1931
|
threadConfig
|
|
2143
1932
|
}) {
|
|
2144
|
-
return this.stores.memory.getMessages({ threadId, resourceId, selectBy,
|
|
1933
|
+
return this.stores.memory.getMessages({ threadId, resourceId, selectBy, threadConfig });
|
|
2145
1934
|
}
|
|
2146
|
-
async
|
|
2147
|
-
messageIds
|
|
2148
|
-
format
|
|
2149
|
-
}) {
|
|
2150
|
-
return this.stores.memory.getMessagesById({ messageIds, format });
|
|
1935
|
+
async listMessagesById({ messageIds }) {
|
|
1936
|
+
return this.stores.memory.listMessagesById({ messageIds });
|
|
2151
1937
|
}
|
|
2152
1938
|
async saveMessages(args) {
|
|
2153
1939
|
return this.stores.memory.saveMessages(args);
|
|
2154
1940
|
}
|
|
2155
|
-
async getThreadsByResourceIdPaginated(args) {
|
|
2156
|
-
return this.stores.memory.getThreadsByResourceIdPaginated(args);
|
|
2157
|
-
}
|
|
2158
|
-
async getMessagesPaginated(args) {
|
|
2159
|
-
return this.stores.memory.getMessagesPaginated(args);
|
|
2160
|
-
}
|
|
2161
1941
|
async updateMessages(_args) {
|
|
2162
1942
|
return this.stores.memory.updateMessages(_args);
|
|
2163
1943
|
}
|
|
2164
|
-
async
|
|
2165
|
-
return this.stores.
|
|
2166
|
-
}
|
|
2167
|
-
async getTraces(args) {
|
|
2168
|
-
return this.stores.traces.getTraces(args);
|
|
2169
|
-
}
|
|
2170
|
-
async getTracesPaginated(args) {
|
|
2171
|
-
return this.stores.traces.getTracesPaginated(args);
|
|
2172
|
-
}
|
|
2173
|
-
async getEvalsByAgentName(agentName, type) {
|
|
2174
|
-
return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
|
|
2175
|
-
}
|
|
2176
|
-
async getEvals(options) {
|
|
2177
|
-
return this.stores.legacyEvals.getEvals(options);
|
|
2178
|
-
}
|
|
2179
|
-
async getWorkflowRuns(args) {
|
|
2180
|
-
return this.stores.workflows.getWorkflowRuns(args);
|
|
1944
|
+
async listWorkflowRuns(args) {
|
|
1945
|
+
return this.stores.workflows.listWorkflowRuns(args);
|
|
2181
1946
|
}
|
|
2182
1947
|
async getWorkflowRunById(args) {
|
|
2183
1948
|
return this.stores.workflows.getWorkflowRunById(args);
|
|
@@ -2187,9 +1952,9 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2187
1952
|
runId,
|
|
2188
1953
|
stepId,
|
|
2189
1954
|
result,
|
|
2190
|
-
|
|
1955
|
+
requestContext
|
|
2191
1956
|
}) {
|
|
2192
|
-
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result,
|
|
1957
|
+
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
|
|
2193
1958
|
}
|
|
2194
1959
|
async updateWorkflowState({
|
|
2195
1960
|
workflowName,
|
|
@@ -2215,30 +1980,37 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
2215
1980
|
async getScoreById({ id: _id }) {
|
|
2216
1981
|
return this.stores.scores.getScoreById({ id: _id });
|
|
2217
1982
|
}
|
|
2218
|
-
async
|
|
1983
|
+
async listScoresByScorerId({
|
|
2219
1984
|
scorerId,
|
|
2220
1985
|
source,
|
|
2221
1986
|
entityId,
|
|
2222
1987
|
entityType,
|
|
2223
1988
|
pagination
|
|
2224
1989
|
}) {
|
|
2225
|
-
return this.stores.scores.
|
|
1990
|
+
return this.stores.scores.listScoresByScorerId({ scorerId, source, pagination, entityId, entityType });
|
|
2226
1991
|
}
|
|
2227
1992
|
async saveScore(_score) {
|
|
2228
1993
|
return this.stores.scores.saveScore(_score);
|
|
2229
1994
|
}
|
|
2230
|
-
async
|
|
1995
|
+
async listScoresByRunId({
|
|
2231
1996
|
runId,
|
|
2232
1997
|
pagination
|
|
2233
1998
|
}) {
|
|
2234
|
-
return this.stores.scores.
|
|
1999
|
+
return this.stores.scores.listScoresByRunId({ runId, pagination });
|
|
2235
2000
|
}
|
|
2236
|
-
async
|
|
2001
|
+
async listScoresByEntityId({
|
|
2237
2002
|
entityId,
|
|
2238
2003
|
entityType,
|
|
2239
2004
|
pagination
|
|
2240
2005
|
}) {
|
|
2241
|
-
return this.stores.scores.
|
|
2006
|
+
return this.stores.scores.listScoresByEntityId({ entityId, entityType, pagination });
|
|
2007
|
+
}
|
|
2008
|
+
async listScoresBySpan({
|
|
2009
|
+
traceId,
|
|
2010
|
+
spanId,
|
|
2011
|
+
pagination
|
|
2012
|
+
}) {
|
|
2013
|
+
return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
|
|
2242
2014
|
}
|
|
2243
2015
|
};
|
|
2244
2016
|
var LanceFilterTranslator = class extends BaseFilterTranslator {
|