@mastra/chroma 0.2.7-alpha.7 → 0.2.7-alpha.8
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/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +8 -0
- package/package.json +3 -3
- package/src/vector/index.test.ts +108 -27
- package/src/vector/index.ts +3 -4
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/chroma@0.2.7-alpha.
|
|
2
|
+
> @mastra/chroma@0.2.7-alpha.8 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
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.4.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 8184ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/chroma/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/chroma/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 8248ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
20
|
[32mCJS[39m [1mdist/index.cjs [22m[32m8.08 KB[39m
|
|
21
|
-
[32mCJS[39m ⚡️ Build success in
|
|
21
|
+
[32mCJS[39m ⚡️ Build success in 618ms
|
|
22
22
|
[32mESM[39m [1mdist/index.js [22m[32m8.05 KB[39m
|
|
23
|
-
[32mESM[39m ⚡️ Build success in
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 624ms
|
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/chroma",
|
|
3
|
-
"version": "0.2.7-alpha.
|
|
3
|
+
"version": "0.2.7-alpha.8",
|
|
4
4
|
"description": "Chroma vector store provider for Mastra",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"./package.json": "./package.json"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"chromadb": "^
|
|
23
|
-
"@mastra/core": "^0.8.0-alpha.
|
|
22
|
+
"chromadb": "^2.2.0",
|
|
23
|
+
"@mastra/core": "^0.8.0-alpha.8"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@microsoft/api-extractor": "^7.52.1",
|
package/src/vector/index.test.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { QueryResult, IndexStats } from '@mastra/core/vector';
|
|
|
2
2
|
import { describe, expect, beforeEach, afterEach, it, beforeAll, afterAll, vi } from 'vitest';
|
|
3
3
|
|
|
4
4
|
import { ChromaVector } from './';
|
|
5
|
-
import { Collection } from 'chromadb';
|
|
6
5
|
|
|
7
6
|
describe('ChromaVector Integration Tests', () => {
|
|
8
7
|
let vectorDB = new ChromaVector({
|
|
@@ -196,8 +195,8 @@ describe('ChromaVector Integration Tests', () => {
|
|
|
196
195
|
expect(results[0]?.vector).toEqual(newVector);
|
|
197
196
|
});
|
|
198
197
|
|
|
199
|
-
it('should throw exception when no updates are given', () => {
|
|
200
|
-
expect(vectorDB.updateIndexById(testIndexName, 'id', {})).rejects.toThrow('No updates provided');
|
|
198
|
+
it('should throw exception when no updates are given', async () => {
|
|
199
|
+
await expect(vectorDB.updateIndexById(testIndexName, 'id', {})).rejects.toThrow('No updates provided');
|
|
201
200
|
});
|
|
202
201
|
|
|
203
202
|
it('should delete the vector by id', async () => {
|
|
@@ -759,22 +758,20 @@ describe('ChromaVector Integration Tests', () => {
|
|
|
759
758
|
expect(results.length).toBeGreaterThan(0);
|
|
760
759
|
});
|
|
761
760
|
|
|
762
|
-
it('
|
|
763
|
-
await
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
).rejects.toThrow();
|
|
761
|
+
it('accepts single conditions in logical operators', async () => {
|
|
762
|
+
const results = await vectorDB.query({
|
|
763
|
+
indexName: testIndexName2,
|
|
764
|
+
queryVector: [1, 0, 0],
|
|
765
|
+
filter: { $and: [{ category: 'electronics' }] },
|
|
766
|
+
});
|
|
767
|
+
expect(results.length).toBeGreaterThan(0);
|
|
770
768
|
|
|
771
|
-
await
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
).rejects.toThrow();
|
|
769
|
+
const results2 = await vectorDB.query({
|
|
770
|
+
indexName: testIndexName2,
|
|
771
|
+
queryVector: [1, 0, 0],
|
|
772
|
+
filter: { $or: [{ price: { $gt: 900 } }] },
|
|
773
|
+
});
|
|
774
|
+
expect(results2.length).toBeGreaterThan(0);
|
|
778
775
|
});
|
|
779
776
|
});
|
|
780
777
|
|
|
@@ -1292,15 +1289,14 @@ describe('ChromaVector Integration Tests', () => {
|
|
|
1292
1289
|
});
|
|
1293
1290
|
|
|
1294
1291
|
describe('Edge Cases and Validation', () => {
|
|
1295
|
-
it('
|
|
1296
|
-
await
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
).rejects.toThrow('Expected where document operand value for operator $contains to be a non-empty str');
|
|
1292
|
+
it('allows empty string in $contains', async () => {
|
|
1293
|
+
const results = await vectorDB.query({
|
|
1294
|
+
indexName: testIndexName3,
|
|
1295
|
+
queryVector: [1.0, 0.0, 0.0],
|
|
1296
|
+
topK: 3,
|
|
1297
|
+
documentFilter: { $contains: '' },
|
|
1298
|
+
});
|
|
1299
|
+
expect(results).toHaveLength(3);
|
|
1304
1300
|
});
|
|
1305
1301
|
|
|
1306
1302
|
it('should be case sensitive', async () => {
|
|
@@ -1515,4 +1511,89 @@ describe('ChromaVector Integration Tests', () => {
|
|
|
1515
1511
|
expect(upsertResults).toHaveLength(1);
|
|
1516
1512
|
});
|
|
1517
1513
|
});
|
|
1514
|
+
|
|
1515
|
+
describe('Performance and Concurrency', () => {
|
|
1516
|
+
const perfTestIndex = 'perf-test-index';
|
|
1517
|
+
|
|
1518
|
+
beforeEach(async () => {
|
|
1519
|
+
try {
|
|
1520
|
+
await vectorDB.deleteIndex(perfTestIndex);
|
|
1521
|
+
} catch {
|
|
1522
|
+
// Ignore errors if index doesn't exist
|
|
1523
|
+
}
|
|
1524
|
+
await vectorDB.createIndex({ indexName: perfTestIndex, dimension });
|
|
1525
|
+
}, 10000);
|
|
1526
|
+
|
|
1527
|
+
afterEach(async () => {
|
|
1528
|
+
try {
|
|
1529
|
+
await vectorDB.deleteIndex(perfTestIndex);
|
|
1530
|
+
} catch {
|
|
1531
|
+
// Ignore cleanup errors
|
|
1532
|
+
}
|
|
1533
|
+
}, 10000);
|
|
1534
|
+
|
|
1535
|
+
it('handles concurrent operations correctly', async () => {
|
|
1536
|
+
const promises = Array(10)
|
|
1537
|
+
.fill(0)
|
|
1538
|
+
.map((_, i) =>
|
|
1539
|
+
vectorDB.upsert({
|
|
1540
|
+
indexName: perfTestIndex,
|
|
1541
|
+
vectors: [[1, 0, 0]],
|
|
1542
|
+
metadata: [{ test: 'concurrent', id: i }],
|
|
1543
|
+
ids: [`concurrent-${i}`],
|
|
1544
|
+
}),
|
|
1545
|
+
);
|
|
1546
|
+
await Promise.all(promises);
|
|
1547
|
+
|
|
1548
|
+
const results = await vectorDB.query({
|
|
1549
|
+
indexName: perfTestIndex,
|
|
1550
|
+
queryVector: [1, 0, 0],
|
|
1551
|
+
filter: { test: 'concurrent' },
|
|
1552
|
+
});
|
|
1553
|
+
expect(results).toHaveLength(10);
|
|
1554
|
+
}, 15000);
|
|
1555
|
+
|
|
1556
|
+
it('handles large batch operations', async () => {
|
|
1557
|
+
const batchSize = 100; // Using 100 instead of 1000 to keep tests fast
|
|
1558
|
+
const vectors = Array(batchSize)
|
|
1559
|
+
.fill(0)
|
|
1560
|
+
.map(() => [1, 0, 0]);
|
|
1561
|
+
const metadata = vectors.map((_, i) => ({ index: i, test: 'batch' }));
|
|
1562
|
+
const ids = vectors.map((_, i) => `batch-${i}`);
|
|
1563
|
+
|
|
1564
|
+
await vectorDB.upsert({
|
|
1565
|
+
indexName: perfTestIndex,
|
|
1566
|
+
vectors,
|
|
1567
|
+
metadata,
|
|
1568
|
+
ids,
|
|
1569
|
+
});
|
|
1570
|
+
|
|
1571
|
+
// Verify all vectors were inserted
|
|
1572
|
+
const stats = await vectorDB.describeIndex(perfTestIndex);
|
|
1573
|
+
expect(stats.count).toBe(batchSize);
|
|
1574
|
+
|
|
1575
|
+
const results = await vectorDB.query({
|
|
1576
|
+
indexName: perfTestIndex,
|
|
1577
|
+
queryVector: [1, 0, 0],
|
|
1578
|
+
filter: { test: 'batch' },
|
|
1579
|
+
topK: batchSize,
|
|
1580
|
+
});
|
|
1581
|
+
expect(results).toHaveLength(batchSize);
|
|
1582
|
+
|
|
1583
|
+
// Test querying with pagination
|
|
1584
|
+
const pageSize = 20;
|
|
1585
|
+
const pages: QueryResult[][] = [];
|
|
1586
|
+
for (let i = 0; i < batchSize; i += pageSize) {
|
|
1587
|
+
const page = await vectorDB.query({
|
|
1588
|
+
indexName: perfTestIndex,
|
|
1589
|
+
queryVector: [1, 0, 0],
|
|
1590
|
+
filter: { test: 'batch' },
|
|
1591
|
+
topK: pageSize,
|
|
1592
|
+
});
|
|
1593
|
+
pages.push(page);
|
|
1594
|
+
expect(page).toHaveLength(Math.min(pageSize, batchSize - i));
|
|
1595
|
+
}
|
|
1596
|
+
expect(pages).toHaveLength(Math.ceil(batchSize / pageSize));
|
|
1597
|
+
}, 30000);
|
|
1598
|
+
});
|
|
1518
1599
|
});
|
package/src/vector/index.ts
CHANGED
|
@@ -10,11 +10,10 @@ import type {
|
|
|
10
10
|
UpsertVectorArgs,
|
|
11
11
|
} from '@mastra/core/vector';
|
|
12
12
|
|
|
13
|
-
import { ChromaClient, Collection } from 'chromadb';
|
|
14
|
-
import { ChromaFilterTranslator } from './filter';
|
|
15
|
-
|
|
16
|
-
import type { UpdateRecordsParams } from 'chromadb';
|
|
17
13
|
import type { VectorFilter } from '@mastra/core/vector/filter';
|
|
14
|
+
import { ChromaClient } from 'chromadb';
|
|
15
|
+
import type { UpdateRecordsParams, Collection } from 'chromadb';
|
|
16
|
+
import { ChromaFilterTranslator } from './filter';
|
|
18
17
|
|
|
19
18
|
interface ChromaUpsertVectorParams extends UpsertVectorParams {
|
|
20
19
|
documents?: string[];
|