@mastra/vectorize 1.1.0-alpha.0 → 1.1.1-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/dist/index.js CHANGED
@@ -1,404 +1,406 @@
1
- import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
- import { createVectorErrorId } from '@mastra/core/storage';
3
- import { MastraVector } from '@mastra/core/vector';
4
- import Cloudflare from 'cloudflare';
5
- import { BaseFilterTranslator } from '@mastra/core/vector/filter';
6
-
7
- // src/vector/index.ts
1
+ import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
2
+ import { createVectorErrorId } from "@mastra/core/storage";
3
+ import { MastraVector } from "@mastra/core/vector";
4
+ import Cloudflare from "cloudflare";
5
+ import { BaseFilterTranslator } from "@mastra/core/vector/filter";
6
+ //#region src/vector/filter.ts
8
7
  var VectorizeFilterTranslator = class extends BaseFilterTranslator {
9
- getSupportedOperators() {
10
- return {
11
- ...BaseFilterTranslator.DEFAULT_OPERATORS,
12
- logical: [],
13
- array: ["$in", "$nin"],
14
- element: [],
15
- regex: [],
16
- custom: []
17
- };
18
- }
19
- translate(filter) {
20
- if (this.isEmpty(filter)) return filter;
21
- this.validateFilter(filter);
22
- return this.translateNode(filter);
23
- }
24
- translateNode(node, currentPath = "") {
25
- if (this.isRegex(node)) {
26
- throw new Error("Regex is not supported in Vectorize");
27
- }
28
- if (this.isPrimitive(node)) return { $eq: this.normalizeComparisonValue(node) };
29
- if (Array.isArray(node)) return { $in: this.normalizeArrayValues(node) };
30
- const entries = Object.entries(node);
31
- const firstEntry = entries[0];
32
- if (entries.length === 1 && firstEntry && this.isOperator(firstEntry[0])) {
33
- const [operator, value] = firstEntry;
34
- return { [operator]: this.normalizeComparisonValue(value) };
35
- }
36
- const result = {};
37
- for (const [key, value] of entries) {
38
- const newPath = currentPath ? `${currentPath}.${key}` : key;
39
- if (this.isOperator(key)) {
40
- result[key] = this.normalizeComparisonValue(value);
41
- continue;
42
- }
43
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
44
- if (Object.keys(value).length === 0) {
45
- result[newPath] = this.translateNode(value);
46
- continue;
47
- }
48
- const hasOperators = Object.keys(value).some((k) => this.isOperator(k));
49
- if (hasOperators) {
50
- result[newPath] = this.translateNode(value);
51
- } else {
52
- Object.assign(result, this.translateNode(value, newPath));
53
- }
54
- } else {
55
- result[newPath] = this.translateNode(value);
56
- }
57
- }
58
- return result;
59
- }
8
+ getSupportedOperators() {
9
+ return {
10
+ ...BaseFilterTranslator.DEFAULT_OPERATORS,
11
+ logical: [],
12
+ array: ["$in", "$nin"],
13
+ element: [],
14
+ regex: [],
15
+ custom: []
16
+ };
17
+ }
18
+ translate(filter) {
19
+ if (this.isEmpty(filter)) return filter;
20
+ this.validateFilter(filter);
21
+ return this.translateNode(filter);
22
+ }
23
+ translateNode(node, currentPath = "") {
24
+ if (this.isRegex(node)) throw new Error("Regex is not supported in Vectorize");
25
+ if (this.isPrimitive(node)) return { $eq: this.normalizeComparisonValue(node) };
26
+ if (Array.isArray(node)) return { $in: this.normalizeArrayValues(node) };
27
+ const entries = Object.entries(node);
28
+ const firstEntry = entries[0];
29
+ if (entries.length === 1 && firstEntry && this.isOperator(firstEntry[0])) {
30
+ const [operator, value] = firstEntry;
31
+ return { [operator]: this.normalizeComparisonValue(value) };
32
+ }
33
+ const result = {};
34
+ for (const [key, value] of entries) {
35
+ const newPath = currentPath ? `${currentPath}.${key}` : key;
36
+ if (this.isOperator(key)) {
37
+ result[key] = this.normalizeComparisonValue(value);
38
+ continue;
39
+ }
40
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
41
+ if (Object.keys(value).length === 0) {
42
+ result[newPath] = this.translateNode(value);
43
+ continue;
44
+ }
45
+ if (Object.keys(value).some((k) => this.isOperator(k))) result[newPath] = this.translateNode(value);
46
+ else Object.assign(result, this.translateNode(value, newPath));
47
+ } else result[newPath] = this.translateNode(value);
48
+ }
49
+ return result;
50
+ }
60
51
  };
61
-
62
- // src/vector/index.ts
52
+ //#endregion
53
+ //#region src/vector/index.ts
63
54
  var CloudflareVector = class extends MastraVector {
64
- client;
65
- accountId;
66
- constructor({ accountId, apiToken, id }) {
67
- super({ id });
68
- this.accountId = accountId;
69
- this.client = new Cloudflare({
70
- apiToken
71
- });
72
- }
73
- get indexSeparator() {
74
- return "-";
75
- }
76
- async upsert({ indexName, vectors, metadata, ids }) {
77
- const generatedIds = ids || vectors.map(() => crypto.randomUUID());
78
- const ndjson = vectors.map(
79
- (vector, index) => JSON.stringify({
80
- id: generatedIds[index],
81
- values: vector,
82
- metadata: metadata?.[index]
83
- })
84
- ).join("\n");
85
- try {
86
- const body = new File([ndjson], `${indexName}.ndjson`, { type: "application/x-ndjson" });
87
- await this.client.vectorize.indexes.upsert(indexName, {
88
- account_id: this.accountId,
89
- body
90
- });
91
- return generatedIds;
92
- } catch (error) {
93
- throw new MastraError(
94
- {
95
- id: createVectorErrorId("VECTORIZE", "UPSERT", "FAILED"),
96
- domain: ErrorDomain.STORAGE,
97
- category: ErrorCategory.THIRD_PARTY,
98
- details: { indexName, vectorCount: vectors?.length }
99
- },
100
- error
101
- );
102
- }
103
- }
104
- transformFilter(filter) {
105
- const translator = new VectorizeFilterTranslator();
106
- return translator.translate(filter);
107
- }
108
- async createIndex({ indexName, dimension, metric = "cosine" }) {
109
- try {
110
- await this.client.vectorize.indexes.create({
111
- account_id: this.accountId,
112
- config: {
113
- dimensions: dimension,
114
- metric: metric === "dotproduct" ? "dot-product" : metric
115
- },
116
- name: indexName
117
- });
118
- } catch (error) {
119
- const message = error?.errors?.[0]?.message || error?.message;
120
- if (error.status === 409 || typeof message === "string" && (message.toLowerCase().includes("already exists") || message.toLowerCase().includes("duplicate"))) {
121
- await this.validateExistingIndex(indexName, dimension, metric);
122
- return;
123
- }
124
- throw new MastraError(
125
- {
126
- id: createVectorErrorId("VECTORIZE", "CREATE_INDEX", "FAILED"),
127
- domain: ErrorDomain.STORAGE,
128
- category: ErrorCategory.THIRD_PARTY,
129
- details: { indexName, dimension, metric }
130
- },
131
- error
132
- );
133
- }
134
- }
135
- async query({
136
- indexName,
137
- queryVector,
138
- topK = 10,
139
- filter,
140
- includeVector = false
141
- }) {
142
- if (!queryVector) {
143
- throw new MastraError({
144
- id: createVectorErrorId("VECTORIZE", "QUERY", "MISSING_VECTOR"),
145
- text: "queryVector is required for Vectorize queries. Metadata-only queries are not supported by this vector store.",
146
- domain: ErrorDomain.STORAGE,
147
- category: ErrorCategory.USER,
148
- details: { indexName }
149
- });
150
- }
151
- try {
152
- const translatedFilter = this.transformFilter(filter) ?? {};
153
- const response = await this.client.vectorize.indexes.query(indexName, {
154
- account_id: this.accountId,
155
- vector: queryVector,
156
- returnValues: includeVector,
157
- returnMetadata: "all",
158
- topK,
159
- filter: translatedFilter
160
- });
161
- return response?.matches?.map((match) => {
162
- return {
163
- id: match.id,
164
- metadata: match.metadata,
165
- score: match.score,
166
- vector: match.values
167
- };
168
- }) || [];
169
- } catch (error) {
170
- throw new MastraError(
171
- {
172
- id: createVectorErrorId("VECTORIZE", "QUERY", "FAILED"),
173
- domain: ErrorDomain.STORAGE,
174
- category: ErrorCategory.THIRD_PARTY,
175
- details: { indexName, topK }
176
- },
177
- error
178
- );
179
- }
180
- }
181
- async listIndexes() {
182
- try {
183
- const res = await this.client.vectorize.indexes.list({
184
- account_id: this.accountId
185
- });
186
- return res?.result?.map((index) => index.name) || [];
187
- } catch (error) {
188
- throw new MastraError(
189
- {
190
- id: createVectorErrorId("VECTORIZE", "LIST_INDEXES", "FAILED"),
191
- domain: ErrorDomain.STORAGE,
192
- category: ErrorCategory.THIRD_PARTY
193
- },
194
- error
195
- );
196
- }
197
- }
198
- /**
199
- * Retrieves statistics about a vector index.
200
- *
201
- * @param {string} indexName - The name of the index to describe
202
- * @returns A promise that resolves to the index statistics including dimension, count and metric
203
- */
204
- async describeIndex({ indexName }) {
205
- try {
206
- const index = await this.client.vectorize.indexes.get(indexName, {
207
- account_id: this.accountId
208
- });
209
- const described = await this.client.vectorize.indexes.info(indexName, {
210
- account_id: this.accountId
211
- });
212
- return {
213
- dimension: described?.dimensions,
214
- // Since vector_count is not available in the response,
215
- // we might need a separate API call to get the count if needed
216
- count: described?.vectorCount || 0,
217
- metric: index?.config?.metric
218
- };
219
- } catch (error) {
220
- throw new MastraError(
221
- {
222
- id: createVectorErrorId("VECTORIZE", "DESCRIBE_INDEX", "FAILED"),
223
- domain: ErrorDomain.STORAGE,
224
- category: ErrorCategory.THIRD_PARTY,
225
- details: { indexName }
226
- },
227
- error
228
- );
229
- }
230
- }
231
- async deleteIndex({ indexName }) {
232
- try {
233
- await this.client.vectorize.indexes.delete(indexName, {
234
- account_id: this.accountId
235
- });
236
- } catch (error) {
237
- throw new MastraError(
238
- {
239
- id: createVectorErrorId("VECTORIZE", "DELETE_INDEX", "FAILED"),
240
- domain: ErrorDomain.STORAGE,
241
- category: ErrorCategory.THIRD_PARTY,
242
- details: { indexName }
243
- },
244
- error
245
- );
246
- }
247
- }
248
- async createMetadataIndex(indexName, propertyName, indexType) {
249
- try {
250
- await this.client.vectorize.indexes.metadataIndex.create(indexName, {
251
- account_id: this.accountId,
252
- propertyName,
253
- indexType
254
- });
255
- } catch (error) {
256
- throw new MastraError(
257
- {
258
- id: createVectorErrorId("VECTORIZE", "CREATE_METADATA_INDEX", "FAILED"),
259
- domain: ErrorDomain.STORAGE,
260
- category: ErrorCategory.THIRD_PARTY,
261
- details: { indexName, propertyName, indexType }
262
- },
263
- error
264
- );
265
- }
266
- }
267
- async deleteMetadataIndex(indexName, propertyName) {
268
- try {
269
- await this.client.vectorize.indexes.metadataIndex.delete(indexName, {
270
- account_id: this.accountId,
271
- propertyName
272
- });
273
- } catch (error) {
274
- throw new MastraError(
275
- {
276
- id: createVectorErrorId("VECTORIZE", "DELETE_METADATA_INDEX", "FAILED"),
277
- domain: ErrorDomain.STORAGE,
278
- category: ErrorCategory.THIRD_PARTY,
279
- details: { indexName, propertyName }
280
- },
281
- error
282
- );
283
- }
284
- }
285
- async listMetadataIndexes(indexName) {
286
- try {
287
- const res = await this.client.vectorize.indexes.metadataIndex.list(indexName, {
288
- account_id: this.accountId
289
- });
290
- return res?.metadataIndexes ?? [];
291
- } catch (error) {
292
- throw new MastraError(
293
- {
294
- id: createVectorErrorId("VECTORIZE", "LIST_METADATA_INDEXES", "FAILED"),
295
- domain: ErrorDomain.STORAGE,
296
- category: ErrorCategory.THIRD_PARTY,
297
- details: { indexName }
298
- },
299
- error
300
- );
301
- }
302
- }
303
- /**
304
- * Updates a vector by its ID with the provided vector and/or metadata.
305
- * @param indexName - The name of the index containing the vector.
306
- * @param id - The ID of the vector to update.
307
- * @param update - An object containing the vector and/or metadata to update.
308
- * @param update.vector - An optional array of numbers representing the new vector.
309
- * @param update.metadata - An optional record containing the new metadata.
310
- * @returns A promise that resolves when the update is complete.
311
- * @throws Will throw an error if no updates are provided or if the update operation fails.
312
- */
313
- async updateVector({ indexName, id, update }) {
314
- if (!id) {
315
- throw new MastraError({
316
- id: createVectorErrorId("VECTORIZE", "UPDATE_VECTOR", "INVALID_ARGS"),
317
- domain: ErrorDomain.STORAGE,
318
- category: ErrorCategory.USER,
319
- text: "id is required for Vectorize updateVector",
320
- details: { indexName }
321
- });
322
- }
323
- if (!update.vector && !update.metadata) {
324
- throw new MastraError({
325
- id: createVectorErrorId("VECTORIZE", "UPDATE_VECTOR", "NO_PAYLOAD"),
326
- domain: ErrorDomain.STORAGE,
327
- category: ErrorCategory.USER,
328
- text: "No update data provided",
329
- details: { indexName, id }
330
- });
331
- }
332
- try {
333
- const updatePayload = {
334
- };
335
- if (update.vector) {
336
- updatePayload.vectors = [update.vector];
337
- }
338
- if (update.metadata) {
339
- updatePayload.metadata = [update.metadata];
340
- }
341
- await this.upsert({ indexName, vectors: updatePayload.vectors, metadata: updatePayload.metadata });
342
- } catch (error) {
343
- throw new MastraError(
344
- {
345
- id: createVectorErrorId("VECTORIZE", "UPDATE_VECTOR", "FAILED"),
346
- domain: ErrorDomain.STORAGE,
347
- category: ErrorCategory.THIRD_PARTY,
348
- details: {
349
- indexName,
350
- ...id && { id }
351
- }
352
- },
353
- error
354
- );
355
- }
356
- }
357
- /**
358
- * Deletes a vector by its ID.
359
- * @param indexName - The name of the index containing the vector.
360
- * @param id - The ID of the vector to delete.
361
- * @returns A promise that resolves when the deletion is complete.
362
- * @throws Will throw an error if the deletion operation fails.
363
- */
364
- async deleteVector({ indexName, id }) {
365
- try {
366
- await this.client.vectorize.indexes.deleteByIds(indexName, {
367
- ids: [id],
368
- account_id: this.accountId
369
- });
370
- } catch (error) {
371
- throw new MastraError(
372
- {
373
- id: createVectorErrorId("VECTORIZE", "DELETE_VECTOR", "FAILED"),
374
- domain: ErrorDomain.STORAGE,
375
- category: ErrorCategory.THIRD_PARTY,
376
- details: {
377
- indexName,
378
- ...id && { id }
379
- }
380
- },
381
- error
382
- );
383
- }
384
- }
385
- async deleteVectors({ indexName, filter, ids }) {
386
- throw new MastraError({
387
- id: createVectorErrorId("VECTORIZE", "DELETE_VECTORS", "NOT_SUPPORTED"),
388
- text: "deleteVectors is not yet implemented for Vectorize vector store",
389
- domain: ErrorDomain.STORAGE,
390
- category: ErrorCategory.SYSTEM,
391
- details: {
392
- indexName,
393
- ...filter && { filter: JSON.stringify(filter) },
394
- ...ids && { idsCount: ids.length }
395
- }
396
- });
397
- }
55
+ client;
56
+ accountId;
57
+ constructor({ accountId, apiToken, id }) {
58
+ super({ id });
59
+ this.accountId = accountId;
60
+ this.client = new Cloudflare({ apiToken });
61
+ }
62
+ get indexSeparator() {
63
+ return "-";
64
+ }
65
+ async upsert({ indexName, vectors, metadata, ids }) {
66
+ const generatedIds = ids || vectors.map(() => crypto.randomUUID());
67
+ const ndjson = vectors.map((vector, index) => JSON.stringify({
68
+ id: generatedIds[index],
69
+ values: vector,
70
+ metadata: metadata?.[index]
71
+ })).join("\n");
72
+ try {
73
+ const body = new File([ndjson], `${indexName}.ndjson`, { type: "application/x-ndjson" });
74
+ await this.client.vectorize.indexes.upsert(indexName, {
75
+ account_id: this.accountId,
76
+ body
77
+ });
78
+ return generatedIds;
79
+ } catch (error) {
80
+ throw new MastraError({
81
+ id: createVectorErrorId("VECTORIZE", "UPSERT", "FAILED"),
82
+ domain: ErrorDomain.STORAGE,
83
+ category: ErrorCategory.THIRD_PARTY,
84
+ details: {
85
+ indexName,
86
+ vectorCount: vectors?.length
87
+ }
88
+ }, error);
89
+ }
90
+ }
91
+ transformFilter(filter) {
92
+ return new VectorizeFilterTranslator().translate(filter);
93
+ }
94
+ async createIndex({ indexName, dimension, metric = "cosine" }) {
95
+ try {
96
+ await this.client.vectorize.indexes.create({
97
+ account_id: this.accountId,
98
+ config: {
99
+ dimensions: dimension,
100
+ metric: metric === "dotproduct" ? "dot-product" : metric
101
+ },
102
+ name: indexName
103
+ });
104
+ } catch (error) {
105
+ const message = error?.errors?.[0]?.message || error?.message;
106
+ if (error.status === 409 || typeof message === "string" && (message.toLowerCase().includes("already exists") || message.toLowerCase().includes("duplicate"))) {
107
+ await this.validateExistingIndex(indexName, dimension, metric);
108
+ return;
109
+ }
110
+ throw new MastraError({
111
+ id: createVectorErrorId("VECTORIZE", "CREATE_INDEX", "FAILED"),
112
+ domain: ErrorDomain.STORAGE,
113
+ category: ErrorCategory.THIRD_PARTY,
114
+ details: {
115
+ indexName,
116
+ dimension,
117
+ metric
118
+ }
119
+ }, error);
120
+ }
121
+ }
122
+ async query({ indexName, queryVector, topK = 10, filter, includeVector = false }) {
123
+ if (!queryVector) throw new MastraError({
124
+ id: createVectorErrorId("VECTORIZE", "QUERY", "MISSING_VECTOR"),
125
+ text: "queryVector is required for Vectorize queries. Metadata-only queries are not supported by this vector store.",
126
+ domain: ErrorDomain.STORAGE,
127
+ category: ErrorCategory.USER,
128
+ details: { indexName }
129
+ });
130
+ try {
131
+ const translatedFilter = this.transformFilter(filter) ?? {};
132
+ return (await this.client.vectorize.indexes.query(indexName, {
133
+ account_id: this.accountId,
134
+ vector: queryVector,
135
+ returnValues: includeVector,
136
+ returnMetadata: "all",
137
+ topK,
138
+ filter: translatedFilter
139
+ }))?.matches?.map((match) => {
140
+ return {
141
+ id: match.id,
142
+ metadata: match.metadata,
143
+ score: match.score,
144
+ vector: match.values
145
+ };
146
+ }) || [];
147
+ } catch (error) {
148
+ throw new MastraError({
149
+ id: createVectorErrorId("VECTORIZE", "QUERY", "FAILED"),
150
+ domain: ErrorDomain.STORAGE,
151
+ category: ErrorCategory.THIRD_PARTY,
152
+ details: {
153
+ indexName,
154
+ topK
155
+ }
156
+ }, error);
157
+ }
158
+ }
159
+ async listIndexes() {
160
+ try {
161
+ return (await this.client.vectorize.indexes.list({ account_id: this.accountId }))?.result?.map((index) => index.name) || [];
162
+ } catch (error) {
163
+ throw new MastraError({
164
+ id: createVectorErrorId("VECTORIZE", "LIST_INDEXES", "FAILED"),
165
+ domain: ErrorDomain.STORAGE,
166
+ category: ErrorCategory.THIRD_PARTY
167
+ }, error);
168
+ }
169
+ }
170
+ /**
171
+ * Retrieves statistics about a vector index.
172
+ *
173
+ * @param {string} indexName - The name of the index to describe
174
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
175
+ */
176
+ async describeIndex({ indexName }) {
177
+ try {
178
+ const index = await this.client.vectorize.indexes.get(indexName, { account_id: this.accountId });
179
+ const described = await this.client.vectorize.indexes.info(indexName, { account_id: this.accountId });
180
+ return {
181
+ dimension: described?.dimensions,
182
+ count: described?.vectorCount || 0,
183
+ metric: index?.config?.metric
184
+ };
185
+ } catch (error) {
186
+ throw new MastraError({
187
+ id: createVectorErrorId("VECTORIZE", "DESCRIBE_INDEX", "FAILED"),
188
+ domain: ErrorDomain.STORAGE,
189
+ category: ErrorCategory.THIRD_PARTY,
190
+ details: { indexName }
191
+ }, error);
192
+ }
193
+ }
194
+ async deleteIndex({ indexName }) {
195
+ try {
196
+ await this.client.vectorize.indexes.delete(indexName, { account_id: this.accountId });
197
+ } catch (error) {
198
+ throw new MastraError({
199
+ id: createVectorErrorId("VECTORIZE", "DELETE_INDEX", "FAILED"),
200
+ domain: ErrorDomain.STORAGE,
201
+ category: ErrorCategory.THIRD_PARTY,
202
+ details: { indexName }
203
+ }, error);
204
+ }
205
+ }
206
+ async createMetadataIndex(indexName, propertyName, indexType) {
207
+ try {
208
+ await this.client.vectorize.indexes.metadataIndex.create(indexName, {
209
+ account_id: this.accountId,
210
+ propertyName,
211
+ indexType
212
+ });
213
+ } catch (error) {
214
+ throw new MastraError({
215
+ id: createVectorErrorId("VECTORIZE", "CREATE_METADATA_INDEX", "FAILED"),
216
+ domain: ErrorDomain.STORAGE,
217
+ category: ErrorCategory.THIRD_PARTY,
218
+ details: {
219
+ indexName,
220
+ propertyName,
221
+ indexType
222
+ }
223
+ }, error);
224
+ }
225
+ }
226
+ async deleteMetadataIndex(indexName, propertyName) {
227
+ try {
228
+ await this.client.vectorize.indexes.metadataIndex.delete(indexName, {
229
+ account_id: this.accountId,
230
+ propertyName
231
+ });
232
+ } catch (error) {
233
+ throw new MastraError({
234
+ id: createVectorErrorId("VECTORIZE", "DELETE_METADATA_INDEX", "FAILED"),
235
+ domain: ErrorDomain.STORAGE,
236
+ category: ErrorCategory.THIRD_PARTY,
237
+ details: {
238
+ indexName,
239
+ propertyName
240
+ }
241
+ }, error);
242
+ }
243
+ }
244
+ async listMetadataIndexes(indexName) {
245
+ try {
246
+ return (await this.client.vectorize.indexes.metadataIndex.list(indexName, { account_id: this.accountId }))?.metadataIndexes ?? [];
247
+ } catch (error) {
248
+ throw new MastraError({
249
+ id: createVectorErrorId("VECTORIZE", "LIST_METADATA_INDEXES", "FAILED"),
250
+ domain: ErrorDomain.STORAGE,
251
+ category: ErrorCategory.THIRD_PARTY,
252
+ details: { indexName }
253
+ }, error);
254
+ }
255
+ }
256
+ /**
257
+ * Updates a vector by its ID with the provided vector and/or metadata.
258
+ * @param indexName - The name of the index containing the vector.
259
+ * @param id - The ID of the vector to update.
260
+ * @param update - An object containing the vector and/or metadata to update.
261
+ * @param update.vector - An optional array of numbers representing the new vector.
262
+ * @param update.metadata - An optional record containing the new metadata.
263
+ * @returns A promise that resolves when the update is complete.
264
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
265
+ */
266
+ async updateVector({ indexName, id, update }) {
267
+ if (!id) throw new MastraError({
268
+ id: createVectorErrorId("VECTORIZE", "UPDATE_VECTOR", "INVALID_ARGS"),
269
+ domain: ErrorDomain.STORAGE,
270
+ category: ErrorCategory.USER,
271
+ text: "id is required for Vectorize updateVector",
272
+ details: { indexName }
273
+ });
274
+ if (!update.vector && !update.metadata) throw new MastraError({
275
+ id: createVectorErrorId("VECTORIZE", "UPDATE_VECTOR", "NO_PAYLOAD"),
276
+ domain: ErrorDomain.STORAGE,
277
+ category: ErrorCategory.USER,
278
+ text: "No update data provided",
279
+ details: {
280
+ indexName,
281
+ id
282
+ }
283
+ });
284
+ if (!update.vector) throw new MastraError({
285
+ id: createVectorErrorId("VECTORIZE", "UPDATE_VECTOR", "MISSING_VECTOR"),
286
+ domain: ErrorDomain.STORAGE,
287
+ category: ErrorCategory.USER,
288
+ text: "Vectorize requires vector values when updating; metadata-only updates are not supported. Provide update.vector alongside update.metadata.",
289
+ details: {
290
+ indexName,
291
+ id
292
+ }
293
+ });
294
+ try {
295
+ await this.upsert({
296
+ indexName,
297
+ ids: [id],
298
+ vectors: [update.vector],
299
+ ...update.metadata && { metadata: [update.metadata] }
300
+ });
301
+ } catch (error) {
302
+ throw new MastraError({
303
+ id: createVectorErrorId("VECTORIZE", "UPDATE_VECTOR", "FAILED"),
304
+ domain: ErrorDomain.STORAGE,
305
+ category: ErrorCategory.THIRD_PARTY,
306
+ details: {
307
+ indexName,
308
+ ...id && { id }
309
+ }
310
+ }, error);
311
+ }
312
+ }
313
+ /**
314
+ * Deletes a vector by its ID.
315
+ * @param indexName - The name of the index containing the vector.
316
+ * @param id - The ID of the vector to delete.
317
+ * @returns A promise that resolves when the deletion is complete.
318
+ * @throws Will throw an error if the deletion operation fails.
319
+ */
320
+ async deleteVector({ indexName, id }) {
321
+ try {
322
+ await this.client.vectorize.indexes.deleteByIds(indexName, {
323
+ ids: [id],
324
+ account_id: this.accountId
325
+ });
326
+ } catch (error) {
327
+ throw new MastraError({
328
+ id: createVectorErrorId("VECTORIZE", "DELETE_VECTOR", "FAILED"),
329
+ domain: ErrorDomain.STORAGE,
330
+ category: ErrorCategory.THIRD_PARTY,
331
+ details: {
332
+ indexName,
333
+ ...id && { id }
334
+ }
335
+ }, error);
336
+ }
337
+ }
338
+ /**
339
+ * Deletes multiple vectors by their IDs.
340
+ *
341
+ * Vectorize has no filtered-delete primitive, so metadata-filter deletion is rejected.
342
+ *
343
+ * @param indexName - The name of the index containing the vectors.
344
+ * @param ids - The IDs of the vectors to delete. Mutually exclusive with `filter`.
345
+ * @throws Will throw an error if the arguments are invalid or the deletion operation fails.
346
+ */
347
+ async deleteVectors({ indexName, filter, ids }) {
348
+ if (ids && filter) throw new MastraError({
349
+ id: createVectorErrorId("VECTORIZE", "DELETE_VECTORS", "MUTUALLY_EXCLUSIVE"),
350
+ text: "Cannot specify both ids and filter - they are mutually exclusive",
351
+ domain: ErrorDomain.STORAGE,
352
+ category: ErrorCategory.USER,
353
+ details: { indexName }
354
+ });
355
+ if (filter) throw new MastraError({
356
+ id: createVectorErrorId("VECTORIZE", "DELETE_VECTORS", "UNSUPPORTED_FILTER"),
357
+ text: "Deleting by metadata filter is not supported for Vectorize vector store - delete by ids instead",
358
+ domain: ErrorDomain.STORAGE,
359
+ category: ErrorCategory.SYSTEM,
360
+ details: {
361
+ indexName,
362
+ filter: JSON.stringify(filter)
363
+ }
364
+ });
365
+ if (!ids) throw new MastraError({
366
+ id: createVectorErrorId("VECTORIZE", "DELETE_VECTORS", "NO_TARGET"),
367
+ text: "Either filter or ids must be provided",
368
+ domain: ErrorDomain.STORAGE,
369
+ category: ErrorCategory.USER,
370
+ details: { indexName }
371
+ });
372
+ if (ids.length === 0) throw new MastraError({
373
+ id: createVectorErrorId("VECTORIZE", "DELETE_VECTORS", "EMPTY_IDS"),
374
+ text: "Cannot delete with empty ids array",
375
+ domain: ErrorDomain.STORAGE,
376
+ category: ErrorCategory.USER,
377
+ details: { indexName }
378
+ });
379
+ try {
380
+ await this.client.vectorize.indexes.deleteByIds(indexName, {
381
+ ids,
382
+ account_id: this.accountId
383
+ });
384
+ } catch (error) {
385
+ throw new MastraError({
386
+ id: createVectorErrorId("VECTORIZE", "DELETE_VECTORS", "FAILED"),
387
+ domain: ErrorDomain.STORAGE,
388
+ category: ErrorCategory.THIRD_PARTY,
389
+ details: {
390
+ indexName,
391
+ idsCount: ids.length
392
+ }
393
+ }, error);
394
+ }
395
+ }
398
396
  };
399
-
400
- // src/vector/prompt.ts
401
- var VECTORIZE_PROMPT = `When querying Vectorize, you can ONLY use the operators listed below. Any other operators will be rejected.
397
+ //#endregion
398
+ //#region src/vector/prompt.ts
399
+ /**
400
+ * Vector store specific prompt that details supported operators and examples.
401
+ * This prompt helps users construct valid filters for Vectorize.
402
+ */
403
+ const VECTORIZE_PROMPT = `When querying Vectorize, you can ONLY use the operators listed below. Any other operators will be rejected.
402
404
  Important: Don't explain how to construct the filter - use the specified operators and fields to search the content and return relevant results.
403
405
  If a user tries to give an explicit operator that is not supported, reject the filter entirely and let them know that the operator is not supported.
404
406
 
@@ -474,7 +476,7 @@ Example Complex Query:
474
476
  ]}
475
477
  ]
476
478
  }`;
477
-
479
+ //#endregion
478
480
  export { CloudflareVector, VECTORIZE_PROMPT };
479
- //# sourceMappingURL=index.js.map
481
+
480
482
  //# sourceMappingURL=index.js.map