@mastra/turbopuffer 1.1.0 → 1.2.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @mastra/turbopuffer
2
2
 
3
+ ## 1.2.0-alpha.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added a `consistency` option to the Turbopuffer vector store. Queries previously always used strong consistency, which adds latency. You can now opt into eventual consistency for lower-latency queries, either for all queries via the constructor or per query. ([#19627](https://github.com/mastra-ai/mastra/pull/19627))
8
+
9
+ ```typescript
10
+ import { TurbopufferVector } from '@mastra/turbopuffer';
11
+
12
+ const vectorStore = new TurbopufferVector({
13
+ id: 'turbopuffer',
14
+ apiKey: process.env.TURBOPUFFER_API_KEY!,
15
+ consistency: 'eventual', // default for all queries (defaults to 'strong')
16
+ });
17
+
18
+ // Per-query override
19
+ await vectorStore.query({
20
+ indexName: 'my-index',
21
+ queryVector: embedding,
22
+ consistency: 'strong',
23
+ });
24
+ ```
25
+
26
+ Fixes https://github.com/mastra-ai/mastra/issues/19591
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [[`ec857fc`](https://github.com/mastra-ai/mastra/commit/ec857fc79c264b53b38e16478c789b7177f2ad59), [`e1f2fae`](https://github.com/mastra-ai/mastra/commit/e1f2faebaf048c3d4c2e2c01d293767c195d5794), [`63aa799`](https://github.com/mastra-ai/mastra/commit/63aa799c6b44eacc7806cda6846b7c5bbee06b37), [`73db8db`](https://github.com/mastra-ai/mastra/commit/73db8db90d69ab6153c7942749f624db0d96952d), [`73db8db`](https://github.com/mastra-ai/mastra/commit/73db8db90d69ab6153c7942749f624db0d96952d), [`76b7181`](https://github.com/mastra-ai/mastra/commit/76b71810366e6d90b9d3973149d1c7ba3659ffb9), [`0c0e8d7`](https://github.com/mastra-ai/mastra/commit/0c0e8d7becd4d1445c656b78d5d845f606c1ff9d), [`9f7c67a`](https://github.com/mastra-ai/mastra/commit/9f7c67abeeb52c41c51a9b5edee60b62afe7cd8d), [`3b65e68`](https://github.com/mastra-ai/mastra/commit/3b65e68d7f1c771c7a70eea42d83fefdd28cad88), [`e3868e2`](https://github.com/mastra-ai/mastra/commit/e3868e22babfffd0133771669ca724501c2dd58e)]:
31
+ - @mastra/core@1.52.0-alpha.5
32
+
3
33
  ## 1.1.0
4
34
 
5
35
  ### Minor Changes
@@ -3,7 +3,7 @@ name: mastra-turbopuffer
3
3
  description: Documentation for @mastra/turbopuffer. Use when working with @mastra/turbopuffer APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/turbopuffer"
6
- version: "1.1.0"
6
+ version: "1.2.0-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.0",
2
+ "version": "1.2.0-alpha.0",
3
3
  "package": "@mastra/turbopuffer",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -1,3 +1,5 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
1
3
  # Turbopuffer vector store
2
4
 
3
5
  The TurbopufferVector class provides vector search using [Turbopuffer](https://turbopuffer.com/), a high-performance vector database optimized for RAG applications. Turbopuffer offers fast vector similarity search with advanced filtering capabilities and efficient storage management.
@@ -16,6 +18,8 @@ The TurbopufferVector class provides vector search using [Turbopuffer](https://t
16
18
 
17
19
  **compression** (`boolean`): Whether to compress requests and accept compressed responses. (Default: `true`)
18
20
 
21
+ **consistency** (`'strong' | 'eventual'`): The default consistency level for queries. Can be overridden per query. "strong" guarantees queries see all data written before the query started, at the cost of higher latency. "eventual" offers lower latency, but recently written data may not be visible yet. (Default: `strong`)
22
+
19
23
  **schemaConfigForIndex** (`function`): A callback function that takes an index name and returns a config object for that index. This allows you to define explicit schemas per index.
20
24
 
21
25
  ## Methods
@@ -48,6 +52,8 @@ The TurbopufferVector class provides vector search using [Turbopuffer](https://t
48
52
 
49
53
  **includeVector** (`boolean`): Whether to include vectors in the results (Default: `false`)
50
54
 
55
+ **consistency** (`'strong' | 'eventual'`): The consistency level for this query. Overrides the consistency level set in the constructor. Defaults to "strong".
56
+
51
57
  ### `listIndexes()`
52
58
 
53
59
  Returns an array of index names as strings.
package/dist/index.cjs CHANGED
@@ -292,7 +292,8 @@ var TurbopufferVector = class extends vector.MastraVector {
292
292
  queryVector,
293
293
  topK,
294
294
  filter,
295
- includeVector
295
+ includeVector,
296
+ consistency
296
297
  }) {
297
298
  if (!queryVector) {
298
299
  throw new error.MastraError({
@@ -339,8 +340,7 @@ var TurbopufferVector = class extends vector.MastraVector {
339
340
  filters: translatedFilter,
340
341
  vector_encoding: includeVector ? "float" : void 0,
341
342
  include_attributes: true,
342
- consistency: { level: "strong" }
343
- // todo: make this configurable somehow?
343
+ consistency: { level: consistency ?? this.opts.consistency ?? "strong" }
344
344
  });
345
345
  return (results.rows ?? []).map((item) => {
346
346
  const { id, vector, $dist, ...metadata } = item;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/vector/filter.ts","../src/vector/index.ts"],"names":["BaseFilterTranslator","op","MastraVector","Turbopuffer","error","MastraError","createVectorErrorId","ErrorDomain","ErrorCategory"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n OperatorSupport,\n VectorFilter,\n OperatorValueMap,\n LogicalOperatorValueMap,\n BlacklistedRootOperators,\n} from '@mastra/core/vector/filter';\nimport { BaseFilterTranslator } from '@mastra/core/vector/filter';\nimport type { Filter } from '@turbopuffer/turbopuffer/resources/custom';\n\ntype TurbopufferFilter = Filter;\ntype FilterCondition = Extract<Filter, [string, string, any]>;\ntype FilterConnective = 'And' | 'Or';\ntype FilterOperator = FilterCondition[1];\n\ntype TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;\n\ntype TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;\n\ntype TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';\n\nexport type TurbopufferVectorFilter = VectorFilter<\n keyof TurbopufferOperatorValueMap,\n TurbopufferOperatorValueMap,\n TurbopufferLogicalOperatorValueMap,\n TurbopufferBlacklistedRootOperators\n>;\n\n/**\n * Translator for converting Mastra filters to Turbopuffer format\n *\n * Mastra filters: { field: { $gt: 10 } }\n * Turbopuffer filters: [\"And\", [[\"field\", \"Gt\", 10]]]\n */\nexport class TurbopufferFilterTranslator extends BaseFilterTranslator<\n TurbopufferVectorFilter,\n TurbopufferFilter | undefined\n> {\n protected override getSupportedOperators(): OperatorSupport {\n return {\n ...BaseFilterTranslator.DEFAULT_OPERATORS,\n logical: ['$and', '$or'],\n array: ['$in', '$nin', '$all'],\n element: ['$exists'],\n regex: [], // No regex support in Turbopuffer\n custom: [], // No custom operators\n };\n }\n\n /**\n * Map Mastra operators to Turbopuffer operators\n */\n private operatorMap: Record<string, FilterOperator> = {\n $eq: 'Eq',\n $ne: 'NotEq',\n $gt: 'Gt',\n $gte: 'Gte',\n $lt: 'Lt',\n $lte: 'Lte',\n $in: 'In',\n $nin: 'NotIn',\n };\n\n /**\n * Convert the Mastra filter to Turbopuffer format\n */\n translate(filter?: TurbopufferVectorFilter): TurbopufferFilter | undefined {\n if (this.isEmpty(filter)) {\n return undefined;\n }\n\n // Validate the filter structure before translating\n this.validateFilter(filter);\n\n // Translate the filter\n const result = this.translateNode(filter);\n\n // If we have a single condition (not a logical operator at the top level),\n // wrap it in an implicit AND to match Turbopuffer's expected format\n if (!Array.isArray(result) || result.length !== 2 || (result[0] !== 'And' && result[0] !== 'Or')) {\n return ['And', [result as FilterCondition]];\n }\n\n return result as TurbopufferFilter;\n }\n\n /**\n * Recursively translate a filter node\n */\n private translateNode(node: TurbopufferVectorFilter): TurbopufferFilter | FilterCondition {\n // Handle empty or null nodes\n if (node === null || node === undefined || Object.keys(node).length === 0) {\n return ['And', []];\n }\n\n // Handle primitive values (direct equality comparison)\n if (this.isPrimitive(node)) {\n throw new Error('Direct primitive values not valid in this context for Turbopuffer');\n }\n\n // Handle direct array value (convert to $in)\n if (Array.isArray(node)) {\n throw new Error('Direct array values not valid in this context for Turbopuffer');\n }\n\n const entries = Object.entries(node);\n\n // Process the first operator or field\n if (entries.length === 0) {\n return ['And', []];\n }\n\n const [key, value] = entries[0] as [string, any];\n\n // Handle logical operators\n if (key && this.isLogicalOperator(key)) {\n return this.translateLogical(key, value);\n }\n\n // Multiple fields at top level - implicit AND\n if (entries.length > 1) {\n const conditions = entries.map(([field, fieldValue]) => this.translateFieldCondition(field, fieldValue));\n return ['And', conditions];\n }\n\n // Single field with condition(s)\n return this.translateFieldCondition(key, value);\n }\n\n /**\n * Translate a field condition\n */\n private translateFieldCondition(field: string, value: any): FilterCondition {\n // Handle Date object directly (convert to ISO string)\n if (value instanceof Date) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle primitive value (direct equality)\n if (this.isPrimitive(value)) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle array value (convert to $in)\n if (Array.isArray(value)) {\n return [field, 'In', this.normalizeArrayValues(value)];\n }\n\n // Handle object with operators\n if (typeof value === 'object' && value !== null) {\n const operators = Object.keys(value);\n\n // If multiple operators for the same field, create an AND condition\n if (operators.length > 1) {\n // Check if all keys are operators\n const allOperators = operators.every(op => this.isOperator(op));\n if (allOperators) {\n // For multiple comparison operators on one field\n const conditions = operators.map(op => this.translateOperator(field, op, value[op]));\n return ['And', conditions] as unknown as FilterCondition;\n } else {\n // For nested objects with multiple fields\n const conditions = operators.map(op => {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n });\n return ['And', conditions] as unknown as FilterCondition;\n }\n }\n\n // Single operator\n const op = operators[0];\n if (op && this.isOperator(op)) {\n return this.translateOperator(field, op, value[op]);\n }\n\n // Nested field path (use dot notation)\n if (op && !this.isOperator(op)) {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n }\n }\n\n throw new Error(`Unsupported filter format for field: ${field}`);\n }\n\n /**\n * Translate a logical operator\n */\n private translateLogical(operator: string, conditions: any[]): TurbopufferFilter {\n // Map Mastra logical operators to Turbopuffer\n const logicalOp: FilterConnective = operator === '$and' ? 'And' : 'Or';\n\n // Validate conditions\n if (!Array.isArray(conditions)) {\n throw new Error(`Logical operator ${operator} requires an array of conditions`);\n }\n\n // Translate each condition\n const translatedConditions = conditions.map(condition => {\n if (typeof condition !== 'object' || condition === null) {\n throw new Error(`Invalid condition for logical operator ${operator}`);\n }\n return this.translateNode(condition);\n });\n\n return [logicalOp, translatedConditions];\n }\n\n /**\n * Translate a specific operator\n */\n private translateOperator(field: string, operator: string, value: any): FilterCondition {\n // Handle comparison operators\n if (operator && this.operatorMap[operator]) {\n return [field, this.operatorMap[operator], this.normalizeValue(value)];\n }\n\n // Handle special cases\n switch (operator) {\n case '$exists':\n // $exists: true -> use NotEq with null (field exists if it's not null)\n // $exists: false -> use Eq with null (field doesn't exist if it is null)\n return value ? [field, 'NotEq', null] : [field, 'Eq', null];\n\n case '$all':\n // $all is not directly supported, simulate with AND + IN conditions\n if (!Array.isArray(value) || value.length === 0) {\n throw new Error('$all operator requires a non-empty array');\n }\n\n const allConditions = value.map(item => [field, 'In', [this.normalizeValue(item)]] as FilterCondition);\n\n // Return the array of conditions directly without nesting\n return ['And', allConditions] as unknown as FilterCondition;\n\n default:\n throw new Error(`Unsupported operator: ${operator || 'undefined'}`);\n }\n }\n\n /**\n * Normalize a value for comparison operations\n */\n protected normalizeValue(value: any): any {\n // Handle special value types\n if (value instanceof Date) {\n return value.toISOString();\n }\n return value;\n }\n\n /**\n * Normalize array values\n */\n protected normalizeArrayValues(values: any[]): any[] {\n return values.map(value => this.normalizeValue(value));\n }\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { createVectorErrorId } from '@mastra/core/storage';\nimport type {\n CreateIndexParams,\n DeleteIndexParams,\n DeleteVectorParams,\n DescribeIndexParams,\n IndexStats,\n QueryResult,\n QueryVectorParams,\n UpdateVectorParams,\n UpsertVectorParams,\n DeleteVectorsParams,\n} from '@mastra/core/vector';\nimport { MastraVector } from '@mastra/core/vector';\nimport { Turbopuffer } from '@turbopuffer/turbopuffer';\nimport type { DistanceMetric, NamespaceWriteParams, Row } from '@turbopuffer/turbopuffer/resources/namespaces';\nimport { TurbopufferFilterTranslator } from './filter';\nimport type { TurbopufferVectorFilter } from './filter';\n\ntype TurbopufferQueryVectorParams = QueryVectorParams<TurbopufferVectorFilter>;\ntype Schema = NonNullable<NamespaceWriteParams['schema']>;\n\nexport interface TurbopufferVectorOptions {\n /** The API key to authenticate with. */\n apiKey: string;\n /** The base URL. Default is https://api.turbopuffer.com. */\n baseUrl?: string;\n /** The timeout to establish a connection, in ms. Default is 10_000. Only applicable in Node and Deno.*/\n connectTimeout?: number;\n /** The socket idle timeout, in ms. Default is 60_000. Only applicable in Node and Deno.*/\n connectionIdleTimeout?: number;\n /** The number of connections to open initially when creating a new client. Default is 0. */\n warmConnections?: number;\n /** Whether to compress requests and accept compressed responses. Default is true. */\n compression?: boolean;\n /**\n * A callback function that takes an index name and returns a config object for that index.\n * This allows you to define explicit schemas per index.\n *\n * Example:\n * ```typescript\n * schemaConfigForIndex: (indexName: string) => {\n * // Mastra's default embedding model and index for memory messages:\n * if (indexName === \"memory_messages_384\") {\n * return {\n * dimensions: 384,\n * schema: {\n * thread_id: {\n * type: \"string\",\n * filterable: true,\n * },\n * },\n * };\n * } else {\n * throw new Error(`TODO: add schema for index: ${indexName}`);\n * }\n * },\n * ```\n */\n schemaConfigForIndex?: (indexName: string) => {\n dimensions: number;\n schema: Schema;\n };\n}\n\nexport class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {\n private client: Turbopuffer;\n private filterTranslator: TurbopufferFilterTranslator;\n // There is no explicit create index operation in Turbopuffer, so just register that\n // someone has called createIndex() and verify that subsequent upsert calls are consistent\n // with how the index was \"created\"\n private createIndexCache: Map<\n string,\n CreateIndexParams & {\n tpufDistanceMetric: DistanceMetric;\n }\n > = new Map();\n private opts: TurbopufferVectorOptions;\n\n constructor(opts: TurbopufferVectorOptions & { id: string }) {\n super({ id: opts.id });\n this.filterTranslator = new TurbopufferFilterTranslator();\n this.opts = opts;\n this.client = new Turbopuffer(opts);\n }\n\n async createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void> {\n metric = metric ?? 'cosine'; // default to cosine distance\n let distanceMetric: DistanceMetric = 'cosine_distance';\n try {\n if (this.createIndexCache.has(indexName)) {\n // verify that the dimensions and distance metric match what we expect\n const expected = this.createIndexCache.get(indexName)!;\n if (dimension !== expected.dimension || metric !== expected.metric) {\n throw new Error(\n `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}`,\n );\n }\n return;\n }\n if (dimension <= 0) {\n throw new Error('Dimension must be a positive integer');\n }\n switch (metric) {\n case 'cosine':\n distanceMetric = 'cosine_distance';\n break;\n case 'euclidean':\n distanceMetric = 'euclidean_squared';\n break;\n case 'dotproduct':\n throw new Error('dotproduct is not supported in Turbopuffer');\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'CREATE_INDEX', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName, dimension, metric },\n },\n error,\n );\n }\n\n this.createIndexCache.set(indexName, {\n indexName,\n dimension,\n metric,\n tpufDistanceMetric: distanceMetric,\n });\n }\n\n async upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]> {\n let index;\n let createIndex;\n try {\n if (vectors.length === 0) {\n throw new Error('upsert() called with empty vectors');\n }\n\n index = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n const distanceMetric = createIndex.tpufDistanceMetric;\n const vectorIds = ids || vectors.map(() => crypto.randomUUID());\n const records: Row[] = vectors.map((vector, i) => ({\n id: vectorIds[i]!,\n vector,\n ...(metadata?.[i] || {}),\n }));\n\n // limit is 256 MB per upsert request, so set a reasonable batch size here that will stay under that for most cases\n // https://turbopuffer.com/docs/limits\n const batchSize = 100;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n const writeOptions: NamespaceWriteParams = {\n upsert_rows: batch,\n distance_metric: distanceMetric,\n };\n\n // Use the schemaForIndex callback if provided\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n writeOptions.schema = schemaConfig.schema;\n if (vectors[0]?.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to upsert vectors[0].length=${vectors[0]?.length}`,\n );\n }\n }\n\n await index.write(writeOptions);\n }\n\n return vectorIds;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async query({\n indexName,\n queryVector,\n topK,\n filter,\n includeVector,\n }: TurbopufferQueryVectorParams): Promise<QueryResult[]> {\n if (!queryVector) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'MISSING_VECTOR'),\n text: 'queryVector is required for Turbopuffer queries. Metadata-only queries are not supported by this vector store.',\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n });\n }\n\n let createIndex;\n try {\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n if (queryVector.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`,\n );\n }\n }\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n const distanceMetric = createIndex.tpufDistanceMetric;\n try {\n const index = this.client.namespace(indexName);\n const translatedFilter = this.filterTranslator.translate(filter);\n const results = await index.query({\n distance_metric: distanceMetric,\n rank_by: ['vector', 'ANN', queryVector],\n top_k: topK,\n filters: translatedFilter,\n vector_encoding: includeVector ? 'float' : undefined,\n include_attributes: true,\n consistency: { level: 'strong' }, // todo: make this configurable somehow?\n });\n return (results.rows ?? []).map(item => {\n const { id, vector, $dist, ...metadata } = item;\n return {\n id: String(id),\n score: typeof $dist === 'number' ? $dist : 0,\n metadata,\n ...(includeVector && Array.isArray(vector) ? { vector } : {}),\n };\n });\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async listIndexes(): Promise<string[]> {\n try {\n const namespacesResult = await this.client.namespaces({});\n return namespacesResult.namespaces.map(namespace => namespace.id);\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'LIST_INDEXES', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n },\n error,\n );\n }\n }\n\n /**\n * Retrieves statistics about a vector index.\n *\n * @param {string} indexName - The name of the index to describe\n * @returns A promise that resolves to the index statistics including dimension, count and metric\n */\n async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {\n try {\n const namespace = this.client.namespace(indexName);\n const metadata = await namespace.metadata();\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n const dimension = createIndex.dimension;\n const count = metadata.approx_row_count;\n return {\n dimension,\n count,\n metric: createIndex.metric,\n };\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DESCRIBE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteIndex({ indexName }: DeleteIndexParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.deleteAll();\n this.createIndexCache.delete(indexName);\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n /**\n * Updates a vector by its ID or filter with the provided vector and/or metadata.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to update.\n * @param filter - The filter to match vectors to update.\n * @param update - An object containing the vector and/or metadata to update.\n * @param update.vector - An optional array of numbers representing the new vector.\n * @param update.metadata - An optional record containing the new metadata.\n * @returns A promise that resolves when the update is complete.\n * @throws Will throw an error if no updates are provided or if the update operation fails.\n */\n async updateVector({ indexName, id, filter, update }: UpdateVectorParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (id && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'id and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!id && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either id or filter must be provided',\n details: { indexName },\n });\n }\n\n if (!update.vector && !update.metadata) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_PAYLOAD'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'No update data provided',\n details: { indexName, ...(id && { id }) },\n });\n }\n\n let namespace;\n let createIndex;\n let distanceMetric;\n try {\n namespace = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n distanceMetric = createIndex.tpufDistanceMetric;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n let idsToUpdate: string[] = [];\n\n if (id) {\n idsToUpdate = [id];\n } else if (filter) {\n // Validate filter is not empty\n if (Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n // Query for matching vectors to get their IDs\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n vector_encoding: update.vector ? undefined : 'float', // Only fetch vectors if we're not replacing them\n include_attributes: true,\n });\n const rows = results.rows ?? [];\n\n idsToUpdate = rows.map(r => String(r.id));\n\n // If we're doing a partial update (only metadata or only vector), we need existing data\n if (!update.vector || !update.metadata) {\n for (const result of rows) {\n const { id: resultId, vector, $dist, ...metadata } = result;\n const record: Row = { id: resultId };\n if (update.vector) {\n record.vector = update.vector;\n } else if (Array.isArray(vector)) {\n record.vector = vector;\n }\n if (update.metadata) {\n Object.assign(record, update.metadata);\n } else {\n Object.assign(record, metadata);\n }\n await namespace.write({\n upsert_rows: [record],\n distance_metric: distanceMetric,\n });\n }\n return;\n }\n }\n\n // If no vectors to update, return early\n if (idsToUpdate.length === 0) {\n this.logger.info(`No vectors matched the criteria for update in ${indexName}`);\n return;\n }\n\n // Full update - we have both vector and metadata (or just one without needing existing data)\n const records: Row[] = idsToUpdate.map(vecId => ({\n id: vecId,\n ...(update.vector ? { vector: update.vector } : {}),\n ...(update.metadata || {}),\n }));\n\n // Batch updates in chunks of 1000\n const batchSize = 1000;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n await namespace.write({\n upsert_rows: batch,\n distance_metric: distanceMetric,\n });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(id && { id }),\n ...(filter && { filter: JSON.stringify(filter) }),\n },\n },\n error,\n );\n }\n }\n\n /**\n * Deletes a vector by its ID.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to delete.\n * @returns A promise that resolves when the deletion is complete.\n * @throws Will throw an error if the deletion operation fails.\n */\n async deleteVector({ indexName, id }: DeleteVectorParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.write({ deletes: [id] });\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteVectors({ indexName, filter, ids }: DeleteVectorsParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (ids && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!ids && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either filter or ids must be provided',\n details: { indexName },\n });\n }\n\n // Validate non-empty arrays and objects\n if (ids && ids.length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_IDS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids array cannot be empty',\n details: { indexName },\n });\n }\n\n if (filter && Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n try {\n const namespace = this.client.namespace(indexName);\n let idsToDelete: string[] = [];\n\n if (ids) {\n idsToDelete = ids;\n } else if (filter) {\n // Query for matching vectors to get their IDs\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n include_attributes: [],\n });\n\n idsToDelete = (results.rows ?? []).map(r => String(r.id));\n }\n\n // If no IDs to delete, return early\n if (idsToDelete.length === 0) {\n this.logger.info(`No vectors matched the criteria for deletion in ${indexName}`);\n return;\n }\n\n // The turbopuffer SDK has a limit of 1000 IDs per delete request.\n const batchSize = 1000;\n for (let i = 0; i < idsToDelete.length; i += batchSize) {\n const batch = idsToDelete.slice(i, i + batchSize);\n await namespace.write({ deletes: batch });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(filter && { filter: JSON.stringify(filter) }),\n ...(ids && { idsCount: ids.length }),\n },\n },\n error,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/vector/filter.ts","../src/vector/index.ts"],"names":["BaseFilterTranslator","op","MastraVector","Turbopuffer","error","MastraError","createVectorErrorId","ErrorDomain","ErrorCategory"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n OperatorSupport,\n VectorFilter,\n OperatorValueMap,\n LogicalOperatorValueMap,\n BlacklistedRootOperators,\n} from '@mastra/core/vector/filter';\nimport { BaseFilterTranslator } from '@mastra/core/vector/filter';\nimport type { Filter } from '@turbopuffer/turbopuffer/resources/custom';\n\ntype TurbopufferFilter = Filter;\ntype FilterCondition = Extract<Filter, [string, string, any]>;\ntype FilterConnective = 'And' | 'Or';\ntype FilterOperator = FilterCondition[1];\n\ntype TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;\n\ntype TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;\n\ntype TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';\n\nexport type TurbopufferVectorFilter = VectorFilter<\n keyof TurbopufferOperatorValueMap,\n TurbopufferOperatorValueMap,\n TurbopufferLogicalOperatorValueMap,\n TurbopufferBlacklistedRootOperators\n>;\n\n/**\n * Translator for converting Mastra filters to Turbopuffer format\n *\n * Mastra filters: { field: { $gt: 10 } }\n * Turbopuffer filters: [\"And\", [[\"field\", \"Gt\", 10]]]\n */\nexport class TurbopufferFilterTranslator extends BaseFilterTranslator<\n TurbopufferVectorFilter,\n TurbopufferFilter | undefined\n> {\n protected override getSupportedOperators(): OperatorSupport {\n return {\n ...BaseFilterTranslator.DEFAULT_OPERATORS,\n logical: ['$and', '$or'],\n array: ['$in', '$nin', '$all'],\n element: ['$exists'],\n regex: [], // No regex support in Turbopuffer\n custom: [], // No custom operators\n };\n }\n\n /**\n * Map Mastra operators to Turbopuffer operators\n */\n private operatorMap: Record<string, FilterOperator> = {\n $eq: 'Eq',\n $ne: 'NotEq',\n $gt: 'Gt',\n $gte: 'Gte',\n $lt: 'Lt',\n $lte: 'Lte',\n $in: 'In',\n $nin: 'NotIn',\n };\n\n /**\n * Convert the Mastra filter to Turbopuffer format\n */\n translate(filter?: TurbopufferVectorFilter): TurbopufferFilter | undefined {\n if (this.isEmpty(filter)) {\n return undefined;\n }\n\n // Validate the filter structure before translating\n this.validateFilter(filter);\n\n // Translate the filter\n const result = this.translateNode(filter);\n\n // If we have a single condition (not a logical operator at the top level),\n // wrap it in an implicit AND to match Turbopuffer's expected format\n if (!Array.isArray(result) || result.length !== 2 || (result[0] !== 'And' && result[0] !== 'Or')) {\n return ['And', [result as FilterCondition]];\n }\n\n return result as TurbopufferFilter;\n }\n\n /**\n * Recursively translate a filter node\n */\n private translateNode(node: TurbopufferVectorFilter): TurbopufferFilter | FilterCondition {\n // Handle empty or null nodes\n if (node === null || node === undefined || Object.keys(node).length === 0) {\n return ['And', []];\n }\n\n // Handle primitive values (direct equality comparison)\n if (this.isPrimitive(node)) {\n throw new Error('Direct primitive values not valid in this context for Turbopuffer');\n }\n\n // Handle direct array value (convert to $in)\n if (Array.isArray(node)) {\n throw new Error('Direct array values not valid in this context for Turbopuffer');\n }\n\n const entries = Object.entries(node);\n\n // Process the first operator or field\n if (entries.length === 0) {\n return ['And', []];\n }\n\n const [key, value] = entries[0] as [string, any];\n\n // Handle logical operators\n if (key && this.isLogicalOperator(key)) {\n return this.translateLogical(key, value);\n }\n\n // Multiple fields at top level - implicit AND\n if (entries.length > 1) {\n const conditions = entries.map(([field, fieldValue]) => this.translateFieldCondition(field, fieldValue));\n return ['And', conditions];\n }\n\n // Single field with condition(s)\n return this.translateFieldCondition(key, value);\n }\n\n /**\n * Translate a field condition\n */\n private translateFieldCondition(field: string, value: any): FilterCondition {\n // Handle Date object directly (convert to ISO string)\n if (value instanceof Date) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle primitive value (direct equality)\n if (this.isPrimitive(value)) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle array value (convert to $in)\n if (Array.isArray(value)) {\n return [field, 'In', this.normalizeArrayValues(value)];\n }\n\n // Handle object with operators\n if (typeof value === 'object' && value !== null) {\n const operators = Object.keys(value);\n\n // If multiple operators for the same field, create an AND condition\n if (operators.length > 1) {\n // Check if all keys are operators\n const allOperators = operators.every(op => this.isOperator(op));\n if (allOperators) {\n // For multiple comparison operators on one field\n const conditions = operators.map(op => this.translateOperator(field, op, value[op]));\n return ['And', conditions] as unknown as FilterCondition;\n } else {\n // For nested objects with multiple fields\n const conditions = operators.map(op => {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n });\n return ['And', conditions] as unknown as FilterCondition;\n }\n }\n\n // Single operator\n const op = operators[0];\n if (op && this.isOperator(op)) {\n return this.translateOperator(field, op, value[op]);\n }\n\n // Nested field path (use dot notation)\n if (op && !this.isOperator(op)) {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n }\n }\n\n throw new Error(`Unsupported filter format for field: ${field}`);\n }\n\n /**\n * Translate a logical operator\n */\n private translateLogical(operator: string, conditions: any[]): TurbopufferFilter {\n // Map Mastra logical operators to Turbopuffer\n const logicalOp: FilterConnective = operator === '$and' ? 'And' : 'Or';\n\n // Validate conditions\n if (!Array.isArray(conditions)) {\n throw new Error(`Logical operator ${operator} requires an array of conditions`);\n }\n\n // Translate each condition\n const translatedConditions = conditions.map(condition => {\n if (typeof condition !== 'object' || condition === null) {\n throw new Error(`Invalid condition for logical operator ${operator}`);\n }\n return this.translateNode(condition);\n });\n\n return [logicalOp, translatedConditions];\n }\n\n /**\n * Translate a specific operator\n */\n private translateOperator(field: string, operator: string, value: any): FilterCondition {\n // Handle comparison operators\n if (operator && this.operatorMap[operator]) {\n return [field, this.operatorMap[operator], this.normalizeValue(value)];\n }\n\n // Handle special cases\n switch (operator) {\n case '$exists':\n // $exists: true -> use NotEq with null (field exists if it's not null)\n // $exists: false -> use Eq with null (field doesn't exist if it is null)\n return value ? [field, 'NotEq', null] : [field, 'Eq', null];\n\n case '$all':\n // $all is not directly supported, simulate with AND + IN conditions\n if (!Array.isArray(value) || value.length === 0) {\n throw new Error('$all operator requires a non-empty array');\n }\n\n const allConditions = value.map(item => [field, 'In', [this.normalizeValue(item)]] as FilterCondition);\n\n // Return the array of conditions directly without nesting\n return ['And', allConditions] as unknown as FilterCondition;\n\n default:\n throw new Error(`Unsupported operator: ${operator || 'undefined'}`);\n }\n }\n\n /**\n * Normalize a value for comparison operations\n */\n protected normalizeValue(value: any): any {\n // Handle special value types\n if (value instanceof Date) {\n return value.toISOString();\n }\n return value;\n }\n\n /**\n * Normalize array values\n */\n protected normalizeArrayValues(values: any[]): any[] {\n return values.map(value => this.normalizeValue(value));\n }\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { createVectorErrorId } from '@mastra/core/storage';\nimport type {\n CreateIndexParams,\n DeleteIndexParams,\n DeleteVectorParams,\n DescribeIndexParams,\n IndexStats,\n QueryResult,\n QueryVectorParams,\n UpdateVectorParams,\n UpsertVectorParams,\n DeleteVectorsParams,\n} from '@mastra/core/vector';\nimport { MastraVector } from '@mastra/core/vector';\nimport { Turbopuffer } from '@turbopuffer/turbopuffer';\nimport type { DistanceMetric, NamespaceWriteParams, Row } from '@turbopuffer/turbopuffer/resources/namespaces';\nimport { TurbopufferFilterTranslator } from './filter';\nimport type { TurbopufferVectorFilter } from './filter';\n\n/**\n * The consistency level for Turbopuffer queries.\n * - 'strong': Queries see all data written before the query started. Higher latency (default).\n * - 'eventual': Lower latency, but recently written data may not be visible yet.\n */\nexport type TurbopufferConsistencyLevel = 'strong' | 'eventual';\n\nexport interface TurbopufferQueryVectorParams extends QueryVectorParams<TurbopufferVectorFilter> {\n /**\n * The consistency level for this query. Overrides the instance-level\n * `consistency` option. Defaults to 'strong'.\n */\n consistency?: TurbopufferConsistencyLevel;\n}\ntype Schema = NonNullable<NamespaceWriteParams['schema']>;\n\nexport interface TurbopufferVectorOptions {\n /** The API key to authenticate with. */\n apiKey: string;\n /** The base URL. Default is https://api.turbopuffer.com. */\n baseUrl?: string;\n /** The timeout to establish a connection, in ms. Default is 10_000. Only applicable in Node and Deno.*/\n connectTimeout?: number;\n /** The socket idle timeout, in ms. Default is 60_000. Only applicable in Node and Deno.*/\n connectionIdleTimeout?: number;\n /** The number of connections to open initially when creating a new client. Default is 0. */\n warmConnections?: number;\n /** Whether to compress requests and accept compressed responses. Default is true. */\n compression?: boolean;\n /**\n * The default consistency level for queries. Can be overridden per query.\n * - 'strong': Queries see all data written before the query started. Higher latency (default).\n * - 'eventual': Lower latency, but recently written data may not be visible yet.\n */\n consistency?: TurbopufferConsistencyLevel;\n /**\n * A callback function that takes an index name and returns a config object for that index.\n * This allows you to define explicit schemas per index.\n *\n * Example:\n * ```typescript\n * schemaConfigForIndex: (indexName: string) => {\n * // Mastra's default embedding model and index for memory messages:\n * if (indexName === \"memory_messages_384\") {\n * return {\n * dimensions: 384,\n * schema: {\n * thread_id: {\n * type: \"string\",\n * filterable: true,\n * },\n * },\n * };\n * } else {\n * throw new Error(`TODO: add schema for index: ${indexName}`);\n * }\n * },\n * ```\n */\n schemaConfigForIndex?: (indexName: string) => {\n dimensions: number;\n schema: Schema;\n };\n}\n\nexport class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {\n private client: Turbopuffer;\n private filterTranslator: TurbopufferFilterTranslator;\n // There is no explicit create index operation in Turbopuffer, so just register that\n // someone has called createIndex() and verify that subsequent upsert calls are consistent\n // with how the index was \"created\"\n private createIndexCache: Map<\n string,\n CreateIndexParams & {\n tpufDistanceMetric: DistanceMetric;\n }\n > = new Map();\n private opts: TurbopufferVectorOptions;\n\n constructor(opts: TurbopufferVectorOptions & { id: string }) {\n super({ id: opts.id });\n this.filterTranslator = new TurbopufferFilterTranslator();\n this.opts = opts;\n this.client = new Turbopuffer(opts);\n }\n\n async createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void> {\n metric = metric ?? 'cosine'; // default to cosine distance\n let distanceMetric: DistanceMetric = 'cosine_distance';\n try {\n if (this.createIndexCache.has(indexName)) {\n // verify that the dimensions and distance metric match what we expect\n const expected = this.createIndexCache.get(indexName)!;\n if (dimension !== expected.dimension || metric !== expected.metric) {\n throw new Error(\n `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}`,\n );\n }\n return;\n }\n if (dimension <= 0) {\n throw new Error('Dimension must be a positive integer');\n }\n switch (metric) {\n case 'cosine':\n distanceMetric = 'cosine_distance';\n break;\n case 'euclidean':\n distanceMetric = 'euclidean_squared';\n break;\n case 'dotproduct':\n throw new Error('dotproduct is not supported in Turbopuffer');\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'CREATE_INDEX', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName, dimension, metric },\n },\n error,\n );\n }\n\n this.createIndexCache.set(indexName, {\n indexName,\n dimension,\n metric,\n tpufDistanceMetric: distanceMetric,\n });\n }\n\n async upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]> {\n let index;\n let createIndex;\n try {\n if (vectors.length === 0) {\n throw new Error('upsert() called with empty vectors');\n }\n\n index = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n const distanceMetric = createIndex.tpufDistanceMetric;\n const vectorIds = ids || vectors.map(() => crypto.randomUUID());\n const records: Row[] = vectors.map((vector, i) => ({\n id: vectorIds[i]!,\n vector,\n ...(metadata?.[i] || {}),\n }));\n\n // limit is 256 MB per upsert request, so set a reasonable batch size here that will stay under that for most cases\n // https://turbopuffer.com/docs/limits\n const batchSize = 100;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n const writeOptions: NamespaceWriteParams = {\n upsert_rows: batch,\n distance_metric: distanceMetric,\n };\n\n // Use the schemaForIndex callback if provided\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n writeOptions.schema = schemaConfig.schema;\n if (vectors[0]?.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to upsert vectors[0].length=${vectors[0]?.length}`,\n );\n }\n }\n\n await index.write(writeOptions);\n }\n\n return vectorIds;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async query({\n indexName,\n queryVector,\n topK,\n filter,\n includeVector,\n consistency,\n }: TurbopufferQueryVectorParams): Promise<QueryResult[]> {\n if (!queryVector) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'MISSING_VECTOR'),\n text: 'queryVector is required for Turbopuffer queries. Metadata-only queries are not supported by this vector store.',\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n });\n }\n\n let createIndex;\n try {\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n if (queryVector.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`,\n );\n }\n }\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n const distanceMetric = createIndex.tpufDistanceMetric;\n try {\n const index = this.client.namespace(indexName);\n const translatedFilter = this.filterTranslator.translate(filter);\n const results = await index.query({\n distance_metric: distanceMetric,\n rank_by: ['vector', 'ANN', queryVector],\n top_k: topK,\n filters: translatedFilter,\n vector_encoding: includeVector ? 'float' : undefined,\n include_attributes: true,\n consistency: { level: consistency ?? this.opts.consistency ?? 'strong' },\n });\n return (results.rows ?? []).map(item => {\n const { id, vector, $dist, ...metadata } = item;\n return {\n id: String(id),\n score: typeof $dist === 'number' ? $dist : 0,\n metadata,\n ...(includeVector && Array.isArray(vector) ? { vector } : {}),\n };\n });\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async listIndexes(): Promise<string[]> {\n try {\n const namespacesResult = await this.client.namespaces({});\n return namespacesResult.namespaces.map(namespace => namespace.id);\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'LIST_INDEXES', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n },\n error,\n );\n }\n }\n\n /**\n * Retrieves statistics about a vector index.\n *\n * @param {string} indexName - The name of the index to describe\n * @returns A promise that resolves to the index statistics including dimension, count and metric\n */\n async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {\n try {\n const namespace = this.client.namespace(indexName);\n const metadata = await namespace.metadata();\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n const dimension = createIndex.dimension;\n const count = metadata.approx_row_count;\n return {\n dimension,\n count,\n metric: createIndex.metric,\n };\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DESCRIBE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteIndex({ indexName }: DeleteIndexParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.deleteAll();\n this.createIndexCache.delete(indexName);\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n /**\n * Updates a vector by its ID or filter with the provided vector and/or metadata.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to update.\n * @param filter - The filter to match vectors to update.\n * @param update - An object containing the vector and/or metadata to update.\n * @param update.vector - An optional array of numbers representing the new vector.\n * @param update.metadata - An optional record containing the new metadata.\n * @returns A promise that resolves when the update is complete.\n * @throws Will throw an error if no updates are provided or if the update operation fails.\n */\n async updateVector({ indexName, id, filter, update }: UpdateVectorParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (id && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'id and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!id && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either id or filter must be provided',\n details: { indexName },\n });\n }\n\n if (!update.vector && !update.metadata) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_PAYLOAD'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'No update data provided',\n details: { indexName, ...(id && { id }) },\n });\n }\n\n let namespace;\n let createIndex;\n let distanceMetric;\n try {\n namespace = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n distanceMetric = createIndex.tpufDistanceMetric;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n let idsToUpdate: string[] = [];\n\n if (id) {\n idsToUpdate = [id];\n } else if (filter) {\n // Validate filter is not empty\n if (Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n // Query for matching vectors to get their IDs\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n vector_encoding: update.vector ? undefined : 'float', // Only fetch vectors if we're not replacing them\n include_attributes: true,\n });\n const rows = results.rows ?? [];\n\n idsToUpdate = rows.map(r => String(r.id));\n\n // If we're doing a partial update (only metadata or only vector), we need existing data\n if (!update.vector || !update.metadata) {\n for (const result of rows) {\n const { id: resultId, vector, $dist, ...metadata } = result;\n const record: Row = { id: resultId };\n if (update.vector) {\n record.vector = update.vector;\n } else if (Array.isArray(vector)) {\n record.vector = vector;\n }\n if (update.metadata) {\n Object.assign(record, update.metadata);\n } else {\n Object.assign(record, metadata);\n }\n await namespace.write({\n upsert_rows: [record],\n distance_metric: distanceMetric,\n });\n }\n return;\n }\n }\n\n // If no vectors to update, return early\n if (idsToUpdate.length === 0) {\n this.logger.info(`No vectors matched the criteria for update in ${indexName}`);\n return;\n }\n\n // Full update - we have both vector and metadata (or just one without needing existing data)\n const records: Row[] = idsToUpdate.map(vecId => ({\n id: vecId,\n ...(update.vector ? { vector: update.vector } : {}),\n ...(update.metadata || {}),\n }));\n\n // Batch updates in chunks of 1000\n const batchSize = 1000;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n await namespace.write({\n upsert_rows: batch,\n distance_metric: distanceMetric,\n });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(id && { id }),\n ...(filter && { filter: JSON.stringify(filter) }),\n },\n },\n error,\n );\n }\n }\n\n /**\n * Deletes a vector by its ID.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to delete.\n * @returns A promise that resolves when the deletion is complete.\n * @throws Will throw an error if the deletion operation fails.\n */\n async deleteVector({ indexName, id }: DeleteVectorParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.write({ deletes: [id] });\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteVectors({ indexName, filter, ids }: DeleteVectorsParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (ids && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!ids && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either filter or ids must be provided',\n details: { indexName },\n });\n }\n\n // Validate non-empty arrays and objects\n if (ids && ids.length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_IDS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids array cannot be empty',\n details: { indexName },\n });\n }\n\n if (filter && Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n try {\n const namespace = this.client.namespace(indexName);\n let idsToDelete: string[] = [];\n\n if (ids) {\n idsToDelete = ids;\n } else if (filter) {\n // Query for matching vectors to get their IDs\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n include_attributes: [],\n });\n\n idsToDelete = (results.rows ?? []).map(r => String(r.id));\n }\n\n // If no IDs to delete, return early\n if (idsToDelete.length === 0) {\n this.logger.info(`No vectors matched the criteria for deletion in ${indexName}`);\n return;\n }\n\n // The turbopuffer SDK has a limit of 1000 IDs per delete request.\n const batchSize = 1000;\n for (let i = 0; i < idsToDelete.length; i += batchSize) {\n const batch = idsToDelete.slice(i, i + batchSize);\n await namespace.write({ deletes: batch });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(filter && { filter: JSON.stringify(filter) }),\n ...(ids && { idsCount: ids.length }),\n },\n },\n error,\n );\n }\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -290,7 +290,8 @@ var TurbopufferVector = class extends MastraVector {
290
290
  queryVector,
291
291
  topK,
292
292
  filter,
293
- includeVector
293
+ includeVector,
294
+ consistency
294
295
  }) {
295
296
  if (!queryVector) {
296
297
  throw new MastraError({
@@ -337,8 +338,7 @@ var TurbopufferVector = class extends MastraVector {
337
338
  filters: translatedFilter,
338
339
  vector_encoding: includeVector ? "float" : void 0,
339
340
  include_attributes: true,
340
- consistency: { level: "strong" }
341
- // todo: make this configurable somehow?
341
+ consistency: { level: consistency ?? this.opts.consistency ?? "strong" }
342
342
  });
343
343
  return (results.rows ?? []).map((item) => {
344
344
  const { id, vector, $dist, ...metadata } = item;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/vector/filter.ts","../src/vector/index.ts"],"names":["op"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n OperatorSupport,\n VectorFilter,\n OperatorValueMap,\n LogicalOperatorValueMap,\n BlacklistedRootOperators,\n} from '@mastra/core/vector/filter';\nimport { BaseFilterTranslator } from '@mastra/core/vector/filter';\nimport type { Filter } from '@turbopuffer/turbopuffer/resources/custom';\n\ntype TurbopufferFilter = Filter;\ntype FilterCondition = Extract<Filter, [string, string, any]>;\ntype FilterConnective = 'And' | 'Or';\ntype FilterOperator = FilterCondition[1];\n\ntype TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;\n\ntype TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;\n\ntype TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';\n\nexport type TurbopufferVectorFilter = VectorFilter<\n keyof TurbopufferOperatorValueMap,\n TurbopufferOperatorValueMap,\n TurbopufferLogicalOperatorValueMap,\n TurbopufferBlacklistedRootOperators\n>;\n\n/**\n * Translator for converting Mastra filters to Turbopuffer format\n *\n * Mastra filters: { field: { $gt: 10 } }\n * Turbopuffer filters: [\"And\", [[\"field\", \"Gt\", 10]]]\n */\nexport class TurbopufferFilterTranslator extends BaseFilterTranslator<\n TurbopufferVectorFilter,\n TurbopufferFilter | undefined\n> {\n protected override getSupportedOperators(): OperatorSupport {\n return {\n ...BaseFilterTranslator.DEFAULT_OPERATORS,\n logical: ['$and', '$or'],\n array: ['$in', '$nin', '$all'],\n element: ['$exists'],\n regex: [], // No regex support in Turbopuffer\n custom: [], // No custom operators\n };\n }\n\n /**\n * Map Mastra operators to Turbopuffer operators\n */\n private operatorMap: Record<string, FilterOperator> = {\n $eq: 'Eq',\n $ne: 'NotEq',\n $gt: 'Gt',\n $gte: 'Gte',\n $lt: 'Lt',\n $lte: 'Lte',\n $in: 'In',\n $nin: 'NotIn',\n };\n\n /**\n * Convert the Mastra filter to Turbopuffer format\n */\n translate(filter?: TurbopufferVectorFilter): TurbopufferFilter | undefined {\n if (this.isEmpty(filter)) {\n return undefined;\n }\n\n // Validate the filter structure before translating\n this.validateFilter(filter);\n\n // Translate the filter\n const result = this.translateNode(filter);\n\n // If we have a single condition (not a logical operator at the top level),\n // wrap it in an implicit AND to match Turbopuffer's expected format\n if (!Array.isArray(result) || result.length !== 2 || (result[0] !== 'And' && result[0] !== 'Or')) {\n return ['And', [result as FilterCondition]];\n }\n\n return result as TurbopufferFilter;\n }\n\n /**\n * Recursively translate a filter node\n */\n private translateNode(node: TurbopufferVectorFilter): TurbopufferFilter | FilterCondition {\n // Handle empty or null nodes\n if (node === null || node === undefined || Object.keys(node).length === 0) {\n return ['And', []];\n }\n\n // Handle primitive values (direct equality comparison)\n if (this.isPrimitive(node)) {\n throw new Error('Direct primitive values not valid in this context for Turbopuffer');\n }\n\n // Handle direct array value (convert to $in)\n if (Array.isArray(node)) {\n throw new Error('Direct array values not valid in this context for Turbopuffer');\n }\n\n const entries = Object.entries(node);\n\n // Process the first operator or field\n if (entries.length === 0) {\n return ['And', []];\n }\n\n const [key, value] = entries[0] as [string, any];\n\n // Handle logical operators\n if (key && this.isLogicalOperator(key)) {\n return this.translateLogical(key, value);\n }\n\n // Multiple fields at top level - implicit AND\n if (entries.length > 1) {\n const conditions = entries.map(([field, fieldValue]) => this.translateFieldCondition(field, fieldValue));\n return ['And', conditions];\n }\n\n // Single field with condition(s)\n return this.translateFieldCondition(key, value);\n }\n\n /**\n * Translate a field condition\n */\n private translateFieldCondition(field: string, value: any): FilterCondition {\n // Handle Date object directly (convert to ISO string)\n if (value instanceof Date) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle primitive value (direct equality)\n if (this.isPrimitive(value)) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle array value (convert to $in)\n if (Array.isArray(value)) {\n return [field, 'In', this.normalizeArrayValues(value)];\n }\n\n // Handle object with operators\n if (typeof value === 'object' && value !== null) {\n const operators = Object.keys(value);\n\n // If multiple operators for the same field, create an AND condition\n if (operators.length > 1) {\n // Check if all keys are operators\n const allOperators = operators.every(op => this.isOperator(op));\n if (allOperators) {\n // For multiple comparison operators on one field\n const conditions = operators.map(op => this.translateOperator(field, op, value[op]));\n return ['And', conditions] as unknown as FilterCondition;\n } else {\n // For nested objects with multiple fields\n const conditions = operators.map(op => {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n });\n return ['And', conditions] as unknown as FilterCondition;\n }\n }\n\n // Single operator\n const op = operators[0];\n if (op && this.isOperator(op)) {\n return this.translateOperator(field, op, value[op]);\n }\n\n // Nested field path (use dot notation)\n if (op && !this.isOperator(op)) {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n }\n }\n\n throw new Error(`Unsupported filter format for field: ${field}`);\n }\n\n /**\n * Translate a logical operator\n */\n private translateLogical(operator: string, conditions: any[]): TurbopufferFilter {\n // Map Mastra logical operators to Turbopuffer\n const logicalOp: FilterConnective = operator === '$and' ? 'And' : 'Or';\n\n // Validate conditions\n if (!Array.isArray(conditions)) {\n throw new Error(`Logical operator ${operator} requires an array of conditions`);\n }\n\n // Translate each condition\n const translatedConditions = conditions.map(condition => {\n if (typeof condition !== 'object' || condition === null) {\n throw new Error(`Invalid condition for logical operator ${operator}`);\n }\n return this.translateNode(condition);\n });\n\n return [logicalOp, translatedConditions];\n }\n\n /**\n * Translate a specific operator\n */\n private translateOperator(field: string, operator: string, value: any): FilterCondition {\n // Handle comparison operators\n if (operator && this.operatorMap[operator]) {\n return [field, this.operatorMap[operator], this.normalizeValue(value)];\n }\n\n // Handle special cases\n switch (operator) {\n case '$exists':\n // $exists: true -> use NotEq with null (field exists if it's not null)\n // $exists: false -> use Eq with null (field doesn't exist if it is null)\n return value ? [field, 'NotEq', null] : [field, 'Eq', null];\n\n case '$all':\n // $all is not directly supported, simulate with AND + IN conditions\n if (!Array.isArray(value) || value.length === 0) {\n throw new Error('$all operator requires a non-empty array');\n }\n\n const allConditions = value.map(item => [field, 'In', [this.normalizeValue(item)]] as FilterCondition);\n\n // Return the array of conditions directly without nesting\n return ['And', allConditions] as unknown as FilterCondition;\n\n default:\n throw new Error(`Unsupported operator: ${operator || 'undefined'}`);\n }\n }\n\n /**\n * Normalize a value for comparison operations\n */\n protected normalizeValue(value: any): any {\n // Handle special value types\n if (value instanceof Date) {\n return value.toISOString();\n }\n return value;\n }\n\n /**\n * Normalize array values\n */\n protected normalizeArrayValues(values: any[]): any[] {\n return values.map(value => this.normalizeValue(value));\n }\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { createVectorErrorId } from '@mastra/core/storage';\nimport type {\n CreateIndexParams,\n DeleteIndexParams,\n DeleteVectorParams,\n DescribeIndexParams,\n IndexStats,\n QueryResult,\n QueryVectorParams,\n UpdateVectorParams,\n UpsertVectorParams,\n DeleteVectorsParams,\n} from '@mastra/core/vector';\nimport { MastraVector } from '@mastra/core/vector';\nimport { Turbopuffer } from '@turbopuffer/turbopuffer';\nimport type { DistanceMetric, NamespaceWriteParams, Row } from '@turbopuffer/turbopuffer/resources/namespaces';\nimport { TurbopufferFilterTranslator } from './filter';\nimport type { TurbopufferVectorFilter } from './filter';\n\ntype TurbopufferQueryVectorParams = QueryVectorParams<TurbopufferVectorFilter>;\ntype Schema = NonNullable<NamespaceWriteParams['schema']>;\n\nexport interface TurbopufferVectorOptions {\n /** The API key to authenticate with. */\n apiKey: string;\n /** The base URL. Default is https://api.turbopuffer.com. */\n baseUrl?: string;\n /** The timeout to establish a connection, in ms. Default is 10_000. Only applicable in Node and Deno.*/\n connectTimeout?: number;\n /** The socket idle timeout, in ms. Default is 60_000. Only applicable in Node and Deno.*/\n connectionIdleTimeout?: number;\n /** The number of connections to open initially when creating a new client. Default is 0. */\n warmConnections?: number;\n /** Whether to compress requests and accept compressed responses. Default is true. */\n compression?: boolean;\n /**\n * A callback function that takes an index name and returns a config object for that index.\n * This allows you to define explicit schemas per index.\n *\n * Example:\n * ```typescript\n * schemaConfigForIndex: (indexName: string) => {\n * // Mastra's default embedding model and index for memory messages:\n * if (indexName === \"memory_messages_384\") {\n * return {\n * dimensions: 384,\n * schema: {\n * thread_id: {\n * type: \"string\",\n * filterable: true,\n * },\n * },\n * };\n * } else {\n * throw new Error(`TODO: add schema for index: ${indexName}`);\n * }\n * },\n * ```\n */\n schemaConfigForIndex?: (indexName: string) => {\n dimensions: number;\n schema: Schema;\n };\n}\n\nexport class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {\n private client: Turbopuffer;\n private filterTranslator: TurbopufferFilterTranslator;\n // There is no explicit create index operation in Turbopuffer, so just register that\n // someone has called createIndex() and verify that subsequent upsert calls are consistent\n // with how the index was \"created\"\n private createIndexCache: Map<\n string,\n CreateIndexParams & {\n tpufDistanceMetric: DistanceMetric;\n }\n > = new Map();\n private opts: TurbopufferVectorOptions;\n\n constructor(opts: TurbopufferVectorOptions & { id: string }) {\n super({ id: opts.id });\n this.filterTranslator = new TurbopufferFilterTranslator();\n this.opts = opts;\n this.client = new Turbopuffer(opts);\n }\n\n async createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void> {\n metric = metric ?? 'cosine'; // default to cosine distance\n let distanceMetric: DistanceMetric = 'cosine_distance';\n try {\n if (this.createIndexCache.has(indexName)) {\n // verify that the dimensions and distance metric match what we expect\n const expected = this.createIndexCache.get(indexName)!;\n if (dimension !== expected.dimension || metric !== expected.metric) {\n throw new Error(\n `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}`,\n );\n }\n return;\n }\n if (dimension <= 0) {\n throw new Error('Dimension must be a positive integer');\n }\n switch (metric) {\n case 'cosine':\n distanceMetric = 'cosine_distance';\n break;\n case 'euclidean':\n distanceMetric = 'euclidean_squared';\n break;\n case 'dotproduct':\n throw new Error('dotproduct is not supported in Turbopuffer');\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'CREATE_INDEX', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName, dimension, metric },\n },\n error,\n );\n }\n\n this.createIndexCache.set(indexName, {\n indexName,\n dimension,\n metric,\n tpufDistanceMetric: distanceMetric,\n });\n }\n\n async upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]> {\n let index;\n let createIndex;\n try {\n if (vectors.length === 0) {\n throw new Error('upsert() called with empty vectors');\n }\n\n index = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n const distanceMetric = createIndex.tpufDistanceMetric;\n const vectorIds = ids || vectors.map(() => crypto.randomUUID());\n const records: Row[] = vectors.map((vector, i) => ({\n id: vectorIds[i]!,\n vector,\n ...(metadata?.[i] || {}),\n }));\n\n // limit is 256 MB per upsert request, so set a reasonable batch size here that will stay under that for most cases\n // https://turbopuffer.com/docs/limits\n const batchSize = 100;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n const writeOptions: NamespaceWriteParams = {\n upsert_rows: batch,\n distance_metric: distanceMetric,\n };\n\n // Use the schemaForIndex callback if provided\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n writeOptions.schema = schemaConfig.schema;\n if (vectors[0]?.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to upsert vectors[0].length=${vectors[0]?.length}`,\n );\n }\n }\n\n await index.write(writeOptions);\n }\n\n return vectorIds;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async query({\n indexName,\n queryVector,\n topK,\n filter,\n includeVector,\n }: TurbopufferQueryVectorParams): Promise<QueryResult[]> {\n if (!queryVector) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'MISSING_VECTOR'),\n text: 'queryVector is required for Turbopuffer queries. Metadata-only queries are not supported by this vector store.',\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n });\n }\n\n let createIndex;\n try {\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n if (queryVector.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`,\n );\n }\n }\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n const distanceMetric = createIndex.tpufDistanceMetric;\n try {\n const index = this.client.namespace(indexName);\n const translatedFilter = this.filterTranslator.translate(filter);\n const results = await index.query({\n distance_metric: distanceMetric,\n rank_by: ['vector', 'ANN', queryVector],\n top_k: topK,\n filters: translatedFilter,\n vector_encoding: includeVector ? 'float' : undefined,\n include_attributes: true,\n consistency: { level: 'strong' }, // todo: make this configurable somehow?\n });\n return (results.rows ?? []).map(item => {\n const { id, vector, $dist, ...metadata } = item;\n return {\n id: String(id),\n score: typeof $dist === 'number' ? $dist : 0,\n metadata,\n ...(includeVector && Array.isArray(vector) ? { vector } : {}),\n };\n });\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async listIndexes(): Promise<string[]> {\n try {\n const namespacesResult = await this.client.namespaces({});\n return namespacesResult.namespaces.map(namespace => namespace.id);\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'LIST_INDEXES', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n },\n error,\n );\n }\n }\n\n /**\n * Retrieves statistics about a vector index.\n *\n * @param {string} indexName - The name of the index to describe\n * @returns A promise that resolves to the index statistics including dimension, count and metric\n */\n async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {\n try {\n const namespace = this.client.namespace(indexName);\n const metadata = await namespace.metadata();\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n const dimension = createIndex.dimension;\n const count = metadata.approx_row_count;\n return {\n dimension,\n count,\n metric: createIndex.metric,\n };\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DESCRIBE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteIndex({ indexName }: DeleteIndexParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.deleteAll();\n this.createIndexCache.delete(indexName);\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n /**\n * Updates a vector by its ID or filter with the provided vector and/or metadata.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to update.\n * @param filter - The filter to match vectors to update.\n * @param update - An object containing the vector and/or metadata to update.\n * @param update.vector - An optional array of numbers representing the new vector.\n * @param update.metadata - An optional record containing the new metadata.\n * @returns A promise that resolves when the update is complete.\n * @throws Will throw an error if no updates are provided or if the update operation fails.\n */\n async updateVector({ indexName, id, filter, update }: UpdateVectorParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (id && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'id and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!id && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either id or filter must be provided',\n details: { indexName },\n });\n }\n\n if (!update.vector && !update.metadata) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_PAYLOAD'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'No update data provided',\n details: { indexName, ...(id && { id }) },\n });\n }\n\n let namespace;\n let createIndex;\n let distanceMetric;\n try {\n namespace = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n distanceMetric = createIndex.tpufDistanceMetric;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n let idsToUpdate: string[] = [];\n\n if (id) {\n idsToUpdate = [id];\n } else if (filter) {\n // Validate filter is not empty\n if (Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n // Query for matching vectors to get their IDs\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n vector_encoding: update.vector ? undefined : 'float', // Only fetch vectors if we're not replacing them\n include_attributes: true,\n });\n const rows = results.rows ?? [];\n\n idsToUpdate = rows.map(r => String(r.id));\n\n // If we're doing a partial update (only metadata or only vector), we need existing data\n if (!update.vector || !update.metadata) {\n for (const result of rows) {\n const { id: resultId, vector, $dist, ...metadata } = result;\n const record: Row = { id: resultId };\n if (update.vector) {\n record.vector = update.vector;\n } else if (Array.isArray(vector)) {\n record.vector = vector;\n }\n if (update.metadata) {\n Object.assign(record, update.metadata);\n } else {\n Object.assign(record, metadata);\n }\n await namespace.write({\n upsert_rows: [record],\n distance_metric: distanceMetric,\n });\n }\n return;\n }\n }\n\n // If no vectors to update, return early\n if (idsToUpdate.length === 0) {\n this.logger.info(`No vectors matched the criteria for update in ${indexName}`);\n return;\n }\n\n // Full update - we have both vector and metadata (or just one without needing existing data)\n const records: Row[] = idsToUpdate.map(vecId => ({\n id: vecId,\n ...(update.vector ? { vector: update.vector } : {}),\n ...(update.metadata || {}),\n }));\n\n // Batch updates in chunks of 1000\n const batchSize = 1000;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n await namespace.write({\n upsert_rows: batch,\n distance_metric: distanceMetric,\n });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(id && { id }),\n ...(filter && { filter: JSON.stringify(filter) }),\n },\n },\n error,\n );\n }\n }\n\n /**\n * Deletes a vector by its ID.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to delete.\n * @returns A promise that resolves when the deletion is complete.\n * @throws Will throw an error if the deletion operation fails.\n */\n async deleteVector({ indexName, id }: DeleteVectorParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.write({ deletes: [id] });\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteVectors({ indexName, filter, ids }: DeleteVectorsParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (ids && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!ids && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either filter or ids must be provided',\n details: { indexName },\n });\n }\n\n // Validate non-empty arrays and objects\n if (ids && ids.length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_IDS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids array cannot be empty',\n details: { indexName },\n });\n }\n\n if (filter && Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n try {\n const namespace = this.client.namespace(indexName);\n let idsToDelete: string[] = [];\n\n if (ids) {\n idsToDelete = ids;\n } else if (filter) {\n // Query for matching vectors to get their IDs\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n include_attributes: [],\n });\n\n idsToDelete = (results.rows ?? []).map(r => String(r.id));\n }\n\n // If no IDs to delete, return early\n if (idsToDelete.length === 0) {\n this.logger.info(`No vectors matched the criteria for deletion in ${indexName}`);\n return;\n }\n\n // The turbopuffer SDK has a limit of 1000 IDs per delete request.\n const batchSize = 1000;\n for (let i = 0; i < idsToDelete.length; i += batchSize) {\n const batch = idsToDelete.slice(i, i + batchSize);\n await namespace.write({ deletes: batch });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(filter && { filter: JSON.stringify(filter) }),\n ...(ids && { idsCount: ids.length }),\n },\n },\n error,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/vector/filter.ts","../src/vector/index.ts"],"names":["op"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n OperatorSupport,\n VectorFilter,\n OperatorValueMap,\n LogicalOperatorValueMap,\n BlacklistedRootOperators,\n} from '@mastra/core/vector/filter';\nimport { BaseFilterTranslator } from '@mastra/core/vector/filter';\nimport type { Filter } from '@turbopuffer/turbopuffer/resources/custom';\n\ntype TurbopufferFilter = Filter;\ntype FilterCondition = Extract<Filter, [string, string, any]>;\ntype FilterConnective = 'And' | 'Or';\ntype FilterOperator = FilterCondition[1];\n\ntype TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;\n\ntype TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;\n\ntype TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';\n\nexport type TurbopufferVectorFilter = VectorFilter<\n keyof TurbopufferOperatorValueMap,\n TurbopufferOperatorValueMap,\n TurbopufferLogicalOperatorValueMap,\n TurbopufferBlacklistedRootOperators\n>;\n\n/**\n * Translator for converting Mastra filters to Turbopuffer format\n *\n * Mastra filters: { field: { $gt: 10 } }\n * Turbopuffer filters: [\"And\", [[\"field\", \"Gt\", 10]]]\n */\nexport class TurbopufferFilterTranslator extends BaseFilterTranslator<\n TurbopufferVectorFilter,\n TurbopufferFilter | undefined\n> {\n protected override getSupportedOperators(): OperatorSupport {\n return {\n ...BaseFilterTranslator.DEFAULT_OPERATORS,\n logical: ['$and', '$or'],\n array: ['$in', '$nin', '$all'],\n element: ['$exists'],\n regex: [], // No regex support in Turbopuffer\n custom: [], // No custom operators\n };\n }\n\n /**\n * Map Mastra operators to Turbopuffer operators\n */\n private operatorMap: Record<string, FilterOperator> = {\n $eq: 'Eq',\n $ne: 'NotEq',\n $gt: 'Gt',\n $gte: 'Gte',\n $lt: 'Lt',\n $lte: 'Lte',\n $in: 'In',\n $nin: 'NotIn',\n };\n\n /**\n * Convert the Mastra filter to Turbopuffer format\n */\n translate(filter?: TurbopufferVectorFilter): TurbopufferFilter | undefined {\n if (this.isEmpty(filter)) {\n return undefined;\n }\n\n // Validate the filter structure before translating\n this.validateFilter(filter);\n\n // Translate the filter\n const result = this.translateNode(filter);\n\n // If we have a single condition (not a logical operator at the top level),\n // wrap it in an implicit AND to match Turbopuffer's expected format\n if (!Array.isArray(result) || result.length !== 2 || (result[0] !== 'And' && result[0] !== 'Or')) {\n return ['And', [result as FilterCondition]];\n }\n\n return result as TurbopufferFilter;\n }\n\n /**\n * Recursively translate a filter node\n */\n private translateNode(node: TurbopufferVectorFilter): TurbopufferFilter | FilterCondition {\n // Handle empty or null nodes\n if (node === null || node === undefined || Object.keys(node).length === 0) {\n return ['And', []];\n }\n\n // Handle primitive values (direct equality comparison)\n if (this.isPrimitive(node)) {\n throw new Error('Direct primitive values not valid in this context for Turbopuffer');\n }\n\n // Handle direct array value (convert to $in)\n if (Array.isArray(node)) {\n throw new Error('Direct array values not valid in this context for Turbopuffer');\n }\n\n const entries = Object.entries(node);\n\n // Process the first operator or field\n if (entries.length === 0) {\n return ['And', []];\n }\n\n const [key, value] = entries[0] as [string, any];\n\n // Handle logical operators\n if (key && this.isLogicalOperator(key)) {\n return this.translateLogical(key, value);\n }\n\n // Multiple fields at top level - implicit AND\n if (entries.length > 1) {\n const conditions = entries.map(([field, fieldValue]) => this.translateFieldCondition(field, fieldValue));\n return ['And', conditions];\n }\n\n // Single field with condition(s)\n return this.translateFieldCondition(key, value);\n }\n\n /**\n * Translate a field condition\n */\n private translateFieldCondition(field: string, value: any): FilterCondition {\n // Handle Date object directly (convert to ISO string)\n if (value instanceof Date) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle primitive value (direct equality)\n if (this.isPrimitive(value)) {\n return [field, 'Eq', this.normalizeValue(value)];\n }\n\n // Handle array value (convert to $in)\n if (Array.isArray(value)) {\n return [field, 'In', this.normalizeArrayValues(value)];\n }\n\n // Handle object with operators\n if (typeof value === 'object' && value !== null) {\n const operators = Object.keys(value);\n\n // If multiple operators for the same field, create an AND condition\n if (operators.length > 1) {\n // Check if all keys are operators\n const allOperators = operators.every(op => this.isOperator(op));\n if (allOperators) {\n // For multiple comparison operators on one field\n const conditions = operators.map(op => this.translateOperator(field, op, value[op]));\n return ['And', conditions] as unknown as FilterCondition;\n } else {\n // For nested objects with multiple fields\n const conditions = operators.map(op => {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n });\n return ['And', conditions] as unknown as FilterCondition;\n }\n }\n\n // Single operator\n const op = operators[0];\n if (op && this.isOperator(op)) {\n return this.translateOperator(field, op, value[op]);\n }\n\n // Nested field path (use dot notation)\n if (op && !this.isOperator(op)) {\n const nestedField = `${field}.${op}`;\n return this.translateFieldCondition(nestedField, value[op]);\n }\n }\n\n throw new Error(`Unsupported filter format for field: ${field}`);\n }\n\n /**\n * Translate a logical operator\n */\n private translateLogical(operator: string, conditions: any[]): TurbopufferFilter {\n // Map Mastra logical operators to Turbopuffer\n const logicalOp: FilterConnective = operator === '$and' ? 'And' : 'Or';\n\n // Validate conditions\n if (!Array.isArray(conditions)) {\n throw new Error(`Logical operator ${operator} requires an array of conditions`);\n }\n\n // Translate each condition\n const translatedConditions = conditions.map(condition => {\n if (typeof condition !== 'object' || condition === null) {\n throw new Error(`Invalid condition for logical operator ${operator}`);\n }\n return this.translateNode(condition);\n });\n\n return [logicalOp, translatedConditions];\n }\n\n /**\n * Translate a specific operator\n */\n private translateOperator(field: string, operator: string, value: any): FilterCondition {\n // Handle comparison operators\n if (operator && this.operatorMap[operator]) {\n return [field, this.operatorMap[operator], this.normalizeValue(value)];\n }\n\n // Handle special cases\n switch (operator) {\n case '$exists':\n // $exists: true -> use NotEq with null (field exists if it's not null)\n // $exists: false -> use Eq with null (field doesn't exist if it is null)\n return value ? [field, 'NotEq', null] : [field, 'Eq', null];\n\n case '$all':\n // $all is not directly supported, simulate with AND + IN conditions\n if (!Array.isArray(value) || value.length === 0) {\n throw new Error('$all operator requires a non-empty array');\n }\n\n const allConditions = value.map(item => [field, 'In', [this.normalizeValue(item)]] as FilterCondition);\n\n // Return the array of conditions directly without nesting\n return ['And', allConditions] as unknown as FilterCondition;\n\n default:\n throw new Error(`Unsupported operator: ${operator || 'undefined'}`);\n }\n }\n\n /**\n * Normalize a value for comparison operations\n */\n protected normalizeValue(value: any): any {\n // Handle special value types\n if (value instanceof Date) {\n return value.toISOString();\n }\n return value;\n }\n\n /**\n * Normalize array values\n */\n protected normalizeArrayValues(values: any[]): any[] {\n return values.map(value => this.normalizeValue(value));\n }\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { createVectorErrorId } from '@mastra/core/storage';\nimport type {\n CreateIndexParams,\n DeleteIndexParams,\n DeleteVectorParams,\n DescribeIndexParams,\n IndexStats,\n QueryResult,\n QueryVectorParams,\n UpdateVectorParams,\n UpsertVectorParams,\n DeleteVectorsParams,\n} from '@mastra/core/vector';\nimport { MastraVector } from '@mastra/core/vector';\nimport { Turbopuffer } from '@turbopuffer/turbopuffer';\nimport type { DistanceMetric, NamespaceWriteParams, Row } from '@turbopuffer/turbopuffer/resources/namespaces';\nimport { TurbopufferFilterTranslator } from './filter';\nimport type { TurbopufferVectorFilter } from './filter';\n\n/**\n * The consistency level for Turbopuffer queries.\n * - 'strong': Queries see all data written before the query started. Higher latency (default).\n * - 'eventual': Lower latency, but recently written data may not be visible yet.\n */\nexport type TurbopufferConsistencyLevel = 'strong' | 'eventual';\n\nexport interface TurbopufferQueryVectorParams extends QueryVectorParams<TurbopufferVectorFilter> {\n /**\n * The consistency level for this query. Overrides the instance-level\n * `consistency` option. Defaults to 'strong'.\n */\n consistency?: TurbopufferConsistencyLevel;\n}\ntype Schema = NonNullable<NamespaceWriteParams['schema']>;\n\nexport interface TurbopufferVectorOptions {\n /** The API key to authenticate with. */\n apiKey: string;\n /** The base URL. Default is https://api.turbopuffer.com. */\n baseUrl?: string;\n /** The timeout to establish a connection, in ms. Default is 10_000. Only applicable in Node and Deno.*/\n connectTimeout?: number;\n /** The socket idle timeout, in ms. Default is 60_000. Only applicable in Node and Deno.*/\n connectionIdleTimeout?: number;\n /** The number of connections to open initially when creating a new client. Default is 0. */\n warmConnections?: number;\n /** Whether to compress requests and accept compressed responses. Default is true. */\n compression?: boolean;\n /**\n * The default consistency level for queries. Can be overridden per query.\n * - 'strong': Queries see all data written before the query started. Higher latency (default).\n * - 'eventual': Lower latency, but recently written data may not be visible yet.\n */\n consistency?: TurbopufferConsistencyLevel;\n /**\n * A callback function that takes an index name and returns a config object for that index.\n * This allows you to define explicit schemas per index.\n *\n * Example:\n * ```typescript\n * schemaConfigForIndex: (indexName: string) => {\n * // Mastra's default embedding model and index for memory messages:\n * if (indexName === \"memory_messages_384\") {\n * return {\n * dimensions: 384,\n * schema: {\n * thread_id: {\n * type: \"string\",\n * filterable: true,\n * },\n * },\n * };\n * } else {\n * throw new Error(`TODO: add schema for index: ${indexName}`);\n * }\n * },\n * ```\n */\n schemaConfigForIndex?: (indexName: string) => {\n dimensions: number;\n schema: Schema;\n };\n}\n\nexport class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {\n private client: Turbopuffer;\n private filterTranslator: TurbopufferFilterTranslator;\n // There is no explicit create index operation in Turbopuffer, so just register that\n // someone has called createIndex() and verify that subsequent upsert calls are consistent\n // with how the index was \"created\"\n private createIndexCache: Map<\n string,\n CreateIndexParams & {\n tpufDistanceMetric: DistanceMetric;\n }\n > = new Map();\n private opts: TurbopufferVectorOptions;\n\n constructor(opts: TurbopufferVectorOptions & { id: string }) {\n super({ id: opts.id });\n this.filterTranslator = new TurbopufferFilterTranslator();\n this.opts = opts;\n this.client = new Turbopuffer(opts);\n }\n\n async createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void> {\n metric = metric ?? 'cosine'; // default to cosine distance\n let distanceMetric: DistanceMetric = 'cosine_distance';\n try {\n if (this.createIndexCache.has(indexName)) {\n // verify that the dimensions and distance metric match what we expect\n const expected = this.createIndexCache.get(indexName)!;\n if (dimension !== expected.dimension || metric !== expected.metric) {\n throw new Error(\n `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}`,\n );\n }\n return;\n }\n if (dimension <= 0) {\n throw new Error('Dimension must be a positive integer');\n }\n switch (metric) {\n case 'cosine':\n distanceMetric = 'cosine_distance';\n break;\n case 'euclidean':\n distanceMetric = 'euclidean_squared';\n break;\n case 'dotproduct':\n throw new Error('dotproduct is not supported in Turbopuffer');\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'CREATE_INDEX', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName, dimension, metric },\n },\n error,\n );\n }\n\n this.createIndexCache.set(indexName, {\n indexName,\n dimension,\n metric,\n tpufDistanceMetric: distanceMetric,\n });\n }\n\n async upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]> {\n let index;\n let createIndex;\n try {\n if (vectors.length === 0) {\n throw new Error('upsert() called with empty vectors');\n }\n\n index = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n const distanceMetric = createIndex.tpufDistanceMetric;\n const vectorIds = ids || vectors.map(() => crypto.randomUUID());\n const records: Row[] = vectors.map((vector, i) => ({\n id: vectorIds[i]!,\n vector,\n ...(metadata?.[i] || {}),\n }));\n\n // limit is 256 MB per upsert request, so set a reasonable batch size here that will stay under that for most cases\n // https://turbopuffer.com/docs/limits\n const batchSize = 100;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n const writeOptions: NamespaceWriteParams = {\n upsert_rows: batch,\n distance_metric: distanceMetric,\n };\n\n // Use the schemaForIndex callback if provided\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n writeOptions.schema = schemaConfig.schema;\n if (vectors[0]?.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to upsert vectors[0].length=${vectors[0]?.length}`,\n );\n }\n }\n\n await index.write(writeOptions);\n }\n\n return vectorIds;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPSERT', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async query({\n indexName,\n queryVector,\n topK,\n filter,\n includeVector,\n consistency,\n }: TurbopufferQueryVectorParams): Promise<QueryResult[]> {\n if (!queryVector) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'MISSING_VECTOR'),\n text: 'queryVector is required for Turbopuffer queries. Metadata-only queries are not supported by this vector store.',\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n });\n }\n\n let createIndex;\n try {\n const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);\n if (schemaConfig) {\n if (queryVector.length !== schemaConfig.dimensions) {\n throw new Error(\n `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`,\n );\n }\n }\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n const distanceMetric = createIndex.tpufDistanceMetric;\n try {\n const index = this.client.namespace(indexName);\n const translatedFilter = this.filterTranslator.translate(filter);\n const results = await index.query({\n distance_metric: distanceMetric,\n rank_by: ['vector', 'ANN', queryVector],\n top_k: topK,\n filters: translatedFilter,\n vector_encoding: includeVector ? 'float' : undefined,\n include_attributes: true,\n consistency: { level: consistency ?? this.opts.consistency ?? 'strong' },\n });\n return (results.rows ?? []).map(item => {\n const { id, vector, $dist, ...metadata } = item;\n return {\n id: String(id),\n score: typeof $dist === 'number' ? $dist : 0,\n metadata,\n ...(includeVector && Array.isArray(vector) ? { vector } : {}),\n };\n });\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'QUERY', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async listIndexes(): Promise<string[]> {\n try {\n const namespacesResult = await this.client.namespaces({});\n return namespacesResult.namespaces.map(namespace => namespace.id);\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'LIST_INDEXES', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n },\n error,\n );\n }\n }\n\n /**\n * Retrieves statistics about a vector index.\n *\n * @param {string} indexName - The name of the index to describe\n * @returns A promise that resolves to the index statistics including dimension, count and metric\n */\n async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {\n try {\n const namespace = this.client.namespace(indexName);\n const metadata = await namespace.metadata();\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n const dimension = createIndex.dimension;\n const count = metadata.approx_row_count;\n return {\n dimension,\n count,\n metric: createIndex.metric,\n };\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DESCRIBE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteIndex({ indexName }: DeleteIndexParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.deleteAll();\n this.createIndexCache.delete(indexName);\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_INDEX', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n /**\n * Updates a vector by its ID or filter with the provided vector and/or metadata.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to update.\n * @param filter - The filter to match vectors to update.\n * @param update - An object containing the vector and/or metadata to update.\n * @param update.vector - An optional array of numbers representing the new vector.\n * @param update.metadata - An optional record containing the new metadata.\n * @returns A promise that resolves when the update is complete.\n * @throws Will throw an error if no updates are provided or if the update operation fails.\n */\n async updateVector({ indexName, id, filter, update }: UpdateVectorParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (id && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'id and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!id && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either id or filter must be provided',\n details: { indexName },\n });\n }\n\n if (!update.vector && !update.metadata) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'NO_PAYLOAD'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'No update data provided',\n details: { indexName, ...(id && { id }) },\n });\n }\n\n let namespace;\n let createIndex;\n let distanceMetric;\n try {\n namespace = this.client.namespace(indexName);\n createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n distanceMetric = createIndex.tpufDistanceMetric;\n } catch (error) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'INVALID_ARGS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n },\n error,\n );\n }\n\n try {\n let idsToUpdate: string[] = [];\n\n if (id) {\n idsToUpdate = [id];\n } else if (filter) {\n // Validate filter is not empty\n if (Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n // Query for matching vectors to get their IDs\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n vector_encoding: update.vector ? undefined : 'float', // Only fetch vectors if we're not replacing them\n include_attributes: true,\n });\n const rows = results.rows ?? [];\n\n idsToUpdate = rows.map(r => String(r.id));\n\n // If we're doing a partial update (only metadata or only vector), we need existing data\n if (!update.vector || !update.metadata) {\n for (const result of rows) {\n const { id: resultId, vector, $dist, ...metadata } = result;\n const record: Row = { id: resultId };\n if (update.vector) {\n record.vector = update.vector;\n } else if (Array.isArray(vector)) {\n record.vector = vector;\n }\n if (update.metadata) {\n Object.assign(record, update.metadata);\n } else {\n Object.assign(record, metadata);\n }\n await namespace.write({\n upsert_rows: [record],\n distance_metric: distanceMetric,\n });\n }\n return;\n }\n }\n\n // If no vectors to update, return early\n if (idsToUpdate.length === 0) {\n this.logger.info(`No vectors matched the criteria for update in ${indexName}`);\n return;\n }\n\n // Full update - we have both vector and metadata (or just one without needing existing data)\n const records: Row[] = idsToUpdate.map(vecId => ({\n id: vecId,\n ...(update.vector ? { vector: update.vector } : {}),\n ...(update.metadata || {}),\n }));\n\n // Batch updates in chunks of 1000\n const batchSize = 1000;\n for (let i = 0; i < records.length; i += batchSize) {\n const batch = records.slice(i, i + batchSize);\n await namespace.write({\n upsert_rows: batch,\n distance_metric: distanceMetric,\n });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'UPDATE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(id && { id }),\n ...(filter && { filter: JSON.stringify(filter) }),\n },\n },\n error,\n );\n }\n }\n\n /**\n * Deletes a vector by its ID.\n * @param indexName - The name of the index containing the vector.\n * @param id - The ID of the vector to delete.\n * @returns A promise that resolves when the deletion is complete.\n * @throws Will throw an error if the deletion operation fails.\n */\n async deleteVector({ indexName, id }: DeleteVectorParams): Promise<void> {\n try {\n const namespace = this.client.namespace(indexName);\n await namespace.write({ deletes: [id] });\n } catch (error: any) {\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTOR', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: { indexName },\n },\n error,\n );\n }\n }\n\n async deleteVectors({ indexName, filter, ids }: DeleteVectorsParams<TurbopufferVectorFilter>): Promise<void> {\n // Validate mutually exclusive parameters\n if (ids && filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'MUTUALLY_EXCLUSIVE'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids and filter are mutually exclusive',\n details: { indexName },\n });\n }\n\n if (!ids && !filter) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'NO_TARGET'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Either filter or ids must be provided',\n details: { indexName },\n });\n }\n\n // Validate non-empty arrays and objects\n if (ids && ids.length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_IDS'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'ids array cannot be empty',\n details: { indexName },\n });\n }\n\n if (filter && Object.keys(filter).length === 0) {\n throw new MastraError({\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'EMPTY_FILTER'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n text: 'Filter cannot be an empty object',\n details: { indexName },\n });\n }\n\n try {\n const namespace = this.client.namespace(indexName);\n let idsToDelete: string[] = [];\n\n if (ids) {\n idsToDelete = ids;\n } else if (filter) {\n // Query for matching vectors to get their IDs\n const createIndex = this.createIndexCache.get(indexName);\n if (!createIndex) {\n throw new Error(`createIndex() not called for this index`);\n }\n\n const dummyVector = new Array(createIndex.dimension).fill(1 / Math.sqrt(createIndex.dimension));\n const translatedFilter = this.filterTranslator.translate(filter);\n\n const results = await namespace.query({\n rank_by: ['vector', 'ANN', dummyVector],\n top_k: 10000, // Get all matching vectors\n filters: translatedFilter,\n include_attributes: [],\n });\n\n idsToDelete = (results.rows ?? []).map(r => String(r.id));\n }\n\n // If no IDs to delete, return early\n if (idsToDelete.length === 0) {\n this.logger.info(`No vectors matched the criteria for deletion in ${indexName}`);\n return;\n }\n\n // The turbopuffer SDK has a limit of 1000 IDs per delete request.\n const batchSize = 1000;\n for (let i = 0; i < idsToDelete.length; i += batchSize) {\n const batch = idsToDelete.slice(i, i + batchSize);\n await namespace.write({ deletes: batch });\n }\n } catch (error: any) {\n if (error instanceof MastraError) throw error;\n throw new MastraError(\n {\n id: createVectorErrorId('TURBOPUFFER', 'DELETE_VECTORS', 'FAILED'),\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.THIRD_PARTY,\n details: {\n indexName,\n ...(filter && { filter: JSON.stringify(filter) }),\n ...(ids && { idsCount: ids.length }),\n },\n },\n error,\n );\n }\n }\n}\n"]}
@@ -2,7 +2,19 @@ import type { CreateIndexParams, DeleteIndexParams, DeleteVectorParams, Describe
2
2
  import { MastraVector } from '@mastra/core/vector';
3
3
  import type { NamespaceWriteParams } from '@turbopuffer/turbopuffer/resources/namespaces';
4
4
  import type { TurbopufferVectorFilter } from './filter.js';
5
- type TurbopufferQueryVectorParams = QueryVectorParams<TurbopufferVectorFilter>;
5
+ /**
6
+ * The consistency level for Turbopuffer queries.
7
+ * - 'strong': Queries see all data written before the query started. Higher latency (default).
8
+ * - 'eventual': Lower latency, but recently written data may not be visible yet.
9
+ */
10
+ export type TurbopufferConsistencyLevel = 'strong' | 'eventual';
11
+ export interface TurbopufferQueryVectorParams extends QueryVectorParams<TurbopufferVectorFilter> {
12
+ /**
13
+ * The consistency level for this query. Overrides the instance-level
14
+ * `consistency` option. Defaults to 'strong'.
15
+ */
16
+ consistency?: TurbopufferConsistencyLevel;
17
+ }
6
18
  type Schema = NonNullable<NamespaceWriteParams['schema']>;
7
19
  export interface TurbopufferVectorOptions {
8
20
  /** The API key to authenticate with. */
@@ -17,6 +29,12 @@ export interface TurbopufferVectorOptions {
17
29
  warmConnections?: number;
18
30
  /** Whether to compress requests and accept compressed responses. Default is true. */
19
31
  compression?: boolean;
32
+ /**
33
+ * The default consistency level for queries. Can be overridden per query.
34
+ * - 'strong': Queries see all data written before the query started. Higher latency (default).
35
+ * - 'eventual': Lower latency, but recently written data may not be visible yet.
36
+ */
37
+ consistency?: TurbopufferConsistencyLevel;
20
38
  /**
21
39
  * A callback function that takes an index name and returns a config object for that index.
22
40
  * This allows you to define explicit schemas per index.
@@ -56,7 +74,7 @@ export declare class TurbopufferVector extends MastraVector<TurbopufferVectorFil
56
74
  });
57
75
  createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void>;
58
76
  upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]>;
59
- query({ indexName, queryVector, topK, filter, includeVector, }: TurbopufferQueryVectorParams): Promise<QueryResult[]>;
77
+ query({ indexName, queryVector, topK, filter, includeVector, consistency, }: TurbopufferQueryVectorParams): Promise<QueryResult[]>;
60
78
  listIndexes(): Promise<string[]>;
61
79
  /**
62
80
  * Retrieves statistics about a vector index.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vector/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,KAAK,EAAkB,oBAAoB,EAAO,MAAM,+CAA+C,CAAC;AAE/G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD,KAAK,4BAA4B,GAAG,iBAAiB,CAAC,uBAAuB,CAAC,CAAC;AAC/E,KAAK,MAAM,GAAG,WAAW,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE1D,MAAM,WAAW,wBAAwB;IACvC,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wGAAwG;IACxG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qFAAqF;IACrF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK;QAC5C,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,uBAAuB,CAAC;IAC1E,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,gBAAgB,CAA8B;IAItD,OAAO,CAAC,gBAAgB,CAKV;IACd,OAAO,CAAC,IAAI,CAA2B;gBAE3B,IAAI,EAAE,wBAAwB,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE;IAOrD,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+C/E,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwEpF,KAAK,CAAC,EACV,SAAS,EACT,WAAW,EACX,IAAI,EACJ,MAAM,EACN,aAAa,GACd,EAAE,4BAA4B,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAwElD,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAgBtC;;;;;OAKG;IACG,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IA4BtE,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlE;;;;;;;;;;OAUG;IACG,YAAY,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,kBAAkB,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAsJjH;;;;;;OAMG;IACG,YAAY,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlE,aAAa,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,mBAAmB,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAkG7G"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vector/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/turbopuffer",
3
- "version": "1.1.0",
3
+ "version": "1.2.0-alpha.0",
4
4
  "description": "Turbopuffer vector store provider for Mastra",
5
5
  "type": "module",
6
6
  "files": [
@@ -27,19 +27,19 @@
27
27
  "@turbopuffer/turbopuffer": "^0.10.18"
28
28
  },
29
29
  "devDependencies": {
30
- "@types/node": "22.19.21",
31
- "@vitest/coverage-v8": "4.1.8",
32
- "@vitest/ui": "4.1.8",
30
+ "@types/node": "22.20.1",
31
+ "@vitest/coverage-v8": "4.1.10",
32
+ "@vitest/ui": "4.1.10",
33
33
  "dotenv": "^17.4.2",
34
- "eslint": "^10.4.1",
34
+ "eslint": "^10.7.0",
35
35
  "tsup": "^8.5.1",
36
36
  "tsx": "^4.22.4",
37
37
  "typescript": "^6.0.3",
38
- "vitest": "4.1.8",
39
- "@internal/lint": "0.0.107",
40
- "@internal/types-builder": "0.0.82",
41
- "@internal/storage-test-utils": "0.0.103",
42
- "@mastra/core": "1.45.0"
38
+ "vitest": "4.1.10",
39
+ "@internal/storage-test-utils": "0.0.110",
40
+ "@internal/lint": "0.0.114",
41
+ "@internal/types-builder": "0.0.89",
42
+ "@mastra/core": "1.52.0-alpha.8"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@mastra/core": ">=1.0.0-0 <2.0.0-0"