@mastra/core 0.0.0-commonjs-20250227130920

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.
Files changed (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -0
  3. package/dist/agent/index.cjs +1865 -0
  4. package/dist/agent/index.d.cts +15 -0
  5. package/dist/agent/index.d.ts +15 -0
  6. package/dist/agent/index.js +1 -0
  7. package/dist/base-D90KQ4XI.d.ts +139 -0
  8. package/dist/base-hs9NDAZ2.d.cts +139 -0
  9. package/dist/base-nKCMCNrM.d.ts +920 -0
  10. package/dist/base-nhesrHv3.d.cts +920 -0
  11. package/dist/base.cjs +138 -0
  12. package/dist/base.d.cts +6 -0
  13. package/dist/base.d.ts +6 -0
  14. package/dist/base.js +1 -0
  15. package/dist/bundler/index.cjs +158 -0
  16. package/dist/bundler/index.d.cts +28 -0
  17. package/dist/bundler/index.d.ts +28 -0
  18. package/dist/bundler/index.js +1 -0
  19. package/dist/chunk-33GSTUNK.js +620 -0
  20. package/dist/chunk-4YRYBCOZ.js +10 -0
  21. package/dist/chunk-55NFNRKO.js +10 -0
  22. package/dist/chunk-5XPCMNGW.js +215 -0
  23. package/dist/chunk-B3M27AMP.js +1479 -0
  24. package/dist/chunk-BB4KXGBU.js +83 -0
  25. package/dist/chunk-C6A6W6XS.js +77 -0
  26. package/dist/chunk-HQ55LN2U.js +318 -0
  27. package/dist/chunk-KNVTCZW7.js +416 -0
  28. package/dist/chunk-LH47WVJL.js +61 -0
  29. package/dist/chunk-NGD2HQYW.js +346 -0
  30. package/dist/chunk-NUDAZEOG.js +35 -0
  31. package/dist/chunk-OZ4XVJ6F.js +49 -0
  32. package/dist/chunk-PHMSPCTC.js +145 -0
  33. package/dist/chunk-PNZK456O.js +88 -0
  34. package/dist/chunk-QAAJAHDB.js +37 -0
  35. package/dist/chunk-RG66XEJT.js +8 -0
  36. package/dist/chunk-SIFBBGY6.js +190 -0
  37. package/dist/chunk-SVEAENO7.js +22 -0
  38. package/dist/chunk-SY5244IR.js +1499 -0
  39. package/dist/chunk-W5HVJX45.js +402 -0
  40. package/dist/chunk-WIBGG4X6.js +173 -0
  41. package/dist/chunk-ZDWFBE5L.js +1 -0
  42. package/dist/chunk-ZINPRHAN.js +22 -0
  43. package/dist/deployer/index.cjs +165 -0
  44. package/dist/deployer/index.d.cts +19 -0
  45. package/dist/deployer/index.d.ts +19 -0
  46. package/dist/deployer/index.js +1 -0
  47. package/dist/eval/index.cjs +110 -0
  48. package/dist/eval/index.d.cts +28 -0
  49. package/dist/eval/index.d.ts +28 -0
  50. package/dist/eval/index.js +1 -0
  51. package/dist/filter/index.cjs +192 -0
  52. package/dist/filter/index.d.cts +90 -0
  53. package/dist/filter/index.d.ts +90 -0
  54. package/dist/filter/index.js +1 -0
  55. package/dist/hooks/index.cjs +87 -0
  56. package/dist/hooks/index.d.cts +33 -0
  57. package/dist/hooks/index.d.ts +33 -0
  58. package/dist/hooks/index.js +1 -0
  59. package/dist/index-mKY1XrpK.d.cts +90 -0
  60. package/dist/index-mKY1XrpK.d.ts +90 -0
  61. package/dist/index.cjs +6844 -0
  62. package/dist/index.d.cts +97 -0
  63. package/dist/index.d.ts +97 -0
  64. package/dist/index.js +119 -0
  65. package/dist/integration/index.cjs +113 -0
  66. package/dist/integration/index.d.cts +52 -0
  67. package/dist/integration/index.d.ts +52 -0
  68. package/dist/integration/index.js +1 -0
  69. package/dist/llm/index.cjs +2 -0
  70. package/dist/llm/index.d.cts +15 -0
  71. package/dist/llm/index.d.ts +15 -0
  72. package/dist/llm/index.js +1 -0
  73. package/dist/logger/index.cjs +159 -0
  74. package/dist/logger/index.d.cts +3 -0
  75. package/dist/logger/index.d.ts +3 -0
  76. package/dist/logger/index.js +1 -0
  77. package/dist/mastra/index.cjs +1741 -0
  78. package/dist/mastra/index.d.cts +67 -0
  79. package/dist/mastra/index.d.ts +67 -0
  80. package/dist/mastra/index.js +1 -0
  81. package/dist/memory/index.cjs +1907 -0
  82. package/dist/memory/index.d.cts +15 -0
  83. package/dist/memory/index.d.ts +15 -0
  84. package/dist/memory/index.js +1 -0
  85. package/dist/relevance/index.cjs +1927 -0
  86. package/dist/relevance/index.d.cts +21 -0
  87. package/dist/relevance/index.d.ts +21 -0
  88. package/dist/relevance/index.js +1 -0
  89. package/dist/storage/index.cjs +361 -0
  90. package/dist/storage/index.d.cts +15 -0
  91. package/dist/storage/index.d.ts +15 -0
  92. package/dist/storage/index.js +2 -0
  93. package/dist/storage/libsql/index.cjs +770 -0
  94. package/dist/storage/libsql/index.d.cts +81 -0
  95. package/dist/storage/libsql/index.d.ts +81 -0
  96. package/dist/storage/libsql/index.js +1 -0
  97. package/dist/telemetry/index.cjs +413 -0
  98. package/dist/telemetry/index.d.cts +51 -0
  99. package/dist/telemetry/index.d.ts +51 -0
  100. package/dist/telemetry/index.js +1 -0
  101. package/dist/telemetry/otel-vendor.cjs +52 -0
  102. package/dist/telemetry/otel-vendor.d.cts +7 -0
  103. package/dist/telemetry/otel-vendor.d.ts +7 -0
  104. package/dist/telemetry/otel-vendor.js +7 -0
  105. package/dist/tools/index.cjs +25 -0
  106. package/dist/tools/index.d.cts +29 -0
  107. package/dist/tools/index.d.ts +29 -0
  108. package/dist/tools/index.js +1 -0
  109. package/dist/tts/index.cjs +328 -0
  110. package/dist/tts/index.d.cts +28 -0
  111. package/dist/tts/index.d.ts +28 -0
  112. package/dist/tts/index.js +1 -0
  113. package/dist/types-m9RryK9a.d.cts +14 -0
  114. package/dist/types-m9RryK9a.d.ts +14 -0
  115. package/dist/utils.cjs +179 -0
  116. package/dist/utils.d.cts +26 -0
  117. package/dist/utils.d.ts +26 -0
  118. package/dist/utils.js +1 -0
  119. package/dist/vector/index.cjs +145 -0
  120. package/dist/vector/index.d.cts +30 -0
  121. package/dist/vector/index.d.ts +30 -0
  122. package/dist/vector/index.js +1 -0
  123. package/dist/vector/libsql/index.cjs +951 -0
  124. package/dist/vector/libsql/index.d.cts +29 -0
  125. package/dist/vector/libsql/index.d.ts +29 -0
  126. package/dist/vector/libsql/index.js +1 -0
  127. package/dist/voice/index.cjs +369 -0
  128. package/dist/voice/index.d.cts +67 -0
  129. package/dist/voice/index.d.ts +67 -0
  130. package/dist/voice/index.js +76 -0
  131. package/dist/workflow-DqQ4pON_.d.cts +84 -0
  132. package/dist/workflow-Ng_F_Zaf.d.ts +84 -0
  133. package/dist/workflows/index.cjs +1628 -0
  134. package/dist/workflows/index.d.cts +48 -0
  135. package/dist/workflows/index.d.ts +48 -0
  136. package/dist/workflows/index.js +1 -0
  137. package/package.json +162 -0
@@ -0,0 +1,951 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+ var client = require('@libsql/client');
5
+ var stream = require('stream');
6
+ var pino = require('pino');
7
+ var pretty = require('pino-pretty');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var pino__default = /*#__PURE__*/_interopDefault(pino);
12
+ var pretty__default = /*#__PURE__*/_interopDefault(pretty);
13
+
14
+ // src/vector/libsql/index.ts
15
+ var RegisteredLogger = {
16
+ LLM: "LLM"};
17
+ var LogLevel = {
18
+ INFO: "info"};
19
+ var Logger = class {
20
+ logger;
21
+ transports;
22
+ constructor(options = {}) {
23
+ this.transports = options.transports || {};
24
+ const transportsAry = Object.entries(this.transports);
25
+ this.logger = pino__default.default(
26
+ {
27
+ name: options.name || "app",
28
+ level: options.level || LogLevel.INFO
29
+ },
30
+ options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? pretty__default.default({
31
+ colorize: true,
32
+ levelFirst: true,
33
+ ignore: "pid,hostname",
34
+ colorizeObjects: true,
35
+ translateTime: "SYS:standard",
36
+ singleLine: false
37
+ }) : pino__default.default.multistream([
38
+ ...transportsAry.map(([_, transport]) => ({
39
+ stream: transport,
40
+ level: options.level || LogLevel.INFO
41
+ })),
42
+ {
43
+ stream: pretty__default.default({
44
+ colorize: true,
45
+ levelFirst: true,
46
+ ignore: "pid,hostname",
47
+ colorizeObjects: true,
48
+ translateTime: "SYS:standard",
49
+ singleLine: false
50
+ }),
51
+ level: options.level || LogLevel.INFO
52
+ }
53
+ ])
54
+ );
55
+ }
56
+ debug(message, args = {}) {
57
+ this.logger.debug(args, message);
58
+ }
59
+ info(message, args = {}) {
60
+ this.logger.info(args, message);
61
+ }
62
+ warn(message, args = {}) {
63
+ this.logger.warn(args, message);
64
+ }
65
+ error(message, args = {}) {
66
+ this.logger.error(args, message);
67
+ }
68
+ // Stream creation for process output handling
69
+ createStream() {
70
+ return new stream.Transform({
71
+ transform: (chunk, _encoding, callback) => {
72
+ const line = chunk.toString().trim();
73
+ if (line) {
74
+ this.info(line);
75
+ }
76
+ callback(null, chunk);
77
+ }
78
+ });
79
+ }
80
+ async getLogs(transportId) {
81
+ if (!transportId || !this.transports[transportId]) {
82
+ return [];
83
+ }
84
+ return this.transports[transportId].getLogs();
85
+ }
86
+ async getLogsByRunId({ runId, transportId }) {
87
+ return this.transports[transportId]?.getLogsByRunId({ runId });
88
+ }
89
+ };
90
+ function createLogger(options) {
91
+ return new Logger(options);
92
+ }
93
+
94
+ // src/base.ts
95
+ var MastraBase = class {
96
+ component = RegisteredLogger.LLM;
97
+ logger;
98
+ name;
99
+ telemetry;
100
+ constructor({ component, name }) {
101
+ this.component = component || RegisteredLogger.LLM;
102
+ this.name = name;
103
+ this.logger = createLogger({ name: `${this.component} - ${this.name}` });
104
+ }
105
+ /**
106
+ * Set the logger for the agent
107
+ * @param logger
108
+ */
109
+ __setLogger(logger) {
110
+ this.logger = logger;
111
+ this.logger.debug(`Logger updated [component=${this.component}] [name=${this.name}]`);
112
+ }
113
+ /**
114
+ * Set the telemetry for the
115
+ * @param telemetry
116
+ */
117
+ __setTelemetry(telemetry) {
118
+ this.telemetry = telemetry;
119
+ this.logger.debug(`Telemetry updated [component=${this.component}] [tracer=${this.telemetry.tracer}]`);
120
+ }
121
+ /**
122
+ * Get the telemetry on the vector
123
+ * @returns telemetry
124
+ */
125
+ __getTelemetry() {
126
+ return this.telemetry;
127
+ }
128
+ /*
129
+ get experimental_telemetry config
130
+ */
131
+ get experimental_telemetry() {
132
+ return this.telemetry ? {
133
+ // tracer: this.telemetry.tracer,
134
+ tracer: this.telemetry.getBaggageTracer(),
135
+ isEnabled: !!this.telemetry.tracer
136
+ } : void 0;
137
+ }
138
+ };
139
+
140
+ // src/vector/index.ts
141
+ var MastraVector = class extends MastraBase {
142
+ constructor() {
143
+ super({ name: "MastraVector", component: "VECTOR" });
144
+ }
145
+ };
146
+
147
+ // src/filter/base.ts
148
+ var BaseFilterTranslator = class _BaseFilterTranslator {
149
+ /**
150
+ * Operator type checks
151
+ */
152
+ isOperator(key) {
153
+ return key.startsWith("$");
154
+ }
155
+ static BASIC_OPERATORS = ["$eq", "$ne"];
156
+ static NUMERIC_OPERATORS = ["$gt", "$gte", "$lt", "$lte"];
157
+ static ARRAY_OPERATORS = ["$in", "$nin", "$all", "$elemMatch"];
158
+ static LOGICAL_OPERATORS = ["$and", "$or", "$not", "$nor"];
159
+ static ELEMENT_OPERATORS = ["$exists"];
160
+ static REGEX_OPERATORS = ["$regex", "$options"];
161
+ static DEFAULT_OPERATORS = {
162
+ logical: _BaseFilterTranslator.LOGICAL_OPERATORS,
163
+ basic: _BaseFilterTranslator.BASIC_OPERATORS,
164
+ numeric: _BaseFilterTranslator.NUMERIC_OPERATORS,
165
+ array: _BaseFilterTranslator.ARRAY_OPERATORS,
166
+ element: _BaseFilterTranslator.ELEMENT_OPERATORS,
167
+ regex: _BaseFilterTranslator.REGEX_OPERATORS
168
+ };
169
+ isLogicalOperator(key) {
170
+ return _BaseFilterTranslator.DEFAULT_OPERATORS.logical.includes(key);
171
+ }
172
+ isBasicOperator(key) {
173
+ return _BaseFilterTranslator.DEFAULT_OPERATORS.basic.includes(key);
174
+ }
175
+ isNumericOperator(key) {
176
+ return _BaseFilterTranslator.DEFAULT_OPERATORS.numeric.includes(key);
177
+ }
178
+ isArrayOperator(key) {
179
+ return _BaseFilterTranslator.DEFAULT_OPERATORS.array.includes(key);
180
+ }
181
+ isElementOperator(key) {
182
+ return _BaseFilterTranslator.DEFAULT_OPERATORS.element.includes(key);
183
+ }
184
+ isRegexOperator(key) {
185
+ return _BaseFilterTranslator.DEFAULT_OPERATORS.regex.includes(key);
186
+ }
187
+ isFieldOperator(key) {
188
+ return this.isOperator(key) && !this.isLogicalOperator(key);
189
+ }
190
+ isCustomOperator(key) {
191
+ const support = this.getSupportedOperators();
192
+ return support.custom?.includes(key) ?? false;
193
+ }
194
+ getSupportedOperators() {
195
+ return _BaseFilterTranslator.DEFAULT_OPERATORS;
196
+ }
197
+ isValidOperator(key) {
198
+ const support = this.getSupportedOperators();
199
+ const allSupported = Object.values(support).flat();
200
+ return allSupported.includes(key);
201
+ }
202
+ /**
203
+ * Value normalization for comparison operators
204
+ */
205
+ normalizeComparisonValue(value) {
206
+ if (value instanceof Date) {
207
+ return value.toISOString();
208
+ }
209
+ if (typeof value === "number" && Object.is(value, -0)) {
210
+ return 0;
211
+ }
212
+ return value;
213
+ }
214
+ /**
215
+ * Helper method to simulate $all operator using $and + $eq when needed.
216
+ * Some vector stores don't support $all natively.
217
+ */
218
+ simulateAllOperator(field, values) {
219
+ return {
220
+ $and: values.map((value) => ({
221
+ [field]: { $in: [this.normalizeComparisonValue(value)] }
222
+ }))
223
+ };
224
+ }
225
+ /**
226
+ * Utility functions for type checking
227
+ */
228
+ isPrimitive(value) {
229
+ return value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
230
+ }
231
+ isRegex(value) {
232
+ return value instanceof RegExp;
233
+ }
234
+ isEmpty(obj) {
235
+ return obj === null || obj === void 0 || typeof obj === "object" && Object.keys(obj).length === 0;
236
+ }
237
+ static ErrorMessages = {
238
+ UNSUPPORTED_OPERATOR: (op) => `Unsupported operator: ${op}`,
239
+ INVALID_LOGICAL_OPERATOR_LOCATION: (op, path) => `Logical operator ${op} cannot be used at field level: ${path}`,
240
+ NOT_REQUIRES_OBJECT: `$not operator requires an object`,
241
+ NOT_CANNOT_BE_EMPTY: `$not operator cannot be empty`,
242
+ INVALID_LOGICAL_OPERATOR_CONTENT: (path) => `Logical operators must contain field conditions, not direct operators: ${path}`,
243
+ INVALID_TOP_LEVEL_OPERATOR: (op) => `Invalid top-level operator: ${op}`,
244
+ ELEM_MATCH_REQUIRES_OBJECT: `$elemMatch requires an object with conditions`
245
+ };
246
+ /**
247
+ * Helper to handle array value normalization consistently
248
+ */
249
+ normalizeArrayValues(values) {
250
+ return values.map((value) => this.normalizeComparisonValue(value));
251
+ }
252
+ validateFilter(filter) {
253
+ const validation = this.validateFilterSupport(filter);
254
+ if (!validation.supported) {
255
+ throw new Error(validation.messages.join(", "));
256
+ }
257
+ }
258
+ /**
259
+ * Validates if a filter structure is supported by the specific vector DB
260
+ * and returns detailed validation information.
261
+ */
262
+ validateFilterSupport(node, path = "") {
263
+ const messages = [];
264
+ if (this.isPrimitive(node) || this.isEmpty(node)) {
265
+ return { supported: true, messages: [] };
266
+ }
267
+ if (Array.isArray(node)) {
268
+ const arrayResults = node.map((item) => this.validateFilterSupport(item, path));
269
+ const arrayMessages = arrayResults.flatMap((r) => r.messages);
270
+ return {
271
+ supported: arrayResults.every((r) => r.supported),
272
+ messages: arrayMessages
273
+ };
274
+ }
275
+ const nodeObj = node;
276
+ let isSupported = true;
277
+ for (const [key, value] of Object.entries(nodeObj)) {
278
+ const newPath = path ? `${path}.${key}` : key;
279
+ if (this.isOperator(key)) {
280
+ if (!this.isValidOperator(key)) {
281
+ isSupported = false;
282
+ messages.push(_BaseFilterTranslator.ErrorMessages.UNSUPPORTED_OPERATOR(key));
283
+ continue;
284
+ }
285
+ if (!path && !this.isLogicalOperator(key)) {
286
+ isSupported = false;
287
+ messages.push(_BaseFilterTranslator.ErrorMessages.INVALID_TOP_LEVEL_OPERATOR(key));
288
+ continue;
289
+ }
290
+ if (key === "$elemMatch" && (typeof value !== "object" || Array.isArray(value))) {
291
+ isSupported = false;
292
+ messages.push(_BaseFilterTranslator.ErrorMessages.ELEM_MATCH_REQUIRES_OBJECT);
293
+ continue;
294
+ }
295
+ if (this.isLogicalOperator(key)) {
296
+ if (key === "$not") {
297
+ if (Array.isArray(value) || typeof value !== "object") {
298
+ isSupported = false;
299
+ messages.push(_BaseFilterTranslator.ErrorMessages.NOT_REQUIRES_OBJECT);
300
+ continue;
301
+ }
302
+ if (this.isEmpty(value)) {
303
+ isSupported = false;
304
+ messages.push(_BaseFilterTranslator.ErrorMessages.NOT_CANNOT_BE_EMPTY);
305
+ continue;
306
+ }
307
+ continue;
308
+ }
309
+ if (path && !this.isLogicalOperator(path.split(".").pop())) {
310
+ isSupported = false;
311
+ messages.push(_BaseFilterTranslator.ErrorMessages.INVALID_LOGICAL_OPERATOR_LOCATION(key, newPath));
312
+ continue;
313
+ }
314
+ if (Array.isArray(value)) {
315
+ const hasDirectOperators = value.some(
316
+ (item) => typeof item === "object" && Object.keys(item).length === 1 && this.isFieldOperator(Object.keys(item)[0])
317
+ );
318
+ if (hasDirectOperators) {
319
+ isSupported = false;
320
+ messages.push(_BaseFilterTranslator.ErrorMessages.INVALID_LOGICAL_OPERATOR_CONTENT(newPath));
321
+ continue;
322
+ }
323
+ }
324
+ }
325
+ }
326
+ const nestedValidation = this.validateFilterSupport(value, newPath);
327
+ if (!nestedValidation.supported) {
328
+ isSupported = false;
329
+ messages.push(...nestedValidation.messages);
330
+ }
331
+ }
332
+ return { supported: isSupported, messages };
333
+ }
334
+ };
335
+
336
+ // src/vector/libsql/filter.ts
337
+ var LibSQLFilterTranslator = class extends BaseFilterTranslator {
338
+ getSupportedOperators() {
339
+ return {
340
+ ...BaseFilterTranslator.DEFAULT_OPERATORS,
341
+ regex: [],
342
+ custom: ["$contains", "$size"]
343
+ };
344
+ }
345
+ translate(filter) {
346
+ if (this.isEmpty(filter)) {
347
+ return filter;
348
+ }
349
+ this.validateFilter(filter);
350
+ return this.translateNode(filter);
351
+ }
352
+ translateNode(node, currentPath = "") {
353
+ if (this.isRegex(node)) {
354
+ throw new Error("Direct regex pattern format is not supported in LibSQL");
355
+ }
356
+ const withPath = (result2) => currentPath ? { [currentPath]: result2 } : result2;
357
+ if (this.isPrimitive(node)) {
358
+ return withPath({ $eq: this.normalizeComparisonValue(node) });
359
+ }
360
+ if (Array.isArray(node)) {
361
+ return withPath({ $in: this.normalizeArrayValues(node) });
362
+ }
363
+ const entries = Object.entries(node);
364
+ const result = {};
365
+ for (const [key, value] of entries) {
366
+ const newPath = currentPath ? `${currentPath}.${key}` : key;
367
+ if (this.isLogicalOperator(key)) {
368
+ result[key] = Array.isArray(value) ? value.map((filter) => this.translateNode(filter)) : this.translateNode(value);
369
+ } else if (this.isOperator(key)) {
370
+ if (this.isArrayOperator(key) && !Array.isArray(value) && key !== "$elemMatch") {
371
+ result[key] = [value];
372
+ } else if (this.isBasicOperator(key) && Array.isArray(value)) {
373
+ result[key] = JSON.stringify(value);
374
+ } else {
375
+ result[key] = value;
376
+ }
377
+ } else if (typeof value === "object" && value !== null) {
378
+ const hasOperators = Object.keys(value).some((k) => this.isOperator(k));
379
+ if (hasOperators) {
380
+ result[newPath] = this.translateNode(value);
381
+ } else {
382
+ Object.assign(result, this.translateNode(value, newPath));
383
+ }
384
+ } else {
385
+ result[newPath] = this.translateNode(value);
386
+ }
387
+ }
388
+ return result;
389
+ }
390
+ // TODO: Look more into regex support for LibSQL
391
+ // private translateRegexPattern(pattern: string, options: string = ''): any {
392
+ // if (!options) return { $regex: pattern };
393
+ // const flags = options
394
+ // .split('')
395
+ // .filter(f => 'imsux'.includes(f))
396
+ // .join('');
397
+ // return {
398
+ // $regex: pattern,
399
+ // $options: flags,
400
+ // };
401
+ // }
402
+ };
403
+
404
+ // src/vector/libsql/sql-builder.ts
405
+ var createBasicOperator = (symbol) => {
406
+ return (key) => ({
407
+ sql: `CASE
408
+ WHEN ? IS NULL THEN json_extract(metadata, '$."${handleKey(key)}"') IS ${symbol === "=" ? "" : "NOT"} NULL
409
+ ELSE json_extract(metadata, '$."${handleKey(key)}"') ${symbol} ?
410
+ END`,
411
+ needsValue: true,
412
+ transformValue: (value) => {
413
+ return [value, value];
414
+ }
415
+ });
416
+ };
417
+ var createNumericOperator = (symbol) => {
418
+ return (key) => ({
419
+ sql: `CAST(json_extract(metadata, '$."${handleKey(key)}"') AS NUMERIC) ${symbol} ?`,
420
+ needsValue: true
421
+ });
422
+ };
423
+ var validateJsonArray = (key) => `json_valid(json_extract(metadata, '$."${handleKey(key)}"'))
424
+ AND json_type(json_extract(metadata, '$."${handleKey(key)}"')) = 'array'`;
425
+ var FILTER_OPERATORS = {
426
+ $eq: createBasicOperator("="),
427
+ $ne: createBasicOperator("!="),
428
+ $gt: createNumericOperator(">"),
429
+ $gte: createNumericOperator(">="),
430
+ $lt: createNumericOperator("<"),
431
+ $lte: createNumericOperator("<="),
432
+ // Array Operators
433
+ $in: (key, value) => ({
434
+ sql: `json_extract(metadata, '$."${handleKey(key)}"') IN (${value.map(() => "?").join(",")})`,
435
+ needsValue: true
436
+ }),
437
+ $nin: (key, value) => ({
438
+ sql: `json_extract(metadata, '$."${handleKey(key)}"') NOT IN (${value.map(() => "?").join(",")})`,
439
+ needsValue: true
440
+ }),
441
+ $all: (key) => ({
442
+ sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
443
+ needsValue: true,
444
+ transformValue: (value) => {
445
+ const arrayValue = Array.isArray(value) ? value : [value];
446
+ if (arrayValue.length === 0) {
447
+ return {
448
+ sql: "1 = 0",
449
+ values: []
450
+ };
451
+ }
452
+ return {
453
+ sql: `(
454
+ CASE
455
+ WHEN ${validateJsonArray(key)} THEN
456
+ NOT EXISTS (
457
+ SELECT value
458
+ FROM json_each(?)
459
+ WHERE value NOT IN (
460
+ SELECT value
461
+ FROM json_each(json_extract(metadata, '$."${handleKey(key)}"'))
462
+ )
463
+ )
464
+ ELSE FALSE
465
+ END
466
+ )`,
467
+ values: [JSON.stringify(arrayValue)]
468
+ };
469
+ }
470
+ }),
471
+ $elemMatch: (key) => ({
472
+ sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
473
+ needsValue: true,
474
+ transformValue: (value) => {
475
+ if (typeof value !== "object" || Array.isArray(value)) {
476
+ throw new Error("$elemMatch requires an object with conditions");
477
+ }
478
+ const conditions = Object.entries(value).map(([field, fieldValue]) => {
479
+ if (field.startsWith("$")) {
480
+ const { sql, values } = buildCondition("elem.value", { [field]: fieldValue });
481
+ const pattern = /json_extract\(metadata, '\$\."[^"]*"(\."[^"]*")*'\)/g;
482
+ const elemSql = sql.replace(pattern, "elem.value");
483
+ return { sql: elemSql, values };
484
+ } else if (typeof fieldValue === "object" && !Array.isArray(fieldValue)) {
485
+ const { sql, values } = buildCondition(field, fieldValue);
486
+ const pattern = /json_extract\(metadata, '\$\."[^"]*"(\."[^"]*")*'\)/g;
487
+ const elemSql = sql.replace(pattern, `json_extract(elem.value, '$."${field}"')`);
488
+ return { sql: elemSql, values };
489
+ } else {
490
+ return {
491
+ sql: `json_extract(elem.value, '$."${field}"') = ?`,
492
+ values: [fieldValue]
493
+ };
494
+ }
495
+ });
496
+ return {
497
+ sql: `(
498
+ CASE
499
+ WHEN ${validateJsonArray(key)} THEN
500
+ EXISTS (
501
+ SELECT 1
502
+ FROM json_each(json_extract(metadata, '$."${handleKey(key)}"')) as elem
503
+ WHERE ${conditions.map((c) => c.sql).join(" AND ")}
504
+ )
505
+ ELSE FALSE
506
+ END
507
+ )`,
508
+ values: conditions.flatMap((c) => c.values)
509
+ };
510
+ }
511
+ }),
512
+ // Element Operators
513
+ $exists: (key) => ({
514
+ sql: `json_extract(metadata, '$."${handleKey(key)}"') IS NOT NULL`,
515
+ needsValue: false
516
+ }),
517
+ // Logical Operators
518
+ $and: (key) => ({
519
+ sql: `(${key})`,
520
+ needsValue: false
521
+ }),
522
+ $or: (key) => ({
523
+ sql: `(${key})`,
524
+ needsValue: false
525
+ }),
526
+ $not: (key) => ({ sql: `NOT (${key})`, needsValue: false }),
527
+ $nor: (key) => ({
528
+ sql: `NOT (${key})`,
529
+ needsValue: false
530
+ }),
531
+ $size: (key, paramIndex) => ({
532
+ sql: `(
533
+ CASE
534
+ WHEN json_type(json_extract(metadata, '$."${handleKey(key)}"')) = 'array' THEN
535
+ json_array_length(json_extract(metadata, '$."${handleKey(key)}"')) = $${paramIndex}
536
+ ELSE FALSE
537
+ END
538
+ )`,
539
+ needsValue: true
540
+ }),
541
+ // /**
542
+ // * Regex Operators
543
+ // * Supports case insensitive and multiline
544
+ // */
545
+ // $regex: (key: string): FilterOperator => ({
546
+ // sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
547
+ // needsValue: true,
548
+ // transformValue: (value: any) => {
549
+ // const pattern = typeof value === 'object' ? value.$regex : value;
550
+ // const options = typeof value === 'object' ? value.$options || '' : '';
551
+ // let sql = `json_extract(metadata, '$."${handleKey(key)}"')`;
552
+ // // Handle multiline
553
+ // // if (options.includes('m')) {
554
+ // // sql = `REPLACE(${sql}, CHAR(10), '\n')`;
555
+ // // }
556
+ // // let finalPattern = pattern;
557
+ // // if (options) {
558
+ // // finalPattern = `(\\?${options})${pattern}`;
559
+ // // }
560
+ // // // Handle case insensitivity
561
+ // // if (options.includes('i')) {
562
+ // // sql = `LOWER(${sql}) REGEXP LOWER(?)`;
563
+ // // } else {
564
+ // // sql = `${sql} REGEXP ?`;
565
+ // // }
566
+ // if (options.includes('m')) {
567
+ // sql = `EXISTS (
568
+ // SELECT 1
569
+ // FROM json_each(
570
+ // json_array(
571
+ // ${sql},
572
+ // REPLACE(${sql}, CHAR(10), CHAR(13))
573
+ // )
574
+ // ) as lines
575
+ // WHERE lines.value REGEXP ?
576
+ // )`;
577
+ // } else {
578
+ // sql = `${sql} REGEXP ?`;
579
+ // }
580
+ // // Handle case insensitivity
581
+ // if (options.includes('i')) {
582
+ // sql = sql.replace('REGEXP ?', 'REGEXP LOWER(?)');
583
+ // sql = sql.replace('value REGEXP', 'LOWER(value) REGEXP');
584
+ // }
585
+ // // Handle extended - allows whitespace and comments in pattern
586
+ // if (options.includes('x')) {
587
+ // // Remove whitespace and comments from pattern
588
+ // const cleanPattern = pattern.replace(/\s+|#.*$/gm, '');
589
+ // return {
590
+ // sql,
591
+ // values: [cleanPattern],
592
+ // };
593
+ // }
594
+ // return {
595
+ // sql,
596
+ // values: [pattern],
597
+ // };
598
+ // },
599
+ // }),
600
+ $contains: (key) => ({
601
+ sql: `json_extract(metadata, '$."${handleKey(key)}"') = ?`,
602
+ needsValue: true,
603
+ transformValue: (value) => {
604
+ if (Array.isArray(value)) {
605
+ return {
606
+ sql: `(
607
+ SELECT ${validateJsonArray(key)}
608
+ AND EXISTS (
609
+ SELECT 1
610
+ FROM json_each(json_extract(metadata, '$."${handleKey(key)}"')) as m
611
+ WHERE m.value IN (SELECT value FROM json_each(?))
612
+ )
613
+ )`,
614
+ values: [JSON.stringify(value)]
615
+ };
616
+ }
617
+ if (value && typeof value === "object") {
618
+ let traverse2 = function(obj, path = []) {
619
+ for (const [k, v] of Object.entries(obj)) {
620
+ const currentPath = [...path, k];
621
+ if (v && typeof v === "object" && !Array.isArray(v)) {
622
+ traverse2(v, currentPath);
623
+ } else {
624
+ paths.push(currentPath.join("."));
625
+ values.push(v);
626
+ }
627
+ }
628
+ };
629
+ const paths = [];
630
+ const values = [];
631
+ traverse2(value);
632
+ return {
633
+ sql: `(${paths.map((path) => `json_extract(metadata, '$."${handleKey(key)}"."${path}"') = ?`).join(" AND ")})`,
634
+ values
635
+ };
636
+ }
637
+ return value;
638
+ }
639
+ })
640
+ };
641
+ var handleKey = (key) => {
642
+ return key.replace(/\./g, '"."');
643
+ };
644
+ function buildFilterQuery(filter) {
645
+ if (!filter) {
646
+ return { sql: "", values: [] };
647
+ }
648
+ const values = [];
649
+ const conditions = Object.entries(filter).map(([key, value]) => {
650
+ const condition = buildCondition(key, value);
651
+ values.push(...condition.values);
652
+ return condition.sql;
653
+ }).join(" AND ");
654
+ return {
655
+ sql: conditions ? `WHERE ${conditions}` : "",
656
+ values
657
+ };
658
+ }
659
+ function buildCondition(key, value, parentPath) {
660
+ if (["$and", "$or", "$not", "$nor"].includes(key)) {
661
+ return handleLogicalOperator(key, value);
662
+ }
663
+ if (!value || typeof value !== "object") {
664
+ return {
665
+ sql: `json_extract(metadata, '$."${key.replace(/\./g, '"."')}"') = ?`,
666
+ values: [value]
667
+ };
668
+ }
669
+ return handleOperator(key, value);
670
+ }
671
+ function handleLogicalOperator(key, value, parentPath) {
672
+ if (!value || value.length === 0) {
673
+ switch (key) {
674
+ case "$and":
675
+ case "$nor":
676
+ return { sql: "true", values: [] };
677
+ case "$or":
678
+ return { sql: "false", values: [] };
679
+ case "$not":
680
+ throw new Error("$not operator cannot be empty");
681
+ default:
682
+ return { sql: "true", values: [] };
683
+ }
684
+ }
685
+ if (key === "$not") {
686
+ const entries = Object.entries(value);
687
+ const conditions2 = entries.map(([fieldKey, fieldValue]) => buildCondition(fieldKey, fieldValue));
688
+ return {
689
+ sql: `NOT (${conditions2.map((c) => c.sql).join(" AND ")})`,
690
+ values: conditions2.flatMap((c) => c.values)
691
+ };
692
+ }
693
+ const values = [];
694
+ const joinOperator = key === "$or" || key === "$nor" ? "OR" : "AND";
695
+ const conditions = Array.isArray(value) ? value.map((f) => {
696
+ const entries = Object.entries(f);
697
+ return entries.map(([k, v]) => buildCondition(k, v));
698
+ }) : [buildCondition(key, value)];
699
+ const joined = conditions.flat().map((c) => {
700
+ values.push(...c.values);
701
+ return c.sql;
702
+ }).join(` ${joinOperator} `);
703
+ return {
704
+ sql: key === "$nor" ? `NOT (${joined})` : `(${joined})`,
705
+ values
706
+ };
707
+ }
708
+ function handleOperator(key, value) {
709
+ if (typeof value === "object" && !Array.isArray(value)) {
710
+ const entries = Object.entries(value);
711
+ const results = entries.map(
712
+ ([operator2, operatorValue2]) => operator2 === "$not" ? {
713
+ sql: `NOT (${Object.entries(operatorValue2).map(([op, val]) => processOperator(key, op, val).sql).join(" AND ")})`,
714
+ values: Object.entries(operatorValue2).flatMap(
715
+ ([op, val]) => processOperator(key, op, val).values
716
+ )
717
+ } : processOperator(key, operator2, operatorValue2)
718
+ );
719
+ return {
720
+ sql: `(${results.map((r) => r.sql).join(" AND ")})`,
721
+ values: results.flatMap((r) => r.values)
722
+ };
723
+ }
724
+ const [[operator, operatorValue] = []] = Object.entries(value);
725
+ return processOperator(key, operator, operatorValue);
726
+ }
727
+ var processOperator = (key, operator, operatorValue) => {
728
+ if (!operator.startsWith("$") || !FILTER_OPERATORS[operator]) {
729
+ throw new Error(`Invalid operator: ${operator}`);
730
+ }
731
+ const operatorFn = FILTER_OPERATORS[operator];
732
+ const operatorResult = operatorFn(key, operatorValue);
733
+ if (!operatorResult.needsValue) {
734
+ return { sql: operatorResult.sql, values: [] };
735
+ }
736
+ const transformed = operatorResult.transformValue ? operatorResult.transformValue(operatorValue) : operatorValue;
737
+ if (transformed && typeof transformed === "object" && "sql" in transformed) {
738
+ return transformed;
739
+ }
740
+ return {
741
+ sql: operatorResult.sql,
742
+ values: Array.isArray(transformed) ? transformed : [transformed]
743
+ };
744
+ };
745
+
746
+ // src/vector/libsql/index.ts
747
+ var LibSQLVector = class extends MastraVector {
748
+ turso;
749
+ constructor({
750
+ connectionUrl,
751
+ authToken,
752
+ syncUrl,
753
+ syncInterval
754
+ }) {
755
+ super();
756
+ this.turso = client.createClient({
757
+ url: this.rewriteDbUrl(connectionUrl),
758
+ syncUrl,
759
+ authToken,
760
+ syncInterval
761
+ });
762
+ }
763
+ rewriteDbUrl(url) {
764
+ if (url.startsWith("file:") && !url.startsWith("file:/")) {
765
+ const cwd = process.cwd();
766
+ const relativePath = url.slice("file:".length);
767
+ if (cwd.endsWith(".mastra") || cwd.endsWith(".mastra/")) {
768
+ const baseDir = path.join(cwd, `..`);
769
+ const fullPath = path.join(baseDir, relativePath);
770
+ this.logger.debug(
771
+ `Initializing LibSQL db with url ${url} with relative file path from inside .mastra directory. Rewriting relative file url to "file:${fullPath}". This ensures it's outside the .mastra directory. If the db is stored inside .mastra it will be deleted when Mastra re-bundles code.`
772
+ );
773
+ return `file:${fullPath}`;
774
+ }
775
+ }
776
+ return url;
777
+ }
778
+ transformFilter(filter) {
779
+ const libsqlFilter = new LibSQLFilterTranslator();
780
+ const translatedFilter = libsqlFilter.translate(filter ?? {});
781
+ return translatedFilter;
782
+ }
783
+ async query(indexName, queryVector, topK = 10, filter, includeVector = false, minScore = 0) {
784
+ try {
785
+ const vectorStr = `[${queryVector.join(",")}]`;
786
+ const translatedFilter = this.transformFilter(filter);
787
+ const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter);
788
+ filterValues.push(minScore);
789
+ const query = `
790
+ WITH vector_scores AS (
791
+ SELECT
792
+ vector_id as id,
793
+ (1-vector_distance_cos(embedding, '${vectorStr}')) as score,
794
+ metadata
795
+ ${includeVector ? ", vector_extract(embedding) as embedding" : ""}
796
+ FROM ${indexName}
797
+ ${filterQuery}
798
+ )
799
+ SELECT *
800
+ FROM vector_scores
801
+ WHERE score > ?
802
+ ORDER BY score DESC
803
+ LIMIT ${topK}`;
804
+ const result = await this.turso.execute({
805
+ sql: query,
806
+ args: filterValues
807
+ });
808
+ return result.rows.map(({ id, score, metadata, embedding }) => ({
809
+ id,
810
+ score,
811
+ metadata: JSON.parse(metadata ?? "{}"),
812
+ ...includeVector && embedding && { vector: JSON.parse(embedding) }
813
+ }));
814
+ } finally {
815
+ }
816
+ }
817
+ async upsert(indexName, vectors, metadata, ids) {
818
+ const tx = await this.turso.transaction("write");
819
+ try {
820
+ const vectorIds = ids || vectors.map(() => crypto.randomUUID());
821
+ for (let i = 0; i < vectors.length; i++) {
822
+ const query = `
823
+ INSERT INTO ${indexName} (vector_id, embedding, metadata)
824
+ VALUES (?, vector32(?), ?)
825
+ ON CONFLICT(vector_id) DO UPDATE SET
826
+ embedding = vector32(?),
827
+ metadata = ?
828
+ `;
829
+ await tx.execute({
830
+ sql: query,
831
+ // @ts-ignore
832
+ args: [
833
+ vectorIds[i],
834
+ JSON.stringify(vectors[i]),
835
+ JSON.stringify(metadata?.[i] || {}),
836
+ JSON.stringify(vectors[i]),
837
+ JSON.stringify(metadata?.[i] || {})
838
+ ]
839
+ });
840
+ }
841
+ await tx.commit();
842
+ return vectorIds;
843
+ } catch (error) {
844
+ await tx.rollback();
845
+ throw error;
846
+ }
847
+ }
848
+ async createIndex(indexName, dimension, _metric = "cosine") {
849
+ try {
850
+ if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
851
+ throw new Error("Invalid index name format");
852
+ }
853
+ if (!Number.isInteger(dimension) || dimension <= 0) {
854
+ throw new Error("Dimension must be a positive integer");
855
+ }
856
+ await this.turso.execute({
857
+ sql: `
858
+ CREATE TABLE IF NOT EXISTS ${indexName} (
859
+ id SERIAL PRIMARY KEY,
860
+ vector_id TEXT UNIQUE NOT NULL,
861
+ embedding F32_BLOB(${dimension}),
862
+ metadata TEXT DEFAULT '{}'
863
+ );
864
+ `,
865
+ args: []
866
+ });
867
+ await this.turso.execute({
868
+ sql: `
869
+ CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
870
+ ON ${indexName} (libsql_vector_idx(embedding))
871
+ `,
872
+ args: []
873
+ });
874
+ } catch (error) {
875
+ console.error("Failed to create vector table:", error);
876
+ throw error;
877
+ } finally {
878
+ }
879
+ }
880
+ async deleteIndex(indexName) {
881
+ try {
882
+ await this.turso.execute({
883
+ sql: `DROP TABLE IF EXISTS ${indexName}`,
884
+ args: []
885
+ });
886
+ } catch (error) {
887
+ console.error("Failed to delete vector table:", error);
888
+ throw new Error(`Failed to delete vector table: ${error.message}`);
889
+ } finally {
890
+ }
891
+ }
892
+ async listIndexes() {
893
+ try {
894
+ const vectorTablesQuery = `
895
+ SELECT name FROM sqlite_master
896
+ WHERE type='table'
897
+ AND sql LIKE '%F32_BLOB%';
898
+ `;
899
+ const result = await this.turso.execute({
900
+ sql: vectorTablesQuery,
901
+ args: []
902
+ });
903
+ return result.rows.map((row) => row.name);
904
+ } catch (error) {
905
+ throw new Error(`Failed to list vector tables: ${error.message}`);
906
+ }
907
+ }
908
+ async describeIndex(indexName) {
909
+ try {
910
+ const tableInfoQuery = `
911
+ SELECT sql
912
+ FROM sqlite_master
913
+ WHERE type='table'
914
+ AND name = ?;
915
+ `;
916
+ const tableInfo = await this.turso.execute({
917
+ sql: tableInfoQuery,
918
+ args: [indexName]
919
+ });
920
+ if (!tableInfo.rows[0]?.sql) {
921
+ throw new Error(`Table ${indexName} not found`);
922
+ }
923
+ const dimension = parseInt(tableInfo.rows[0].sql.match(/F32_BLOB\((\d+)\)/)?.[1] || "0");
924
+ const countQuery = `
925
+ SELECT COUNT(*) as count
926
+ FROM ${indexName};
927
+ `;
928
+ const countResult = await this.turso.execute({
929
+ sql: countQuery,
930
+ args: []
931
+ });
932
+ const metric = "cosine";
933
+ return {
934
+ dimension,
935
+ count: countResult?.rows?.[0]?.count ?? 0,
936
+ metric
937
+ };
938
+ } catch (e) {
939
+ throw new Error(`Failed to describe vector table: ${e.message}`);
940
+ }
941
+ }
942
+ async truncateIndex(indexName) {
943
+ await this.turso.execute({
944
+ sql: `DELETE FROM ${indexName}`,
945
+ args: []
946
+ });
947
+ }
948
+ };
949
+
950
+ exports.DefaultVectorDB = LibSQLVector;
951
+ exports.LibSQLVector = LibSQLVector;