chromadb 3.2.0 → 3.2.2
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/dist/chromadb.d.ts +38 -3
- package/dist/chromadb.legacy-esm.js +98 -23
- package/dist/chromadb.mjs +98 -23
- package/dist/chromadb.mjs.map +1 -1
- package/dist/cjs/chromadb.cjs +99 -23
- package/dist/cjs/chromadb.cjs.map +1 -1
- package/dist/cjs/chromadb.d.cts +38 -3
- package/package.json +6 -6
- package/src/api/sdk.gen.ts +11 -1
- package/src/api/types.gen.ts +60 -0
- package/src/chroma-fetch.ts +16 -8
- package/src/collection-configuration.ts +15 -6
- package/src/collection.ts +34 -2
- package/src/execution/expression/common.ts +3 -1
- package/src/execution/expression/groupBy.ts +5 -9
- package/src/execution/expression/rank.ts +69 -20
- package/src/execution/expression/searchResult.ts +12 -3
- package/src/execution/expression/select.ts +4 -1
- package/src/execution/expression/where.ts +34 -8
- package/src/schema.ts +11 -16
- package/src/types.ts +26 -1
- package/src/utils.ts +9 -3
package/dist/cjs/chromadb.d.cts
CHANGED
|
@@ -86,6 +86,12 @@ type HnswIndexConfig = {
|
|
|
86
86
|
sync_threshold?: number | null;
|
|
87
87
|
};
|
|
88
88
|
type Include = 'distances' | 'documents' | 'embeddings' | 'metadatas' | 'uris';
|
|
89
|
+
type IndexStatusResponse = {
|
|
90
|
+
num_indexed_ops: number;
|
|
91
|
+
num_unindexed_ops: number;
|
|
92
|
+
op_indexing_progress: number;
|
|
93
|
+
total_ops: number;
|
|
94
|
+
};
|
|
89
95
|
type IntInvertedIndexConfig$1 = {
|
|
90
96
|
[key: string]: never;
|
|
91
97
|
};
|
|
@@ -366,6 +372,19 @@ type VectorIndexType$1 = {
|
|
|
366
372
|
* User identity information including tenant and database access.
|
|
367
373
|
*/
|
|
368
374
|
type UserIdentity = GetUserIdentityResponse;
|
|
375
|
+
/**
|
|
376
|
+
* Read level controls whether queries read from the write-ahead log (WAL).
|
|
377
|
+
*
|
|
378
|
+
* - INDEX_AND_WAL: Read from both the compacted index and the WAL.
|
|
379
|
+
* All committed writes will be visible. This is the default.
|
|
380
|
+
* - INDEX_ONLY: Read only from the compacted index, skipping the WAL.
|
|
381
|
+
* Recent writes that haven't been compacted may not be visible, but queries are faster.
|
|
382
|
+
*/
|
|
383
|
+
declare const ReadLevel: {
|
|
384
|
+
readonly INDEX_AND_WAL: "index_and_wal";
|
|
385
|
+
readonly INDEX_ONLY: "index_only";
|
|
386
|
+
};
|
|
387
|
+
type ReadLevel = (typeof ReadLevel)[keyof typeof ReadLevel];
|
|
369
388
|
|
|
370
389
|
/**
|
|
371
390
|
* Metadata that can be associated with a collection.
|
|
@@ -567,6 +586,10 @@ declare class QueryResult<TMeta extends Metadata = Metadata> {
|
|
|
567
586
|
*/
|
|
568
587
|
rows(): QueryRowResult<TMeta>[][];
|
|
569
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Re-export IndexStatusResponse type for external use
|
|
591
|
+
*/
|
|
592
|
+
type IndexingStatus = IndexStatusResponse;
|
|
570
593
|
|
|
571
594
|
/**
|
|
572
595
|
* Supported vector space types.
|
|
@@ -842,7 +865,7 @@ interface RrfOptions {
|
|
|
842
865
|
weights?: number[];
|
|
843
866
|
normalize?: boolean;
|
|
844
867
|
}
|
|
845
|
-
declare const Rrf: ({ ranks, k, weights, normalize }: RrfOptions) => RankExpression;
|
|
868
|
+
declare const Rrf: ({ ranks, k, weights, normalize, }: RrfOptions) => RankExpression;
|
|
846
869
|
declare const Sum: (...inputs: RankInput[]) => RankExpression;
|
|
847
870
|
declare const Sub: (left: RankInput, right: RankInput) => RankExpression;
|
|
848
871
|
declare const Mul: (...inputs: RankInput[]) => RankExpression;
|
|
@@ -1642,7 +1665,19 @@ interface Collection {
|
|
|
1642
1665
|
* @param searches - Single search payload or array of payloads
|
|
1643
1666
|
* @returns Promise resolving to column-major search results
|
|
1644
1667
|
*/
|
|
1645
|
-
search(searches: SearchLike | SearchLike[]
|
|
1668
|
+
search(searches: SearchLike | SearchLike[], options?: {
|
|
1669
|
+
/**
|
|
1670
|
+
* Controls whether to read from the write-ahead log.
|
|
1671
|
+
* - ReadLevel.INDEX_AND_WAL: Read from both index and WAL (default)
|
|
1672
|
+
* - ReadLevel.INDEX_ONLY: Read only from index, faster but recent writes may not be visible
|
|
1673
|
+
*/
|
|
1674
|
+
readLevel?: ReadLevel;
|
|
1675
|
+
}): Promise<SearchResult>;
|
|
1676
|
+
/**
|
|
1677
|
+
* Gets the indexing status of the collection.
|
|
1678
|
+
* @returns Promise resolving to indexing status information
|
|
1679
|
+
*/
|
|
1680
|
+
getIndexingStatus(): Promise<IndexingStatus>;
|
|
1646
1681
|
}
|
|
1647
1682
|
|
|
1648
1683
|
declare function withChroma(userNextConfig?: any): any;
|
|
@@ -1862,4 +1897,4 @@ declare class ChromaRateLimitError extends Error {
|
|
|
1862
1897
|
}
|
|
1863
1898
|
declare function createErrorByType(type: string, message: string): InvalidCollectionError | InvalidArgumentError | undefined;
|
|
1864
1899
|
|
|
1865
|
-
export { Abs, AdminClient, type AdminClientArgs, AdminCloudClient, Aggregate, type AggregateInput, type AggregateJSON, type AnyEmbeddingFunction, type BaseRecordSet, BoolInvertedIndexConfig, BoolInvertedIndexType, BoolValueType, ChromaClient, type ChromaClientArgs, ChromaClientError, ChromaConnectionError, ChromaError, ChromaForbiddenError, ChromaNotFoundError, ChromaQuotaExceededError, ChromaRateLimitError, ChromaServerError, ChromaUnauthorizedError, ChromaUniqueError, ChromaValueError, CloudClient, Cmek, CmekProvider, type Collection, type CollectionConfiguration, type CollectionMetadata, type CreateCollectionConfiguration, DOCUMENT_KEY, Div, EMBEDDING_KEY, type EmbeddingFunction, type EmbeddingFunctionClass, type EmbeddingFunctionSpace, Exp, FloatInvertedIndexConfig, FloatInvertedIndexType, FloatListValueType, FloatValueType, FtsIndexConfig, FtsIndexType, GetResult, GroupBy, type GroupByInput, type GroupByJSON, type HNSWConfiguration, IncludeEnum, type IndexConfig, IntInvertedIndexConfig, IntInvertedIndexType, IntValueType, InvalidArgumentError, InvalidCollectionError, K, Key, type KeyFactory, Knn, type KnnOptions, Limit, type LimitInput, type LimitOptions, type ListDatabasesArgs, Log, Max, MaxK, type Metadata, Min, MinK, Mul, type PreparedInsertRecordSet, type PreparedRecordSet, type QueryRecordSet, QueryResult, type QueryRowResult, RankExpression, type RankInput, type RankLiteral, type RecordSet, Rrf, type RrfOptions, Schema, Search, type SearchInit, type SearchLike, SearchResult, type SearchResultRow, Select, type SelectInput, type SelectKeyInput, type SparseEmbeddingFunction, type SparseEmbeddingFunctionClass, type SparseVector, SparseVectorIndexConfig, type SparseVectorIndexConfigOptions, SparseVectorIndexType, SparseVectorValueType, StringInvertedIndexConfig, StringInvertedIndexType, StringValueType, Sub, Sum, type UpdateCollectionConfiguration, type UpdateHNSWConfiguration, type UpdateSPANNConfiguration, type UserIdentity, Val, ValueTypes, VectorIndexConfig, type VectorIndexConfigOptions, VectorIndexType, type Where, type WhereDocument, WhereExpression, type WhereInput, type WhereJSON, baseRecordSetFields, createErrorByType, getDefaultEFConfig, getEmbeddingFunction, getSparseEmbeddingFunction, knownEmbeddingFunctions, knownSparseEmbeddingFunctions, processCreateCollectionConfig, processUpdateCollectionConfig, recordSetFields, registerEmbeddingFunction, registerSparseEmbeddingFunction, serializeEmbeddingFunction, toSearch, withChroma };
|
|
1900
|
+
export { Abs, AdminClient, type AdminClientArgs, AdminCloudClient, Aggregate, type AggregateInput, type AggregateJSON, type AnyEmbeddingFunction, type BaseRecordSet, BoolInvertedIndexConfig, BoolInvertedIndexType, BoolValueType, ChromaClient, type ChromaClientArgs, ChromaClientError, ChromaConnectionError, ChromaError, ChromaForbiddenError, ChromaNotFoundError, ChromaQuotaExceededError, ChromaRateLimitError, ChromaServerError, ChromaUnauthorizedError, ChromaUniqueError, ChromaValueError, CloudClient, Cmek, CmekProvider, type Collection, type CollectionConfiguration, type CollectionMetadata, type CreateCollectionConfiguration, DOCUMENT_KEY, Div, EMBEDDING_KEY, type EmbeddingFunction, type EmbeddingFunctionClass, type EmbeddingFunctionSpace, Exp, FloatInvertedIndexConfig, FloatInvertedIndexType, FloatListValueType, FloatValueType, FtsIndexConfig, FtsIndexType, GetResult, GroupBy, type GroupByInput, type GroupByJSON, type HNSWConfiguration, IncludeEnum, type IndexConfig, type IndexingStatus, IntInvertedIndexConfig, IntInvertedIndexType, IntValueType, InvalidArgumentError, InvalidCollectionError, K, Key, type KeyFactory, Knn, type KnnOptions, Limit, type LimitInput, type LimitOptions, type ListDatabasesArgs, Log, Max, MaxK, type Metadata, Min, MinK, Mul, type PreparedInsertRecordSet, type PreparedRecordSet, type QueryRecordSet, QueryResult, type QueryRowResult, RankExpression, type RankInput, type RankLiteral, ReadLevel, type RecordSet, Rrf, type RrfOptions, Schema, Search, type SearchInit, type SearchLike, SearchResult, type SearchResultRow, Select, type SelectInput, type SelectKeyInput, type SparseEmbeddingFunction, type SparseEmbeddingFunctionClass, type SparseVector, SparseVectorIndexConfig, type SparseVectorIndexConfigOptions, SparseVectorIndexType, SparseVectorValueType, StringInvertedIndexConfig, StringInvertedIndexType, StringValueType, Sub, Sum, type UpdateCollectionConfiguration, type UpdateHNSWConfiguration, type UpdateSPANNConfiguration, type UserIdentity, Val, ValueTypes, VectorIndexConfig, type VectorIndexConfigOptions, VectorIndexType, type Where, type WhereDocument, WhereExpression, type WhereInput, type WhereJSON, baseRecordSetFields, createErrorByType, getDefaultEFConfig, getEmbeddingFunction, getSparseEmbeddingFunction, knownEmbeddingFunctions, knownSparseEmbeddingFunctions, processCreateCollectionConfig, processUpdateCollectionConfig, recordSetFields, registerEmbeddingFunction, registerSparseEmbeddingFunction, serializeEmbeddingFunction, toSearch, withChroma };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chromadb",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "A JavaScript interface for chroma",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chroma",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
"@chroma-core/default-embed": "^0.1.9"
|
|
61
61
|
},
|
|
62
62
|
"optionalDependencies": {
|
|
63
|
-
"chromadb-js-bindings-darwin-arm64": "^1.2.
|
|
64
|
-
"chromadb-js-bindings-darwin-x64": "^1.2.
|
|
65
|
-
"chromadb-js-bindings-linux-arm64-gnu": "^1.2.
|
|
66
|
-
"chromadb-js-bindings-linux-x64-gnu": "^1.2.
|
|
67
|
-
"chromadb-js-bindings-win32-x64-msvc": "^1.2.
|
|
63
|
+
"chromadb-js-bindings-darwin-arm64": "^1.2.1",
|
|
64
|
+
"chromadb-js-bindings-darwin-x64": "^1.2.1",
|
|
65
|
+
"chromadb-js-bindings-linux-arm64-gnu": "^1.2.1",
|
|
66
|
+
"chromadb-js-bindings-linux-x64-gnu": "^1.2.1",
|
|
67
|
+
"chromadb-js-bindings-win32-x64-msvc": "^1.2.1"
|
|
68
68
|
},
|
|
69
69
|
"engines": {
|
|
70
70
|
"node": ">=20"
|
package/src/api/sdk.gen.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
2
|
|
|
3
3
|
import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';
|
|
4
|
-
import type { GetUserIdentityData, GetUserIdentityResponse2, GetUserIdentityError, GetCollectionByCrnData, GetCollectionByCrnResponse, GetCollectionByCrnError, HealthcheckData, HealthcheckResponse, HealthcheckError, HeartbeatData, HeartbeatResponse2, HeartbeatError, PreFlightChecksData, PreFlightChecksResponse, PreFlightChecksError, ResetData, ResetResponse, ResetError, CreateTenantData, CreateTenantResponse2, CreateTenantError, GetTenantData, GetTenantResponse2, GetTenantError, UpdateTenantData, UpdateTenantResponse2, UpdateTenantError, ListDatabasesData, ListDatabasesResponse, ListDatabasesError, CreateDatabaseData, CreateDatabaseResponse2, CreateDatabaseError, DeleteDatabaseData, DeleteDatabaseResponse2, DeleteDatabaseError, GetDatabaseData, GetDatabaseResponse, GetDatabaseError, ListCollectionsData, ListCollectionsResponse, ListCollectionsError, CreateCollectionData, CreateCollectionResponse, CreateCollectionError, DeleteCollectionData, DeleteCollectionResponse, DeleteCollectionError, GetCollectionData, GetCollectionResponse, GetCollectionError, UpdateCollectionData, UpdateCollectionResponse2, UpdateCollectionError, CollectionAddData, CollectionAddResponse, DetachFunctionData, DetachFunctionResponse2, DetachFunctionError, CollectionCountData, CollectionCountResponse, CollectionCountError, CollectionDeleteData, CollectionDeleteResponse, CollectionDeleteError, ForkCollectionData, ForkCollectionResponse, ForkCollectionError, AttachFunctionData, AttachFunctionResponse2, AttachFunctionError, GetAttachedFunctionData, GetAttachedFunctionResponse2, GetAttachedFunctionError, CollectionGetData, CollectionGetResponse, CollectionGetError, CollectionQueryData, CollectionQueryResponse, CollectionQueryError, CollectionSearchData, CollectionSearchResponse, CollectionSearchError, CollectionUpdateData, CollectionUpdateResponse, CollectionUpsertData, CollectionUpsertResponse, CollectionUpsertError, CountCollectionsData, CountCollectionsResponse, CountCollectionsError, VersionData, VersionResponse } from './types.gen';
|
|
4
|
+
import type { GetUserIdentityData, GetUserIdentityResponse2, GetUserIdentityError, GetCollectionByCrnData, GetCollectionByCrnResponse, GetCollectionByCrnError, HealthcheckData, HealthcheckResponse, HealthcheckError, HeartbeatData, HeartbeatResponse2, HeartbeatError, PreFlightChecksData, PreFlightChecksResponse, PreFlightChecksError, ResetData, ResetResponse, ResetError, CreateTenantData, CreateTenantResponse2, CreateTenantError, GetTenantData, GetTenantResponse2, GetTenantError, UpdateTenantData, UpdateTenantResponse2, UpdateTenantError, ListDatabasesData, ListDatabasesResponse, ListDatabasesError, CreateDatabaseData, CreateDatabaseResponse2, CreateDatabaseError, DeleteDatabaseData, DeleteDatabaseResponse2, DeleteDatabaseError, GetDatabaseData, GetDatabaseResponse, GetDatabaseError, ListCollectionsData, ListCollectionsResponse, ListCollectionsError, CreateCollectionData, CreateCollectionResponse, CreateCollectionError, DeleteCollectionData, DeleteCollectionResponse, DeleteCollectionError, GetCollectionData, GetCollectionResponse, GetCollectionError, UpdateCollectionData, UpdateCollectionResponse2, UpdateCollectionError, CollectionAddData, CollectionAddResponse, DetachFunctionData, DetachFunctionResponse2, DetachFunctionError, CollectionCountData, CollectionCountResponse, CollectionCountError, CollectionDeleteData, CollectionDeleteResponse, CollectionDeleteError, ForkCollectionData, ForkCollectionResponse, ForkCollectionError, AttachFunctionData, AttachFunctionResponse2, AttachFunctionError, GetAttachedFunctionData, GetAttachedFunctionResponse2, GetAttachedFunctionError, CollectionGetData, CollectionGetResponse, CollectionGetError, IndexingStatusData, IndexingStatusResponse, IndexingStatusError, CollectionQueryData, CollectionQueryResponse, CollectionQueryError, CollectionSearchData, CollectionSearchResponse, CollectionSearchError, CollectionUpdateData, CollectionUpdateResponse, CollectionUpsertData, CollectionUpsertResponse, CollectionUpsertError, CountCollectionsData, CountCollectionsResponse, CountCollectionsError, VersionData, VersionResponse } from './types.gen';
|
|
5
5
|
import { client as _heyApiClient } from './client.gen';
|
|
6
6
|
|
|
7
7
|
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
|
|
@@ -323,6 +323,16 @@ export class DefaultService {
|
|
|
323
323
|
});
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Retrieves the indexing status of a collection.
|
|
328
|
+
*/
|
|
329
|
+
public static indexingStatus<ThrowOnError extends boolean = true>(options: Options<IndexingStatusData, ThrowOnError>) {
|
|
330
|
+
return (options.client ?? _heyApiClient).get<IndexingStatusResponse, IndexingStatusError, ThrowOnError>({
|
|
331
|
+
url: '/api/v2/tenants/{tenant}/databases/{database}/collections/{collection_id}/indexing_status',
|
|
332
|
+
...options
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
326
336
|
/**
|
|
327
337
|
* Query a collection in a variety of ways, including vector search, metadata filtering, and full-text search
|
|
328
338
|
*/
|
package/src/api/types.gen.ts
CHANGED
|
@@ -304,6 +304,13 @@ export type Include = 'distances' | 'documents' | 'embeddings' | 'metadatas' | '
|
|
|
304
304
|
|
|
305
305
|
export type IncludeList = Array<Include>;
|
|
306
306
|
|
|
307
|
+
export type IndexStatusResponse = {
|
|
308
|
+
num_indexed_ops: number;
|
|
309
|
+
num_unindexed_ops: number;
|
|
310
|
+
op_indexing_progress: number;
|
|
311
|
+
total_ops: number;
|
|
312
|
+
};
|
|
313
|
+
|
|
307
314
|
export type IntInvertedIndexConfig = {
|
|
308
315
|
[key: string]: never;
|
|
309
316
|
};
|
|
@@ -412,6 +419,8 @@ export type RawWhereFields = {
|
|
|
412
419
|
where_document?: unknown;
|
|
413
420
|
};
|
|
414
421
|
|
|
422
|
+
export type ReadLevel = 'index_and_wal' | 'index_only';
|
|
423
|
+
|
|
415
424
|
/**
|
|
416
425
|
* Schema representation for collection index configurations
|
|
417
426
|
*
|
|
@@ -467,6 +476,11 @@ export type SearchPayload = {
|
|
|
467
476
|
};
|
|
468
477
|
|
|
469
478
|
export type SearchRequestPayload = {
|
|
479
|
+
/**
|
|
480
|
+
* Specifies the read level for consistency vs performance tradeoffs.
|
|
481
|
+
* Defaults to IndexAndWal (full consistency).
|
|
482
|
+
*/
|
|
483
|
+
read_level?: ReadLevel;
|
|
470
484
|
searches: Array<SearchPayload>;
|
|
471
485
|
};
|
|
472
486
|
|
|
@@ -1696,6 +1710,52 @@ export type CollectionGetResponses = {
|
|
|
1696
1710
|
|
|
1697
1711
|
export type CollectionGetResponse = CollectionGetResponses[keyof CollectionGetResponses];
|
|
1698
1712
|
|
|
1713
|
+
export type IndexingStatusData = {
|
|
1714
|
+
body?: never;
|
|
1715
|
+
path: {
|
|
1716
|
+
/**
|
|
1717
|
+
* Tenant ID
|
|
1718
|
+
*/
|
|
1719
|
+
tenant: string;
|
|
1720
|
+
/**
|
|
1721
|
+
* Database name for the collection
|
|
1722
|
+
*/
|
|
1723
|
+
database: string;
|
|
1724
|
+
/**
|
|
1725
|
+
* Collection ID to get index status for
|
|
1726
|
+
*/
|
|
1727
|
+
collection_id: string;
|
|
1728
|
+
};
|
|
1729
|
+
query?: never;
|
|
1730
|
+
url: '/api/v2/tenants/{tenant}/databases/{database}/collections/{collection_id}/indexing_status';
|
|
1731
|
+
};
|
|
1732
|
+
|
|
1733
|
+
export type IndexingStatusErrors = {
|
|
1734
|
+
/**
|
|
1735
|
+
* Unauthorized
|
|
1736
|
+
*/
|
|
1737
|
+
401: ErrorResponse;
|
|
1738
|
+
/**
|
|
1739
|
+
* Collection not found
|
|
1740
|
+
*/
|
|
1741
|
+
404: ErrorResponse;
|
|
1742
|
+
/**
|
|
1743
|
+
* Server error
|
|
1744
|
+
*/
|
|
1745
|
+
500: ErrorResponse;
|
|
1746
|
+
};
|
|
1747
|
+
|
|
1748
|
+
export type IndexingStatusError = IndexingStatusErrors[keyof IndexingStatusErrors];
|
|
1749
|
+
|
|
1750
|
+
export type IndexingStatusResponses = {
|
|
1751
|
+
/**
|
|
1752
|
+
* Index status retrieved successfully
|
|
1753
|
+
*/
|
|
1754
|
+
200: IndexStatusResponse;
|
|
1755
|
+
};
|
|
1756
|
+
|
|
1757
|
+
export type IndexingStatusResponse = IndexingStatusResponses[keyof IndexingStatusResponses];
|
|
1758
|
+
|
|
1699
1759
|
export type CollectionQueryData = {
|
|
1700
1760
|
body: QueryRequestPayload;
|
|
1701
1761
|
path: {
|
package/src/chroma-fetch.ts
CHANGED
|
@@ -14,16 +14,18 @@ import {
|
|
|
14
14
|
const offlineError = (error: any): boolean => {
|
|
15
15
|
return Boolean(
|
|
16
16
|
(error?.name === "TypeError" || error?.name === "FetchError") &&
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
(error.message?.includes("fetch failed") ||
|
|
18
|
+
error.message?.includes("Failed to fetch") ||
|
|
19
|
+
error.message?.includes("ENOTFOUND")),
|
|
20
20
|
);
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const getErrorMessage = async (response: Response): Promise<string> => {
|
|
24
24
|
try {
|
|
25
25
|
const body = await response.clone().json();
|
|
26
|
-
return
|
|
26
|
+
return (
|
|
27
|
+
body.message || body.error || `${response.status}: ${response.statusText}`
|
|
28
|
+
);
|
|
27
29
|
} catch {
|
|
28
30
|
return `${response.status}: ${response.statusText}`;
|
|
29
31
|
}
|
|
@@ -52,9 +54,10 @@ export const chromaFetch: typeof fetch = async (input, init) => {
|
|
|
52
54
|
try {
|
|
53
55
|
const responseBody = await response.json();
|
|
54
56
|
status = responseBody.message || status;
|
|
55
|
-
} catch {
|
|
57
|
+
} catch {}
|
|
56
58
|
throw new ChromaClientError(
|
|
57
|
-
`Bad request to ${
|
|
59
|
+
`Bad request to ${
|
|
60
|
+
(input as Request).url || "Chroma"
|
|
58
61
|
} with status: ${status}`,
|
|
59
62
|
);
|
|
60
63
|
case 401:
|
|
@@ -82,10 +85,15 @@ export const chromaFetch: typeof fetch = async (input, init) => {
|
|
|
82
85
|
}
|
|
83
86
|
throw new ChromaClientError(body?.message || "Unprocessable Entity");
|
|
84
87
|
} catch (error) {
|
|
85
|
-
if (
|
|
88
|
+
if (
|
|
89
|
+
error instanceof ChromaQuotaExceededError ||
|
|
90
|
+
error instanceof ChromaClientError
|
|
91
|
+
) {
|
|
86
92
|
throw error;
|
|
87
93
|
}
|
|
88
|
-
throw new ChromaClientError(
|
|
94
|
+
throw new ChromaClientError(
|
|
95
|
+
`Unprocessable Entity: ${response.statusText}`,
|
|
96
|
+
);
|
|
89
97
|
}
|
|
90
98
|
case 429:
|
|
91
99
|
throw new ChromaRateLimitError("Rate limit exceeded");
|
|
@@ -126,8 +126,11 @@ export const processCreateCollectionConfig = async ({
|
|
|
126
126
|
!supportedSpaces.includes(configuration.hnsw.space)
|
|
127
127
|
) {
|
|
128
128
|
console.warn(
|
|
129
|
-
`Space '${
|
|
130
|
-
|
|
129
|
+
`Space '${
|
|
130
|
+
configuration.hnsw.space
|
|
131
|
+
}' is not supported by embedding function '${
|
|
132
|
+
overallEf.name || "unknown"
|
|
133
|
+
}'. ` + `Supported spaces: ${supportedSpaces.join(", ")}`,
|
|
131
134
|
);
|
|
132
135
|
}
|
|
133
136
|
|
|
@@ -136,8 +139,11 @@ export const processCreateCollectionConfig = async ({
|
|
|
136
139
|
!supportedSpaces.includes(configuration.spann.space)
|
|
137
140
|
) {
|
|
138
141
|
console.warn(
|
|
139
|
-
`Space '${
|
|
140
|
-
|
|
142
|
+
`Space '${
|
|
143
|
+
configuration.spann.space
|
|
144
|
+
}' is not supported by embedding function '${
|
|
145
|
+
overallEf.name || "unknown"
|
|
146
|
+
}'. ` + `Supported spaces: ${supportedSpaces.join(", ")}`,
|
|
141
147
|
);
|
|
142
148
|
}
|
|
143
149
|
|
|
@@ -151,8 +157,11 @@ export const processCreateCollectionConfig = async ({
|
|
|
151
157
|
)
|
|
152
158
|
) {
|
|
153
159
|
console.warn(
|
|
154
|
-
`Space '${
|
|
155
|
-
|
|
160
|
+
`Space '${
|
|
161
|
+
metadata["hnsw:space"]
|
|
162
|
+
}' from metadata is not supported by embedding function '${
|
|
163
|
+
overallEf.name || "unknown"
|
|
164
|
+
}'. ` + `Supported spaces: ${supportedSpaces.join(", ")}`,
|
|
156
165
|
);
|
|
157
166
|
}
|
|
158
167
|
}
|
package/src/collection.ts
CHANGED
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
BaseRecordSet,
|
|
8
8
|
CollectionMetadata,
|
|
9
9
|
GetResult,
|
|
10
|
+
IndexingStatus,
|
|
10
11
|
Metadata,
|
|
11
12
|
PreparedRecordSet,
|
|
12
13
|
PreparedInsertRecordSet,
|
|
13
14
|
QueryRecordSet,
|
|
14
15
|
QueryResult,
|
|
16
|
+
ReadLevel,
|
|
15
17
|
RecordSet,
|
|
16
18
|
Where,
|
|
17
19
|
WhereDocument,
|
|
@@ -203,7 +205,22 @@ export interface Collection {
|
|
|
203
205
|
* @param searches - Single search payload or array of payloads
|
|
204
206
|
* @returns Promise resolving to column-major search results
|
|
205
207
|
*/
|
|
206
|
-
search(
|
|
208
|
+
search(
|
|
209
|
+
searches: SearchLike | SearchLike[],
|
|
210
|
+
options?: {
|
|
211
|
+
/**
|
|
212
|
+
* Controls whether to read from the write-ahead log.
|
|
213
|
+
* - ReadLevel.INDEX_AND_WAL: Read from both index and WAL (default)
|
|
214
|
+
* - ReadLevel.INDEX_ONLY: Read only from index, faster but recent writes may not be visible
|
|
215
|
+
*/
|
|
216
|
+
readLevel?: ReadLevel;
|
|
217
|
+
},
|
|
218
|
+
): Promise<SearchResult>;
|
|
219
|
+
/**
|
|
220
|
+
* Gets the indexing status of the collection.
|
|
221
|
+
* @returns Promise resolving to indexing status information
|
|
222
|
+
*/
|
|
223
|
+
getIndexingStatus(): Promise<IndexingStatus>;
|
|
207
224
|
}
|
|
208
225
|
|
|
209
226
|
/**
|
|
@@ -887,6 +904,9 @@ export class CollectionImpl implements Collection {
|
|
|
887
904
|
|
|
888
905
|
public async search(
|
|
889
906
|
searches: SearchLike | SearchLike[],
|
|
907
|
+
options?: {
|
|
908
|
+
readLevel?: ReadLevel;
|
|
909
|
+
},
|
|
890
910
|
): Promise<SearchResult> {
|
|
891
911
|
const items = Array.isArray(searches) ? searches : [searches];
|
|
892
912
|
|
|
@@ -906,7 +926,10 @@ export class CollectionImpl implements Collection {
|
|
|
906
926
|
const { data } = await Api.collectionSearch({
|
|
907
927
|
client: this.apiClient,
|
|
908
928
|
path: await this.path(),
|
|
909
|
-
body: {
|
|
929
|
+
body: {
|
|
930
|
+
searches: payloads,
|
|
931
|
+
read_level: options?.readLevel,
|
|
932
|
+
},
|
|
910
933
|
});
|
|
911
934
|
|
|
912
935
|
return new SearchResult(data);
|
|
@@ -1079,4 +1102,13 @@ export class CollectionImpl implements Collection {
|
|
|
1079
1102
|
},
|
|
1080
1103
|
});
|
|
1081
1104
|
}
|
|
1105
|
+
|
|
1106
|
+
public async getIndexingStatus(): Promise<IndexingStatus> {
|
|
1107
|
+
const { data } = await Api.indexingStatus({
|
|
1108
|
+
client: this.apiClient,
|
|
1109
|
+
path: await this.path(),
|
|
1110
|
+
});
|
|
1111
|
+
|
|
1112
|
+
return data;
|
|
1113
|
+
}
|
|
1082
1114
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type IterableInput<T> = Iterable<T> | ArrayLike<T>;
|
|
2
2
|
|
|
3
|
-
export const isPlainObject = (
|
|
3
|
+
export const isPlainObject = (
|
|
4
|
+
value: unknown,
|
|
5
|
+
): value is Record<string, unknown> => {
|
|
4
6
|
if (typeof value !== "object" || value === null) {
|
|
5
7
|
return false;
|
|
6
8
|
}
|
|
@@ -59,10 +59,7 @@ export abstract class Aggregate {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
export class MinK extends Aggregate {
|
|
62
|
-
constructor(
|
|
63
|
-
public readonly keys: Key[],
|
|
64
|
-
public readonly k: number,
|
|
65
|
-
) {
|
|
62
|
+
constructor(public readonly keys: Key[], public readonly k: number) {
|
|
66
63
|
super();
|
|
67
64
|
if (keys.length === 0) {
|
|
68
65
|
throw new Error("MinK keys cannot be empty");
|
|
@@ -83,10 +80,7 @@ export class MinK extends Aggregate {
|
|
|
83
80
|
}
|
|
84
81
|
|
|
85
82
|
export class MaxK extends Aggregate {
|
|
86
|
-
constructor(
|
|
87
|
-
public readonly keys: Key[],
|
|
88
|
-
public readonly k: number,
|
|
89
|
-
) {
|
|
83
|
+
constructor(public readonly keys: Key[], public readonly k: number) {
|
|
90
84
|
super();
|
|
91
85
|
if (keys.length === 0) {
|
|
92
86
|
throw new Error("MaxK keys cannot be empty");
|
|
@@ -143,7 +137,9 @@ export class GroupBy {
|
|
|
143
137
|
Aggregate.from(data.aggregate),
|
|
144
138
|
);
|
|
145
139
|
}
|
|
146
|
-
throw new TypeError(
|
|
140
|
+
throw new TypeError(
|
|
141
|
+
"GroupBy input must be a GroupBy instance or plain object",
|
|
142
|
+
);
|
|
147
143
|
}
|
|
148
144
|
|
|
149
145
|
public toJSON(): GroupByJSON {
|
|
@@ -3,10 +3,19 @@ import { deepClone, isPlainObject, IterableInput } from "./common";
|
|
|
3
3
|
import { Key } from "./key";
|
|
4
4
|
|
|
5
5
|
export type RankLiteral = Record<string, unknown>;
|
|
6
|
-
export type RankInput =
|
|
6
|
+
export type RankInput =
|
|
7
|
+
| RankExpression
|
|
8
|
+
| RankLiteral
|
|
9
|
+
| number
|
|
10
|
+
| null
|
|
11
|
+
| undefined;
|
|
7
12
|
|
|
8
13
|
const requireNumber = (value: unknown, message: string): number => {
|
|
9
|
-
if (
|
|
14
|
+
if (
|
|
15
|
+
typeof value !== "number" ||
|
|
16
|
+
Number.isNaN(value) ||
|
|
17
|
+
!Number.isFinite(value)
|
|
18
|
+
) {
|
|
10
19
|
throw new TypeError(message);
|
|
11
20
|
}
|
|
12
21
|
return value;
|
|
@@ -39,7 +48,9 @@ abstract class RankExpressionBase {
|
|
|
39
48
|
}
|
|
40
49
|
const expressions = [
|
|
41
50
|
this as unknown as RankExpression,
|
|
42
|
-
...others.map((item, index) =>
|
|
51
|
+
...others.map((item, index) =>
|
|
52
|
+
requireRank(item, `multiply operand ${index}`),
|
|
53
|
+
),
|
|
43
54
|
];
|
|
44
55
|
return MulRankExpression.create(expressions);
|
|
45
56
|
}
|
|
@@ -104,7 +115,9 @@ export abstract class RankExpression extends RankExpressionBase {
|
|
|
104
115
|
if (isPlainObject(input)) {
|
|
105
116
|
return new RawRankExpression(input);
|
|
106
117
|
}
|
|
107
|
-
throw new TypeError(
|
|
118
|
+
throw new TypeError(
|
|
119
|
+
"Rank input must be a RankExpression, number, or plain object",
|
|
120
|
+
);
|
|
108
121
|
}
|
|
109
122
|
}
|
|
110
123
|
|
|
@@ -355,7 +368,11 @@ const normalizeDenseVector = (vector: IterableInput<number>): number[] => {
|
|
|
355
368
|
return vector.slice();
|
|
356
369
|
}
|
|
357
370
|
return Array.from(vector as Iterable<number>, (value) => {
|
|
358
|
-
if (
|
|
371
|
+
if (
|
|
372
|
+
typeof value !== "number" ||
|
|
373
|
+
Number.isNaN(value) ||
|
|
374
|
+
!Number.isFinite(value)
|
|
375
|
+
) {
|
|
359
376
|
throw new TypeError("Dense query vector values must be finite numbers");
|
|
360
377
|
}
|
|
361
378
|
return value;
|
|
@@ -387,7 +404,8 @@ const normalizeKnnOptions = (options: KnnOptions): KnnOptionsNormalized => {
|
|
|
387
404
|
query = normalizeDenseVector(queryInput as IterableInput<number>);
|
|
388
405
|
}
|
|
389
406
|
|
|
390
|
-
const key =
|
|
407
|
+
const key =
|
|
408
|
+
options.key instanceof Key ? options.key.name : options.key ?? "#embedding";
|
|
391
409
|
if (typeof key !== "string") {
|
|
392
410
|
throw new TypeError("Knn key must be a string or Key instance");
|
|
393
411
|
}
|
|
@@ -402,7 +420,10 @@ const normalizeKnnOptions = (options: KnnOptions): KnnOptionsNormalized => {
|
|
|
402
420
|
}
|
|
403
421
|
|
|
404
422
|
return {
|
|
405
|
-
query:
|
|
423
|
+
query:
|
|
424
|
+
Array.isArray(query) || typeof query === "string"
|
|
425
|
+
? query
|
|
426
|
+
: deepClone(query),
|
|
406
427
|
key,
|
|
407
428
|
limit,
|
|
408
429
|
defaultValue,
|
|
@@ -431,7 +452,12 @@ export interface RrfOptions {
|
|
|
431
452
|
normalize?: boolean;
|
|
432
453
|
}
|
|
433
454
|
|
|
434
|
-
export const Rrf = ({
|
|
455
|
+
export const Rrf = ({
|
|
456
|
+
ranks,
|
|
457
|
+
k = 60,
|
|
458
|
+
weights,
|
|
459
|
+
normalize = false,
|
|
460
|
+
}: RrfOptions): RankExpression => {
|
|
435
461
|
if (!Number.isInteger(k) || k <= 0) {
|
|
436
462
|
throw new TypeError("Rrf k must be a positive integer");
|
|
437
463
|
}
|
|
@@ -439,9 +465,13 @@ export const Rrf = ({ ranks, k = 60, weights, normalize = false }: RrfOptions):
|
|
|
439
465
|
throw new TypeError("Rrf requires at least one rank expression");
|
|
440
466
|
}
|
|
441
467
|
|
|
442
|
-
const expressions = ranks.map((rank, index) =>
|
|
468
|
+
const expressions = ranks.map((rank, index) =>
|
|
469
|
+
requireRank(rank, `ranks[${index}]`),
|
|
470
|
+
);
|
|
443
471
|
|
|
444
|
-
let weightValues = weights
|
|
472
|
+
let weightValues = weights
|
|
473
|
+
? weights.slice()
|
|
474
|
+
: new Array(expressions.length).fill(1);
|
|
445
475
|
if (weightValues.length !== expressions.length) {
|
|
446
476
|
throw new Error("Number of weights must match number of ranks");
|
|
447
477
|
}
|
|
@@ -452,7 +482,9 @@ export const Rrf = ({ ranks, k = 60, weights, normalize = false }: RrfOptions):
|
|
|
452
482
|
if (normalize) {
|
|
453
483
|
const total = weightValues.reduce((sum, value) => sum + value, 0);
|
|
454
484
|
if (total <= 0) {
|
|
455
|
-
throw new Error(
|
|
485
|
+
throw new Error(
|
|
486
|
+
"Weights must sum to a positive value when normalize=true",
|
|
487
|
+
);
|
|
456
488
|
}
|
|
457
489
|
weightValues = weightValues.map((value) => value / total);
|
|
458
490
|
}
|
|
@@ -472,35 +504,50 @@ export const Sum = (...inputs: RankInput[]): RankExpression => {
|
|
|
472
504
|
if (inputs.length === 0) {
|
|
473
505
|
throw new Error("Sum requires at least one rank expression");
|
|
474
506
|
}
|
|
475
|
-
const expressions = inputs.map((rank, index) =>
|
|
507
|
+
const expressions = inputs.map((rank, index) =>
|
|
508
|
+
requireRank(rank, `Sum operand ${index}`),
|
|
509
|
+
);
|
|
476
510
|
return SumRankExpression.create(expressions);
|
|
477
511
|
};
|
|
478
512
|
|
|
479
513
|
export const Sub = (left: RankInput, right: RankInput): RankExpression =>
|
|
480
|
-
new SubRankExpression(
|
|
514
|
+
new SubRankExpression(
|
|
515
|
+
requireRank(left, "Sub left"),
|
|
516
|
+
requireRank(right, "Sub right"),
|
|
517
|
+
);
|
|
481
518
|
|
|
482
519
|
export const Mul = (...inputs: RankInput[]): RankExpression => {
|
|
483
520
|
if (inputs.length === 0) {
|
|
484
521
|
throw new Error("Mul requires at least one rank expression");
|
|
485
522
|
}
|
|
486
|
-
const expressions = inputs.map((rank, index) =>
|
|
523
|
+
const expressions = inputs.map((rank, index) =>
|
|
524
|
+
requireRank(rank, `Mul operand ${index}`),
|
|
525
|
+
);
|
|
487
526
|
return MulRankExpression.create(expressions);
|
|
488
527
|
};
|
|
489
528
|
|
|
490
529
|
export const Div = (left: RankInput, right: RankInput): RankExpression =>
|
|
491
|
-
new DivRankExpression(
|
|
530
|
+
new DivRankExpression(
|
|
531
|
+
requireRank(left, "Div left"),
|
|
532
|
+
requireRank(right, "Div right"),
|
|
533
|
+
);
|
|
492
534
|
|
|
493
|
-
export const Abs = (input: RankInput): RankExpression =>
|
|
535
|
+
export const Abs = (input: RankInput): RankExpression =>
|
|
536
|
+
requireRank(input, "Abs").abs();
|
|
494
537
|
|
|
495
|
-
export const Exp = (input: RankInput): RankExpression =>
|
|
538
|
+
export const Exp = (input: RankInput): RankExpression =>
|
|
539
|
+
requireRank(input, "Exp").exp();
|
|
496
540
|
|
|
497
|
-
export const Log = (input: RankInput): RankExpression =>
|
|
541
|
+
export const Log = (input: RankInput): RankExpression =>
|
|
542
|
+
requireRank(input, "Log").log();
|
|
498
543
|
|
|
499
544
|
export const Max = (...inputs: RankInput[]): RankExpression => {
|
|
500
545
|
if (inputs.length === 0) {
|
|
501
546
|
throw new Error("Max requires at least one rank expression");
|
|
502
547
|
}
|
|
503
|
-
const expressions = inputs.map((rank, index) =>
|
|
548
|
+
const expressions = inputs.map((rank, index) =>
|
|
549
|
+
requireRank(rank, `Max operand ${index}`),
|
|
550
|
+
);
|
|
504
551
|
return MaxRankExpression.create(expressions);
|
|
505
552
|
};
|
|
506
553
|
|
|
@@ -508,6 +555,8 @@ export const Min = (...inputs: RankInput[]): RankExpression => {
|
|
|
508
555
|
if (inputs.length === 0) {
|
|
509
556
|
throw new Error("Min requires at least one rank expression");
|
|
510
557
|
}
|
|
511
|
-
const expressions = inputs.map((rank, index) =>
|
|
558
|
+
const expressions = inputs.map((rank, index) =>
|
|
559
|
+
requireRank(rank, `Min operand ${index}`),
|
|
560
|
+
);
|
|
512
561
|
return MinRankExpression.create(expressions);
|
|
513
562
|
};
|
|
@@ -20,7 +20,9 @@ const normalizePayloadArray = <T>(
|
|
|
20
20
|
if (payload.length === count) {
|
|
21
21
|
return payload.map((item) => (item ? item.slice() : null));
|
|
22
22
|
}
|
|
23
|
-
const result: Array<T[] | null> = payload.map((item) =>
|
|
23
|
+
const result: Array<T[] | null> = payload.map((item) =>
|
|
24
|
+
item ? item.slice() : null,
|
|
25
|
+
);
|
|
24
26
|
while (result.length < count) {
|
|
25
27
|
result.push(null);
|
|
26
28
|
}
|
|
@@ -40,7 +42,10 @@ export class SearchResult {
|
|
|
40
42
|
const payloadCount = this.ids.length;
|
|
41
43
|
this.documents = normalizePayloadArray(response.documents, payloadCount);
|
|
42
44
|
this.embeddings = normalizePayloadArray(response.embeddings, payloadCount);
|
|
43
|
-
const rawMetadatas = normalizePayloadArray(
|
|
45
|
+
const rawMetadatas = normalizePayloadArray(
|
|
46
|
+
response.metadatas,
|
|
47
|
+
payloadCount,
|
|
48
|
+
);
|
|
44
49
|
this.metadatas = rawMetadatas.map((payload) => {
|
|
45
50
|
if (!payload) {
|
|
46
51
|
return null;
|
|
@@ -54,7 +59,11 @@ export class SearchResult {
|
|
|
54
59
|
public rows(): SearchResultRow[][] {
|
|
55
60
|
const results: SearchResultRow[][] = [];
|
|
56
61
|
|
|
57
|
-
for (
|
|
62
|
+
for (
|
|
63
|
+
let payloadIndex = 0;
|
|
64
|
+
payloadIndex < this.ids.length;
|
|
65
|
+
payloadIndex += 1
|
|
66
|
+
) {
|
|
58
67
|
const ids = this.ids[payloadIndex];
|
|
59
68
|
const docPayload = this.documents[payloadIndex] ?? [];
|
|
60
69
|
const embedPayload = this.embeddings[payloadIndex] ?? [];
|