@mastra/core 0.2.0-alpha.91 → 0.2.0-alpha.93
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/dist/action/index.d.ts +1 -1
- package/dist/agent/index.js +3 -3
- package/dist/bundler/index.d.ts +11 -3
- package/dist/bundler/index.js +1 -1
- package/dist/{chunk-5NQ3MEZM.js → chunk-BOS3IA23.js} +0 -1
- package/dist/{chunk-XDXRDRTQ.js → chunk-EULBQ77C.js} +4 -4
- package/dist/chunk-F7ILHRX5.js +659 -0
- package/dist/{chunk-WGUGRCAP.js → chunk-GGYXCZUW.js} +1 -1
- package/dist/{chunk-FD4KOA4T.js → chunk-HH5JIATB.js} +1 -1
- package/dist/{chunk-YKASGA6R.js → chunk-JJ57BXQR.js} +1 -1
- package/dist/{chunk-MMJCCJNP.js → chunk-JWVCENG2.js} +2 -3
- package/dist/{chunk-RDEXABVY.js → chunk-MCB4M5W4.js} +2 -2
- package/dist/{chunk-YPMAHKBC.js → chunk-RI3ECMVF.js} +0 -1
- package/dist/{chunk-ECXV3EAT.js → chunk-WBPDZBUT.js} +3 -9
- package/dist/deployer/index.d.ts +6 -3
- package/dist/deployer/index.js +2 -2
- package/dist/embeddings/index.js +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +17 -15
- package/dist/llm/index.js +1 -1
- package/dist/mastra/index.d.ts +2 -2
- package/dist/mastra/index.js +2 -2
- package/dist/relevance/index.js +4 -4
- package/dist/storage/index.d.ts +5 -3
- package/dist/storage/index.js +5 -1
- package/dist/vector/index.js +2 -2
- package/dist/vector/libsql/index.d.ts +2 -2
- package/dist/vector/libsql/index.js +5 -660
- package/package.json +1 -1
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
import { MastraVector } from './chunk-HH5JIATB.js';
|
|
2
|
+
import { BaseFilterTranslator } from './chunk-4LJFWC2Q.js';
|
|
3
|
+
import { __name, __publicField } from './chunk-AJJZUHB4.js';
|
|
4
|
+
import { createClient } from '@libsql/client';
|
|
5
|
+
|
|
6
|
+
// src/vector/libsql/filter.ts
|
|
7
|
+
var _LibSQLFilterTranslator = class _LibSQLFilterTranslator extends BaseFilterTranslator {
|
|
8
|
+
getSupportedOperators() {
|
|
9
|
+
return {
|
|
10
|
+
...BaseFilterTranslator.DEFAULT_OPERATORS,
|
|
11
|
+
regex: [],
|
|
12
|
+
custom: [
|
|
13
|
+
"$contains",
|
|
14
|
+
"$size"
|
|
15
|
+
]
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
translate(filter) {
|
|
19
|
+
if (this.isEmpty(filter)) {
|
|
20
|
+
return filter;
|
|
21
|
+
}
|
|
22
|
+
this.validateFilter(filter);
|
|
23
|
+
return this.translateNode(filter);
|
|
24
|
+
}
|
|
25
|
+
translateNode(node, currentPath = "") {
|
|
26
|
+
if (this.isRegex(node)) {
|
|
27
|
+
throw new Error("Direct regex pattern format is not supported in LibSQL");
|
|
28
|
+
}
|
|
29
|
+
const withPath = /* @__PURE__ */ __name((result2) => currentPath ? {
|
|
30
|
+
[currentPath]: result2
|
|
31
|
+
} : result2, "withPath");
|
|
32
|
+
if (this.isPrimitive(node)) {
|
|
33
|
+
return withPath({
|
|
34
|
+
$eq: this.normalizeComparisonValue(node)
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(node)) {
|
|
38
|
+
return withPath({
|
|
39
|
+
$in: this.normalizeArrayValues(node)
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const entries = Object.entries(node);
|
|
43
|
+
const result = {};
|
|
44
|
+
for (const [key, value] of entries) {
|
|
45
|
+
const newPath = currentPath ? `${currentPath}.${key}` : key;
|
|
46
|
+
if (this.isLogicalOperator(key)) {
|
|
47
|
+
result[key] = Array.isArray(value) ? value.map((filter) => this.translateNode(filter)) : this.translateNode(value);
|
|
48
|
+
} else if (this.isOperator(key)) {
|
|
49
|
+
if (this.isArrayOperator(key) && !Array.isArray(value) && key !== "$elemMatch") {
|
|
50
|
+
result[key] = [
|
|
51
|
+
value
|
|
52
|
+
];
|
|
53
|
+
} else if (this.isBasicOperator(key) && Array.isArray(value)) {
|
|
54
|
+
result[key] = JSON.stringify(value);
|
|
55
|
+
} else {
|
|
56
|
+
result[key] = value;
|
|
57
|
+
}
|
|
58
|
+
} else if (typeof value === "object" && value !== null) {
|
|
59
|
+
const hasOperators = Object.keys(value).some((k) => this.isOperator(k));
|
|
60
|
+
if (hasOperators) {
|
|
61
|
+
result[newPath] = this.translateNode(value);
|
|
62
|
+
} else {
|
|
63
|
+
Object.assign(result, this.translateNode(value, newPath));
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
result[newPath] = this.translateNode(value);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
__name(_LibSQLFilterTranslator, "LibSQLFilterTranslator");
|
|
73
|
+
var LibSQLFilterTranslator = _LibSQLFilterTranslator;
|
|
74
|
+
|
|
75
|
+
// src/vector/libsql/sql-builder.ts
|
|
76
|
+
var createBasicOperator = /* @__PURE__ */ __name((symbol) => {
|
|
77
|
+
return (key) => ({
|
|
78
|
+
sql: `CASE
|
|
79
|
+
WHEN ? IS NULL THEN json_extract(metadata, '$."${handleKey(key)}"') IS ${symbol === "=" ? "" : "NOT"} NULL
|
|
80
|
+
ELSE json_extract(metadata, '$."${handleKey(key)}"') ${symbol} ?
|
|
81
|
+
END`,
|
|
82
|
+
needsValue: true,
|
|
83
|
+
transformValue: /* @__PURE__ */ __name((value) => {
|
|
84
|
+
return [
|
|
85
|
+
value,
|
|
86
|
+
value
|
|
87
|
+
];
|
|
88
|
+
}, "transformValue")
|
|
89
|
+
});
|
|
90
|
+
}, "createBasicOperator");
|
|
91
|
+
var createNumericOperator = /* @__PURE__ */ __name((symbol) => {
|
|
92
|
+
return (key) => ({
|
|
93
|
+
sql: `CAST(json_extract(metadata, '$."${handleKey(key)}"') AS NUMERIC) ${symbol} ?`,
|
|
94
|
+
needsValue: true
|
|
95
|
+
});
|
|
96
|
+
}, "createNumericOperator");
|
|
97
|
+
var validateJsonArray = /* @__PURE__ */ __name((key) => `json_valid(json_extract(metadata, '$."${handleKey(key)}"'))
|
|
98
|
+
AND json_type(json_extract(metadata, '$."${handleKey(key)}"')) = 'array'`, "validateJsonArray");
|
|
99
|
+
var FILTER_OPERATORS = {
|
|
100
|
+
$eq: createBasicOperator("="),
|
|
101
|
+
$ne: createBasicOperator("!="),
|
|
102
|
+
$gt: createNumericOperator(">"),
|
|
103
|
+
$gte: createNumericOperator(">="),
|
|
104
|
+
$lt: createNumericOperator("<"),
|
|
105
|
+
$lte: createNumericOperator("<="),
|
|
106
|
+
// Array Operators
|
|
107
|
+
$in: /* @__PURE__ */ __name((key, value) => ({
|
|
108
|
+
sql: `json_extract(metadata, '$."${handleKey(key)}"') IN (${value.map(() => "?").join(",")})`,
|
|
109
|
+
needsValue: true
|
|
110
|
+
}), "$in"),
|
|
111
|
+
$nin: /* @__PURE__ */ __name((key, value) => ({
|
|
112
|
+
sql: `json_extract(metadata, '$."${handleKey(key)}"') NOT IN (${value.map(() => "?").join(",")})`,
|
|
113
|
+
needsValue: true
|
|
114
|
+
}), "$nin"),
|
|
115
|
+
$all: /* @__PURE__ */ __name((key) => ({
|
|
116
|
+
sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
|
|
117
|
+
needsValue: true,
|
|
118
|
+
transformValue: /* @__PURE__ */ __name((value) => {
|
|
119
|
+
const arrayValue = Array.isArray(value) ? value : [
|
|
120
|
+
value
|
|
121
|
+
];
|
|
122
|
+
if (arrayValue.length === 0) {
|
|
123
|
+
return {
|
|
124
|
+
sql: "1 = 0",
|
|
125
|
+
values: []
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
sql: `(
|
|
130
|
+
CASE
|
|
131
|
+
WHEN ${validateJsonArray(key)} THEN
|
|
132
|
+
NOT EXISTS (
|
|
133
|
+
SELECT value
|
|
134
|
+
FROM json_each(?)
|
|
135
|
+
WHERE value NOT IN (
|
|
136
|
+
SELECT value
|
|
137
|
+
FROM json_each(json_extract(metadata, '$."${handleKey(key)}"'))
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
ELSE FALSE
|
|
141
|
+
END
|
|
142
|
+
)`,
|
|
143
|
+
values: [
|
|
144
|
+
JSON.stringify(arrayValue)
|
|
145
|
+
]
|
|
146
|
+
};
|
|
147
|
+
}, "transformValue")
|
|
148
|
+
}), "$all"),
|
|
149
|
+
$elemMatch: /* @__PURE__ */ __name((key) => ({
|
|
150
|
+
sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
|
|
151
|
+
needsValue: true,
|
|
152
|
+
transformValue: /* @__PURE__ */ __name((value) => {
|
|
153
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
154
|
+
throw new Error("$elemMatch requires an object with conditions");
|
|
155
|
+
}
|
|
156
|
+
const conditions = Object.entries(value).map(([field, fieldValue]) => {
|
|
157
|
+
if (field.startsWith("$")) {
|
|
158
|
+
const { sql, values } = buildCondition("elem.value", {
|
|
159
|
+
[field]: fieldValue
|
|
160
|
+
});
|
|
161
|
+
const pattern = /json_extract\(metadata, '\$\."[^"]*"(\."[^"]*")*'\)/g;
|
|
162
|
+
const elemSql = sql.replace(pattern, "elem.value");
|
|
163
|
+
return {
|
|
164
|
+
sql: elemSql,
|
|
165
|
+
values
|
|
166
|
+
};
|
|
167
|
+
} else if (typeof fieldValue === "object" && !Array.isArray(fieldValue)) {
|
|
168
|
+
const { sql, values } = buildCondition(field, fieldValue);
|
|
169
|
+
const pattern = /json_extract\(metadata, '\$\."[^"]*"(\."[^"]*")*'\)/g;
|
|
170
|
+
const elemSql = sql.replace(pattern, `json_extract(elem.value, '$."${field}"')`);
|
|
171
|
+
return {
|
|
172
|
+
sql: elemSql,
|
|
173
|
+
values
|
|
174
|
+
};
|
|
175
|
+
} else {
|
|
176
|
+
return {
|
|
177
|
+
sql: `json_extract(elem.value, '$."${field}"') = ?`,
|
|
178
|
+
values: [
|
|
179
|
+
fieldValue
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
sql: `(
|
|
186
|
+
CASE
|
|
187
|
+
WHEN ${validateJsonArray(key)} THEN
|
|
188
|
+
EXISTS (
|
|
189
|
+
SELECT 1
|
|
190
|
+
FROM json_each(json_extract(metadata, '$."${handleKey(key)}"')) as elem
|
|
191
|
+
WHERE ${conditions.map((c) => c.sql).join(" AND ")}
|
|
192
|
+
)
|
|
193
|
+
ELSE FALSE
|
|
194
|
+
END
|
|
195
|
+
)`,
|
|
196
|
+
values: conditions.flatMap((c) => c.values)
|
|
197
|
+
};
|
|
198
|
+
}, "transformValue")
|
|
199
|
+
}), "$elemMatch"),
|
|
200
|
+
// Element Operators
|
|
201
|
+
$exists: /* @__PURE__ */ __name((key) => ({
|
|
202
|
+
sql: `json_extract(metadata, '$."${handleKey(key)}"') IS NOT NULL`,
|
|
203
|
+
needsValue: false
|
|
204
|
+
}), "$exists"),
|
|
205
|
+
// Logical Operators
|
|
206
|
+
$and: /* @__PURE__ */ __name((key) => ({
|
|
207
|
+
sql: `(${key})`,
|
|
208
|
+
needsValue: false
|
|
209
|
+
}), "$and"),
|
|
210
|
+
$or: /* @__PURE__ */ __name((key) => ({
|
|
211
|
+
sql: `(${key})`,
|
|
212
|
+
needsValue: false
|
|
213
|
+
}), "$or"),
|
|
214
|
+
$not: /* @__PURE__ */ __name((key) => ({
|
|
215
|
+
sql: `NOT (${key})`,
|
|
216
|
+
needsValue: false
|
|
217
|
+
}), "$not"),
|
|
218
|
+
$nor: /* @__PURE__ */ __name((key) => ({
|
|
219
|
+
sql: `NOT (${key})`,
|
|
220
|
+
needsValue: false
|
|
221
|
+
}), "$nor"),
|
|
222
|
+
$size: /* @__PURE__ */ __name((key, paramIndex) => ({
|
|
223
|
+
sql: `(
|
|
224
|
+
CASE
|
|
225
|
+
WHEN json_type(json_extract(metadata, '$."${handleKey(key)}"')) = 'array' THEN
|
|
226
|
+
json_array_length(json_extract(metadata, '$."${handleKey(key)}"')) = $${paramIndex}
|
|
227
|
+
ELSE FALSE
|
|
228
|
+
END
|
|
229
|
+
)`,
|
|
230
|
+
needsValue: true
|
|
231
|
+
}), "$size"),
|
|
232
|
+
// /**
|
|
233
|
+
// * Regex Operators
|
|
234
|
+
// * Supports case insensitive and multiline
|
|
235
|
+
// */
|
|
236
|
+
// $regex: (key: string): FilterOperator => ({
|
|
237
|
+
// sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
|
|
238
|
+
// needsValue: true,
|
|
239
|
+
// transformValue: (value: any) => {
|
|
240
|
+
// const pattern = typeof value === 'object' ? value.$regex : value;
|
|
241
|
+
// const options = typeof value === 'object' ? value.$options || '' : '';
|
|
242
|
+
// let sql = `json_extract(metadata, '$."${handleKey(key)}"')`;
|
|
243
|
+
// // Handle multiline
|
|
244
|
+
// // if (options.includes('m')) {
|
|
245
|
+
// // sql = `REPLACE(${sql}, CHAR(10), '\n')`;
|
|
246
|
+
// // }
|
|
247
|
+
// // let finalPattern = pattern;
|
|
248
|
+
// // if (options) {
|
|
249
|
+
// // finalPattern = `(\\?${options})${pattern}`;
|
|
250
|
+
// // }
|
|
251
|
+
// // // Handle case insensitivity
|
|
252
|
+
// // if (options.includes('i')) {
|
|
253
|
+
// // sql = `LOWER(${sql}) REGEXP LOWER(?)`;
|
|
254
|
+
// // } else {
|
|
255
|
+
// // sql = `${sql} REGEXP ?`;
|
|
256
|
+
// // }
|
|
257
|
+
// if (options.includes('m')) {
|
|
258
|
+
// sql = `EXISTS (
|
|
259
|
+
// SELECT 1
|
|
260
|
+
// FROM json_each(
|
|
261
|
+
// json_array(
|
|
262
|
+
// ${sql},
|
|
263
|
+
// REPLACE(${sql}, CHAR(10), CHAR(13))
|
|
264
|
+
// )
|
|
265
|
+
// ) as lines
|
|
266
|
+
// WHERE lines.value REGEXP ?
|
|
267
|
+
// )`;
|
|
268
|
+
// } else {
|
|
269
|
+
// sql = `${sql} REGEXP ?`;
|
|
270
|
+
// }
|
|
271
|
+
// // Handle case insensitivity
|
|
272
|
+
// if (options.includes('i')) {
|
|
273
|
+
// sql = sql.replace('REGEXP ?', 'REGEXP LOWER(?)');
|
|
274
|
+
// sql = sql.replace('value REGEXP', 'LOWER(value) REGEXP');
|
|
275
|
+
// }
|
|
276
|
+
// // Handle extended - allows whitespace and comments in pattern
|
|
277
|
+
// if (options.includes('x')) {
|
|
278
|
+
// // Remove whitespace and comments from pattern
|
|
279
|
+
// const cleanPattern = pattern.replace(/\s+|#.*$/gm, '');
|
|
280
|
+
// return {
|
|
281
|
+
// sql,
|
|
282
|
+
// values: [cleanPattern],
|
|
283
|
+
// };
|
|
284
|
+
// }
|
|
285
|
+
// return {
|
|
286
|
+
// sql,
|
|
287
|
+
// values: [pattern],
|
|
288
|
+
// };
|
|
289
|
+
// },
|
|
290
|
+
// }),
|
|
291
|
+
$contains: /* @__PURE__ */ __name((key) => ({
|
|
292
|
+
sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
|
|
293
|
+
needsValue: true,
|
|
294
|
+
transformValue: /* @__PURE__ */ __name((value) => {
|
|
295
|
+
if (Array.isArray(value)) {
|
|
296
|
+
return {
|
|
297
|
+
sql: `(
|
|
298
|
+
SELECT ${validateJsonArray(key)}
|
|
299
|
+
AND EXISTS (
|
|
300
|
+
SELECT 1
|
|
301
|
+
FROM json_each(json_extract(metadata, '$."${handleKey(key)}"')) as m
|
|
302
|
+
WHERE m.value IN (SELECT value FROM json_each(?))
|
|
303
|
+
)
|
|
304
|
+
)`,
|
|
305
|
+
values: [
|
|
306
|
+
JSON.stringify(value)
|
|
307
|
+
]
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
if (value && typeof value === "object") {
|
|
311
|
+
let traverse2 = function(obj, path = []) {
|
|
312
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
313
|
+
const currentPath = [
|
|
314
|
+
...path,
|
|
315
|
+
k
|
|
316
|
+
];
|
|
317
|
+
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
318
|
+
traverse2(v, currentPath);
|
|
319
|
+
} else {
|
|
320
|
+
paths.push(currentPath.join("."));
|
|
321
|
+
values.push(v);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
__name(traverse2, "traverse");
|
|
326
|
+
const paths = [];
|
|
327
|
+
const values = [];
|
|
328
|
+
traverse2(value);
|
|
329
|
+
return {
|
|
330
|
+
sql: `(${paths.map((path) => `json_extract(metadata, '$."${handleKey(key)}"."${path}"') = ?`).join(" AND ")})`,
|
|
331
|
+
values
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
return value;
|
|
335
|
+
}, "transformValue")
|
|
336
|
+
}), "$contains")
|
|
337
|
+
};
|
|
338
|
+
var handleKey = /* @__PURE__ */ __name((key) => {
|
|
339
|
+
return key.replace(/\./g, '"."');
|
|
340
|
+
}, "handleKey");
|
|
341
|
+
function buildFilterQuery(filter) {
|
|
342
|
+
if (!filter) {
|
|
343
|
+
return {
|
|
344
|
+
sql: "",
|
|
345
|
+
values: []
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
const values = [];
|
|
349
|
+
const conditions = Object.entries(filter).map(([key, value]) => {
|
|
350
|
+
const condition = buildCondition(key, value);
|
|
351
|
+
values.push(...condition.values);
|
|
352
|
+
return condition.sql;
|
|
353
|
+
}).join(" AND ");
|
|
354
|
+
return {
|
|
355
|
+
sql: conditions ? `WHERE ${conditions}` : "",
|
|
356
|
+
values
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
__name(buildFilterQuery, "buildFilterQuery");
|
|
360
|
+
function buildCondition(key, value, parentPath) {
|
|
361
|
+
if ([
|
|
362
|
+
"$and",
|
|
363
|
+
"$or",
|
|
364
|
+
"$not",
|
|
365
|
+
"$nor"
|
|
366
|
+
].includes(key)) {
|
|
367
|
+
return handleLogicalOperator(key, value);
|
|
368
|
+
}
|
|
369
|
+
if (!value || typeof value !== "object") {
|
|
370
|
+
return {
|
|
371
|
+
sql: `json_extract(metadata, '$."${key.replace(/\./g, '"."')}"') = ?`,
|
|
372
|
+
values: [
|
|
373
|
+
value
|
|
374
|
+
]
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
return handleOperator(key, value);
|
|
378
|
+
}
|
|
379
|
+
__name(buildCondition, "buildCondition");
|
|
380
|
+
function handleLogicalOperator(key, value, parentPath) {
|
|
381
|
+
if (!value || value.length === 0) {
|
|
382
|
+
switch (key) {
|
|
383
|
+
case "$and":
|
|
384
|
+
case "$nor":
|
|
385
|
+
return {
|
|
386
|
+
sql: "true",
|
|
387
|
+
values: []
|
|
388
|
+
};
|
|
389
|
+
case "$or":
|
|
390
|
+
return {
|
|
391
|
+
sql: "false",
|
|
392
|
+
values: []
|
|
393
|
+
};
|
|
394
|
+
case "$not":
|
|
395
|
+
throw new Error("$not operator cannot be empty");
|
|
396
|
+
default:
|
|
397
|
+
return {
|
|
398
|
+
sql: "true",
|
|
399
|
+
values: []
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (key === "$not") {
|
|
404
|
+
const entries = Object.entries(value);
|
|
405
|
+
const conditions2 = entries.map(([fieldKey, fieldValue]) => buildCondition(fieldKey, fieldValue));
|
|
406
|
+
return {
|
|
407
|
+
sql: `NOT (${conditions2.map((c) => c.sql).join(" AND ")})`,
|
|
408
|
+
values: conditions2.flatMap((c) => c.values)
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
const values = [];
|
|
412
|
+
const joinOperator = key === "$or" || key === "$nor" ? "OR" : "AND";
|
|
413
|
+
const conditions = Array.isArray(value) ? value.map((f) => {
|
|
414
|
+
const entries = Object.entries(f);
|
|
415
|
+
return entries.map(([k, v]) => buildCondition(k, v));
|
|
416
|
+
}) : [
|
|
417
|
+
buildCondition(key, value)
|
|
418
|
+
];
|
|
419
|
+
const joined = conditions.flat().map((c) => {
|
|
420
|
+
values.push(...c.values);
|
|
421
|
+
return c.sql;
|
|
422
|
+
}).join(` ${joinOperator} `);
|
|
423
|
+
return {
|
|
424
|
+
sql: key === "$nor" ? `NOT (${joined})` : `(${joined})`,
|
|
425
|
+
values
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
__name(handleLogicalOperator, "handleLogicalOperator");
|
|
429
|
+
function handleOperator(key, value) {
|
|
430
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
431
|
+
const entries = Object.entries(value);
|
|
432
|
+
const results = entries.map(([operator2, operatorValue2]) => operator2 === "$not" ? {
|
|
433
|
+
sql: `NOT (${Object.entries(operatorValue2).map(([op, val]) => processOperator(key, op, val).sql).join(" AND ")})`,
|
|
434
|
+
values: Object.entries(operatorValue2).flatMap(([op, val]) => processOperator(key, op, val).values)
|
|
435
|
+
} : processOperator(key, operator2, operatorValue2));
|
|
436
|
+
return {
|
|
437
|
+
sql: `(${results.map((r) => r.sql).join(" AND ")})`,
|
|
438
|
+
values: results.flatMap((r) => r.values)
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
const [[operator, operatorValue] = []] = Object.entries(value);
|
|
442
|
+
return processOperator(key, operator, operatorValue);
|
|
443
|
+
}
|
|
444
|
+
__name(handleOperator, "handleOperator");
|
|
445
|
+
var processOperator = /* @__PURE__ */ __name((key, operator, operatorValue) => {
|
|
446
|
+
if (!operator.startsWith("$") || !FILTER_OPERATORS[operator]) {
|
|
447
|
+
throw new Error(`Invalid operator: ${operator}`);
|
|
448
|
+
}
|
|
449
|
+
const operatorFn = FILTER_OPERATORS[operator];
|
|
450
|
+
const operatorResult = operatorFn(key, operatorValue);
|
|
451
|
+
if (!operatorResult.needsValue) {
|
|
452
|
+
return {
|
|
453
|
+
sql: operatorResult.sql,
|
|
454
|
+
values: []
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
const transformed = operatorResult.transformValue ? operatorResult.transformValue(operatorValue) : operatorValue;
|
|
458
|
+
if (transformed && typeof transformed === "object" && "sql" in transformed) {
|
|
459
|
+
return transformed;
|
|
460
|
+
}
|
|
461
|
+
return {
|
|
462
|
+
sql: operatorResult.sql,
|
|
463
|
+
values: Array.isArray(transformed) ? transformed : [
|
|
464
|
+
transformed
|
|
465
|
+
]
|
|
466
|
+
};
|
|
467
|
+
}, "processOperator");
|
|
468
|
+
|
|
469
|
+
// src/vector/libsql/index.ts
|
|
470
|
+
var _DefaultVectorDB = class _DefaultVectorDB extends MastraVector {
|
|
471
|
+
constructor({ connectionUrl, authToken, syncUrl, syncInterval }) {
|
|
472
|
+
super();
|
|
473
|
+
__publicField(this, "turso");
|
|
474
|
+
this.turso = createClient({
|
|
475
|
+
url: connectionUrl,
|
|
476
|
+
syncUrl,
|
|
477
|
+
authToken,
|
|
478
|
+
syncInterval
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
transformFilter(filter) {
|
|
482
|
+
const libsqlFilter = new LibSQLFilterTranslator();
|
|
483
|
+
const translatedFilter = libsqlFilter.translate(filter ?? {});
|
|
484
|
+
return translatedFilter;
|
|
485
|
+
}
|
|
486
|
+
async query(indexName, queryVector, topK = 10, filter, includeVector = false, minScore = 0) {
|
|
487
|
+
try {
|
|
488
|
+
const vectorStr = `[${queryVector.join(",")}]`;
|
|
489
|
+
const translatedFilter = this.transformFilter(filter);
|
|
490
|
+
const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
491
|
+
filterValues.push(minScore);
|
|
492
|
+
const query = `
|
|
493
|
+
WITH vector_scores AS (
|
|
494
|
+
SELECT
|
|
495
|
+
vector_id as id,
|
|
496
|
+
(1-vector_distance_cos(embedding, '${vectorStr}')) as score,
|
|
497
|
+
metadata
|
|
498
|
+
${includeVector ? ", vector_extract(embedding) as embedding" : ""}
|
|
499
|
+
FROM ${indexName}
|
|
500
|
+
${filterQuery}
|
|
501
|
+
)
|
|
502
|
+
SELECT *
|
|
503
|
+
FROM vector_scores
|
|
504
|
+
WHERE score > ?
|
|
505
|
+
ORDER BY score DESC
|
|
506
|
+
LIMIT ${topK}`;
|
|
507
|
+
const result = await this.turso.execute({
|
|
508
|
+
sql: query,
|
|
509
|
+
args: filterValues
|
|
510
|
+
});
|
|
511
|
+
return result.rows.map(({ id, score, metadata, embedding }) => ({
|
|
512
|
+
id,
|
|
513
|
+
score,
|
|
514
|
+
metadata: JSON.parse(metadata ?? "{}"),
|
|
515
|
+
...includeVector && embedding && {
|
|
516
|
+
vector: JSON.parse(embedding)
|
|
517
|
+
}
|
|
518
|
+
}));
|
|
519
|
+
} finally {
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
async upsert(indexName, vectors, metadata, ids) {
|
|
523
|
+
const tx = await this.turso.transaction("write");
|
|
524
|
+
try {
|
|
525
|
+
const vectorIds = ids || vectors.map(() => crypto.randomUUID());
|
|
526
|
+
for (let i = 0; i < vectors.length; i++) {
|
|
527
|
+
const query = `
|
|
528
|
+
INSERT INTO ${indexName} (vector_id, embedding, metadata)
|
|
529
|
+
VALUES (?, vector32(?), ?)
|
|
530
|
+
ON CONFLICT(vector_id) DO UPDATE SET
|
|
531
|
+
embedding = vector32(?),
|
|
532
|
+
metadata = ?
|
|
533
|
+
`;
|
|
534
|
+
await tx.execute({
|
|
535
|
+
sql: query,
|
|
536
|
+
// @ts-ignore
|
|
537
|
+
args: [
|
|
538
|
+
vectorIds[i],
|
|
539
|
+
JSON.stringify(vectors[i]),
|
|
540
|
+
JSON.stringify(metadata?.[i] || {}),
|
|
541
|
+
JSON.stringify(vectors[i]),
|
|
542
|
+
JSON.stringify(metadata?.[i] || {})
|
|
543
|
+
]
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
await tx.commit();
|
|
547
|
+
return vectorIds;
|
|
548
|
+
} catch (error) {
|
|
549
|
+
await tx.rollback();
|
|
550
|
+
throw error;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async createIndex(indexName, dimension, _metric = "cosine") {
|
|
554
|
+
try {
|
|
555
|
+
if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
|
|
556
|
+
throw new Error("Invalid index name format");
|
|
557
|
+
}
|
|
558
|
+
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
559
|
+
throw new Error("Dimension must be a positive integer");
|
|
560
|
+
}
|
|
561
|
+
await this.turso.execute({
|
|
562
|
+
sql: `
|
|
563
|
+
CREATE TABLE IF NOT EXISTS ${indexName} (
|
|
564
|
+
id SERIAL PRIMARY KEY,
|
|
565
|
+
vector_id TEXT UNIQUE NOT NULL,
|
|
566
|
+
embedding F32_BLOB(${dimension}),
|
|
567
|
+
metadata TEXT DEFAULT '{}'
|
|
568
|
+
);
|
|
569
|
+
`,
|
|
570
|
+
args: []
|
|
571
|
+
});
|
|
572
|
+
await this.turso.execute({
|
|
573
|
+
sql: `
|
|
574
|
+
CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
|
|
575
|
+
ON ${indexName} (libsql_vector_idx(embedding))
|
|
576
|
+
`,
|
|
577
|
+
args: []
|
|
578
|
+
});
|
|
579
|
+
} catch (error) {
|
|
580
|
+
console.error("Failed to create vector table:", error);
|
|
581
|
+
throw error;
|
|
582
|
+
} finally {
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async deleteIndex(indexName) {
|
|
586
|
+
try {
|
|
587
|
+
await this.turso.execute({
|
|
588
|
+
sql: `DROP TABLE IF EXISTS ${indexName}`,
|
|
589
|
+
args: []
|
|
590
|
+
});
|
|
591
|
+
} catch (error) {
|
|
592
|
+
console.error("Failed to delete vector table:", error);
|
|
593
|
+
throw new Error(`Failed to delete vector table: ${error.message}`);
|
|
594
|
+
} finally {
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
async listIndexes() {
|
|
598
|
+
try {
|
|
599
|
+
const vectorTablesQuery = `
|
|
600
|
+
SELECT name FROM sqlite_master
|
|
601
|
+
WHERE type='table'
|
|
602
|
+
AND sql LIKE '%F32_BLOB%';
|
|
603
|
+
`;
|
|
604
|
+
const result = await this.turso.execute({
|
|
605
|
+
sql: vectorTablesQuery,
|
|
606
|
+
args: []
|
|
607
|
+
});
|
|
608
|
+
return result.rows.map((row) => row.name);
|
|
609
|
+
} catch (error) {
|
|
610
|
+
throw new Error(`Failed to list vector tables: ${error.message}`);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
async describeIndex(indexName) {
|
|
614
|
+
try {
|
|
615
|
+
const tableInfoQuery = `
|
|
616
|
+
SELECT sql
|
|
617
|
+
FROM sqlite_master
|
|
618
|
+
WHERE type='table'
|
|
619
|
+
AND name = ?;
|
|
620
|
+
`;
|
|
621
|
+
const tableInfo = await this.turso.execute({
|
|
622
|
+
sql: tableInfoQuery,
|
|
623
|
+
args: [
|
|
624
|
+
indexName
|
|
625
|
+
]
|
|
626
|
+
});
|
|
627
|
+
if (!tableInfo.rows[0]?.sql) {
|
|
628
|
+
throw new Error(`Table ${indexName} not found`);
|
|
629
|
+
}
|
|
630
|
+
const dimension = parseInt(tableInfo.rows[0].sql.match(/F32_BLOB\((\d+)\)/)?.[1] || "0");
|
|
631
|
+
const countQuery = `
|
|
632
|
+
SELECT COUNT(*) as count
|
|
633
|
+
FROM ${indexName};
|
|
634
|
+
`;
|
|
635
|
+
const countResult = await this.turso.execute({
|
|
636
|
+
sql: countQuery,
|
|
637
|
+
args: []
|
|
638
|
+
});
|
|
639
|
+
const metric = "cosine";
|
|
640
|
+
return {
|
|
641
|
+
dimension,
|
|
642
|
+
count: countResult?.rows?.[0]?.count ?? 0,
|
|
643
|
+
metric
|
|
644
|
+
};
|
|
645
|
+
} catch (e) {
|
|
646
|
+
throw new Error(`Failed to describe vector table: ${e.message}`);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
async truncateIndex(indexName) {
|
|
650
|
+
await this.turso.execute({
|
|
651
|
+
sql: `DELETE FROM ${indexName}`,
|
|
652
|
+
args: []
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
__name(_DefaultVectorDB, "DefaultVectorDB");
|
|
657
|
+
var DefaultVectorDB = _DefaultVectorDB;
|
|
658
|
+
|
|
659
|
+
export { DefaultVectorDB };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LLM } from './chunk-YPMAHKBC.js';
|
|
1
|
+
import { LLM } from './chunk-RI3ECMVF.js';
|
|
3
2
|
import { InstrumentClass } from './chunk-6ZVFVYLE.js';
|
|
4
3
|
import { MastraBase } from './chunk-G4MCO7XF.js';
|
|
5
4
|
import { RegisteredLogger, LogLevel } from './chunk-ICMEXHKD.js';
|
|
5
|
+
import { executeHook, AvailableHooks } from './chunk-HBTQNIAX.js';
|
|
6
6
|
import { __name, __publicField, __privateAdd, __privateSet, __privateGet } from './chunk-AJJZUHB4.js';
|
|
7
7
|
import { randomUUID } from 'crypto';
|
|
8
8
|
import { z } from 'zod';
|
|
9
|
-
import 'dotenv/config';
|
|
10
9
|
|
|
11
10
|
function _ts_decorate(decorators, target, key, desc) {
|
|
12
11
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|