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