UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

91 lines (90 loc) • 4.01 kB
/** * Chroma vector store adapter * * Implements the `VectorStore` contract (see `src/lib/types/rag.ts`) against * a Chroma collection. This module has zero runtime dependency on the * `chromadb` package: callers construct their own `ChromaClient` (or any * compatible object) and inject it here. The structural interfaces below * mirror the subset of the `chromadb` API this adapter relies on * (`getOrCreateCollection`, `collection.upsert/query/delete`). * * ## Distance -> similarity scoring * * Chroma returns *distances*, not similarities, and the meaning of that * distance depends entirely on the collection's configured `hnsw:space` * (this adapter does not — and cannot — set that; it is chosen when the * collection is created on the Chroma side). `distanceMetric` tells this * adapter which space the collection uses so it can invert the distance * into a `score` consistent with `InMemoryVectorStore` (higher = more * similar): * * - `"cosine"` (default): Chroma returns `distance = 1 - cosineSimilarity`, * so `score = 1 - distance` reproduces `InMemoryVectorStore`'s cosine * score exactly. * - `"ip"`: Chroma returns `distance = 1 - dot(a, b)`, so * `score = 1 - distance` yields the raw dot product — only equal to * cosine similarity if both vectors are unit-normalized. * - `"l2"`: Chroma returns squared Euclidean distance, range * `[0, Infinity)`, which has no exact inverse into a cosine-similarity * scale. It is converted via `score = 1 / (1 + distance)`, a * monotonically decreasing-in-distance map into `(0, 1]`. This preserves * result ordering but is NOT numerically comparable to cosine scores. * * Passing a `distanceMetric` that does not match the collection's actual * `hnsw:space` will silently produce meaningless scores (Chroma has no way * to report its configured space back to the client), so callers must keep * the two in sync. * * ## Metadata round-tripping * * Chroma metadata values must be strings, numbers, or booleans. Values that * are `undefined` are dropped (Chroma rejects `undefined`); any other * non-primitive value (object, array, `null`) is `JSON.stringify`-ed on * write. This is lossy: such values come back as JSON-encoded strings on * read, not their original type. Store only primitive metadata values if * you need exact round-tripping. * * ## indexName -> collection mapping * * `indexName` is used verbatim as the Chroma collection name (1:1, * lazily created via `getOrCreateCollection` and cached for the lifetime of * this adapter instance). */ import type { ChromaClientLike, ChromaVectorStoreOptions, ChromaWhere, MetadataFilter, VectorQueryResult, VectorStore } from "../../types/index.js"; /** * Translates a `MetadataFilter` into a Chroma `where` clause. * * Throws a clear error for any operator Chroma's metadata `where` clause * cannot express ($not, $nor, $exists, $contains, $regex, $size) rather than * silently dropping the constraint and mis-filtering results. */ export declare function translateMetadataFilter(filter: MetadataFilter): ChromaWhere; export declare class ChromaVectorStore implements VectorStore { private readonly client; private readonly collections; private readonly distanceMetric; constructor(client: ChromaClientLike, options?: ChromaVectorStoreOptions); private getCollection; /** * Add or update vectors in an index (Chroma collection). */ upsert(indexName: string, items: Array<{ id: string; vector: number[]; metadata?: Record<string, unknown>; }>): Promise<void>; /** * Query vectors by similarity. */ query(params: { indexName: string; queryVector: number[]; topK?: number; filter?: MetadataFilter; includeVectors?: boolean; }): Promise<VectorQueryResult[]>; /** * Delete vectors from an index (Chroma collection) by id. */ delete(indexName: string, ids: string[]): Promise<void>; }