@mastra/chroma 0.10.3 → 0.10.4-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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/chroma@0.10.3-alpha.0 build /home/runner/work/mastra/mastra/stores/chroma
2
+ > @mastra/chroma@0.10.4-alpha.0 build /home/runner/work/mastra/mastra/stores/chroma
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 8884ms
9
+ TSC ⚡️ Build success in 8383ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/stores/chroma/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/stores/chroma/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 9546ms
16
+ DTS ⚡️ Build success in 8540ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- ESM dist/index.js 12.30 KB
21
- ESM ⚡️ Build success in 820ms
22
- CJS dist/index.cjs 12.35 KB
23
- CJS ⚡️ Build success in 817ms
20
+ ESM dist/index.js 14.87 KB
21
+ ESM ⚡️ Build success in 776ms
22
+ CJS dist/index.cjs 15.17 KB
23
+ CJS ⚡️ Build success in 779ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @mastra/chroma
2
2
 
3
+ ## 0.10.4-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 0e17048: Throw mastra errors in storage packages
8
+ - Updated dependencies [d1baedb]
9
+ - Updated dependencies [4d21bf2]
10
+ - Updated dependencies [2097952]
11
+ - Updated dependencies [4fb0cc2]
12
+ - Updated dependencies [d2a7a31]
13
+ - Updated dependencies [0e17048]
14
+ - @mastra/core@0.10.7-alpha.1
15
+
3
16
  ## 0.10.3
4
17
 
5
18
  ### Patch Changes
@@ -77,13 +77,6 @@ declare class ChromaVector extends MastraVector {
77
77
  * @throws Will throw an error if no updates are provided or if the update operation fails.
78
78
  */
79
79
  updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void>;
80
- /**
81
- * Deletes a vector by its ID.
82
- * @param indexName - The name of the index containing the vector.
83
- * @param id - The ID of the vector to delete.
84
- * @returns A promise that resolves when the deletion is complete.
85
- * @throws Will throw an error if the deletion operation fails.
86
- */
87
80
  deleteVector({ indexName, id }: DeleteVectorParams): Promise<void>;
88
81
  }
89
82
  export { ChromaVector }
@@ -77,13 +77,6 @@ declare class ChromaVector extends MastraVector {
77
77
  * @throws Will throw an error if no updates are provided or if the update operation fails.
78
78
  */
79
79
  updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void>;
80
- /**
81
- * Deletes a vector by its ID.
82
- * @param indexName - The name of the index containing the vector.
83
- * @param id - The ID of the vector to delete.
84
- * @returns A promise that resolves when the deletion is complete.
85
- * @throws Will throw an error if the deletion operation fails.
86
- */
87
80
  deleteVector({ indexName, id }: DeleteVectorParams): Promise<void>;
88
81
  }
89
82
  export { ChromaVector }
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var error = require('@mastra/core/error');
3
4
  var vector = require('@mastra/core/vector');
4
5
  var chromadb = require('chromadb');
5
6
  var filter = require('@mastra/core/vector/filter');
@@ -125,18 +126,31 @@ var ChromaVector = class extends vector.MastraVector {
125
126
  }
126
127
  }
127
128
  async upsert({ indexName, vectors, metadata, ids, documents }) {
128
- const collection = await this.getCollection(indexName);
129
- const stats = await this.describeIndex({ indexName });
130
- this.validateVectorDimensions(vectors, stats.dimension);
131
- const generatedIds = ids || vectors.map(() => crypto.randomUUID());
132
- const normalizedMetadata = metadata || vectors.map(() => ({}));
133
- await collection.upsert({
134
- ids: generatedIds,
135
- embeddings: vectors,
136
- metadatas: normalizedMetadata,
137
- documents
138
- });
139
- return generatedIds;
129
+ try {
130
+ const collection = await this.getCollection(indexName);
131
+ const stats = await this.describeIndex({ indexName });
132
+ this.validateVectorDimensions(vectors, stats.dimension);
133
+ const generatedIds = ids || vectors.map(() => crypto.randomUUID());
134
+ const normalizedMetadata = metadata || vectors.map(() => ({}));
135
+ await collection.upsert({
136
+ ids: generatedIds,
137
+ embeddings: vectors,
138
+ metadatas: normalizedMetadata,
139
+ documents
140
+ });
141
+ return generatedIds;
142
+ } catch (error$1) {
143
+ if (error$1 instanceof error.MastraError) throw error$1;
144
+ throw new error.MastraError(
145
+ {
146
+ id: "CHROMA_VECTOR_UPSERT_FAILED",
147
+ domain: error.ErrorDomain.MASTRA_VECTOR,
148
+ category: error.ErrorCategory.THIRD_PARTY,
149
+ details: { indexName }
150
+ },
151
+ error$1
152
+ );
153
+ }
140
154
  }
141
155
  HnswSpaceMap = {
142
156
  cosine: "cosine",
@@ -147,11 +161,23 @@ var ChromaVector = class extends vector.MastraVector {
147
161
  };
148
162
  async createIndex({ indexName, dimension, metric = "cosine" }) {
149
163
  if (!Number.isInteger(dimension) || dimension <= 0) {
150
- throw new Error("Dimension must be a positive integer");
164
+ throw new error.MastraError({
165
+ id: "CHROMA_VECTOR_CREATE_INDEX_INVALID_DIMENSION",
166
+ text: "Dimension must be a positive integer",
167
+ domain: error.ErrorDomain.MASTRA_VECTOR,
168
+ category: error.ErrorCategory.USER,
169
+ details: { dimension }
170
+ });
151
171
  }
152
172
  const hnswSpace = this.HnswSpaceMap[metric];
153
- if (!["cosine", "l2", "ip"].includes(hnswSpace)) {
154
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
173
+ if (!hnswSpace || !["cosine", "l2", "ip"].includes(hnswSpace)) {
174
+ throw new error.MastraError({
175
+ id: "CHROMA_VECTOR_CREATE_INDEX_INVALID_METRIC",
176
+ text: `Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`,
177
+ domain: error.ErrorDomain.MASTRA_VECTOR,
178
+ category: error.ErrorCategory.USER,
179
+ details: { metric }
180
+ });
155
181
  }
156
182
  try {
157
183
  await this.client.createCollection({
@@ -161,13 +187,21 @@ var ChromaVector = class extends vector.MastraVector {
161
187
  "hnsw:space": hnswSpace
162
188
  }
163
189
  });
164
- } catch (error) {
165
- const message = error?.message || error?.toString();
190
+ } catch (error$1) {
191
+ const message = error$1?.message || error$1?.toString();
166
192
  if (message && message.toLowerCase().includes("already exists")) {
167
193
  await this.validateExistingIndex(indexName, dimension, metric);
168
194
  return;
169
195
  }
170
- throw error;
196
+ throw new error.MastraError(
197
+ {
198
+ id: "CHROMA_VECTOR_CREATE_INDEX_FAILED",
199
+ domain: error.ErrorDomain.MASTRA_VECTOR,
200
+ category: error.ErrorCategory.THIRD_PARTY,
201
+ details: { indexName }
202
+ },
203
+ error$1
204
+ );
171
205
  }
172
206
  }
173
207
  transformFilter(filter) {
@@ -182,27 +216,51 @@ var ChromaVector = class extends vector.MastraVector {
182
216
  includeVector = false,
183
217
  documentFilter
184
218
  }) {
185
- const collection = await this.getCollection(indexName, true);
186
- const defaultInclude = ["documents", "metadatas", "distances"];
187
- const translatedFilter = this.transformFilter(filter);
188
- const results = await collection.query({
189
- queryEmbeddings: [queryVector],
190
- nResults: topK,
191
- where: translatedFilter,
192
- whereDocument: documentFilter,
193
- include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
194
- });
195
- return (results.ids[0] || []).map((id, index) => ({
196
- id,
197
- score: results.distances?.[0]?.[index] || 0,
198
- metadata: results.metadatas?.[0]?.[index] || {},
199
- document: results.documents?.[0]?.[index],
200
- ...includeVector && { vector: results.embeddings?.[0]?.[index] || [] }
201
- }));
219
+ try {
220
+ const collection = await this.getCollection(indexName, true);
221
+ const defaultInclude = ["documents", "metadatas", "distances"];
222
+ const translatedFilter = this.transformFilter(filter);
223
+ const results = await collection.query({
224
+ queryEmbeddings: [queryVector],
225
+ nResults: topK,
226
+ where: translatedFilter,
227
+ whereDocument: documentFilter,
228
+ include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
229
+ });
230
+ return (results.ids[0] || []).map((id, index) => ({
231
+ id,
232
+ score: results.distances?.[0]?.[index] || 0,
233
+ metadata: results.metadatas?.[0]?.[index] || {},
234
+ document: results.documents?.[0]?.[index],
235
+ ...includeVector && { vector: results.embeddings?.[0]?.[index] || [] }
236
+ }));
237
+ } catch (error$1) {
238
+ if (error$1 instanceof error.MastraError) throw error$1;
239
+ throw new error.MastraError(
240
+ {
241
+ id: "CHROMA_VECTOR_QUERY_FAILED",
242
+ domain: error.ErrorDomain.MASTRA_VECTOR,
243
+ category: error.ErrorCategory.THIRD_PARTY,
244
+ details: { indexName }
245
+ },
246
+ error$1
247
+ );
248
+ }
202
249
  }
203
250
  async listIndexes() {
204
- const collections = await this.client.listCollections();
205
- return collections.map((collection) => collection);
251
+ try {
252
+ const collections = await this.client.listCollections();
253
+ return collections.map((collection) => collection);
254
+ } catch (error$1) {
255
+ throw new error.MastraError(
256
+ {
257
+ id: "CHROMA_VECTOR_LIST_INDEXES_FAILED",
258
+ domain: error.ErrorDomain.MASTRA_VECTOR,
259
+ category: error.ErrorCategory.THIRD_PARTY
260
+ },
261
+ error$1
262
+ );
263
+ }
206
264
  }
207
265
  /**
208
266
  * Retrieves statistics about a vector index.
@@ -211,19 +269,44 @@ var ChromaVector = class extends vector.MastraVector {
211
269
  * @returns A promise that resolves to the index statistics including dimension, count and metric
212
270
  */
213
271
  async describeIndex({ indexName }) {
214
- const collection = await this.getCollection(indexName);
215
- const count = await collection.count();
216
- const metadata = collection.metadata;
217
- const hnswSpace = metadata?.["hnsw:space"];
218
- return {
219
- dimension: metadata?.dimension || 0,
220
- count,
221
- metric: this.HnswSpaceMap[hnswSpace]
222
- };
272
+ try {
273
+ const collection = await this.getCollection(indexName);
274
+ const count = await collection.count();
275
+ const metadata = collection.metadata;
276
+ const hnswSpace = metadata?.["hnsw:space"];
277
+ return {
278
+ dimension: metadata?.dimension || 0,
279
+ count,
280
+ metric: this.HnswSpaceMap[hnswSpace]
281
+ };
282
+ } catch (error$1) {
283
+ if (error$1 instanceof error.MastraError) throw error$1;
284
+ throw new error.MastraError(
285
+ {
286
+ id: "CHROMA_VECTOR_DESCRIBE_INDEX_FAILED",
287
+ domain: error.ErrorDomain.MASTRA_VECTOR,
288
+ category: error.ErrorCategory.THIRD_PARTY,
289
+ details: { indexName }
290
+ },
291
+ error$1
292
+ );
293
+ }
223
294
  }
224
295
  async deleteIndex({ indexName }) {
225
- await this.client.deleteCollection({ name: indexName });
226
- this.collections.delete(indexName);
296
+ try {
297
+ await this.client.deleteCollection({ name: indexName });
298
+ this.collections.delete(indexName);
299
+ } catch (error$1) {
300
+ throw new error.MastraError(
301
+ {
302
+ id: "CHROMA_VECTOR_DELETE_INDEX_FAILED",
303
+ domain: error.ErrorDomain.MASTRA_VECTOR,
304
+ category: error.ErrorCategory.THIRD_PARTY,
305
+ details: { indexName }
306
+ },
307
+ error$1
308
+ );
309
+ }
227
310
  }
228
311
  /**
229
312
  * Updates a vector by its ID with the provided vector and/or metadata.
@@ -236,10 +319,16 @@ var ChromaVector = class extends vector.MastraVector {
236
319
  * @throws Will throw an error if no updates are provided or if the update operation fails.
237
320
  */
238
321
  async updateVector({ indexName, id, update }) {
322
+ if (!update.vector && !update.metadata) {
323
+ throw new error.MastraError({
324
+ id: "CHROMA_VECTOR_UPDATE_NO_PAYLOAD",
325
+ text: "No updates provided for vector",
326
+ domain: error.ErrorDomain.MASTRA_VECTOR,
327
+ category: error.ErrorCategory.USER,
328
+ details: { indexName, id }
329
+ });
330
+ }
239
331
  try {
240
- if (!update.vector && !update.metadata) {
241
- throw new Error("No updates provided");
242
- }
243
332
  const collection = await this.getCollection(indexName, true);
244
333
  const updateOptions = { ids: [id] };
245
334
  if (update?.vector) {
@@ -251,23 +340,34 @@ var ChromaVector = class extends vector.MastraVector {
251
340
  updateOptions.metadatas = [update.metadata];
252
341
  }
253
342
  return await collection.update(updateOptions);
254
- } catch (error) {
255
- throw new Error(`Failed to update vector by id: ${id} for index name: ${indexName}: ${error.message}`);
343
+ } catch (error$1) {
344
+ if (error$1 instanceof error.MastraError) throw error$1;
345
+ throw new error.MastraError(
346
+ {
347
+ id: "CHROMA_VECTOR_UPDATE_FAILED",
348
+ domain: error.ErrorDomain.MASTRA_VECTOR,
349
+ category: error.ErrorCategory.THIRD_PARTY,
350
+ details: { indexName, id }
351
+ },
352
+ error$1
353
+ );
256
354
  }
257
355
  }
258
- /**
259
- * Deletes a vector by its ID.
260
- * @param indexName - The name of the index containing the vector.
261
- * @param id - The ID of the vector to delete.
262
- * @returns A promise that resolves when the deletion is complete.
263
- * @throws Will throw an error if the deletion operation fails.
264
- */
265
356
  async deleteVector({ indexName, id }) {
266
357
  try {
267
358
  const collection = await this.getCollection(indexName, true);
268
359
  await collection.delete({ ids: [id] });
269
- } catch (error) {
270
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
360
+ } catch (error$1) {
361
+ if (error$1 instanceof error.MastraError) throw error$1;
362
+ throw new error.MastraError(
363
+ {
364
+ id: "CHROMA_VECTOR_DELETE_FAILED",
365
+ domain: error.ErrorDomain.MASTRA_VECTOR,
366
+ category: error.ErrorCategory.THIRD_PARTY,
367
+ details: { indexName, id }
368
+ },
369
+ error$1
370
+ );
271
371
  }
272
372
  }
273
373
  };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import { ChromaClient } from 'chromadb';
3
4
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
@@ -123,18 +124,31 @@ var ChromaVector = class extends MastraVector {
123
124
  }
124
125
  }
125
126
  async upsert({ indexName, vectors, metadata, ids, documents }) {
126
- const collection = await this.getCollection(indexName);
127
- const stats = await this.describeIndex({ indexName });
128
- this.validateVectorDimensions(vectors, stats.dimension);
129
- const generatedIds = ids || vectors.map(() => crypto.randomUUID());
130
- const normalizedMetadata = metadata || vectors.map(() => ({}));
131
- await collection.upsert({
132
- ids: generatedIds,
133
- embeddings: vectors,
134
- metadatas: normalizedMetadata,
135
- documents
136
- });
137
- return generatedIds;
127
+ try {
128
+ const collection = await this.getCollection(indexName);
129
+ const stats = await this.describeIndex({ indexName });
130
+ this.validateVectorDimensions(vectors, stats.dimension);
131
+ const generatedIds = ids || vectors.map(() => crypto.randomUUID());
132
+ const normalizedMetadata = metadata || vectors.map(() => ({}));
133
+ await collection.upsert({
134
+ ids: generatedIds,
135
+ embeddings: vectors,
136
+ metadatas: normalizedMetadata,
137
+ documents
138
+ });
139
+ return generatedIds;
140
+ } catch (error) {
141
+ if (error instanceof MastraError) throw error;
142
+ throw new MastraError(
143
+ {
144
+ id: "CHROMA_VECTOR_UPSERT_FAILED",
145
+ domain: ErrorDomain.MASTRA_VECTOR,
146
+ category: ErrorCategory.THIRD_PARTY,
147
+ details: { indexName }
148
+ },
149
+ error
150
+ );
151
+ }
138
152
  }
139
153
  HnswSpaceMap = {
140
154
  cosine: "cosine",
@@ -145,11 +159,23 @@ var ChromaVector = class extends MastraVector {
145
159
  };
146
160
  async createIndex({ indexName, dimension, metric = "cosine" }) {
147
161
  if (!Number.isInteger(dimension) || dimension <= 0) {
148
- throw new Error("Dimension must be a positive integer");
162
+ throw new MastraError({
163
+ id: "CHROMA_VECTOR_CREATE_INDEX_INVALID_DIMENSION",
164
+ text: "Dimension must be a positive integer",
165
+ domain: ErrorDomain.MASTRA_VECTOR,
166
+ category: ErrorCategory.USER,
167
+ details: { dimension }
168
+ });
149
169
  }
150
170
  const hnswSpace = this.HnswSpaceMap[metric];
151
- if (!["cosine", "l2", "ip"].includes(hnswSpace)) {
152
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
171
+ if (!hnswSpace || !["cosine", "l2", "ip"].includes(hnswSpace)) {
172
+ throw new MastraError({
173
+ id: "CHROMA_VECTOR_CREATE_INDEX_INVALID_METRIC",
174
+ text: `Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`,
175
+ domain: ErrorDomain.MASTRA_VECTOR,
176
+ category: ErrorCategory.USER,
177
+ details: { metric }
178
+ });
153
179
  }
154
180
  try {
155
181
  await this.client.createCollection({
@@ -165,7 +191,15 @@ var ChromaVector = class extends MastraVector {
165
191
  await this.validateExistingIndex(indexName, dimension, metric);
166
192
  return;
167
193
  }
168
- throw error;
194
+ throw new MastraError(
195
+ {
196
+ id: "CHROMA_VECTOR_CREATE_INDEX_FAILED",
197
+ domain: ErrorDomain.MASTRA_VECTOR,
198
+ category: ErrorCategory.THIRD_PARTY,
199
+ details: { indexName }
200
+ },
201
+ error
202
+ );
169
203
  }
170
204
  }
171
205
  transformFilter(filter) {
@@ -180,27 +214,51 @@ var ChromaVector = class extends MastraVector {
180
214
  includeVector = false,
181
215
  documentFilter
182
216
  }) {
183
- const collection = await this.getCollection(indexName, true);
184
- const defaultInclude = ["documents", "metadatas", "distances"];
185
- const translatedFilter = this.transformFilter(filter);
186
- const results = await collection.query({
187
- queryEmbeddings: [queryVector],
188
- nResults: topK,
189
- where: translatedFilter,
190
- whereDocument: documentFilter,
191
- include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
192
- });
193
- return (results.ids[0] || []).map((id, index) => ({
194
- id,
195
- score: results.distances?.[0]?.[index] || 0,
196
- metadata: results.metadatas?.[0]?.[index] || {},
197
- document: results.documents?.[0]?.[index],
198
- ...includeVector && { vector: results.embeddings?.[0]?.[index] || [] }
199
- }));
217
+ try {
218
+ const collection = await this.getCollection(indexName, true);
219
+ const defaultInclude = ["documents", "metadatas", "distances"];
220
+ const translatedFilter = this.transformFilter(filter);
221
+ const results = await collection.query({
222
+ queryEmbeddings: [queryVector],
223
+ nResults: topK,
224
+ where: translatedFilter,
225
+ whereDocument: documentFilter,
226
+ include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
227
+ });
228
+ return (results.ids[0] || []).map((id, index) => ({
229
+ id,
230
+ score: results.distances?.[0]?.[index] || 0,
231
+ metadata: results.metadatas?.[0]?.[index] || {},
232
+ document: results.documents?.[0]?.[index],
233
+ ...includeVector && { vector: results.embeddings?.[0]?.[index] || [] }
234
+ }));
235
+ } catch (error) {
236
+ if (error instanceof MastraError) throw error;
237
+ throw new MastraError(
238
+ {
239
+ id: "CHROMA_VECTOR_QUERY_FAILED",
240
+ domain: ErrorDomain.MASTRA_VECTOR,
241
+ category: ErrorCategory.THIRD_PARTY,
242
+ details: { indexName }
243
+ },
244
+ error
245
+ );
246
+ }
200
247
  }
201
248
  async listIndexes() {
202
- const collections = await this.client.listCollections();
203
- return collections.map((collection) => collection);
249
+ try {
250
+ const collections = await this.client.listCollections();
251
+ return collections.map((collection) => collection);
252
+ } catch (error) {
253
+ throw new MastraError(
254
+ {
255
+ id: "CHROMA_VECTOR_LIST_INDEXES_FAILED",
256
+ domain: ErrorDomain.MASTRA_VECTOR,
257
+ category: ErrorCategory.THIRD_PARTY
258
+ },
259
+ error
260
+ );
261
+ }
204
262
  }
205
263
  /**
206
264
  * Retrieves statistics about a vector index.
@@ -209,19 +267,44 @@ var ChromaVector = class extends MastraVector {
209
267
  * @returns A promise that resolves to the index statistics including dimension, count and metric
210
268
  */
211
269
  async describeIndex({ indexName }) {
212
- const collection = await this.getCollection(indexName);
213
- const count = await collection.count();
214
- const metadata = collection.metadata;
215
- const hnswSpace = metadata?.["hnsw:space"];
216
- return {
217
- dimension: metadata?.dimension || 0,
218
- count,
219
- metric: this.HnswSpaceMap[hnswSpace]
220
- };
270
+ try {
271
+ const collection = await this.getCollection(indexName);
272
+ const count = await collection.count();
273
+ const metadata = collection.metadata;
274
+ const hnswSpace = metadata?.["hnsw:space"];
275
+ return {
276
+ dimension: metadata?.dimension || 0,
277
+ count,
278
+ metric: this.HnswSpaceMap[hnswSpace]
279
+ };
280
+ } catch (error) {
281
+ if (error instanceof MastraError) throw error;
282
+ throw new MastraError(
283
+ {
284
+ id: "CHROMA_VECTOR_DESCRIBE_INDEX_FAILED",
285
+ domain: ErrorDomain.MASTRA_VECTOR,
286
+ category: ErrorCategory.THIRD_PARTY,
287
+ details: { indexName }
288
+ },
289
+ error
290
+ );
291
+ }
221
292
  }
222
293
  async deleteIndex({ indexName }) {
223
- await this.client.deleteCollection({ name: indexName });
224
- this.collections.delete(indexName);
294
+ try {
295
+ await this.client.deleteCollection({ name: indexName });
296
+ this.collections.delete(indexName);
297
+ } catch (error) {
298
+ throw new MastraError(
299
+ {
300
+ id: "CHROMA_VECTOR_DELETE_INDEX_FAILED",
301
+ domain: ErrorDomain.MASTRA_VECTOR,
302
+ category: ErrorCategory.THIRD_PARTY,
303
+ details: { indexName }
304
+ },
305
+ error
306
+ );
307
+ }
225
308
  }
226
309
  /**
227
310
  * Updates a vector by its ID with the provided vector and/or metadata.
@@ -234,10 +317,16 @@ var ChromaVector = class extends MastraVector {
234
317
  * @throws Will throw an error if no updates are provided or if the update operation fails.
235
318
  */
236
319
  async updateVector({ indexName, id, update }) {
320
+ if (!update.vector && !update.metadata) {
321
+ throw new MastraError({
322
+ id: "CHROMA_VECTOR_UPDATE_NO_PAYLOAD",
323
+ text: "No updates provided for vector",
324
+ domain: ErrorDomain.MASTRA_VECTOR,
325
+ category: ErrorCategory.USER,
326
+ details: { indexName, id }
327
+ });
328
+ }
237
329
  try {
238
- if (!update.vector && !update.metadata) {
239
- throw new Error("No updates provided");
240
- }
241
330
  const collection = await this.getCollection(indexName, true);
242
331
  const updateOptions = { ids: [id] };
243
332
  if (update?.vector) {
@@ -250,22 +339,33 @@ var ChromaVector = class extends MastraVector {
250
339
  }
251
340
  return await collection.update(updateOptions);
252
341
  } catch (error) {
253
- throw new Error(`Failed to update vector by id: ${id} for index name: ${indexName}: ${error.message}`);
342
+ if (error instanceof MastraError) throw error;
343
+ throw new MastraError(
344
+ {
345
+ id: "CHROMA_VECTOR_UPDATE_FAILED",
346
+ domain: ErrorDomain.MASTRA_VECTOR,
347
+ category: ErrorCategory.THIRD_PARTY,
348
+ details: { indexName, id }
349
+ },
350
+ error
351
+ );
254
352
  }
255
353
  }
256
- /**
257
- * Deletes a vector by its ID.
258
- * @param indexName - The name of the index containing the vector.
259
- * @param id - The ID of the vector to delete.
260
- * @returns A promise that resolves when the deletion is complete.
261
- * @throws Will throw an error if the deletion operation fails.
262
- */
263
354
  async deleteVector({ indexName, id }) {
264
355
  try {
265
356
  const collection = await this.getCollection(indexName, true);
266
357
  await collection.delete({ ids: [id] });
267
358
  } catch (error) {
268
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
359
+ if (error instanceof MastraError) throw error;
360
+ throw new MastraError(
361
+ {
362
+ id: "CHROMA_VECTOR_DELETE_FAILED",
363
+ domain: ErrorDomain.MASTRA_VECTOR,
364
+ category: ErrorCategory.THIRD_PARTY,
365
+ details: { indexName, id }
366
+ },
367
+ error
368
+ );
269
369
  }
270
370
  }
271
371
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/chroma",
3
- "version": "0.10.3",
3
+ "version": "0.10.4-alpha.0",
4
4
  "description": "Chroma vector store provider for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "typescript": "^5.8.3",
31
31
  "vitest": "^3.2.3",
32
32
  "@internal/lint": "0.0.13",
33
- "@mastra/core": "0.10.6"
33
+ "@mastra/core": "0.10.7-alpha.1"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@mastra/core": ">=0.10.4-0 <0.11.0"
@@ -1,3 +1,4 @@
1
+ import { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import type {
3
4
  QueryResult,
@@ -10,7 +11,6 @@ import type {
10
11
  DeleteVectorParams,
11
12
  UpdateVectorParams,
12
13
  } from '@mastra/core/vector';
13
-
14
14
  import type { VectorFilter } from '@mastra/core/vector/filter';
15
15
  import { ChromaClient } from 'chromadb';
16
16
  import type { UpdateRecordsParams, Collection } from 'chromadb';
@@ -70,28 +70,34 @@ export class ChromaVector extends MastraVector {
70
70
  }
71
71
 
72
72
  async upsert({ indexName, vectors, metadata, ids, documents }: ChromaUpsertVectorParams): Promise<string[]> {
73
- const collection = await this.getCollection(indexName);
74
-
75
- // Get index stats to check dimension
76
- const stats = await this.describeIndex({ indexName });
77
-
78
- // Validate vector dimensions
79
- this.validateVectorDimensions(vectors, stats.dimension);
80
-
81
- // Generate IDs if not provided
82
- const generatedIds = ids || vectors.map(() => crypto.randomUUID());
83
-
84
- // Ensure metadata exists for each vector
85
- const normalizedMetadata = metadata || vectors.map(() => ({}));
86
-
87
- await collection.upsert({
88
- ids: generatedIds,
89
- embeddings: vectors,
90
- metadatas: normalizedMetadata,
91
- documents: documents,
92
- });
73
+ try {
74
+ const collection = await this.getCollection(indexName);
75
+
76
+ const stats = await this.describeIndex({ indexName });
77
+ this.validateVectorDimensions(vectors, stats.dimension);
78
+ const generatedIds = ids || vectors.map(() => crypto.randomUUID());
79
+ const normalizedMetadata = metadata || vectors.map(() => ({}));
80
+
81
+ await collection.upsert({
82
+ ids: generatedIds,
83
+ embeddings: vectors,
84
+ metadatas: normalizedMetadata,
85
+ documents: documents,
86
+ });
93
87
 
94
- return generatedIds;
88
+ return generatedIds;
89
+ } catch (error: any) {
90
+ if (error instanceof MastraError) throw error;
91
+ throw new MastraError(
92
+ {
93
+ id: 'CHROMA_VECTOR_UPSERT_FAILED',
94
+ domain: ErrorDomain.MASTRA_VECTOR,
95
+ category: ErrorCategory.THIRD_PARTY,
96
+ details: { indexName },
97
+ },
98
+ error,
99
+ );
100
+ }
95
101
  }
96
102
 
97
103
  private HnswSpaceMap = {
@@ -104,11 +110,23 @@ export class ChromaVector extends MastraVector {
104
110
 
105
111
  async createIndex({ indexName, dimension, metric = 'cosine' }: CreateIndexParams): Promise<void> {
106
112
  if (!Number.isInteger(dimension) || dimension <= 0) {
107
- throw new Error('Dimension must be a positive integer');
113
+ throw new MastraError({
114
+ id: 'CHROMA_VECTOR_CREATE_INDEX_INVALID_DIMENSION',
115
+ text: 'Dimension must be a positive integer',
116
+ domain: ErrorDomain.MASTRA_VECTOR,
117
+ category: ErrorCategory.USER,
118
+ details: { dimension },
119
+ });
108
120
  }
109
121
  const hnswSpace = this.HnswSpaceMap[metric];
110
- if (!['cosine', 'l2', 'ip'].includes(hnswSpace)) {
111
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
122
+ if (!hnswSpace || !['cosine', 'l2', 'ip'].includes(hnswSpace)) {
123
+ throw new MastraError({
124
+ id: 'CHROMA_VECTOR_CREATE_INDEX_INVALID_METRIC',
125
+ text: `Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`,
126
+ domain: ErrorDomain.MASTRA_VECTOR,
127
+ category: ErrorCategory.USER,
128
+ details: { metric },
129
+ });
112
130
  }
113
131
  try {
114
132
  await this.client.createCollection({
@@ -126,7 +144,15 @@ export class ChromaVector extends MastraVector {
126
144
  await this.validateExistingIndex(indexName, dimension, metric);
127
145
  return;
128
146
  }
129
- throw error;
147
+ throw new MastraError(
148
+ {
149
+ id: 'CHROMA_VECTOR_CREATE_INDEX_FAILED',
150
+ domain: ErrorDomain.MASTRA_VECTOR,
151
+ category: ErrorCategory.THIRD_PARTY,
152
+ details: { indexName },
153
+ },
154
+ error,
155
+ );
130
156
  }
131
157
  }
132
158
 
@@ -142,32 +168,55 @@ export class ChromaVector extends MastraVector {
142
168
  includeVector = false,
143
169
  documentFilter,
144
170
  }: ChromaQueryVectorParams): Promise<QueryResult[]> {
145
- const collection = await this.getCollection(indexName, true);
171
+ try {
172
+ const collection = await this.getCollection(indexName, true);
146
173
 
147
- const defaultInclude = ['documents', 'metadatas', 'distances'];
174
+ const defaultInclude = ['documents', 'metadatas', 'distances'];
148
175
 
149
- const translatedFilter = this.transformFilter(filter);
150
- const results = await collection.query({
151
- queryEmbeddings: [queryVector],
152
- nResults: topK,
153
- where: translatedFilter,
154
- whereDocument: documentFilter,
155
- include: includeVector ? [...defaultInclude, 'embeddings'] : defaultInclude,
156
- });
176
+ const translatedFilter = this.transformFilter(filter);
177
+ const results = await collection.query({
178
+ queryEmbeddings: [queryVector],
179
+ nResults: topK,
180
+ where: translatedFilter,
181
+ whereDocument: documentFilter,
182
+ include: includeVector ? [...defaultInclude, 'embeddings'] : defaultInclude,
183
+ });
157
184
 
158
- // Transform ChromaDB results to QueryResult format
159
- return (results.ids[0] || []).map((id: string, index: number) => ({
160
- id,
161
- score: results.distances?.[0]?.[index] || 0,
162
- metadata: results.metadatas?.[0]?.[index] || {},
163
- document: results.documents?.[0]?.[index],
164
- ...(includeVector && { vector: results.embeddings?.[0]?.[index] || [] }),
165
- }));
185
+ return (results.ids[0] || []).map((id: string, index: number) => ({
186
+ id,
187
+ score: results.distances?.[0]?.[index] || 0,
188
+ metadata: results.metadatas?.[0]?.[index] || {},
189
+ document: results.documents?.[0]?.[index],
190
+ ...(includeVector && { vector: results.embeddings?.[0]?.[index] || [] }),
191
+ }));
192
+ } catch (error: any) {
193
+ if (error instanceof MastraError) throw error;
194
+ throw new MastraError(
195
+ {
196
+ id: 'CHROMA_VECTOR_QUERY_FAILED',
197
+ domain: ErrorDomain.MASTRA_VECTOR,
198
+ category: ErrorCategory.THIRD_PARTY,
199
+ details: { indexName },
200
+ },
201
+ error,
202
+ );
203
+ }
166
204
  }
167
205
 
168
206
  async listIndexes(): Promise<string[]> {
169
- const collections = await this.client.listCollections();
170
- return collections.map(collection => collection);
207
+ try {
208
+ const collections = await this.client.listCollections();
209
+ return collections.map(collection => collection);
210
+ } catch (error: any) {
211
+ throw new MastraError(
212
+ {
213
+ id: 'CHROMA_VECTOR_LIST_INDEXES_FAILED',
214
+ domain: ErrorDomain.MASTRA_VECTOR,
215
+ category: ErrorCategory.THIRD_PARTY,
216
+ },
217
+ error,
218
+ );
219
+ }
171
220
  }
172
221
 
173
222
  /**
@@ -177,22 +226,47 @@ export class ChromaVector extends MastraVector {
177
226
  * @returns A promise that resolves to the index statistics including dimension, count and metric
178
227
  */
179
228
  async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {
180
- const collection = await this.getCollection(indexName);
181
- const count = await collection.count();
182
- const metadata = collection.metadata;
229
+ try {
230
+ const collection = await this.getCollection(indexName);
231
+ const count = await collection.count();
232
+ const metadata = collection.metadata;
183
233
 
184
- const hnswSpace = metadata?.['hnsw:space'] as 'cosine' | 'l2' | 'ip';
234
+ const hnswSpace = metadata?.['hnsw:space'] as 'cosine' | 'l2' | 'ip';
185
235
 
186
- return {
187
- dimension: metadata?.dimension || 0,
188
- count,
189
- metric: this.HnswSpaceMap[hnswSpace] as 'cosine' | 'euclidean' | 'dotproduct',
190
- };
236
+ return {
237
+ dimension: metadata?.dimension || 0,
238
+ count,
239
+ metric: this.HnswSpaceMap[hnswSpace] as 'cosine' | 'euclidean' | 'dotproduct',
240
+ };
241
+ } catch (error: any) {
242
+ if (error instanceof MastraError) throw error;
243
+ throw new MastraError(
244
+ {
245
+ id: 'CHROMA_VECTOR_DESCRIBE_INDEX_FAILED',
246
+ domain: ErrorDomain.MASTRA_VECTOR,
247
+ category: ErrorCategory.THIRD_PARTY,
248
+ details: { indexName },
249
+ },
250
+ error,
251
+ );
252
+ }
191
253
  }
192
254
 
193
255
  async deleteIndex({ indexName }: DeleteIndexParams): Promise<void> {
194
- await this.client.deleteCollection({ name: indexName });
195
- this.collections.delete(indexName);
256
+ try {
257
+ await this.client.deleteCollection({ name: indexName });
258
+ this.collections.delete(indexName);
259
+ } catch (error: any) {
260
+ throw new MastraError(
261
+ {
262
+ id: 'CHROMA_VECTOR_DELETE_INDEX_FAILED',
263
+ domain: ErrorDomain.MASTRA_VECTOR,
264
+ category: ErrorCategory.THIRD_PARTY,
265
+ details: { indexName },
266
+ },
267
+ error,
268
+ );
269
+ }
196
270
  }
197
271
 
198
272
  /**
@@ -206,11 +280,17 @@ export class ChromaVector extends MastraVector {
206
280
  * @throws Will throw an error if no updates are provided or if the update operation fails.
207
281
  */
208
282
  async updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void> {
209
- try {
210
- if (!update.vector && !update.metadata) {
211
- throw new Error('No updates provided');
212
- }
283
+ if (!update.vector && !update.metadata) {
284
+ throw new MastraError({
285
+ id: 'CHROMA_VECTOR_UPDATE_NO_PAYLOAD',
286
+ text: 'No updates provided for vector',
287
+ domain: ErrorDomain.MASTRA_VECTOR,
288
+ category: ErrorCategory.USER,
289
+ details: { indexName, id },
290
+ });
291
+ }
213
292
 
293
+ try {
214
294
  const collection: Collection = await this.getCollection(indexName, true);
215
295
 
216
296
  const updateOptions: UpdateRecordsParams = { ids: [id] };
@@ -227,23 +307,34 @@ export class ChromaVector extends MastraVector {
227
307
 
228
308
  return await collection.update(updateOptions);
229
309
  } catch (error: any) {
230
- throw new Error(`Failed to update vector by id: ${id} for index name: ${indexName}: ${error.message}`);
310
+ if (error instanceof MastraError) throw error;
311
+ throw new MastraError(
312
+ {
313
+ id: 'CHROMA_VECTOR_UPDATE_FAILED',
314
+ domain: ErrorDomain.MASTRA_VECTOR,
315
+ category: ErrorCategory.THIRD_PARTY,
316
+ details: { indexName, id },
317
+ },
318
+ error,
319
+ );
231
320
  }
232
321
  }
233
322
 
234
- /**
235
- * Deletes a vector by its ID.
236
- * @param indexName - The name of the index containing the vector.
237
- * @param id - The ID of the vector to delete.
238
- * @returns A promise that resolves when the deletion is complete.
239
- * @throws Will throw an error if the deletion operation fails.
240
- */
241
323
  async deleteVector({ indexName, id }: DeleteVectorParams): Promise<void> {
242
324
  try {
243
325
  const collection: Collection = await this.getCollection(indexName, true);
244
326
  await collection.delete({ ids: [id] });
245
327
  } catch (error: any) {
246
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
328
+ if (error instanceof MastraError) throw error;
329
+ throw new MastraError(
330
+ {
331
+ id: 'CHROMA_VECTOR_DELETE_FAILED',
332
+ domain: ErrorDomain.MASTRA_VECTOR,
333
+ category: ErrorCategory.THIRD_PARTY,
334
+ details: { indexName, id },
335
+ },
336
+ error,
337
+ );
247
338
  }
248
339
  }
249
340
  }