chromadb 3.3.2 → 3.4.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.
- package/README.md +1 -1
- package/dist/chromadb.d.ts +224 -3
- package/dist/chromadb.legacy-esm.js +128 -67
- package/dist/chromadb.mjs +128 -67
- package/dist/chromadb.mjs.map +1 -1
- package/dist/cjs/chromadb.cjs +129 -67
- package/dist/cjs/chromadb.cjs.map +1 -1
- package/dist/cjs/chromadb.d.cts +224 -3
- package/package.json +1 -1
- package/src/api/sdk.gen.ts +18 -1
- package/src/api/types.gen.ts +56 -0
- package/src/chroma-client.ts +28 -6
- package/src/collection-configuration.ts +0 -1
- package/src/collection.ts +162 -6
- package/src/embedding-function.ts +11 -68
- package/src/index.ts +1 -1
- package/src/schema.ts +0 -2
package/src/collection.ts
CHANGED
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
processUpdateCollectionConfig,
|
|
46
46
|
UpdateCollectionConfiguration,
|
|
47
47
|
} from "./collection-configuration";
|
|
48
|
-
import { SearchLike, SearchResult, toSearch } from "./execution
|
|
48
|
+
import { SearchLike, SearchResult, toSearch } from "./execution";
|
|
49
49
|
import { isPlainObject } from "./execution/expression/common";
|
|
50
50
|
import { Schema, EMBEDDING_KEY, DOCUMENT_KEY } from "./schema";
|
|
51
51
|
import type { SparseVectorIndexConfig } from "./schema";
|
|
@@ -167,6 +167,11 @@ export interface Collection {
|
|
|
167
167
|
* @returns Promise resolving to the new Collection instance
|
|
168
168
|
*/
|
|
169
169
|
fork({ name }: { name: string }): Promise<Collection>;
|
|
170
|
+
/**
|
|
171
|
+
* Gets the number of forks for this collection.
|
|
172
|
+
* @returns Promise resolving to the number of forks
|
|
173
|
+
*/
|
|
174
|
+
forkCount(): Promise<number>;
|
|
170
175
|
/**
|
|
171
176
|
* Updates existing records in the collection.
|
|
172
177
|
* @param args - Record data to update
|
|
@@ -216,6 +221,7 @@ export interface Collection {
|
|
|
216
221
|
/**
|
|
217
222
|
* Performs hybrid search on the collection using expression builders.
|
|
218
223
|
* @param searches - Single search payload or array of payloads
|
|
224
|
+
* @param options
|
|
219
225
|
* @returns Promise resolving to column-major search results
|
|
220
226
|
*/
|
|
221
227
|
search(
|
|
@@ -366,7 +372,9 @@ export class CollectionImpl implements Collection {
|
|
|
366
372
|
|
|
367
373
|
if (!embeddingFunction) {
|
|
368
374
|
throw new ChromaValueError(
|
|
369
|
-
|
|
375
|
+
`No embedding function found for collection '${this._name}'. ` +
|
|
376
|
+
"You can either provide embeddings directly, or ensure the appropriate " +
|
|
377
|
+
"embedding function package (e.g. @chroma-core/default-embed) is installed.",
|
|
370
378
|
);
|
|
371
379
|
}
|
|
372
380
|
|
|
@@ -459,10 +467,8 @@ export class CollectionImpl implements Collection {
|
|
|
459
467
|
// Get document at this position
|
|
460
468
|
if (index < documentsList.length) {
|
|
461
469
|
const doc = documentsList[index];
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
positions.push(index);
|
|
465
|
-
}
|
|
470
|
+
inputs.push(doc);
|
|
471
|
+
positions.push(index);
|
|
466
472
|
}
|
|
467
473
|
});
|
|
468
474
|
|
|
@@ -1027,6 +1033,15 @@ export class CollectionImpl implements Collection {
|
|
|
1027
1033
|
});
|
|
1028
1034
|
}
|
|
1029
1035
|
|
|
1036
|
+
public async forkCount(): Promise<number> {
|
|
1037
|
+
const { data } = await CollectionService.forkCount({
|
|
1038
|
+
client: this.apiClient,
|
|
1039
|
+
path: await this.path(),
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
return data.count;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1030
1045
|
public async update({
|
|
1031
1046
|
ids,
|
|
1032
1047
|
embeddings,
|
|
@@ -1140,3 +1155,144 @@ export class CollectionImpl implements Collection {
|
|
|
1140
1155
|
return data;
|
|
1141
1156
|
}
|
|
1142
1157
|
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Arguments for creating a CollectionHandle instance.
|
|
1161
|
+
*/
|
|
1162
|
+
export interface CollectionHandleArgs {
|
|
1163
|
+
/** ChromaDB client instance */
|
|
1164
|
+
chromaClient: ChromaClient;
|
|
1165
|
+
/** HTTP API client */
|
|
1166
|
+
apiClient: ReturnType<typeof createClient>;
|
|
1167
|
+
/** Collection ID */
|
|
1168
|
+
id: string;
|
|
1169
|
+
/** Tenant name */
|
|
1170
|
+
tenant: string;
|
|
1171
|
+
/** Database name */
|
|
1172
|
+
database: string;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
const HANDLE_EMBEDDING_ERROR =
|
|
1176
|
+
"This operation requires an embedding function, which is not available on " +
|
|
1177
|
+
"a collection obtained via client.collection(id). Provide pre-computed " +
|
|
1178
|
+
"embeddings directly, or use client.getCollection() to get a full " +
|
|
1179
|
+
"collection with embedding support.";
|
|
1180
|
+
|
|
1181
|
+
const HANDLE_NOT_SUPPORTED_ERROR =
|
|
1182
|
+
"is not supported on a collection obtained via client.collection(id). " +
|
|
1183
|
+
"Use client.getCollection() to get a full collection instance.";
|
|
1184
|
+
|
|
1185
|
+
/**
|
|
1186
|
+
* A lightweight collection handle that holds only the collection ID and
|
|
1187
|
+
* client context. Supports operations that don't require an embedding
|
|
1188
|
+
* function or schema. Obtained via {@link ChromaClient.collection}.
|
|
1189
|
+
*/
|
|
1190
|
+
export class CollectionHandle extends CollectionImpl {
|
|
1191
|
+
constructor({ chromaClient, apiClient, id, tenant, database }: CollectionHandleArgs) {
|
|
1192
|
+
super({
|
|
1193
|
+
chromaClient,
|
|
1194
|
+
apiClient,
|
|
1195
|
+
id,
|
|
1196
|
+
tenant,
|
|
1197
|
+
database,
|
|
1198
|
+
name: "",
|
|
1199
|
+
configuration: {},
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
public override async add(args: {
|
|
1204
|
+
ids: string[];
|
|
1205
|
+
embeddings?: number[][];
|
|
1206
|
+
metadatas?: Metadata[];
|
|
1207
|
+
documents?: string[];
|
|
1208
|
+
uris?: string[];
|
|
1209
|
+
}): Promise<void> {
|
|
1210
|
+
if (!args.embeddings) {
|
|
1211
|
+
throw new ChromaValueError(HANDLE_EMBEDDING_ERROR);
|
|
1212
|
+
}
|
|
1213
|
+
return super.add(args);
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
public override async update(args: {
|
|
1217
|
+
ids: string[];
|
|
1218
|
+
embeddings?: number[][];
|
|
1219
|
+
metadatas?: Metadata[];
|
|
1220
|
+
documents?: string[];
|
|
1221
|
+
uris?: string[];
|
|
1222
|
+
}): Promise<void> {
|
|
1223
|
+
if (!args.embeddings && args.documents) {
|
|
1224
|
+
throw new ChromaValueError(HANDLE_EMBEDDING_ERROR);
|
|
1225
|
+
}
|
|
1226
|
+
return super.update(args);
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
public override async upsert(args: {
|
|
1230
|
+
ids: string[];
|
|
1231
|
+
embeddings?: number[][];
|
|
1232
|
+
metadatas?: Metadata[];
|
|
1233
|
+
documents?: string[];
|
|
1234
|
+
uris?: string[];
|
|
1235
|
+
}): Promise<void> {
|
|
1236
|
+
if (!args.embeddings) {
|
|
1237
|
+
throw new ChromaValueError(HANDLE_EMBEDDING_ERROR);
|
|
1238
|
+
}
|
|
1239
|
+
return super.upsert(args);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
public override async query<TMeta extends Metadata = Metadata>(args: {
|
|
1243
|
+
queryEmbeddings?: number[][];
|
|
1244
|
+
queryTexts?: string[];
|
|
1245
|
+
queryURIs?: string[];
|
|
1246
|
+
ids?: string[];
|
|
1247
|
+
nResults?: number;
|
|
1248
|
+
where?: Where;
|
|
1249
|
+
whereDocument?: WhereDocument;
|
|
1250
|
+
include?: Include[];
|
|
1251
|
+
}): Promise<QueryResult<TMeta>> {
|
|
1252
|
+
if (!args.queryEmbeddings) {
|
|
1253
|
+
throw new ChromaValueError(HANDLE_EMBEDDING_ERROR);
|
|
1254
|
+
}
|
|
1255
|
+
return super.query(args);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
public override async search(
|
|
1259
|
+
searches: SearchLike | SearchLike[],
|
|
1260
|
+
options?: { readLevel?: ReadLevel },
|
|
1261
|
+
): Promise<SearchResult> {
|
|
1262
|
+
const items = Array.isArray(searches) ? searches : [searches];
|
|
1263
|
+
for (const search of items) {
|
|
1264
|
+
const payload = toSearch(search).toPayload();
|
|
1265
|
+
if (this.hasStringKnnQuery(payload.rank)) {
|
|
1266
|
+
throw new ChromaValueError(HANDLE_EMBEDDING_ERROR);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
return super.search(searches, options);
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
public override async modify(_args: {
|
|
1273
|
+
name?: string;
|
|
1274
|
+
metadata?: CollectionMetadata;
|
|
1275
|
+
configuration?: UpdateCollectionConfiguration;
|
|
1276
|
+
}): Promise<void> {
|
|
1277
|
+
throw new ChromaValueError(`modify() ${HANDLE_NOT_SUPPORTED_ERROR}`);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
public override async fork(_args: { name: string }): Promise<Collection> {
|
|
1281
|
+
throw new ChromaValueError(`fork() ${HANDLE_NOT_SUPPORTED_ERROR}`);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
private hasStringKnnQuery(obj: unknown): boolean {
|
|
1285
|
+
if (!obj || typeof obj !== "object") return false;
|
|
1286
|
+
if (Array.isArray(obj)) {
|
|
1287
|
+
return obj.some((item) => this.hasStringKnnQuery(item));
|
|
1288
|
+
}
|
|
1289
|
+
const record = obj as Record<string, unknown>;
|
|
1290
|
+
if ("$knn" in record && isPlainObject(record.$knn)) {
|
|
1291
|
+
const knn = record.$knn as Record<string, unknown>;
|
|
1292
|
+
if (typeof knn.query === "string") return true;
|
|
1293
|
+
}
|
|
1294
|
+
return Object.values(record).some((value) =>
|
|
1295
|
+
this.hasStringKnnQuery(value),
|
|
1296
|
+
);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { EmbeddingFunctionConfiguration, SparseVector } from "./api";
|
|
2
2
|
import { ChromaValueError } from "./errors";
|
|
3
|
-
import { DefaultEmbeddingFunction } from "@chroma-core/default-embed";
|
|
4
3
|
import { ChromaClient } from "./chroma-client";
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -140,7 +139,8 @@ const pythonEmbeddingFunctions: Record<string, string> = {
|
|
|
140
139
|
default: "default-embed",
|
|
141
140
|
together_ai: "together-ai",
|
|
142
141
|
sentence_transformer: "sentence-transformer",
|
|
143
|
-
|
|
142
|
+
google_gemini: "google-gemini",
|
|
143
|
+
google_genai: "google-gemini", // Backward compatibility alias
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
const unsupportedEmbeddingFunctions: Set<string> = new Set([
|
|
@@ -225,41 +225,16 @@ export const registerSparseEmbeddingFunction = (
|
|
|
225
225
|
* @returns EmbeddingFunction instance or undefined if it cannot be constructed
|
|
226
226
|
*/
|
|
227
227
|
export const getEmbeddingFunction = async (args: {
|
|
228
|
-
collectionName: string;
|
|
229
228
|
client: ChromaClient;
|
|
230
229
|
efConfig?: EmbeddingFunctionConfiguration;
|
|
231
230
|
}) => {
|
|
232
|
-
const {
|
|
231
|
+
const { client, efConfig } = args;
|
|
233
232
|
|
|
234
|
-
if (
|
|
235
|
-
console.warn(
|
|
236
|
-
`No embedding function configuration found for collection ${collectionName}. 'add' and 'query' will fail unless you provide them embeddings directly.`,
|
|
237
|
-
);
|
|
238
|
-
return undefined;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (efConfig.type === "legacy") {
|
|
242
|
-
console.warn(
|
|
243
|
-
`No embedding function configuration found for collection ${collectionName}. 'add' and 'query' will fail unless you provide them embeddings directly.`,
|
|
244
|
-
);
|
|
245
|
-
return undefined;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (efConfig.type === "unknown") {
|
|
249
|
-
console.warn(
|
|
250
|
-
`Unknown embedding function configuration for collection ${collectionName}. 'add' and 'query' will fail unless you provide them embeddings directly.`,
|
|
251
|
-
);
|
|
252
|
-
return undefined;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (efConfig.type !== "known") {
|
|
233
|
+
if (efConfig?.type !== "known") {
|
|
256
234
|
return undefined;
|
|
257
235
|
}
|
|
258
236
|
|
|
259
237
|
if (unsupportedEmbeddingFunctions.has(efConfig.name)) {
|
|
260
|
-
console.warn(
|
|
261
|
-
`Embedding function ${efConfig.name} is not supported in the JS/TS SDK. 'add' and 'query' will fail unless you provide them embeddings directly.`,
|
|
262
|
-
);
|
|
263
238
|
return undefined;
|
|
264
239
|
}
|
|
265
240
|
|
|
@@ -276,33 +251,23 @@ export const getEmbeddingFunction = async (args: {
|
|
|
276
251
|
await import(fullPackageName);
|
|
277
252
|
embeddingFunction = knownEmbeddingFunctions.get(packageName);
|
|
278
253
|
} catch (error) {
|
|
279
|
-
// Dynamic loading failed
|
|
254
|
+
// Dynamic loading failed
|
|
280
255
|
}
|
|
281
256
|
|
|
282
257
|
if (!embeddingFunction) {
|
|
283
|
-
console.warn(
|
|
284
|
-
`Collection ${collectionName} was created with the ${packageName} embedding function. However, the @chroma-core/${packageName} package is not installed. 'add' and 'query' will fail unless you provide them embeddings directly, or install the @chroma-core/${packageName} package.`,
|
|
285
|
-
);
|
|
286
258
|
return undefined;
|
|
287
259
|
}
|
|
288
260
|
}
|
|
289
261
|
|
|
290
|
-
|
|
291
|
-
|
|
262
|
+
const constructorConfig: Record<string, any> =
|
|
263
|
+
(efConfig.config as Record<string, any>) ?? {};
|
|
292
264
|
|
|
293
265
|
try {
|
|
294
266
|
if (embeddingFunction.buildFromConfig) {
|
|
295
267
|
return embeddingFunction.buildFromConfig(constructorConfig, client);
|
|
296
268
|
}
|
|
297
|
-
|
|
298
|
-
console.warn(
|
|
299
|
-
`Embedding function ${packageName} does not define a 'buildFromConfig' function. 'add' and 'query' will fail unless you provide them embeddings directly.`,
|
|
300
|
-
);
|
|
301
269
|
return undefined;
|
|
302
270
|
} catch (e) {
|
|
303
|
-
console.warn(
|
|
304
|
-
`Embedding function ${packageName} failed to build with config: ${constructorConfig}. 'add' and 'query' will fail unless you provide them embeddings directly. Error: ${e}`,
|
|
305
|
-
);
|
|
306
271
|
return undefined;
|
|
307
272
|
}
|
|
308
273
|
};
|
|
@@ -312,26 +277,14 @@ export const getEmbeddingFunction = async (args: {
|
|
|
312
277
|
* @returns SparseEmbeddingFunction instance or undefined if it cannot be constructed
|
|
313
278
|
*/
|
|
314
279
|
export const getSparseEmbeddingFunction = async (
|
|
315
|
-
collectionName: string,
|
|
316
280
|
client: ChromaClient,
|
|
317
281
|
efConfig?: EmbeddingFunctionConfiguration,
|
|
318
282
|
) => {
|
|
319
|
-
if (
|
|
320
|
-
return undefined;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (efConfig.type === "legacy") {
|
|
324
|
-
return undefined;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (efConfig.type !== "known") {
|
|
283
|
+
if (efConfig?.type !== "known") {
|
|
328
284
|
return undefined;
|
|
329
285
|
}
|
|
330
286
|
|
|
331
287
|
if (unsupportedSparseEmbeddingFunctions.has(efConfig.name)) {
|
|
332
|
-
console.warn(
|
|
333
|
-
"Embedding function ${efConfig.name} is not supported in the JS/TS SDK. 'add' and 'query' will fail unless you provide them embeddings directly.",
|
|
334
|
-
);
|
|
335
288
|
return undefined;
|
|
336
289
|
}
|
|
337
290
|
|
|
@@ -345,33 +298,23 @@ export const getSparseEmbeddingFunction = async (
|
|
|
345
298
|
await import(fullPackageName);
|
|
346
299
|
sparseEmbeddingFunction = knownSparseEmbeddingFunctions.get(packageName);
|
|
347
300
|
} catch (error) {
|
|
348
|
-
// Dynamic loading failed
|
|
301
|
+
// Dynamic loading failed
|
|
349
302
|
}
|
|
350
303
|
|
|
351
304
|
if (!sparseEmbeddingFunction) {
|
|
352
|
-
console.warn(
|
|
353
|
-
`Collection ${collectionName} was created with the ${packageName} sparse embedding function. However, the @chroma-core/${packageName} package is not installed.`,
|
|
354
|
-
);
|
|
355
305
|
return undefined;
|
|
356
306
|
}
|
|
357
307
|
}
|
|
358
308
|
|
|
359
|
-
|
|
360
|
-
|
|
309
|
+
const constructorConfig: Record<string, any> =
|
|
310
|
+
(efConfig.config as Record<string, any>) ?? {};
|
|
361
311
|
|
|
362
312
|
try {
|
|
363
313
|
if (sparseEmbeddingFunction.buildFromConfig) {
|
|
364
314
|
return sparseEmbeddingFunction.buildFromConfig(constructorConfig, client);
|
|
365
315
|
}
|
|
366
|
-
|
|
367
|
-
console.warn(
|
|
368
|
-
`Sparse embedding function ${packageName} does not define a 'buildFromConfig' function.`,
|
|
369
|
-
);
|
|
370
316
|
return undefined;
|
|
371
317
|
} catch (e) {
|
|
372
|
-
console.warn(
|
|
373
|
-
`Sparse embedding function ${packageName} failed to build with config: ${constructorConfig}. Error: ${e}`,
|
|
374
|
-
);
|
|
375
318
|
return undefined;
|
|
376
319
|
}
|
|
377
320
|
};
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// Apply Deno compatibility patch
|
|
7
7
|
import "./deno";
|
|
8
8
|
|
|
9
|
-
export { Collection } from "./collection";
|
|
9
|
+
export { Collection, CollectionHandle } from "./collection";
|
|
10
10
|
export { withChroma } from "./next";
|
|
11
11
|
export * from "./types";
|
|
12
12
|
export * from "./admin-client";
|
package/src/schema.ts
CHANGED
|
@@ -1285,7 +1285,6 @@ export class Schema {
|
|
|
1285
1285
|
});
|
|
1286
1286
|
|
|
1287
1287
|
config.embeddingFunction = await getEmbeddingFunction({
|
|
1288
|
-
collectionName: "schema deserialization",
|
|
1289
1288
|
client,
|
|
1290
1289
|
efConfig: json.embedding_function as EmbeddingFunctionConfiguration,
|
|
1291
1290
|
});
|
|
@@ -1307,7 +1306,6 @@ export class Schema {
|
|
|
1307
1306
|
|
|
1308
1307
|
const embeddingFunction =
|
|
1309
1308
|
(await getSparseEmbeddingFunction(
|
|
1310
|
-
"schema deserialization",
|
|
1311
1309
|
client,
|
|
1312
1310
|
json.embedding_function as EmbeddingFunctionConfiguration,
|
|
1313
1311
|
)) ??
|