@mastra/turbopuffer 0.10.3 → 0.11.0-alpha.1
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/_tsup-dts-rollup.d.cts +17 -4
- package/dist/_tsup-dts-rollup.d.ts +17 -4
- package/dist/index.cjs +169 -52
- package/dist/index.js +162 -45
- package/package.json +4 -4
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
2
|
+
import type { BlacklistedRootOperators } from '@mastra/core/vector/filter';
|
|
2
3
|
import type { CreateIndexParams } from '@mastra/core/vector';
|
|
3
4
|
import type { DeleteIndexParams } from '@mastra/core/vector';
|
|
4
5
|
import type { DeleteVectorParams } from '@mastra/core/vector';
|
|
5
6
|
import type { DescribeIndexParams } from '@mastra/core/vector';
|
|
6
7
|
import type { Filters } from '@turbopuffer/turbopuffer';
|
|
7
8
|
import type { IndexStats } from '@mastra/core/vector';
|
|
9
|
+
import type { LogicalOperatorValueMap } from '@mastra/core/vector/filter';
|
|
8
10
|
import { MastraVector } from '@mastra/core/vector';
|
|
9
11
|
import type { OperatorSupport } from '@mastra/core/vector/filter';
|
|
12
|
+
import type { OperatorValueMap } from '@mastra/core/vector/filter';
|
|
10
13
|
import type { QueryResult } from '@mastra/core/vector';
|
|
11
14
|
import type { QueryVectorParams } from '@mastra/core/vector';
|
|
12
15
|
import type { Schema } from '@turbopuffer/turbopuffer';
|
|
@@ -14,13 +17,15 @@ import type { UpdateVectorParams } from '@mastra/core/vector';
|
|
|
14
17
|
import type { UpsertVectorParams } from '@mastra/core/vector';
|
|
15
18
|
import type { VectorFilter } from '@mastra/core/vector/filter';
|
|
16
19
|
|
|
20
|
+
declare type TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* Translator for converting Mastra filters to Turbopuffer format
|
|
19
24
|
*
|
|
20
25
|
* Mastra filters: { field: { $gt: 10 } }
|
|
21
26
|
* Turbopuffer filters: ["And", [["field", "Gt", 10]]]
|
|
22
27
|
*/
|
|
23
|
-
export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
|
|
28
|
+
export declare class TurbopufferFilterTranslator extends BaseFilterTranslator<TurbopufferVectorFilter, Filters | undefined> {
|
|
24
29
|
protected getSupportedOperators(): OperatorSupport;
|
|
25
30
|
/**
|
|
26
31
|
* Map Mastra operators to Turbopuffer operators
|
|
@@ -29,7 +34,7 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
|
|
|
29
34
|
/**
|
|
30
35
|
* Convert the Mastra filter to Turbopuffer format
|
|
31
36
|
*/
|
|
32
|
-
translate(filter?:
|
|
37
|
+
translate(filter?: TurbopufferVectorFilter): Filters | undefined;
|
|
33
38
|
/**
|
|
34
39
|
* Recursively translate a filter node
|
|
35
40
|
*/
|
|
@@ -56,7 +61,13 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
|
|
|
56
61
|
protected normalizeArrayValues(values: any[]): any[];
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
declare
|
|
64
|
+
declare type TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;
|
|
65
|
+
|
|
66
|
+
declare type TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;
|
|
67
|
+
|
|
68
|
+
declare type TurbopufferQueryVectorParams = QueryVectorParams<TurbopufferVectorFilter>;
|
|
69
|
+
|
|
70
|
+
declare class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {
|
|
60
71
|
private client;
|
|
61
72
|
private filterTranslator;
|
|
62
73
|
private createIndexCache;
|
|
@@ -64,7 +75,7 @@ declare class TurbopufferVector extends MastraVector {
|
|
|
64
75
|
constructor(opts: TurbopufferVectorOptions);
|
|
65
76
|
createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void>;
|
|
66
77
|
upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]>;
|
|
67
|
-
query({ indexName, queryVector, topK, filter, includeVector }:
|
|
78
|
+
query({ indexName, queryVector, topK, filter, includeVector, }: TurbopufferQueryVectorParams): Promise<QueryResult[]>;
|
|
68
79
|
listIndexes(): Promise<string[]>;
|
|
69
80
|
/**
|
|
70
81
|
* Retrieves statistics about a vector index.
|
|
@@ -97,6 +108,8 @@ declare class TurbopufferVector extends MastraVector {
|
|
|
97
108
|
export { TurbopufferVector }
|
|
98
109
|
export { TurbopufferVector as TurbopufferVector_alias_1 }
|
|
99
110
|
|
|
111
|
+
export declare type TurbopufferVectorFilter = VectorFilter<keyof TurbopufferOperatorValueMap, TurbopufferOperatorValueMap, TurbopufferLogicalOperatorValueMap, TurbopufferBlacklistedRootOperators>;
|
|
112
|
+
|
|
100
113
|
declare interface TurbopufferVectorOptions {
|
|
101
114
|
/** The API key to authenticate with. */
|
|
102
115
|
apiKey: string;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
2
|
+
import type { BlacklistedRootOperators } from '@mastra/core/vector/filter';
|
|
2
3
|
import type { CreateIndexParams } from '@mastra/core/vector';
|
|
3
4
|
import type { DeleteIndexParams } from '@mastra/core/vector';
|
|
4
5
|
import type { DeleteVectorParams } from '@mastra/core/vector';
|
|
5
6
|
import type { DescribeIndexParams } from '@mastra/core/vector';
|
|
6
7
|
import type { Filters } from '@turbopuffer/turbopuffer';
|
|
7
8
|
import type { IndexStats } from '@mastra/core/vector';
|
|
9
|
+
import type { LogicalOperatorValueMap } from '@mastra/core/vector/filter';
|
|
8
10
|
import { MastraVector } from '@mastra/core/vector';
|
|
9
11
|
import type { OperatorSupport } from '@mastra/core/vector/filter';
|
|
12
|
+
import type { OperatorValueMap } from '@mastra/core/vector/filter';
|
|
10
13
|
import type { QueryResult } from '@mastra/core/vector';
|
|
11
14
|
import type { QueryVectorParams } from '@mastra/core/vector';
|
|
12
15
|
import type { Schema } from '@turbopuffer/turbopuffer';
|
|
@@ -14,13 +17,15 @@ import type { UpdateVectorParams } from '@mastra/core/vector';
|
|
|
14
17
|
import type { UpsertVectorParams } from '@mastra/core/vector';
|
|
15
18
|
import type { VectorFilter } from '@mastra/core/vector/filter';
|
|
16
19
|
|
|
20
|
+
declare type TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* Translator for converting Mastra filters to Turbopuffer format
|
|
19
24
|
*
|
|
20
25
|
* Mastra filters: { field: { $gt: 10 } }
|
|
21
26
|
* Turbopuffer filters: ["And", [["field", "Gt", 10]]]
|
|
22
27
|
*/
|
|
23
|
-
export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
|
|
28
|
+
export declare class TurbopufferFilterTranslator extends BaseFilterTranslator<TurbopufferVectorFilter, Filters | undefined> {
|
|
24
29
|
protected getSupportedOperators(): OperatorSupport;
|
|
25
30
|
/**
|
|
26
31
|
* Map Mastra operators to Turbopuffer operators
|
|
@@ -29,7 +34,7 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
|
|
|
29
34
|
/**
|
|
30
35
|
* Convert the Mastra filter to Turbopuffer format
|
|
31
36
|
*/
|
|
32
|
-
translate(filter?:
|
|
37
|
+
translate(filter?: TurbopufferVectorFilter): Filters | undefined;
|
|
33
38
|
/**
|
|
34
39
|
* Recursively translate a filter node
|
|
35
40
|
*/
|
|
@@ -56,7 +61,13 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
|
|
|
56
61
|
protected normalizeArrayValues(values: any[]): any[];
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
declare
|
|
64
|
+
declare type TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;
|
|
65
|
+
|
|
66
|
+
declare type TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;
|
|
67
|
+
|
|
68
|
+
declare type TurbopufferQueryVectorParams = QueryVectorParams<TurbopufferVectorFilter>;
|
|
69
|
+
|
|
70
|
+
declare class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {
|
|
60
71
|
private client;
|
|
61
72
|
private filterTranslator;
|
|
62
73
|
private createIndexCache;
|
|
@@ -64,7 +75,7 @@ declare class TurbopufferVector extends MastraVector {
|
|
|
64
75
|
constructor(opts: TurbopufferVectorOptions);
|
|
65
76
|
createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void>;
|
|
66
77
|
upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]>;
|
|
67
|
-
query({ indexName, queryVector, topK, filter, includeVector }:
|
|
78
|
+
query({ indexName, queryVector, topK, filter, includeVector, }: TurbopufferQueryVectorParams): Promise<QueryResult[]>;
|
|
68
79
|
listIndexes(): Promise<string[]>;
|
|
69
80
|
/**
|
|
70
81
|
* Retrieves statistics about a vector index.
|
|
@@ -97,6 +108,8 @@ declare class TurbopufferVector extends MastraVector {
|
|
|
97
108
|
export { TurbopufferVector }
|
|
98
109
|
export { TurbopufferVector as TurbopufferVector_alias_1 }
|
|
99
110
|
|
|
111
|
+
export declare type TurbopufferVectorFilter = VectorFilter<keyof TurbopufferOperatorValueMap, TurbopufferOperatorValueMap, TurbopufferLogicalOperatorValueMap, TurbopufferBlacklistedRootOperators>;
|
|
112
|
+
|
|
100
113
|
declare interface TurbopufferVectorOptions {
|
|
101
114
|
/** The API key to authenticate with. */
|
|
102
115
|
apiKey: string;
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var error = require('@mastra/core/error');
|
|
3
4
|
var vector = require('@mastra/core/vector');
|
|
4
5
|
var turbopuffer = require('@turbopuffer/turbopuffer');
|
|
5
6
|
var filter = require('@mastra/core/vector/filter');
|
|
@@ -188,28 +189,40 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
188
189
|
}
|
|
189
190
|
async createIndex({ indexName, dimension, metric }) {
|
|
190
191
|
metric = metric ?? "cosine";
|
|
191
|
-
if (this.createIndexCache.has(indexName)) {
|
|
192
|
-
const expected = this.createIndexCache.get(indexName);
|
|
193
|
-
if (dimension !== expected.dimension || metric !== expected.metric) {
|
|
194
|
-
throw new Error(
|
|
195
|
-
`createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
if (dimension <= 0) {
|
|
201
|
-
throw new Error("Dimension must be a positive integer");
|
|
202
|
-
}
|
|
203
192
|
let distanceMetric = "cosine_distance";
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
193
|
+
try {
|
|
194
|
+
if (this.createIndexCache.has(indexName)) {
|
|
195
|
+
const expected = this.createIndexCache.get(indexName);
|
|
196
|
+
if (dimension !== expected.dimension || metric !== expected.metric) {
|
|
197
|
+
throw new Error(
|
|
198
|
+
`createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (dimension <= 0) {
|
|
204
|
+
throw new Error("Dimension must be a positive integer");
|
|
205
|
+
}
|
|
206
|
+
switch (metric) {
|
|
207
|
+
case "cosine":
|
|
208
|
+
distanceMetric = "cosine_distance";
|
|
209
|
+
break;
|
|
210
|
+
case "euclidean":
|
|
211
|
+
distanceMetric = "euclidean_squared";
|
|
212
|
+
break;
|
|
213
|
+
case "dotproduct":
|
|
214
|
+
throw new Error("dotproduct is not supported in Turbopuffer");
|
|
215
|
+
}
|
|
216
|
+
} catch (error$1) {
|
|
217
|
+
throw new error.MastraError(
|
|
218
|
+
{
|
|
219
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_CREATE_INDEX_INVALID_ARGS",
|
|
220
|
+
domain: error.ErrorDomain.STORAGE,
|
|
221
|
+
category: error.ErrorCategory.USER,
|
|
222
|
+
details: { indexName, dimension, metric }
|
|
223
|
+
},
|
|
224
|
+
error$1
|
|
225
|
+
);
|
|
213
226
|
}
|
|
214
227
|
this.createIndexCache.set(indexName, {
|
|
215
228
|
indexName,
|
|
@@ -219,15 +232,29 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
219
232
|
});
|
|
220
233
|
}
|
|
221
234
|
async upsert({ indexName, vectors, metadata, ids }) {
|
|
235
|
+
let index;
|
|
236
|
+
let createIndex;
|
|
222
237
|
try {
|
|
223
238
|
if (vectors.length === 0) {
|
|
224
239
|
throw new Error("upsert() called with empty vectors");
|
|
225
240
|
}
|
|
226
|
-
|
|
227
|
-
|
|
241
|
+
index = this.client.namespace(indexName);
|
|
242
|
+
createIndex = this.createIndexCache.get(indexName);
|
|
228
243
|
if (!createIndex) {
|
|
229
244
|
throw new Error(`createIndex() not called for this index`);
|
|
230
245
|
}
|
|
246
|
+
} catch (error$1) {
|
|
247
|
+
throw new error.MastraError(
|
|
248
|
+
{
|
|
249
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_INVALID_ARGS",
|
|
250
|
+
domain: error.ErrorDomain.STORAGE,
|
|
251
|
+
category: error.ErrorCategory.USER,
|
|
252
|
+
details: { indexName }
|
|
253
|
+
},
|
|
254
|
+
error$1
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
231
258
|
const distanceMetric = createIndex.tpufDistanceMetric;
|
|
232
259
|
const vectorIds = ids || vectors.map(() => crypto.randomUUID());
|
|
233
260
|
const records = vectors.map((vector, i) => ({
|
|
@@ -254,22 +281,49 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
254
281
|
await index.upsert(upsertOptions);
|
|
255
282
|
}
|
|
256
283
|
return vectorIds;
|
|
257
|
-
} catch (error) {
|
|
258
|
-
throw new
|
|
284
|
+
} catch (error$1) {
|
|
285
|
+
throw new error.MastraError(
|
|
286
|
+
{
|
|
287
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_FAILED",
|
|
288
|
+
domain: error.ErrorDomain.STORAGE,
|
|
289
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
290
|
+
details: { indexName }
|
|
291
|
+
},
|
|
292
|
+
error$1
|
|
293
|
+
);
|
|
259
294
|
}
|
|
260
295
|
}
|
|
261
|
-
async query({
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
296
|
+
async query({
|
|
297
|
+
indexName,
|
|
298
|
+
queryVector,
|
|
299
|
+
topK,
|
|
300
|
+
filter,
|
|
301
|
+
includeVector
|
|
302
|
+
}) {
|
|
303
|
+
let createIndex;
|
|
304
|
+
try {
|
|
305
|
+
const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);
|
|
306
|
+
if (schemaConfig) {
|
|
307
|
+
if (queryVector.length !== schemaConfig.dimensions) {
|
|
308
|
+
throw new Error(
|
|
309
|
+
`Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
268
312
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
313
|
+
createIndex = this.createIndexCache.get(indexName);
|
|
314
|
+
if (!createIndex) {
|
|
315
|
+
throw new Error(`createIndex() not called for this index`);
|
|
316
|
+
}
|
|
317
|
+
} catch (error$1) {
|
|
318
|
+
throw new error.MastraError(
|
|
319
|
+
{
|
|
320
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_INVALID_ARGS",
|
|
321
|
+
domain: error.ErrorDomain.STORAGE,
|
|
322
|
+
category: error.ErrorCategory.USER,
|
|
323
|
+
details: { indexName }
|
|
324
|
+
},
|
|
325
|
+
error$1
|
|
326
|
+
);
|
|
273
327
|
}
|
|
274
328
|
const distanceMetric = createIndex.tpufDistanceMetric;
|
|
275
329
|
try {
|
|
@@ -291,16 +345,31 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
291
345
|
metadata: item.attributes || {},
|
|
292
346
|
...includeVector && item.vector ? { vector: item.vector } : {}
|
|
293
347
|
}));
|
|
294
|
-
} catch (error) {
|
|
295
|
-
throw new
|
|
348
|
+
} catch (error$1) {
|
|
349
|
+
throw new error.MastraError(
|
|
350
|
+
{
|
|
351
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_FAILED",
|
|
352
|
+
domain: error.ErrorDomain.STORAGE,
|
|
353
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
354
|
+
details: { indexName }
|
|
355
|
+
},
|
|
356
|
+
error$1
|
|
357
|
+
);
|
|
296
358
|
}
|
|
297
359
|
}
|
|
298
360
|
async listIndexes() {
|
|
299
361
|
try {
|
|
300
362
|
const namespacesResult = await this.client.namespaces({});
|
|
301
363
|
return namespacesResult.namespaces.map((namespace) => namespace.id);
|
|
302
|
-
} catch (error) {
|
|
303
|
-
throw new
|
|
364
|
+
} catch (error$1) {
|
|
365
|
+
throw new error.MastraError(
|
|
366
|
+
{
|
|
367
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_LIST_INDEXES_FAILED",
|
|
368
|
+
domain: error.ErrorDomain.STORAGE,
|
|
369
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
370
|
+
},
|
|
371
|
+
error$1
|
|
372
|
+
);
|
|
304
373
|
}
|
|
305
374
|
}
|
|
306
375
|
/**
|
|
@@ -324,8 +393,16 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
324
393
|
count,
|
|
325
394
|
metric: createIndex.metric
|
|
326
395
|
};
|
|
327
|
-
} catch (error) {
|
|
328
|
-
throw new
|
|
396
|
+
} catch (error$1) {
|
|
397
|
+
throw new error.MastraError(
|
|
398
|
+
{
|
|
399
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_DESCRIBE_INDEX_FAILED",
|
|
400
|
+
domain: error.ErrorDomain.STORAGE,
|
|
401
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
402
|
+
details: { indexName }
|
|
403
|
+
},
|
|
404
|
+
error$1
|
|
405
|
+
);
|
|
329
406
|
}
|
|
330
407
|
}
|
|
331
408
|
async deleteIndex({ indexName }) {
|
|
@@ -333,8 +410,16 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
333
410
|
const namespace = this.client.namespace(indexName);
|
|
334
411
|
await namespace.deleteAll();
|
|
335
412
|
this.createIndexCache.delete(indexName);
|
|
336
|
-
} catch (error) {
|
|
337
|
-
throw new
|
|
413
|
+
} catch (error$1) {
|
|
414
|
+
throw new error.MastraError(
|
|
415
|
+
{
|
|
416
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_INDEX_FAILED",
|
|
417
|
+
domain: error.ErrorDomain.STORAGE,
|
|
418
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
419
|
+
details: { indexName }
|
|
420
|
+
},
|
|
421
|
+
error$1
|
|
422
|
+
);
|
|
338
423
|
}
|
|
339
424
|
}
|
|
340
425
|
/**
|
|
@@ -348,22 +433,46 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
348
433
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
349
434
|
*/
|
|
350
435
|
async updateVector({ indexName, id, update }) {
|
|
436
|
+
let namespace;
|
|
437
|
+
let createIndex;
|
|
438
|
+
let distanceMetric;
|
|
439
|
+
let record;
|
|
351
440
|
try {
|
|
352
|
-
|
|
353
|
-
|
|
441
|
+
namespace = this.client.namespace(indexName);
|
|
442
|
+
createIndex = this.createIndexCache.get(indexName);
|
|
354
443
|
if (!createIndex) {
|
|
355
444
|
throw new Error(`createIndex() not called for this index`);
|
|
356
445
|
}
|
|
357
|
-
|
|
358
|
-
|
|
446
|
+
distanceMetric = createIndex.tpufDistanceMetric;
|
|
447
|
+
record = { id };
|
|
359
448
|
if (update.vector) record.vector = update.vector;
|
|
360
449
|
if (update.metadata) record.attributes = update.metadata;
|
|
450
|
+
} catch (error$1) {
|
|
451
|
+
throw new error.MastraError(
|
|
452
|
+
{
|
|
453
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
454
|
+
domain: error.ErrorDomain.STORAGE,
|
|
455
|
+
category: error.ErrorCategory.USER,
|
|
456
|
+
details: { indexName }
|
|
457
|
+
},
|
|
458
|
+
error$1
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
try {
|
|
361
462
|
await namespace.upsert({
|
|
362
463
|
vectors: [record],
|
|
363
464
|
distance_metric: distanceMetric
|
|
364
465
|
});
|
|
365
|
-
} catch (error) {
|
|
366
|
-
throw new
|
|
466
|
+
} catch (error$1) {
|
|
467
|
+
throw new error.MastraError(
|
|
468
|
+
{
|
|
469
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_FAILED",
|
|
470
|
+
domain: error.ErrorDomain.STORAGE,
|
|
471
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
472
|
+
details: { indexName }
|
|
473
|
+
},
|
|
474
|
+
error$1
|
|
475
|
+
);
|
|
367
476
|
}
|
|
368
477
|
}
|
|
369
478
|
/**
|
|
@@ -377,8 +486,16 @@ var TurbopufferVector = class extends vector.MastraVector {
|
|
|
377
486
|
try {
|
|
378
487
|
const namespace = this.client.namespace(indexName);
|
|
379
488
|
await namespace.delete({ ids: [id] });
|
|
380
|
-
} catch (error) {
|
|
381
|
-
throw new
|
|
489
|
+
} catch (error$1) {
|
|
490
|
+
throw new error.MastraError(
|
|
491
|
+
{
|
|
492
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_VECTOR_FAILED",
|
|
493
|
+
domain: error.ErrorDomain.STORAGE,
|
|
494
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
495
|
+
details: { indexName }
|
|
496
|
+
},
|
|
497
|
+
error$1
|
|
498
|
+
);
|
|
382
499
|
}
|
|
383
500
|
}
|
|
384
501
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
1
2
|
import { MastraVector } from '@mastra/core/vector';
|
|
2
3
|
import { Turbopuffer } from '@turbopuffer/turbopuffer';
|
|
3
4
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
@@ -186,28 +187,40 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
186
187
|
}
|
|
187
188
|
async createIndex({ indexName, dimension, metric }) {
|
|
188
189
|
metric = metric ?? "cosine";
|
|
189
|
-
if (this.createIndexCache.has(indexName)) {
|
|
190
|
-
const expected = this.createIndexCache.get(indexName);
|
|
191
|
-
if (dimension !== expected.dimension || metric !== expected.metric) {
|
|
192
|
-
throw new Error(
|
|
193
|
-
`createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
if (dimension <= 0) {
|
|
199
|
-
throw new Error("Dimension must be a positive integer");
|
|
200
|
-
}
|
|
201
190
|
let distanceMetric = "cosine_distance";
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
191
|
+
try {
|
|
192
|
+
if (this.createIndexCache.has(indexName)) {
|
|
193
|
+
const expected = this.createIndexCache.get(indexName);
|
|
194
|
+
if (dimension !== expected.dimension || metric !== expected.metric) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
`createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (dimension <= 0) {
|
|
202
|
+
throw new Error("Dimension must be a positive integer");
|
|
203
|
+
}
|
|
204
|
+
switch (metric) {
|
|
205
|
+
case "cosine":
|
|
206
|
+
distanceMetric = "cosine_distance";
|
|
207
|
+
break;
|
|
208
|
+
case "euclidean":
|
|
209
|
+
distanceMetric = "euclidean_squared";
|
|
210
|
+
break;
|
|
211
|
+
case "dotproduct":
|
|
212
|
+
throw new Error("dotproduct is not supported in Turbopuffer");
|
|
213
|
+
}
|
|
214
|
+
} catch (error) {
|
|
215
|
+
throw new MastraError(
|
|
216
|
+
{
|
|
217
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_CREATE_INDEX_INVALID_ARGS",
|
|
218
|
+
domain: ErrorDomain.STORAGE,
|
|
219
|
+
category: ErrorCategory.USER,
|
|
220
|
+
details: { indexName, dimension, metric }
|
|
221
|
+
},
|
|
222
|
+
error
|
|
223
|
+
);
|
|
211
224
|
}
|
|
212
225
|
this.createIndexCache.set(indexName, {
|
|
213
226
|
indexName,
|
|
@@ -217,15 +230,29 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
217
230
|
});
|
|
218
231
|
}
|
|
219
232
|
async upsert({ indexName, vectors, metadata, ids }) {
|
|
233
|
+
let index;
|
|
234
|
+
let createIndex;
|
|
220
235
|
try {
|
|
221
236
|
if (vectors.length === 0) {
|
|
222
237
|
throw new Error("upsert() called with empty vectors");
|
|
223
238
|
}
|
|
224
|
-
|
|
225
|
-
|
|
239
|
+
index = this.client.namespace(indexName);
|
|
240
|
+
createIndex = this.createIndexCache.get(indexName);
|
|
226
241
|
if (!createIndex) {
|
|
227
242
|
throw new Error(`createIndex() not called for this index`);
|
|
228
243
|
}
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new MastraError(
|
|
246
|
+
{
|
|
247
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_INVALID_ARGS",
|
|
248
|
+
domain: ErrorDomain.STORAGE,
|
|
249
|
+
category: ErrorCategory.USER,
|
|
250
|
+
details: { indexName }
|
|
251
|
+
},
|
|
252
|
+
error
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
229
256
|
const distanceMetric = createIndex.tpufDistanceMetric;
|
|
230
257
|
const vectorIds = ids || vectors.map(() => crypto.randomUUID());
|
|
231
258
|
const records = vectors.map((vector, i) => ({
|
|
@@ -253,21 +280,48 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
253
280
|
}
|
|
254
281
|
return vectorIds;
|
|
255
282
|
} catch (error) {
|
|
256
|
-
throw new
|
|
283
|
+
throw new MastraError(
|
|
284
|
+
{
|
|
285
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_FAILED",
|
|
286
|
+
domain: ErrorDomain.STORAGE,
|
|
287
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
288
|
+
details: { indexName }
|
|
289
|
+
},
|
|
290
|
+
error
|
|
291
|
+
);
|
|
257
292
|
}
|
|
258
293
|
}
|
|
259
|
-
async query({
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
294
|
+
async query({
|
|
295
|
+
indexName,
|
|
296
|
+
queryVector,
|
|
297
|
+
topK,
|
|
298
|
+
filter,
|
|
299
|
+
includeVector
|
|
300
|
+
}) {
|
|
301
|
+
let createIndex;
|
|
302
|
+
try {
|
|
303
|
+
const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);
|
|
304
|
+
if (schemaConfig) {
|
|
305
|
+
if (queryVector.length !== schemaConfig.dimensions) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
`Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
266
310
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
311
|
+
createIndex = this.createIndexCache.get(indexName);
|
|
312
|
+
if (!createIndex) {
|
|
313
|
+
throw new Error(`createIndex() not called for this index`);
|
|
314
|
+
}
|
|
315
|
+
} catch (error) {
|
|
316
|
+
throw new MastraError(
|
|
317
|
+
{
|
|
318
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_INVALID_ARGS",
|
|
319
|
+
domain: ErrorDomain.STORAGE,
|
|
320
|
+
category: ErrorCategory.USER,
|
|
321
|
+
details: { indexName }
|
|
322
|
+
},
|
|
323
|
+
error
|
|
324
|
+
);
|
|
271
325
|
}
|
|
272
326
|
const distanceMetric = createIndex.tpufDistanceMetric;
|
|
273
327
|
try {
|
|
@@ -290,7 +344,15 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
290
344
|
...includeVector && item.vector ? { vector: item.vector } : {}
|
|
291
345
|
}));
|
|
292
346
|
} catch (error) {
|
|
293
|
-
throw new
|
|
347
|
+
throw new MastraError(
|
|
348
|
+
{
|
|
349
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_FAILED",
|
|
350
|
+
domain: ErrorDomain.STORAGE,
|
|
351
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
352
|
+
details: { indexName }
|
|
353
|
+
},
|
|
354
|
+
error
|
|
355
|
+
);
|
|
294
356
|
}
|
|
295
357
|
}
|
|
296
358
|
async listIndexes() {
|
|
@@ -298,7 +360,14 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
298
360
|
const namespacesResult = await this.client.namespaces({});
|
|
299
361
|
return namespacesResult.namespaces.map((namespace) => namespace.id);
|
|
300
362
|
} catch (error) {
|
|
301
|
-
throw new
|
|
363
|
+
throw new MastraError(
|
|
364
|
+
{
|
|
365
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_LIST_INDEXES_FAILED",
|
|
366
|
+
domain: ErrorDomain.STORAGE,
|
|
367
|
+
category: ErrorCategory.THIRD_PARTY
|
|
368
|
+
},
|
|
369
|
+
error
|
|
370
|
+
);
|
|
302
371
|
}
|
|
303
372
|
}
|
|
304
373
|
/**
|
|
@@ -323,7 +392,15 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
323
392
|
metric: createIndex.metric
|
|
324
393
|
};
|
|
325
394
|
} catch (error) {
|
|
326
|
-
throw new
|
|
395
|
+
throw new MastraError(
|
|
396
|
+
{
|
|
397
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_DESCRIBE_INDEX_FAILED",
|
|
398
|
+
domain: ErrorDomain.STORAGE,
|
|
399
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
400
|
+
details: { indexName }
|
|
401
|
+
},
|
|
402
|
+
error
|
|
403
|
+
);
|
|
327
404
|
}
|
|
328
405
|
}
|
|
329
406
|
async deleteIndex({ indexName }) {
|
|
@@ -332,7 +409,15 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
332
409
|
await namespace.deleteAll();
|
|
333
410
|
this.createIndexCache.delete(indexName);
|
|
334
411
|
} catch (error) {
|
|
335
|
-
throw new
|
|
412
|
+
throw new MastraError(
|
|
413
|
+
{
|
|
414
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_INDEX_FAILED",
|
|
415
|
+
domain: ErrorDomain.STORAGE,
|
|
416
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
417
|
+
details: { indexName }
|
|
418
|
+
},
|
|
419
|
+
error
|
|
420
|
+
);
|
|
336
421
|
}
|
|
337
422
|
}
|
|
338
423
|
/**
|
|
@@ -346,22 +431,46 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
346
431
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
347
432
|
*/
|
|
348
433
|
async updateVector({ indexName, id, update }) {
|
|
434
|
+
let namespace;
|
|
435
|
+
let createIndex;
|
|
436
|
+
let distanceMetric;
|
|
437
|
+
let record;
|
|
349
438
|
try {
|
|
350
|
-
|
|
351
|
-
|
|
439
|
+
namespace = this.client.namespace(indexName);
|
|
440
|
+
createIndex = this.createIndexCache.get(indexName);
|
|
352
441
|
if (!createIndex) {
|
|
353
442
|
throw new Error(`createIndex() not called for this index`);
|
|
354
443
|
}
|
|
355
|
-
|
|
356
|
-
|
|
444
|
+
distanceMetric = createIndex.tpufDistanceMetric;
|
|
445
|
+
record = { id };
|
|
357
446
|
if (update.vector) record.vector = update.vector;
|
|
358
447
|
if (update.metadata) record.attributes = update.metadata;
|
|
448
|
+
} catch (error) {
|
|
449
|
+
throw new MastraError(
|
|
450
|
+
{
|
|
451
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
452
|
+
domain: ErrorDomain.STORAGE,
|
|
453
|
+
category: ErrorCategory.USER,
|
|
454
|
+
details: { indexName }
|
|
455
|
+
},
|
|
456
|
+
error
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
359
460
|
await namespace.upsert({
|
|
360
461
|
vectors: [record],
|
|
361
462
|
distance_metric: distanceMetric
|
|
362
463
|
});
|
|
363
464
|
} catch (error) {
|
|
364
|
-
throw new
|
|
465
|
+
throw new MastraError(
|
|
466
|
+
{
|
|
467
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_FAILED",
|
|
468
|
+
domain: ErrorDomain.STORAGE,
|
|
469
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
470
|
+
details: { indexName }
|
|
471
|
+
},
|
|
472
|
+
error
|
|
473
|
+
);
|
|
365
474
|
}
|
|
366
475
|
}
|
|
367
476
|
/**
|
|
@@ -376,7 +485,15 @@ var TurbopufferVector = class extends MastraVector {
|
|
|
376
485
|
const namespace = this.client.namespace(indexName);
|
|
377
486
|
await namespace.delete({ ids: [id] });
|
|
378
487
|
} catch (error) {
|
|
379
|
-
throw new
|
|
488
|
+
throw new MastraError(
|
|
489
|
+
{
|
|
490
|
+
id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_VECTOR_FAILED",
|
|
491
|
+
domain: ErrorDomain.STORAGE,
|
|
492
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
493
|
+
details: { indexName }
|
|
494
|
+
},
|
|
495
|
+
error
|
|
496
|
+
);
|
|
380
497
|
}
|
|
381
498
|
}
|
|
382
499
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/turbopuffer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-alpha.1",
|
|
4
4
|
"description": "Turbopuffer vector store provider for Mastra",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
"@microsoft/api-extractor": "^7.52.8",
|
|
30
30
|
"@types/node": "^20.19.0",
|
|
31
31
|
"dotenv": "^16.5.0",
|
|
32
|
-
"eslint": "^9.
|
|
32
|
+
"eslint": "^9.29.0",
|
|
33
33
|
"tsup": "^8.5.0",
|
|
34
34
|
"typescript": "^5.8.3",
|
|
35
35
|
"vitest": "^3.2.3",
|
|
36
36
|
"@internal/lint": "0.0.13",
|
|
37
|
-
"@mastra/core": "0.10.
|
|
37
|
+
"@mastra/core": "0.10.7-alpha.3"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@mastra/core": ">=0.10.
|
|
40
|
+
"@mastra/core": ">=0.10.7-0 <0.11.0-0"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
|