@mastra/chroma 0.2.13 → 0.2.14-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/chroma@0.2.13-alpha.6 build /home/runner/work/mastra/mastra/stores/chroma
2
+ > @mastra/chroma@0.2.14-alpha.1 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.4.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 8507ms
9
+ TSC ⚡️ Build success in 8360ms
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 9564ms
16
+ DTS ⚡️ Build success in 9498ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- CJS dist/index.cjs 10.90 KB
21
- CJS ⚡️ Build success in 707ms
22
- ESM dist/index.js 10.85 KB
23
- ESM ⚡️ Build success in 708ms
20
+ ESM dist/index.js 11.12 KB
21
+ ESM ⚡️ Build success in 520ms
22
+ CJS dist/index.cjs 11.18 KB
23
+ CJS ⚡️ Build success in 520ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @mastra/chroma
2
2
 
3
+ ## 0.2.14-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 9cd1a46: [MASTRA-3338] update naming scheme for embedding index based on vector store rules and added duplicate index checks
8
+ - Updated dependencies [e450778]
9
+ - Updated dependencies [8902157]
10
+ - Updated dependencies [ca0dc88]
11
+ - Updated dependencies [9cd1a46]
12
+ - Updated dependencies [70dbf51]
13
+ - @mastra/core@0.9.3-alpha.1
14
+
15
+ ## 0.2.14-alpha.0
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [526c570]
20
+ - Updated dependencies [b5d2de0]
21
+ - Updated dependencies [644f8ad]
22
+ - @mastra/core@0.9.3-alpha.0
23
+
3
24
  ## 0.2.13
4
25
 
5
26
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -157,13 +157,22 @@ var ChromaVector = class extends vector.MastraVector {
157
157
  if (!["cosine", "l2", "ip"].includes(hnswSpace)) {
158
158
  throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
159
159
  }
160
- await this.client.createCollection({
161
- name: indexName,
162
- metadata: {
163
- dimension,
164
- "hnsw:space": this.HnswSpaceMap[metric]
160
+ try {
161
+ await this.client.createCollection({
162
+ name: indexName,
163
+ metadata: {
164
+ dimension,
165
+ "hnsw:space": hnswSpace
166
+ }
167
+ });
168
+ } catch (error) {
169
+ const message = error?.message || error?.toString();
170
+ if (message && message.toLowerCase().includes("already exists")) {
171
+ await this.validateExistingIndex(indexName, dimension, metric);
172
+ return;
165
173
  }
166
- });
174
+ throw error;
175
+ }
167
176
  }
168
177
  transformFilter(filter) {
169
178
  const translator = new ChromaFilterTranslator();
package/dist/index.js CHANGED
@@ -155,13 +155,22 @@ var ChromaVector = class extends MastraVector {
155
155
  if (!["cosine", "l2", "ip"].includes(hnswSpace)) {
156
156
  throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
157
157
  }
158
- await this.client.createCollection({
159
- name: indexName,
160
- metadata: {
161
- dimension,
162
- "hnsw:space": this.HnswSpaceMap[metric]
158
+ try {
159
+ await this.client.createCollection({
160
+ name: indexName,
161
+ metadata: {
162
+ dimension,
163
+ "hnsw:space": hnswSpace
164
+ }
165
+ });
166
+ } catch (error) {
167
+ const message = error?.message || error?.toString();
168
+ if (message && message.toLowerCase().includes("already exists")) {
169
+ await this.validateExistingIndex(indexName, dimension, metric);
170
+ return;
163
171
  }
164
- });
172
+ throw error;
173
+ }
165
174
  }
166
175
  transformFilter(filter) {
167
176
  const translator = new ChromaFilterTranslator();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/chroma",
3
- "version": "0.2.13",
3
+ "version": "0.2.14-alpha.1",
4
4
  "description": "Chroma vector store provider for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
23
  "chromadb": "^2.2.0",
24
- "@mastra/core": "^0.9.2"
24
+ "@mastra/core": "^0.9.3-alpha.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@microsoft/api-extractor": "^7.52.5",
@@ -273,8 +273,17 @@ describe('ChromaVector Integration Tests', () => {
273
273
  });
274
274
 
275
275
  describe('Error Handling', () => {
276
+ const testIndexName = 'test_index_error';
277
+ beforeAll(async () => {
278
+ await vectorDB.createIndex({ indexName: testIndexName, dimension: 3 });
279
+ });
280
+
281
+ afterAll(async () => {
282
+ await vectorDB.deleteIndex(testIndexName);
283
+ });
284
+
276
285
  it('should handle non-existent index queries', async () => {
277
- await expect(vectorDB.query({ indexName: 'non-existent-index-yu', queryVector: [1, 2, 3] })).rejects.toThrow();
286
+ await expect(vectorDB.query({ indexName: 'non-existent-index', queryVector: [1, 2, 3] })).rejects.toThrow();
278
287
  });
279
288
 
280
289
  it('should handle invalid dimension vectors', async () => {
@@ -282,10 +291,59 @@ describe('ChromaVector Integration Tests', () => {
282
291
  await expect(vectorDB.upsert({ indexName: testIndexName, vectors: [invalidVector] })).rejects.toThrow();
283
292
  });
284
293
 
285
- it('should handle mismatched metadata and vectors length', async () => {
286
- const vectors = [[1, 2, 3]];
287
- const metadata = [{}, {}]; // More metadata than vectors
288
- await expect(vectorDB.upsert({ indexName: testIndexName, vectors, metadata })).rejects.toThrow();
294
+ it('should handle duplicate index creation gracefully', async () => {
295
+ const infoSpy = vi.spyOn(vectorDB['logger'], 'info');
296
+ const warnSpy = vi.spyOn(vectorDB['logger'], 'warn');
297
+
298
+ const duplicateIndexName = `duplicate-test`;
299
+ const dimension = 768;
300
+
301
+ try {
302
+ // Create index first time
303
+ await vectorDB.createIndex({
304
+ indexName: duplicateIndexName,
305
+ dimension,
306
+ metric: 'cosine',
307
+ });
308
+
309
+ // Try to create with same dimensions - should not throw
310
+ await expect(
311
+ vectorDB.createIndex({
312
+ indexName: duplicateIndexName,
313
+ dimension,
314
+ metric: 'cosine',
315
+ }),
316
+ ).resolves.not.toThrow();
317
+
318
+ expect(infoSpy).toHaveBeenCalledWith(expect.stringContaining('already exists with'));
319
+
320
+ // Try to create with same dimensions and different metric - should not throw
321
+ await expect(
322
+ vectorDB.createIndex({
323
+ indexName: duplicateIndexName,
324
+ dimension,
325
+ metric: 'euclidean',
326
+ }),
327
+ ).resolves.not.toThrow();
328
+
329
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Attempted to create index with metric'));
330
+
331
+ // Try to create with different dimensions - should throw
332
+ await expect(
333
+ vectorDB.createIndex({
334
+ indexName: duplicateIndexName,
335
+ dimension: dimension + 1,
336
+ metric: 'cosine',
337
+ }),
338
+ ).rejects.toThrow(
339
+ `Index "${duplicateIndexName}" already exists with ${dimension} dimensions, but ${dimension + 1} dimensions were requested`,
340
+ );
341
+ } finally {
342
+ infoSpy.mockRestore();
343
+ warnSpy.mockRestore();
344
+ // Cleanup
345
+ await vectorDB.deleteIndex(duplicateIndexName);
346
+ }
289
347
  });
290
348
  });
291
349
 
@@ -111,7 +111,6 @@ export class ChromaVector extends MastraVector {
111
111
 
112
112
  async createIndex(...args: ParamsToArgs<CreateIndexParams>): Promise<void> {
113
113
  const params = this.normalizeArgs<CreateIndexParams>('createIndex', args);
114
-
115
114
  const { indexName, dimension, metric = 'cosine' } = params;
116
115
 
117
116
  if (!Number.isInteger(dimension) || dimension <= 0) {
@@ -121,13 +120,24 @@ export class ChromaVector extends MastraVector {
121
120
  if (!['cosine', 'l2', 'ip'].includes(hnswSpace)) {
122
121
  throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
123
122
  }
124
- await this.client.createCollection({
125
- name: indexName,
126
- metadata: {
127
- dimension,
128
- 'hnsw:space': this.HnswSpaceMap[metric],
129
- },
130
- });
123
+ try {
124
+ await this.client.createCollection({
125
+ name: indexName,
126
+ metadata: {
127
+ dimension,
128
+ 'hnsw:space': hnswSpace,
129
+ },
130
+ });
131
+ } catch (error: any) {
132
+ // Check for 'already exists' error
133
+ const message = error?.message || error?.toString();
134
+ if (message && message.toLowerCase().includes('already exists')) {
135
+ // Fetch collection info and check dimension
136
+ await this.validateExistingIndex(indexName, dimension, metric);
137
+ return;
138
+ }
139
+ throw error;
140
+ }
131
141
  }
132
142
 
133
143
  transformFilter(filter?: VectorFilter) {