@mastra/chroma 0.1.0-alpha.34 → 0.1.0-alpha.36
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/CHANGELOG.md +16 -0
- package/package.json +5 -5
- package/src/vector/filter.ts +7 -1
- package/src/vector/index.ts +2 -2
- package/tsconfig.json +1 -6
- package/dist/index.d.ts +0 -25
- package/dist/index.js +0 -190
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @mastra/chroma
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.36
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4f1d1a1: Enforce types ann cleanup package.json
|
|
8
|
+
- Updated dependencies [66a03ec]
|
|
9
|
+
- Updated dependencies [4f1d1a1]
|
|
10
|
+
- @mastra/core@0.2.0-alpha.101
|
|
11
|
+
|
|
12
|
+
## 0.1.0-alpha.35
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [9d1796d]
|
|
17
|
+
- @mastra/core@0.2.0-alpha.100
|
|
18
|
+
|
|
3
19
|
## 0.1.0-alpha.34
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/chroma",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.36",
|
|
4
4
|
"description": "Chroma vector store provider for Mastra",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"chromadb": "^1.9.4",
|
|
19
|
-
"@mastra/core": "^0.2.0-alpha.
|
|
19
|
+
"@mastra/core": "^0.2.0-alpha.101"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@
|
|
23
|
-
"@types/node": "^22.
|
|
22
|
+
"@microsoft/api-extractor": "^7.49.2",
|
|
23
|
+
"@types/node": "^22.13.1",
|
|
24
24
|
"tsup": "^8.0.1",
|
|
25
25
|
"vitest": "^3.0.4"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
|
-
"build": "tsup src/index.ts --format esm --dts --clean --treeshake",
|
|
28
|
+
"build": "tsup src/index.ts --format esm --experimental-dts --clean --treeshake",
|
|
29
29
|
"build:watch": "pnpm build --watch",
|
|
30
30
|
"test": "vitest run"
|
|
31
31
|
}
|
package/src/vector/filter.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BaseFilterTranslator,
|
|
3
|
+
type FieldCondition,
|
|
4
|
+
type Filter,
|
|
5
|
+
type OperatorSupport,
|
|
6
|
+
type QueryOperator,
|
|
7
|
+
} from '@mastra/core/filter';
|
|
2
8
|
|
|
3
9
|
/**
|
|
4
10
|
* Translator for Chroma filter queries.
|
package/src/vector/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Filter } from '@mastra/core/filter';
|
|
2
|
-
import { MastraVector, QueryResult, IndexStats } from '@mastra/core/vector';
|
|
1
|
+
import { type Filter } from '@mastra/core/filter';
|
|
2
|
+
import { MastraVector, type QueryResult, type IndexStats } from '@mastra/core/vector';
|
|
3
3
|
import { ChromaClient } from 'chromadb';
|
|
4
4
|
|
|
5
5
|
import { ChromaFilterTranslator } from './filter';
|
package/tsconfig.json
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends": "../../tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"moduleResolution": "bundler",
|
|
5
|
-
"outDir": "./dist",
|
|
6
|
-
"rootDir": "./src"
|
|
7
|
-
},
|
|
2
|
+
"extends": "../../tsconfig.node.json",
|
|
8
3
|
"include": ["src/**/*"],
|
|
9
4
|
"exclude": ["node_modules", "**/*.test.ts"]
|
|
10
5
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Filter } from '@mastra/core/filter';
|
|
2
|
-
import { MastraVector, QueryResult, IndexStats } from '@mastra/core/vector';
|
|
3
|
-
|
|
4
|
-
declare class ChromaVector extends MastraVector {
|
|
5
|
-
private client;
|
|
6
|
-
private collections;
|
|
7
|
-
constructor({ path, auth, }: {
|
|
8
|
-
path: string;
|
|
9
|
-
auth?: {
|
|
10
|
-
provider: string;
|
|
11
|
-
credentials: string;
|
|
12
|
-
};
|
|
13
|
-
});
|
|
14
|
-
private getCollection;
|
|
15
|
-
private validateVectorDimensions;
|
|
16
|
-
upsert(indexName: string, vectors: number[][], metadata?: Record<string, any>[], ids?: string[]): Promise<string[]>;
|
|
17
|
-
createIndex(indexName: string, dimension: number, metric?: 'cosine' | 'euclidean' | 'dotproduct'): Promise<void>;
|
|
18
|
-
transformFilter(filter?: Filter): Filter | undefined;
|
|
19
|
-
query(indexName: string, queryVector: number[], topK?: number, filter?: Filter, includeVector?: boolean): Promise<QueryResult[]>;
|
|
20
|
-
listIndexes(): Promise<string[]>;
|
|
21
|
-
describeIndex(indexName: string): Promise<IndexStats>;
|
|
22
|
-
deleteIndex(indexName: string): Promise<void>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export { ChromaVector };
|
package/dist/index.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import { MastraVector } from '@mastra/core/vector';
|
|
2
|
-
import { ChromaClient } from 'chromadb';
|
|
3
|
-
import { BaseFilterTranslator } from '@mastra/core/filter';
|
|
4
|
-
|
|
5
|
-
// src/vector/index.ts
|
|
6
|
-
var ChromaFilterTranslator = class extends BaseFilterTranslator {
|
|
7
|
-
getSupportedOperators() {
|
|
8
|
-
return {
|
|
9
|
-
...BaseFilterTranslator.DEFAULT_OPERATORS,
|
|
10
|
-
logical: ["$and", "$or"],
|
|
11
|
-
array: ["$in", "$nin"],
|
|
12
|
-
element: [],
|
|
13
|
-
regex: [],
|
|
14
|
-
custom: []
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
translate(filter) {
|
|
18
|
-
if (this.isEmpty(filter)) return filter;
|
|
19
|
-
this.validateFilter(filter);
|
|
20
|
-
return this.translateNode(filter);
|
|
21
|
-
}
|
|
22
|
-
translateNode(node, currentPath = "") {
|
|
23
|
-
if (this.isRegex(node)) {
|
|
24
|
-
throw new Error("Regex is not supported in Chroma");
|
|
25
|
-
}
|
|
26
|
-
if (this.isPrimitive(node)) return this.normalizeComparisonValue(node);
|
|
27
|
-
if (Array.isArray(node)) return { $in: this.normalizeArrayValues(node) };
|
|
28
|
-
const entries = Object.entries(node);
|
|
29
|
-
const firstEntry = entries[0];
|
|
30
|
-
if (entries.length === 1 && firstEntry && this.isOperator(firstEntry[0])) {
|
|
31
|
-
const [operator, value] = firstEntry;
|
|
32
|
-
const translated = this.translateOperator(operator, value);
|
|
33
|
-
return this.isLogicalOperator(operator) ? { [operator]: translated } : translated;
|
|
34
|
-
}
|
|
35
|
-
const result = {};
|
|
36
|
-
const multiOperatorConditions = [];
|
|
37
|
-
for (const [key, value] of entries) {
|
|
38
|
-
const newPath = currentPath ? `${currentPath}.${key}` : key;
|
|
39
|
-
if (this.isOperator(key)) {
|
|
40
|
-
result[key] = this.translateOperator(key, value);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
44
|
-
const valueEntries = Object.entries(value);
|
|
45
|
-
if (valueEntries.every(([op]) => this.isOperator(op)) && valueEntries.length > 1) {
|
|
46
|
-
valueEntries.forEach(([op, opValue]) => {
|
|
47
|
-
multiOperatorConditions.push({
|
|
48
|
-
[newPath]: { [op]: this.normalizeComparisonValue(opValue) }
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
if (Object.keys(value).length === 0) {
|
|
54
|
-
result[newPath] = this.translateNode(value);
|
|
55
|
-
} else {
|
|
56
|
-
const hasOperators = Object.keys(value).some((k) => this.isOperator(k));
|
|
57
|
-
if (hasOperators) {
|
|
58
|
-
const normalizedValue = {};
|
|
59
|
-
for (const [op, opValue] of Object.entries(value)) {
|
|
60
|
-
normalizedValue[op] = this.isOperator(op) ? this.translateOperator(op, opValue) : opValue;
|
|
61
|
-
}
|
|
62
|
-
result[newPath] = normalizedValue;
|
|
63
|
-
} else {
|
|
64
|
-
Object.assign(result, this.translateNode(value, newPath));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
} else {
|
|
68
|
-
result[newPath] = this.translateNode(value);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (multiOperatorConditions.length > 0) {
|
|
72
|
-
return { $and: multiOperatorConditions };
|
|
73
|
-
}
|
|
74
|
-
if (Object.keys(result).length > 1 && !currentPath) {
|
|
75
|
-
return {
|
|
76
|
-
$and: Object.entries(result).map(([key, value]) => ({ [key]: value }))
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
return result;
|
|
80
|
-
}
|
|
81
|
-
translateOperator(operator, value) {
|
|
82
|
-
if (this.isLogicalOperator(operator)) {
|
|
83
|
-
return Array.isArray(value) ? value.map((item) => this.translateNode(item)) : this.translateNode(value);
|
|
84
|
-
}
|
|
85
|
-
return this.normalizeComparisonValue(value);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// src/vector/index.ts
|
|
90
|
-
var ChromaVector = class extends MastraVector {
|
|
91
|
-
constructor({
|
|
92
|
-
path,
|
|
93
|
-
auth
|
|
94
|
-
}) {
|
|
95
|
-
super();
|
|
96
|
-
this.client = new ChromaClient({
|
|
97
|
-
path,
|
|
98
|
-
auth
|
|
99
|
-
});
|
|
100
|
-
this.collections = /* @__PURE__ */ new Map();
|
|
101
|
-
}
|
|
102
|
-
async getCollection(indexName, throwIfNotExists = true) {
|
|
103
|
-
try {
|
|
104
|
-
const collection = await this.client.getCollection({ name: indexName, embeddingFunction: void 0 });
|
|
105
|
-
this.collections.set(indexName, collection);
|
|
106
|
-
} catch (error) {
|
|
107
|
-
if (throwIfNotExists) {
|
|
108
|
-
throw new Error(`Index ${indexName} does not exist`);
|
|
109
|
-
}
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
return this.collections.get(indexName);
|
|
113
|
-
}
|
|
114
|
-
validateVectorDimensions(vectors, dimension) {
|
|
115
|
-
for (let i = 0; i < vectors.length; i++) {
|
|
116
|
-
if (vectors?.[i]?.length !== dimension) {
|
|
117
|
-
throw new Error(
|
|
118
|
-
`Vector at index ${i} has invalid dimension ${vectors?.[i]?.length}. Expected ${dimension} dimensions.`
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
async upsert(indexName, vectors, metadata, ids) {
|
|
124
|
-
const collection = await this.getCollection(indexName);
|
|
125
|
-
const stats = await this.describeIndex(indexName);
|
|
126
|
-
this.validateVectorDimensions(vectors, stats.dimension);
|
|
127
|
-
const generatedIds = ids || vectors.map(() => crypto.randomUUID());
|
|
128
|
-
const normalizedMetadata = metadata || vectors.map(() => ({}));
|
|
129
|
-
await collection.upsert({
|
|
130
|
-
ids: generatedIds,
|
|
131
|
-
embeddings: vectors,
|
|
132
|
-
metadatas: normalizedMetadata
|
|
133
|
-
});
|
|
134
|
-
return generatedIds;
|
|
135
|
-
}
|
|
136
|
-
async createIndex(indexName, dimension, metric = "cosine") {
|
|
137
|
-
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
138
|
-
throw new Error("Dimension must be a positive integer");
|
|
139
|
-
}
|
|
140
|
-
await this.client.createCollection({
|
|
141
|
-
name: indexName,
|
|
142
|
-
metadata: {
|
|
143
|
-
dimension,
|
|
144
|
-
metric
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
transformFilter(filter) {
|
|
149
|
-
const chromaFilter = new ChromaFilterTranslator();
|
|
150
|
-
const translatedFilter = chromaFilter.translate(filter);
|
|
151
|
-
return translatedFilter;
|
|
152
|
-
}
|
|
153
|
-
async query(indexName, queryVector, topK = 10, filter, includeVector = false) {
|
|
154
|
-
const collection = await this.getCollection(indexName, true);
|
|
155
|
-
const defaultInclude = ["documents", "metadatas", "distances"];
|
|
156
|
-
const translatedFilter = this.transformFilter(filter);
|
|
157
|
-
const results = await collection.query({
|
|
158
|
-
queryEmbeddings: [queryVector],
|
|
159
|
-
nResults: topK,
|
|
160
|
-
where: translatedFilter,
|
|
161
|
-
include: includeVector ? [...defaultInclude, "embeddings"] : defaultInclude
|
|
162
|
-
});
|
|
163
|
-
return (results.ids[0] || []).map((id, index) => ({
|
|
164
|
-
id,
|
|
165
|
-
score: results.distances?.[0]?.[index] || 0,
|
|
166
|
-
metadata: results.metadatas?.[0]?.[index] || {},
|
|
167
|
-
...includeVector && { vector: results.embeddings?.[0]?.[index] || [] }
|
|
168
|
-
}));
|
|
169
|
-
}
|
|
170
|
-
async listIndexes() {
|
|
171
|
-
const collections = await this.client.listCollections();
|
|
172
|
-
return collections.map((collection) => collection);
|
|
173
|
-
}
|
|
174
|
-
async describeIndex(indexName) {
|
|
175
|
-
const collection = await this.getCollection(indexName);
|
|
176
|
-
const count = await collection.count();
|
|
177
|
-
const metadata = collection.metadata;
|
|
178
|
-
return {
|
|
179
|
-
dimension: metadata?.dimension || 0,
|
|
180
|
-
count,
|
|
181
|
-
metric: metadata?.metric
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
async deleteIndex(indexName) {
|
|
185
|
-
await this.client.deleteCollection({ name: indexName });
|
|
186
|
-
this.collections.delete(indexName);
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
export { ChromaVector };
|