@mastra/chroma 1.1.1 → 1.1.2

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.cjs CHANGED
@@ -1,636 +1,518 @@
1
- 'use strict';
2
-
3
- var error = require('@mastra/core/error');
4
- var storage = require('@mastra/core/storage');
5
- var vector = require('@mastra/core/vector');
6
- var chromadb = require('chromadb');
7
- var filter = require('@mastra/core/vector/filter');
8
-
9
- // src/vector/index.ts
10
-
11
- // src/vector/distance-to-score.ts
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _mastra_core_error = require("@mastra/core/error");
3
+ let _mastra_core_storage = require("@mastra/core/storage");
4
+ let _mastra_core_vector = require("@mastra/core/vector");
5
+ let chromadb = require("chromadb");
6
+ let _mastra_core_vector_filter = require("@mastra/core/vector/filter");
7
+ //#region src/vector/distance-to-score.ts
12
8
  function distanceToScore(distance, metric) {
13
- switch (metric) {
14
- case "euclidean":
15
- return 1 / (1 + Math.sqrt(distance));
16
- case "dotproduct":
17
- case "cosine":
18
- default:
19
- return 1 - distance;
20
- }
9
+ switch (metric) {
10
+ case "euclidean": return 1 / (1 + Math.sqrt(distance));
11
+ default: return 1 - distance;
12
+ }
21
13
  }
22
- var ChromaFilterTranslator = class extends filter.BaseFilterTranslator {
23
- getSupportedOperators() {
24
- return {
25
- ...filter.BaseFilterTranslator.DEFAULT_OPERATORS,
26
- logical: ["$and", "$or"],
27
- array: ["$in", "$nin"],
28
- element: [],
29
- regex: [],
30
- custom: []
31
- };
32
- }
33
- translate(filter) {
34
- if (this.isEmpty(filter)) return filter;
35
- this.validateFilter(filter);
36
- return this.translateNode(filter);
37
- }
38
- translateNode(node, currentPath = "") {
39
- if (this.isRegex(node)) {
40
- throw new Error("Regex is supported in Chroma via the `documentFilter` argument");
41
- }
42
- if (this.isPrimitive(node)) return this.normalizeComparisonValue(node);
43
- if (Array.isArray(node)) return { $in: this.normalizeArrayValues(node) };
44
- const entries = Object.entries(node);
45
- const firstEntry = entries[0];
46
- if (entries.length === 1 && firstEntry && this.isOperator(firstEntry[0])) {
47
- const [operator, value] = firstEntry;
48
- const translated = this.translateOperator(operator, value);
49
- if (this.isLogicalOperator(operator) && Array.isArray(translated) && translated.length === 1) {
50
- return translated[0];
51
- }
52
- return this.isLogicalOperator(operator) ? { [operator]: translated } : translated;
53
- }
54
- const result = {};
55
- const multiOperatorConditions = [];
56
- for (const [key, value] of entries) {
57
- const newPath = currentPath ? `${currentPath}.${key}` : key;
58
- if (this.isOperator(key)) {
59
- result[key] = this.translateOperator(key, value);
60
- continue;
61
- }
62
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
63
- const valueEntries = Object.entries(value);
64
- if (valueEntries.every(([op]) => this.isOperator(op)) && valueEntries.length > 1) {
65
- valueEntries.forEach(([op, opValue]) => {
66
- multiOperatorConditions.push({
67
- [newPath]: { [op]: this.normalizeComparisonValue(opValue) }
68
- });
69
- });
70
- continue;
71
- }
72
- if (Object.keys(value).length === 0) {
73
- result[newPath] = this.translateNode(value);
74
- } else {
75
- const hasOperators = Object.keys(value).some((k) => this.isOperator(k));
76
- if (hasOperators) {
77
- const normalizedValue = {};
78
- for (const [op, opValue] of Object.entries(value)) {
79
- normalizedValue[op] = this.isOperator(op) ? this.translateOperator(op, opValue) : opValue;
80
- }
81
- result[newPath] = normalizedValue;
82
- } else {
83
- Object.assign(result, this.translateNode(value, newPath));
84
- }
85
- }
86
- } else {
87
- result[newPath] = this.translateNode(value);
88
- }
89
- }
90
- if (multiOperatorConditions.length > 0) {
91
- const resultConditions = Object.entries(result).map(([key, value]) => ({ [key]: value }));
92
- const allConditions = [...multiOperatorConditions, ...resultConditions];
93
- if (allConditions.length === 1) {
94
- return allConditions[0];
95
- }
96
- return { $and: allConditions };
97
- }
98
- if (Object.keys(result).length > 1 && !currentPath) {
99
- return {
100
- $and: Object.entries(result).map(([key, value]) => ({ [key]: value }))
101
- };
102
- }
103
- return result;
104
- }
105
- translateOperator(operator, value) {
106
- if (this.isLogicalOperator(operator)) {
107
- return Array.isArray(value) ? value.map((item) => this.translateNode(item)) : this.translateNode(value);
108
- }
109
- return this.normalizeComparisonValue(value);
110
- }
14
+ //#endregion
15
+ //#region src/vector/filter.ts
16
+ /**
17
+ * Translator for Chroma filter queries.
18
+ * Maintains MongoDB-compatible syntax while ensuring proper validation
19
+ * and normalization of values.
20
+ */
21
+ var ChromaFilterTranslator = class extends _mastra_core_vector_filter.BaseFilterTranslator {
22
+ getSupportedOperators() {
23
+ return {
24
+ ..._mastra_core_vector_filter.BaseFilterTranslator.DEFAULT_OPERATORS,
25
+ logical: ["$and", "$or"],
26
+ array: ["$in", "$nin"],
27
+ element: [],
28
+ regex: [],
29
+ custom: []
30
+ };
31
+ }
32
+ translate(filter) {
33
+ if (this.isEmpty(filter)) return filter;
34
+ this.validateFilter(filter);
35
+ return this.translateNode(filter);
36
+ }
37
+ translateNode(node, currentPath = "") {
38
+ if (this.isRegex(node)) throw new Error("Regex is supported in Chroma via the `documentFilter` argument");
39
+ if (this.isPrimitive(node)) return this.normalizeComparisonValue(node);
40
+ if (Array.isArray(node)) return { $in: this.normalizeArrayValues(node) };
41
+ const entries = Object.entries(node);
42
+ const firstEntry = entries[0];
43
+ if (entries.length === 1 && firstEntry && this.isOperator(firstEntry[0])) {
44
+ const [operator, value] = firstEntry;
45
+ const translated = this.translateOperator(operator, value);
46
+ if (this.isLogicalOperator(operator) && Array.isArray(translated) && translated.length === 1) return translated[0];
47
+ return this.isLogicalOperator(operator) ? { [operator]: translated } : translated;
48
+ }
49
+ const result = {};
50
+ const multiOperatorConditions = [];
51
+ for (const [key, value] of entries) {
52
+ const newPath = currentPath ? `${currentPath}.${key}` : key;
53
+ if (this.isOperator(key)) {
54
+ result[key] = this.translateOperator(key, value);
55
+ continue;
56
+ }
57
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
58
+ const valueEntries = Object.entries(value);
59
+ if (valueEntries.every(([op]) => this.isOperator(op)) && valueEntries.length > 1) {
60
+ valueEntries.forEach(([op, opValue]) => {
61
+ multiOperatorConditions.push({ [newPath]: { [op]: this.normalizeComparisonValue(opValue) } });
62
+ });
63
+ continue;
64
+ }
65
+ if (Object.keys(value).length === 0) result[newPath] = this.translateNode(value);
66
+ else if (Object.keys(value).some((k) => this.isOperator(k))) {
67
+ const normalizedValue = {};
68
+ for (const [op, opValue] of Object.entries(value)) normalizedValue[op] = this.isOperator(op) ? this.translateOperator(op, opValue) : opValue;
69
+ result[newPath] = normalizedValue;
70
+ } else Object.assign(result, this.translateNode(value, newPath));
71
+ } else result[newPath] = this.translateNode(value);
72
+ }
73
+ if (multiOperatorConditions.length > 0) {
74
+ const resultConditions = Object.entries(result).map(([key, value]) => ({ [key]: value }));
75
+ const allConditions = [...multiOperatorConditions, ...resultConditions];
76
+ if (allConditions.length === 1) return allConditions[0];
77
+ return { $and: allConditions };
78
+ }
79
+ if (Object.keys(result).length > 1 && !currentPath) return { $and: Object.entries(result).map(([key, value]) => ({ [key]: value })) };
80
+ return result;
81
+ }
82
+ translateOperator(operator, value) {
83
+ if (this.isLogicalOperator(operator)) return Array.isArray(value) ? value.map((item) => this.translateNode(item)) : this.translateNode(value);
84
+ return this.normalizeComparisonValue(value);
85
+ }
111
86
  };
112
-
113
- // src/vector/index.ts
114
- var spaceMappings = {
115
- cosine: "cosine",
116
- euclidean: "l2",
117
- dotproduct: "ip",
118
- l2: "euclidean",
119
- ip: "dotproduct"
87
+ //#endregion
88
+ //#region src/vector/index.ts
89
+ const spaceMappings = {
90
+ cosine: "cosine",
91
+ euclidean: "l2",
92
+ dotproduct: "ip",
93
+ l2: "euclidean",
94
+ ip: "dotproduct"
120
95
  };
121
- var ChromaVector = class extends vector.MastraVector {
122
- client;
123
- collections;
124
- constructor({ id, ...chromaClientArgs }) {
125
- super({ id });
126
- if (chromaClientArgs?.apiKey) {
127
- this.client = new chromadb.CloudClient({
128
- apiKey: chromaClientArgs.apiKey,
129
- tenant: chromaClientArgs.tenant,
130
- database: chromaClientArgs.database
131
- });
132
- } else {
133
- this.client = new chromadb.ChromaClient(chromaClientArgs);
134
- }
135
- this.collections = /* @__PURE__ */ new Map();
136
- }
137
- async getCollection({ indexName, forceUpdate = false }) {
138
- let collection = this.collections.get(indexName);
139
- if (forceUpdate || !collection) {
140
- try {
141
- collection = await this.client.getCollection({ name: indexName });
142
- this.collections.set(indexName, collection);
143
- return collection;
144
- } catch {
145
- throw new error.MastraError({
146
- id: storage.createVectorErrorId("CHROMA", "GET_COLLECTION", "FAILED"),
147
- domain: error.ErrorDomain.MASTRA_VECTOR,
148
- category: error.ErrorCategory.THIRD_PARTY,
149
- details: { indexName }
150
- });
151
- }
152
- }
153
- return collection;
154
- }
155
- validateVectorDimensions(vectors, dimension) {
156
- for (let i = 0; i < vectors.length; i++) {
157
- if (vectors?.[i]?.length !== dimension) {
158
- throw new Error(
159
- `Vector at index ${i} has invalid dimension ${vectors?.[i]?.length}. Expected ${dimension} dimensions.`
160
- );
161
- }
162
- }
163
- }
164
- async upsert({ indexName, vectors, metadata, ids, documents }) {
165
- vector.validateUpsert("CHROMA", vectors, metadata, ids, true);
166
- try {
167
- const collection = await this.getCollection({ indexName });
168
- const stats = await this.describeIndex({ indexName });
169
- this.validateVectorDimensions(vectors, stats.dimension);
170
- const generatedIds = ids || vectors.map(() => crypto.randomUUID());
171
- await collection.upsert({
172
- ids: generatedIds,
173
- embeddings: vectors,
174
- metadatas: metadata,
175
- documents
176
- });
177
- return generatedIds;
178
- } catch (error$1) {
179
- if (error$1 instanceof error.MastraError) throw error$1;
180
- throw new error.MastraError(
181
- {
182
- id: storage.createVectorErrorId("CHROMA", "UPSERT", "FAILED"),
183
- domain: error.ErrorDomain.MASTRA_VECTOR,
184
- category: error.ErrorCategory.THIRD_PARTY,
185
- details: { indexName }
186
- },
187
- error$1
188
- );
189
- }
190
- }
191
- async createIndex({ indexName, dimension, metric = "cosine" }) {
192
- if (!Number.isInteger(dimension) || dimension <= 0) {
193
- throw new error.MastraError({
194
- id: storage.createVectorErrorId("CHROMA", "CREATE_INDEX", "INVALID_DIMENSION"),
195
- text: "Dimension must be a positive integer",
196
- domain: error.ErrorDomain.MASTRA_VECTOR,
197
- category: error.ErrorCategory.USER,
198
- details: { dimension }
199
- });
200
- }
201
- const hnswSpace = spaceMappings[metric];
202
- if (!hnswSpace || !["cosine", "l2", "ip"].includes(hnswSpace)) {
203
- throw new error.MastraError({
204
- id: storage.createVectorErrorId("CHROMA", "CREATE_INDEX", "INVALID_METRIC"),
205
- text: `Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`,
206
- domain: error.ErrorDomain.MASTRA_VECTOR,
207
- category: error.ErrorCategory.USER,
208
- details: { metric }
209
- });
210
- }
211
- try {
212
- const collection = await this.client.createCollection({
213
- name: indexName,
214
- metadata: { dimension },
215
- configuration: { hnsw: { space: hnswSpace } },
216
- embeddingFunction: null
217
- });
218
- this.collections.set(indexName, collection);
219
- } catch (error$1) {
220
- const message = error$1?.message || error$1?.toString();
221
- if (message && message.toLowerCase().includes("already exists")) {
222
- await this.validateExistingIndex(indexName, dimension, metric);
223
- return;
224
- }
225
- throw new error.MastraError(
226
- {
227
- id: storage.createVectorErrorId("CHROMA", "CREATE_INDEX", "FAILED"),
228
- domain: error.ErrorDomain.MASTRA_VECTOR,
229
- category: error.ErrorCategory.THIRD_PARTY,
230
- details: { indexName }
231
- },
232
- error$1
233
- );
234
- }
235
- }
236
- transformFilter(filter) {
237
- const translator = new ChromaFilterTranslator();
238
- const translatedFilter = translator.translate(filter);
239
- return translatedFilter ? translatedFilter : void 0;
240
- }
241
- async query({
242
- indexName,
243
- queryVector,
244
- topK = 10,
245
- filter,
246
- includeVector = false,
247
- documentFilter
248
- }) {
249
- if (!queryVector) {
250
- throw new error.MastraError({
251
- id: storage.createVectorErrorId("CHROMA", "QUERY", "MISSING_VECTOR"),
252
- text: "queryVector is required for Chroma queries. Metadata-only queries are not supported by this vector store.",
253
- domain: error.ErrorDomain.MASTRA_VECTOR,
254
- category: error.ErrorCategory.USER,
255
- details: { indexName }
256
- });
257
- }
258
- vector.validateTopK("CHROMA", topK);
259
- try {
260
- const collection = await this.getCollection({ indexName });
261
- const defaultInclude = ["documents", "metadatas", "distances"];
262
- const translatedFilter = this.transformFilter(filter);
263
- const results = await collection.query({
264
- queryEmbeddings: [queryVector],
265
- nResults: topK,
266
- where: translatedFilter ?? void 0,
267
- whereDocument: documentFilter ?? void 0,
268
- include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
269
- });
270
- const space = collection.configuration?.hnsw?.space || collection.configuration?.spann?.space || "cosine";
271
- const metric = spaceMappings[space];
272
- return (results.ids[0] || []).map((id, index) => {
273
- const distance = results.distances?.[0]?.[index];
274
- const score = distance == null ? 0 : distanceToScore(distance, metric);
275
- return {
276
- id,
277
- score,
278
- metadata: results.metadatas?.[0]?.[index] || {},
279
- document: results.documents?.[0]?.[index] ?? void 0,
280
- ...includeVector && { vector: results.embeddings?.[0]?.[index] || [] }
281
- };
282
- });
283
- } catch (error$1) {
284
- if (error$1 instanceof error.MastraError) throw error$1;
285
- throw new error.MastraError(
286
- {
287
- id: storage.createVectorErrorId("CHROMA", "QUERY", "FAILED"),
288
- domain: error.ErrorDomain.MASTRA_VECTOR,
289
- category: error.ErrorCategory.THIRD_PARTY,
290
- details: { indexName }
291
- },
292
- error$1
293
- );
294
- }
295
- }
296
- async hybridSearch({ indexName, search }) {
297
- try {
298
- const collection = await this.getCollection({ indexName });
299
- const results = await collection.search(search);
300
- return (results.rows()[0] ?? []).map((record) => ({
301
- id: record.id,
302
- score: record.score ?? 0,
303
- metadata: record.metadata ?? void 0,
304
- vector: record.embedding ?? void 0,
305
- document: record.document ?? void 0
306
- }));
307
- } catch (error$1) {
308
- if (error$1 instanceof error.MastraError) throw error$1;
309
- throw new error.MastraError(
310
- {
311
- id: storage.createVectorErrorId("CHROMA", "SEARCH_API", "FAILED"),
312
- domain: error.ErrorDomain.MASTRA_VECTOR,
313
- category: error.ErrorCategory.THIRD_PARTY,
314
- details: { indexName }
315
- },
316
- error$1
317
- );
318
- }
319
- }
320
- async get({
321
- indexName,
322
- ids,
323
- filter,
324
- includeVector = false,
325
- documentFilter,
326
- offset,
327
- limit
328
- }) {
329
- try {
330
- const collection = await this.getCollection({ indexName });
331
- const defaultInclude = ["documents", "metadatas"];
332
- const translatedFilter = this.transformFilter(filter);
333
- const result = await collection.get({
334
- ids,
335
- where: translatedFilter ?? void 0,
336
- whereDocument: documentFilter ?? void 0,
337
- offset,
338
- limit,
339
- include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
340
- });
341
- return result.rows();
342
- } catch (error$1) {
343
- if (error$1 instanceof error.MastraError) throw error$1;
344
- throw new error.MastraError(
345
- {
346
- id: storage.createVectorErrorId("CHROMA", "GET", "FAILED"),
347
- domain: error.ErrorDomain.MASTRA_VECTOR,
348
- category: error.ErrorCategory.THIRD_PARTY,
349
- details: { indexName }
350
- },
351
- error$1
352
- );
353
- }
354
- }
355
- async listIndexes() {
356
- try {
357
- const collections = await this.client.listCollections();
358
- return collections.map((collection) => collection.name);
359
- } catch (error$1) {
360
- throw new error.MastraError(
361
- {
362
- id: storage.createVectorErrorId("CHROMA", "LIST_INDEXES", "FAILED"),
363
- domain: error.ErrorDomain.MASTRA_VECTOR,
364
- category: error.ErrorCategory.THIRD_PARTY
365
- },
366
- error$1
367
- );
368
- }
369
- }
370
- /**
371
- * Retrieves statistics about a vector index.
372
- *
373
- * @param {string} indexName - The name of the index to describe
374
- * @returns A promise that resolves to the index statistics including dimension, count and metric
375
- */
376
- async describeIndex({ indexName }) {
377
- try {
378
- const collection = await this.getCollection({ indexName });
379
- const count = await collection.count();
380
- const metadata = collection.metadata;
381
- const space = collection.configuration.hnsw?.space || collection.configuration.spann?.space || void 0;
382
- return {
383
- dimension: metadata?.dimension || 0,
384
- count,
385
- metric: space ? spaceMappings[space] : void 0
386
- };
387
- } catch (error$1) {
388
- if (error$1 instanceof error.MastraError) throw error$1;
389
- throw new error.MastraError(
390
- {
391
- id: storage.createVectorErrorId("CHROMA", "DESCRIBE_INDEX", "FAILED"),
392
- domain: error.ErrorDomain.MASTRA_VECTOR,
393
- category: error.ErrorCategory.THIRD_PARTY,
394
- details: { indexName }
395
- },
396
- error$1
397
- );
398
- }
399
- }
400
- async deleteIndex({ indexName }) {
401
- try {
402
- await this.client.deleteCollection({ name: indexName });
403
- this.collections.delete(indexName);
404
- } catch (error$1) {
405
- throw new error.MastraError(
406
- {
407
- id: storage.createVectorErrorId("CHROMA", "DELETE_INDEX", "FAILED"),
408
- domain: error.ErrorDomain.MASTRA_VECTOR,
409
- category: error.ErrorCategory.THIRD_PARTY,
410
- details: { indexName }
411
- },
412
- error$1
413
- );
414
- }
415
- }
416
- async forkIndex({ indexName, newIndexName }) {
417
- try {
418
- const collection = await this.getCollection({ indexName, forceUpdate: true });
419
- const forkedCollection = await collection.fork({ name: newIndexName });
420
- this.collections.set(newIndexName, forkedCollection);
421
- } catch (error$1) {
422
- if (error$1 instanceof error.MastraError) throw error$1;
423
- throw new error.MastraError(
424
- {
425
- id: storage.createVectorErrorId("CHROMA", "FORK_INDEX", "FAILED"),
426
- domain: error.ErrorDomain.MASTRA_VECTOR,
427
- category: error.ErrorCategory.THIRD_PARTY,
428
- details: { indexName }
429
- },
430
- error$1
431
- );
432
- }
433
- }
434
- /**
435
- * Updates a vector by its ID or multiple vectors matching a filter.
436
- * @param indexName - The name of the index containing the vector(s).
437
- * @param id - The ID of the vector to update (mutually exclusive with filter).
438
- * @param filter - Filter to match multiple vectors to update (mutually exclusive with id).
439
- * @param update - An object containing the vector and/or metadata to update.
440
- * @param update.vector - An optional array of numbers representing the new vector.
441
- * @param update.metadata - An optional record containing the new metadata.
442
- * @returns A promise that resolves when the update is complete.
443
- * @throws Will throw an error if no updates are provided or if the update operation fails.
444
- */
445
- async updateVector({ indexName, id, filter, update }) {
446
- if (id && filter) {
447
- throw new error.MastraError({
448
- id: storage.createVectorErrorId("CHROMA", "UPDATE_VECTOR", "MUTUALLY_EXCLUSIVE"),
449
- text: "Cannot specify both id and filter - they are mutually exclusive",
450
- domain: error.ErrorDomain.MASTRA_VECTOR,
451
- category: error.ErrorCategory.USER,
452
- details: { indexName }
453
- });
454
- }
455
- if (!id && !filter) {
456
- throw new error.MastraError({
457
- id: storage.createVectorErrorId("CHROMA", "UPDATE_VECTOR", "NO_TARGET"),
458
- text: "Either id or filter must be provided",
459
- domain: error.ErrorDomain.MASTRA_VECTOR,
460
- category: error.ErrorCategory.USER,
461
- details: { indexName }
462
- });
463
- }
464
- if (!update.vector && !update.metadata) {
465
- throw new error.MastraError({
466
- id: storage.createVectorErrorId("CHROMA", "UPDATE_VECTOR", "NO_PAYLOAD"),
467
- text: "No updates provided",
468
- domain: error.ErrorDomain.MASTRA_VECTOR,
469
- category: error.ErrorCategory.USER,
470
- details: {
471
- indexName,
472
- ...id && { id }
473
- }
474
- });
475
- }
476
- if (filter && Object.keys(filter).length === 0) {
477
- throw new error.MastraError({
478
- id: storage.createVectorErrorId("CHROMA", "UPDATE_VECTOR", "EMPTY_FILTER"),
479
- text: "Filter cannot be an empty filter object",
480
- domain: error.ErrorDomain.MASTRA_VECTOR,
481
- category: error.ErrorCategory.USER,
482
- details: { indexName }
483
- });
484
- }
485
- try {
486
- const collection = await this.getCollection({ indexName });
487
- if (update?.vector) {
488
- const stats = await this.describeIndex({ indexName });
489
- this.validateVectorDimensions([update.vector], stats.dimension);
490
- }
491
- if (id) {
492
- const updateRecordSet = { ids: [id] };
493
- if (update?.vector) {
494
- updateRecordSet.embeddings = [update.vector];
495
- }
496
- if (update?.metadata) {
497
- updateRecordSet.metadatas = [update.metadata];
498
- }
499
- return await collection.update(updateRecordSet);
500
- } else if (filter) {
501
- const translatedFilter = this.transformFilter(filter);
502
- const matchingVectors = await collection.get({
503
- where: translatedFilter ?? void 0,
504
- include: ["embeddings", "metadatas"]
505
- });
506
- const vectorRows = matchingVectors.rows();
507
- if (vectorRows.length === 0) {
508
- return;
509
- }
510
- const updateRecordSet = {
511
- ids: vectorRows.map((row) => row.id)
512
- };
513
- if (update?.vector) {
514
- updateRecordSet.embeddings = vectorRows.map(() => update.vector);
515
- }
516
- if (update?.metadata) {
517
- updateRecordSet.metadatas = vectorRows.map(() => update.metadata);
518
- }
519
- return await collection.update(updateRecordSet);
520
- }
521
- } catch (error$1) {
522
- if (error$1 instanceof error.MastraError) throw error$1;
523
- throw new error.MastraError(
524
- {
525
- id: storage.createVectorErrorId("CHROMA", "UPDATE_VECTOR", "FAILED"),
526
- domain: error.ErrorDomain.MASTRA_VECTOR,
527
- category: error.ErrorCategory.THIRD_PARTY,
528
- details: {
529
- indexName,
530
- ...id && { id },
531
- ...filter && { filter: JSON.stringify(filter) }
532
- }
533
- },
534
- error$1
535
- );
536
- }
537
- }
538
- async deleteVector({ indexName, id }) {
539
- try {
540
- const collection = await this.getCollection({ indexName });
541
- await collection.delete({ ids: [id] });
542
- } catch (error$1) {
543
- if (error$1 instanceof error.MastraError) throw error$1;
544
- throw new error.MastraError(
545
- {
546
- id: storage.createVectorErrorId("CHROMA", "DELETE_VECTOR", "FAILED"),
547
- domain: error.ErrorDomain.MASTRA_VECTOR,
548
- category: error.ErrorCategory.THIRD_PARTY,
549
- details: {
550
- indexName,
551
- ...id && { id }
552
- }
553
- },
554
- error$1
555
- );
556
- }
557
- }
558
- /**
559
- * Deletes multiple vectors by IDs or filter.
560
- * @param indexName - The name of the index containing the vectors.
561
- * @param ids - Array of vector IDs to delete (mutually exclusive with filter).
562
- * @param filter - Filter to match vectors to delete (mutually exclusive with ids).
563
- * @returns A promise that resolves when the deletion is complete.
564
- * @throws Will throw an error if both ids and filter are provided, or if neither is provided.
565
- */
566
- async deleteVectors({ indexName, filter, ids }) {
567
- if (ids && filter) {
568
- throw new error.MastraError({
569
- id: storage.createVectorErrorId("CHROMA", "DELETE_VECTORS", "MUTUALLY_EXCLUSIVE"),
570
- text: "Cannot specify both ids and filter - they are mutually exclusive",
571
- domain: error.ErrorDomain.MASTRA_VECTOR,
572
- category: error.ErrorCategory.USER,
573
- details: { indexName }
574
- });
575
- }
576
- if (!ids && !filter) {
577
- throw new error.MastraError({
578
- id: storage.createVectorErrorId("CHROMA", "DELETE_VECTORS", "NO_TARGET"),
579
- text: "Either filter or ids must be provided",
580
- domain: error.ErrorDomain.MASTRA_VECTOR,
581
- category: error.ErrorCategory.USER,
582
- details: { indexName }
583
- });
584
- }
585
- if (ids && ids.length === 0) {
586
- throw new error.MastraError({
587
- id: storage.createVectorErrorId("CHROMA", "DELETE_VECTORS", "EMPTY_IDS"),
588
- text: "Cannot delete with empty ids array",
589
- domain: error.ErrorDomain.MASTRA_VECTOR,
590
- category: error.ErrorCategory.USER,
591
- details: { indexName }
592
- });
593
- }
594
- if (filter && Object.keys(filter).length === 0) {
595
- throw new error.MastraError({
596
- id: storage.createVectorErrorId("CHROMA", "DELETE_VECTORS", "EMPTY_FILTER"),
597
- text: "Cannot delete with empty filter object",
598
- domain: error.ErrorDomain.MASTRA_VECTOR,
599
- category: error.ErrorCategory.USER,
600
- details: { indexName }
601
- });
602
- }
603
- try {
604
- const collection = await this.getCollection({ indexName });
605
- if (ids) {
606
- await collection.delete({ ids });
607
- } else if (filter) {
608
- const translatedFilter = this.transformFilter(filter);
609
- await collection.delete({
610
- where: translatedFilter ?? void 0
611
- });
612
- }
613
- } catch (error$1) {
614
- if (error$1 instanceof error.MastraError) throw error$1;
615
- throw new error.MastraError(
616
- {
617
- id: storage.createVectorErrorId("CHROMA", "DELETE_VECTORS", "FAILED"),
618
- domain: error.ErrorDomain.MASTRA_VECTOR,
619
- category: error.ErrorCategory.THIRD_PARTY,
620
- details: {
621
- indexName,
622
- ...filter && { filter: JSON.stringify(filter) },
623
- ...ids && { idsCount: ids.length }
624
- }
625
- },
626
- error$1
627
- );
628
- }
629
- }
96
+ var ChromaVector = class extends _mastra_core_vector.MastraVector {
97
+ client;
98
+ collections;
99
+ constructor({ id, ...chromaClientArgs }) {
100
+ super({ id });
101
+ if (chromaClientArgs?.apiKey) this.client = new chromadb.CloudClient({
102
+ apiKey: chromaClientArgs.apiKey,
103
+ tenant: chromaClientArgs.tenant,
104
+ database: chromaClientArgs.database
105
+ });
106
+ else this.client = new chromadb.ChromaClient(chromaClientArgs);
107
+ this.collections = /* @__PURE__ */ new Map();
108
+ }
109
+ async getCollection({ indexName, forceUpdate = false }) {
110
+ let collection = this.collections.get(indexName);
111
+ if (forceUpdate || !collection) try {
112
+ collection = await this.client.getCollection({ name: indexName });
113
+ this.collections.set(indexName, collection);
114
+ return collection;
115
+ } catch {
116
+ throw new _mastra_core_error.MastraError({
117
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "GET_COLLECTION", "FAILED"),
118
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
119
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
120
+ details: { indexName }
121
+ });
122
+ }
123
+ return collection;
124
+ }
125
+ validateVectorDimensions(vectors, dimension) {
126
+ for (let i = 0; i < vectors.length; i++) if (vectors?.[i]?.length !== dimension) throw new Error(`Vector at index ${i} has invalid dimension ${vectors?.[i]?.length}. Expected ${dimension} dimensions.`);
127
+ }
128
+ async upsert({ indexName, vectors, metadata, ids, documents }) {
129
+ (0, _mastra_core_vector.validateUpsert)("CHROMA", vectors, metadata, ids, true);
130
+ try {
131
+ const collection = await this.getCollection({ indexName });
132
+ const stats = await this.describeIndex({ indexName });
133
+ this.validateVectorDimensions(vectors, stats.dimension);
134
+ const generatedIds = ids || vectors.map(() => crypto.randomUUID());
135
+ await collection.upsert({
136
+ ids: generatedIds,
137
+ embeddings: vectors,
138
+ metadatas: metadata,
139
+ documents
140
+ });
141
+ return generatedIds;
142
+ } catch (error) {
143
+ if (error instanceof _mastra_core_error.MastraError) throw error;
144
+ throw new _mastra_core_error.MastraError({
145
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "UPSERT", "FAILED"),
146
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
147
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
148
+ details: { indexName }
149
+ }, error);
150
+ }
151
+ }
152
+ async createIndex({ indexName, dimension, metric = "cosine" }) {
153
+ if (!Number.isInteger(dimension) || dimension <= 0) throw new _mastra_core_error.MastraError({
154
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "CREATE_INDEX", "INVALID_DIMENSION"),
155
+ text: "Dimension must be a positive integer",
156
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
157
+ category: _mastra_core_error.ErrorCategory.USER,
158
+ details: { dimension }
159
+ });
160
+ const hnswSpace = spaceMappings[metric];
161
+ if (!hnswSpace || ![
162
+ "cosine",
163
+ "l2",
164
+ "ip"
165
+ ].includes(hnswSpace)) throw new _mastra_core_error.MastraError({
166
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "CREATE_INDEX", "INVALID_METRIC"),
167
+ text: `Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`,
168
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
169
+ category: _mastra_core_error.ErrorCategory.USER,
170
+ details: { metric }
171
+ });
172
+ try {
173
+ const collection = await this.client.createCollection({
174
+ name: indexName,
175
+ metadata: { dimension },
176
+ configuration: { hnsw: { space: hnswSpace } },
177
+ embeddingFunction: null
178
+ });
179
+ this.collections.set(indexName, collection);
180
+ } catch (error) {
181
+ const message = error?.message || error?.toString();
182
+ if (message && message.toLowerCase().includes("already exists")) {
183
+ await this.validateExistingIndex(indexName, dimension, metric);
184
+ return;
185
+ }
186
+ throw new _mastra_core_error.MastraError({
187
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "CREATE_INDEX", "FAILED"),
188
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
189
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
190
+ details: { indexName }
191
+ }, error);
192
+ }
193
+ }
194
+ transformFilter(filter) {
195
+ const translatedFilter = new ChromaFilterTranslator().translate(filter);
196
+ return translatedFilter ? translatedFilter : void 0;
197
+ }
198
+ async query({ indexName, queryVector, topK = 10, filter, includeVector = false, documentFilter }) {
199
+ if (!queryVector) throw new _mastra_core_error.MastraError({
200
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "QUERY", "MISSING_VECTOR"),
201
+ text: "queryVector is required for Chroma queries. Metadata-only queries are not supported by this vector store.",
202
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
203
+ category: _mastra_core_error.ErrorCategory.USER,
204
+ details: { indexName }
205
+ });
206
+ (0, _mastra_core_vector.validateTopK)("CHROMA", topK);
207
+ try {
208
+ const collection = await this.getCollection({ indexName });
209
+ const defaultInclude = [
210
+ "documents",
211
+ "metadatas",
212
+ "distances"
213
+ ];
214
+ const translatedFilter = this.transformFilter(filter);
215
+ const results = await collection.query({
216
+ queryEmbeddings: [queryVector],
217
+ nResults: topK,
218
+ where: translatedFilter ?? void 0,
219
+ whereDocument: documentFilter ?? void 0,
220
+ include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
221
+ });
222
+ const space = collection.configuration?.hnsw?.space || collection.configuration?.spann?.space || "cosine";
223
+ const metric = spaceMappings[space];
224
+ return (results.ids[0] || []).map((id, index) => {
225
+ const distance = results.distances?.[0]?.[index];
226
+ return {
227
+ id,
228
+ score: distance == null ? 0 : distanceToScore(distance, metric),
229
+ metadata: results.metadatas?.[0]?.[index] || {},
230
+ document: results.documents?.[0]?.[index] ?? void 0,
231
+ ...includeVector && { vector: results.embeddings?.[0]?.[index] || [] }
232
+ };
233
+ });
234
+ } catch (error) {
235
+ if (error instanceof _mastra_core_error.MastraError) throw error;
236
+ throw new _mastra_core_error.MastraError({
237
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "QUERY", "FAILED"),
238
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
239
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
240
+ details: { indexName }
241
+ }, error);
242
+ }
243
+ }
244
+ async hybridSearch({ indexName, search }) {
245
+ try {
246
+ return ((await (await this.getCollection({ indexName })).search(search)).rows()[0] ?? []).map((record) => ({
247
+ id: record.id,
248
+ score: record.score ?? 0,
249
+ metadata: record.metadata ?? void 0,
250
+ vector: record.embedding ?? void 0,
251
+ document: record.document ?? void 0
252
+ }));
253
+ } catch (error) {
254
+ if (error instanceof _mastra_core_error.MastraError) throw error;
255
+ throw new _mastra_core_error.MastraError({
256
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "SEARCH_API", "FAILED"),
257
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
258
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
259
+ details: { indexName }
260
+ }, error);
261
+ }
262
+ }
263
+ async get({ indexName, ids, filter, includeVector = false, documentFilter, offset, limit }) {
264
+ try {
265
+ const collection = await this.getCollection({ indexName });
266
+ const defaultInclude = ["documents", "metadatas"];
267
+ const translatedFilter = this.transformFilter(filter);
268
+ return (await collection.get({
269
+ ids,
270
+ where: translatedFilter ?? void 0,
271
+ whereDocument: documentFilter ?? void 0,
272
+ offset,
273
+ limit,
274
+ include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
275
+ })).rows();
276
+ } catch (error) {
277
+ if (error instanceof _mastra_core_error.MastraError) throw error;
278
+ throw new _mastra_core_error.MastraError({
279
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "GET", "FAILED"),
280
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
281
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
282
+ details: { indexName }
283
+ }, error);
284
+ }
285
+ }
286
+ async listIndexes() {
287
+ try {
288
+ return (await this.client.listCollections()).map((collection) => collection.name);
289
+ } catch (error) {
290
+ throw new _mastra_core_error.MastraError({
291
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "LIST_INDEXES", "FAILED"),
292
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
293
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
294
+ }, error);
295
+ }
296
+ }
297
+ /**
298
+ * Retrieves statistics about a vector index.
299
+ *
300
+ * @param {string} indexName - The name of the index to describe
301
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
302
+ */
303
+ async describeIndex({ indexName }) {
304
+ try {
305
+ const collection = await this.getCollection({ indexName });
306
+ const count = await collection.count();
307
+ const metadata = collection.metadata;
308
+ const space = collection.configuration.hnsw?.space || collection.configuration.spann?.space || void 0;
309
+ return {
310
+ dimension: metadata?.dimension || 0,
311
+ count,
312
+ metric: space ? spaceMappings[space] : void 0
313
+ };
314
+ } catch (error) {
315
+ if (error instanceof _mastra_core_error.MastraError) throw error;
316
+ throw new _mastra_core_error.MastraError({
317
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DESCRIBE_INDEX", "FAILED"),
318
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
319
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
320
+ details: { indexName }
321
+ }, error);
322
+ }
323
+ }
324
+ async deleteIndex({ indexName }) {
325
+ try {
326
+ await this.client.deleteCollection({ name: indexName });
327
+ this.collections.delete(indexName);
328
+ } catch (error) {
329
+ throw new _mastra_core_error.MastraError({
330
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DELETE_INDEX", "FAILED"),
331
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
332
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
333
+ details: { indexName }
334
+ }, error);
335
+ }
336
+ }
337
+ async forkIndex({ indexName, newIndexName }) {
338
+ try {
339
+ const forkedCollection = await (await this.getCollection({
340
+ indexName,
341
+ forceUpdate: true
342
+ })).fork({ name: newIndexName });
343
+ this.collections.set(newIndexName, forkedCollection);
344
+ } catch (error) {
345
+ if (error instanceof _mastra_core_error.MastraError) throw error;
346
+ throw new _mastra_core_error.MastraError({
347
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "FORK_INDEX", "FAILED"),
348
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
349
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
350
+ details: { indexName }
351
+ }, error);
352
+ }
353
+ }
354
+ /**
355
+ * Updates a vector by its ID or multiple vectors matching a filter.
356
+ * @param indexName - The name of the index containing the vector(s).
357
+ * @param id - The ID of the vector to update (mutually exclusive with filter).
358
+ * @param filter - Filter to match multiple vectors to update (mutually exclusive with id).
359
+ * @param update - An object containing the vector and/or metadata to update.
360
+ * @param update.vector - An optional array of numbers representing the new vector.
361
+ * @param update.metadata - An optional record containing the new metadata.
362
+ * @returns A promise that resolves when the update is complete.
363
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
364
+ */
365
+ async updateVector({ indexName, id, filter, update }) {
366
+ if (id && filter) throw new _mastra_core_error.MastraError({
367
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "UPDATE_VECTOR", "MUTUALLY_EXCLUSIVE"),
368
+ text: "Cannot specify both id and filter - they are mutually exclusive",
369
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
370
+ category: _mastra_core_error.ErrorCategory.USER,
371
+ details: { indexName }
372
+ });
373
+ if (!id && !filter) throw new _mastra_core_error.MastraError({
374
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "UPDATE_VECTOR", "NO_TARGET"),
375
+ text: "Either id or filter must be provided",
376
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
377
+ category: _mastra_core_error.ErrorCategory.USER,
378
+ details: { indexName }
379
+ });
380
+ if (!update.vector && !update.metadata) throw new _mastra_core_error.MastraError({
381
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "UPDATE_VECTOR", "NO_PAYLOAD"),
382
+ text: "No updates provided",
383
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
384
+ category: _mastra_core_error.ErrorCategory.USER,
385
+ details: {
386
+ indexName,
387
+ ...id && { id }
388
+ }
389
+ });
390
+ if (filter && Object.keys(filter).length === 0) throw new _mastra_core_error.MastraError({
391
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "UPDATE_VECTOR", "EMPTY_FILTER"),
392
+ text: "Filter cannot be an empty filter object",
393
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
394
+ category: _mastra_core_error.ErrorCategory.USER,
395
+ details: { indexName }
396
+ });
397
+ try {
398
+ const collection = await this.getCollection({ indexName });
399
+ if (update?.vector) {
400
+ const stats = await this.describeIndex({ indexName });
401
+ this.validateVectorDimensions([update.vector], stats.dimension);
402
+ }
403
+ if (id) {
404
+ const updateRecordSet = { ids: [id] };
405
+ if (update?.vector) updateRecordSet.embeddings = [update.vector];
406
+ if (update?.metadata) updateRecordSet.metadatas = [update.metadata];
407
+ return await collection.update(updateRecordSet);
408
+ } else if (filter) {
409
+ const translatedFilter = this.transformFilter(filter);
410
+ const vectorRows = (await collection.get({
411
+ where: translatedFilter ?? void 0,
412
+ include: ["embeddings", "metadatas"]
413
+ })).rows();
414
+ if (vectorRows.length === 0) return;
415
+ const updateRecordSet = { ids: vectorRows.map((row) => row.id) };
416
+ if (update?.vector) updateRecordSet.embeddings = vectorRows.map(() => update.vector);
417
+ if (update?.metadata) updateRecordSet.metadatas = vectorRows.map(() => update.metadata);
418
+ return await collection.update(updateRecordSet);
419
+ }
420
+ } catch (error) {
421
+ if (error instanceof _mastra_core_error.MastraError) throw error;
422
+ throw new _mastra_core_error.MastraError({
423
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "UPDATE_VECTOR", "FAILED"),
424
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
425
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
426
+ details: {
427
+ indexName,
428
+ ...id && { id },
429
+ ...filter && { filter: JSON.stringify(filter) }
430
+ }
431
+ }, error);
432
+ }
433
+ }
434
+ async deleteVector({ indexName, id }) {
435
+ try {
436
+ await (await this.getCollection({ indexName })).delete({ ids: [id] });
437
+ } catch (error) {
438
+ if (error instanceof _mastra_core_error.MastraError) throw error;
439
+ throw new _mastra_core_error.MastraError({
440
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DELETE_VECTOR", "FAILED"),
441
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
442
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
443
+ details: {
444
+ indexName,
445
+ ...id && { id }
446
+ }
447
+ }, error);
448
+ }
449
+ }
450
+ /**
451
+ * Deletes multiple vectors by IDs or filter.
452
+ * @param indexName - The name of the index containing the vectors.
453
+ * @param ids - Array of vector IDs to delete (mutually exclusive with filter).
454
+ * @param filter - Filter to match vectors to delete (mutually exclusive with ids).
455
+ * @returns A promise that resolves when the deletion is complete.
456
+ * @throws Will throw an error if both ids and filter are provided, or if neither is provided.
457
+ */
458
+ async deleteVectors({ indexName, filter, ids }) {
459
+ if (ids && filter) throw new _mastra_core_error.MastraError({
460
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DELETE_VECTORS", "MUTUALLY_EXCLUSIVE"),
461
+ text: "Cannot specify both ids and filter - they are mutually exclusive",
462
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
463
+ category: _mastra_core_error.ErrorCategory.USER,
464
+ details: { indexName }
465
+ });
466
+ if (!ids && !filter) throw new _mastra_core_error.MastraError({
467
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DELETE_VECTORS", "NO_TARGET"),
468
+ text: "Either filter or ids must be provided",
469
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
470
+ category: _mastra_core_error.ErrorCategory.USER,
471
+ details: { indexName }
472
+ });
473
+ if (ids && ids.length === 0) throw new _mastra_core_error.MastraError({
474
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DELETE_VECTORS", "EMPTY_IDS"),
475
+ text: "Cannot delete with empty ids array",
476
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
477
+ category: _mastra_core_error.ErrorCategory.USER,
478
+ details: { indexName }
479
+ });
480
+ if (filter && Object.keys(filter).length === 0) throw new _mastra_core_error.MastraError({
481
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DELETE_VECTORS", "EMPTY_FILTER"),
482
+ text: "Cannot delete with empty filter object",
483
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
484
+ category: _mastra_core_error.ErrorCategory.USER,
485
+ details: { indexName }
486
+ });
487
+ try {
488
+ const collection = await this.getCollection({ indexName });
489
+ if (ids) await collection.delete({ ids });
490
+ else if (filter) {
491
+ const translatedFilter = this.transformFilter(filter);
492
+ await collection.delete({ where: translatedFilter ?? void 0 });
493
+ }
494
+ } catch (error) {
495
+ if (error instanceof _mastra_core_error.MastraError) throw error;
496
+ throw new _mastra_core_error.MastraError({
497
+ id: (0, _mastra_core_storage.createVectorErrorId)("CHROMA", "DELETE_VECTORS", "FAILED"),
498
+ domain: _mastra_core_error.ErrorDomain.MASTRA_VECTOR,
499
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
500
+ details: {
501
+ indexName,
502
+ ...filter && { filter: JSON.stringify(filter) },
503
+ ...ids && { idsCount: ids.length }
504
+ }
505
+ }, error);
506
+ }
507
+ }
630
508
  };
631
-
632
- // src/vector/prompt.ts
633
- var CHROMA_PROMPT = `When querying Chroma, you can ONLY use the operators listed below. Any other operators will be rejected.
509
+ //#endregion
510
+ //#region src/vector/prompt.ts
511
+ /**
512
+ * Vector store specific prompt that details supported operators and examples.
513
+ * This prompt helps users construct valid filters for Chroma Vector.
514
+ */
515
+ const CHROMA_PROMPT = `When querying Chroma, you can ONLY use the operators listed below. Any other operators will be rejected.
634
516
  Important: Don't explain how to construct the filter - use the specified operators and fields to search the content and return relevant results.
635
517
  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.
636
518
 
@@ -698,8 +580,8 @@ Example Complex Query:
698
580
  ]}
699
581
  ]
700
582
  }`;
701
-
583
+ //#endregion
702
584
  exports.CHROMA_PROMPT = CHROMA_PROMPT;
703
585
  exports.ChromaVector = ChromaVector;
704
- //# sourceMappingURL=index.cjs.map
586
+
705
587
  //# sourceMappingURL=index.cjs.map