← All @molecule/* packages · App templates
@molecule/api-ai-vector-storeCore interface · ai-vector-store · API (Node) · v1.0.1 · Apache-2.0
Vector store core interface — named collections of embedding vectors with upsert and similarity query (metadata filters, topK) via swappable providers (pgvector, Pinecone, Chroma, memory).
npm install @molecule/api-ai-vector-store@molecule/api-ai-vector-store is the ai-vector-store core interface on the API (Node) side: the API your app calls, with no vendor inside.
Choose the implementation by bonding one of its 4 providers: @molecule/api-ai-vector-store-chroma, @molecule/api-ai-vector-store-memory, @molecule/api-ai-vector-store-pgvector, @molecule/api-ai-vector-store-pinecone.
import { setProvider, requireProvider } from '@molecule/api-ai-vector-store'
import { provider as memory } from '@molecule/api-ai-vector-store-memory'
// Wire at startup — memory for dev; swap to pgvector/pinecone when provisioned.
setProvider(memory)
const store = requireProvider()
await store.createCollection({ name: 'docs', dimension: 1536, metric: 'cosine' })
await store.upsert({
collection: 'docs',
records: [{ id: 'a', embedding: vec, content: 'PTO policy…', metadata: { userId: 'u1' } }],
})
const hits = await store.query({
collection: 'docs',
embedding: queryVec,
topK: 5,
filter: [{ field: 'userId', operator: 'eq', value: 'u1' }],
})Providers (4): @molecule/api-ai-vector-store-chroma, @molecule/api-ai-vector-store-memory, @molecule/api-ai-vector-store-pgvector, @molecule/api-ai-vector-store-pinecone
Works with: @molecule/api-bond
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
AI vector-store core interface for molecule.dev.
Defines the AIVectorStoreProvider contract — named collections of embedding
vectors with upsert, similarity query (metadata filters, topK,
minScore), fetch, and delete — plus the accessor (setProvider/
getProvider/hasProvider/requireProvider). Interface-only: bond a
provider package (@molecule/api-ai-vector-store-pgvector, -pinecone,
-chroma, or -memory for dev/tests).
import { setProvider, requireProvider } from '@molecule/api-ai-vector-store'
import { provider as memory } from '@molecule/api-ai-vector-store-memory'
// Wire at startup — memory for dev; swap to pgvector/pinecone when provisioned.
setProvider(memory)
const store = requireProvider()
await store.createCollection({ name: 'docs', dimension: 1536, metric: 'cosine' })
await store.upsert({
collection: 'docs',
records: [{ id: 'a', embedding: vec, content: 'PTO policy…', metadata: { userId: 'u1' } }],
})
const hits = await store.query({
collection: 'docs',
embedding: queryVec,
topK: 5,
filter: [{ field: 'userId', operator: 'eq', value: 'u1' }],
})
core
npm install @molecule/api-ai-vector-store @molecule/api-bond
AIVectorStoreConfigBase configuration for vector store providers.
interface AIVectorStoreConfig {
/** Connection string or URL for the vector store. */
connectionString?: string
/** API key for managed vector store services. */
apiKey?: string
/** Additional provider-specific options. */
[key: string]: unknown
}
AIVectorStoreProviderAIVectorStore provider interface.
Each bond package (pgvector, Pinecone, Chroma, etc.) implements this interface to provide vector database operations.
interface AIVectorStoreProvider {
/** Provider name identifier. */
readonly name: string
/**
* Create a new collection/namespace for storing vectors.
*
* Idempotent: re-creating a collection that already exists with the SAME
* dimension is a no-op, so callers can safely call this at startup on every
* boot. Only a genuine dimension CONFLICT (same name, different dimension)
* throws. Providers MUST implement this contract so an app that works against
* one bond (e.g. the in-memory store in dev) behaves identically against
* another (e.g. pgvector in prod) instead of crashing on the second boot.
*
* @param params - Collection creation parameters.
* @throws {Error} if a collection with the same name exists at a different dimension.
*/
createCollection(params: CreateCollectionParams): Promise<void>
/**
* Delete a collection/namespace and all its vectors.
*
* @param name - Name of the collection to delete.
*/
deleteCollection(name: string): Promise<void>
/**
* List all available collections.
*
* @returns Array of collection names.
*/
listCollections(): Promise<string[]>
/**
* Upsert (insert or update) vector records into a collection.
*
* @param params - Upsert parameters including collection and records.
*/
upsert(params: VectorUpsertParams): Promise<void>
/**
* Query for similar vectors using a query embedding.
*
* @param params - Query parameters including embedding, topK, and filters.
* @returns Array of search results sorted by similarity (highest first).
*/
query(params: VectorQueryParams): Promise<VectorSearchResult[]>
/**
* Fetch vector records by their IDs.
*
* @param params - Fetch parameters including collection and IDs.
* @returns Array of found vector records (missing IDs are omitted).
*/
fetch(params: VectorFetchParams): Promise<VectorRecord[]>
/**
* Delete vector records by their IDs.
*
* @param params - Delete parameters including collection and IDs.
*/
delete(params: VectorDeleteParams): Promise<void>
}
CreateCollectionParamsParameters for creating a collection/namespace.
interface CreateCollectionParams {
/** Name of the collection to create. */
name: string
/** Dimensionality of vectors in this collection. */
dimension: number
/** Distance metric for similarity search. Defaults to 'cosine'. */
metric?: DistanceMetric
}
VectorDeleteParamsParameters for deleting vectors.
interface VectorDeleteParams {
/** The collection/namespace to delete from. */
collection: string
/** IDs of vectors to delete. */
ids: string[]
}
VectorFetchParamsParameters for fetching vectors by ID.
interface VectorFetchParams {
/** The collection/namespace to fetch from. */
collection: string
/** IDs of vectors to fetch. */
ids: string[]
}
VectorQueryParamsParameters for similarity search queries.
interface VectorQueryParams {
/** The query embedding vector to find similar vectors for. */
embedding: number[]
/** Maximum number of results to return. Defaults to 10. */
topK?: number
/** Optional metadata filters to narrow results. */
filter?: MetadataFilter[]
/** Minimum similarity score threshold (0–1). Results below this are excluded. */
minScore?: number
/** The collection/namespace to query. */
collection: string
}
VectorRecordA stored vector record with its embedding, metadata, and optional content.
interface VectorRecord {
/** Unique identifier for this vector record. */
id: string
/** The embedding vector (array of floats). */
embedding: number[]
/** Arbitrary metadata associated with this vector. */
metadata?: Record<string, unknown>
/** Optional text content that produced this embedding. */
content?: string
}
VectorRecordInputInput for upserting a vector record. Same as VectorRecord but embedding is optional when the store handles embedding generation internally.
interface VectorRecordInput {
/** Unique identifier for this vector record. */
id: string
/** The embedding vector (array of floats). */
embedding: number[]
/** Arbitrary metadata associated with this vector. */
metadata?: Record<string, unknown>
/** Optional text content that produced this embedding. */
content?: string
}
VectorSearchResultA result from a similarity search query.
interface VectorSearchResult {
/** The matched vector record. */
record: VectorRecord
/** Similarity score (higher is more similar, normalized 0–1 when possible). */
score: number
}
VectorUpsertParamsParameters for upserting vectors.
interface VectorUpsertParams {
/** The collection/namespace to upsert into. */
collection: string
/** Vector records to upsert. */
records: VectorRecordInput[]
}
DistanceMetricDistance metric for similarity calculations.
type DistanceMetric = 'cosine' | 'euclidean' | 'inner_product'
MetadataFilterMetadata filter operators for querying vectors.
type MetadataFilter =
| { field: string; operator: 'eq'; value: string | number | boolean }
| { field: string; operator: 'ne'; value: string | number | boolean }
| { field: string; operator: 'gt'; value: number }
| { field: string; operator: 'gte'; value: number }
| { field: string; operator: 'lt'; value: number }
| { field: string; operator: 'lte'; value: number }
| { field: string; operator: 'in'; value: (string | number)[] }
getProvider()Get the active vector store provider, or null if none is configured.
function getProvider(): AIVectorStoreProvider | null
Returns: The current provider or null.
hasProvider()Check whether a vector store provider is configured.
function hasProvider(): boolean
Returns: True if a provider has been set.
requireProvider()Get the active vector store provider, throwing if none is configured.
function requireProvider(): AIVectorStoreProvider
Returns: The current provider.
setProvider(provider)Set the active vector store provider.
function setProvider(provider: AIVectorStoreProvider): void
provider — The vector store provider to register.| Provider | Package |
|---|---|
| Ai Vector Store | @molecule/api-ai-vector-store-chroma |
| Ai Vector Store | @molecule/api-ai-vector-store-memory |
| Ai Vector Store | @molecule/api-ai-vector-store-pgvector |
| Ai Vector Store | @molecule/api-ai-vector-store-pinecone |
Peer dependencies:
@molecule/api-bond ^1.0.1@molecule/api-bond
Wire it at startup with setProvider(...) — or the equivalent
bond('ai-vector-store', provider). This core routes through the shared
@molecule/api-bond registry, so either call registers the same provider and
validateBonds() reports it as missing when unwired.
Pick the bond by what is actually provisioned. -memory needs nothing but
holds vectors in process memory (lost on restart — dev/tests only). -pgvector
reuses the app's existing Postgres (DATABASE_URL) and provisions its own
extension/tables. Managed stores (Pinecone, Chroma) require their service and
key to actually exist — don't wire one on the assumption that it does.
This store does NOT embed. upsert takes precomputed embedding vectors —
pair it with @molecule/api-ai-embeddings, or use
@molecule/api-semantic-search (composes both) / @molecule/api-ai-rag
(grounded Q&A) instead of calling this directly.
One collection = one embedding model + dimension. createCollection fixes
dimension; upserting vectors from a different model/dimension corrupts search
results (or throws). Re-embed the corpus when switching models.
Scope multi-tenant data. Put the owner (user/tenant id) in metadata and
filter on it in EVERY query (or use per-tenant collections) — a shared,
unfiltered collection leaks one tenant's documents into another's results.
query results are sorted by score (higher = more similar, 0–1 where
possible); use minScore to drop weak matches rather than trusting topK
alone.
Integration checklist — drive the real flow (no mocks): upsert real
vectors, run real query calls, and verify through the FEATURE this store
powers (semantic search / RAG retrieval / related-items) plus direct property
checks on the returned VectorSearchResult[]. Adapt each item to this app's
actual corpus/screens and check every box off. A box you can't check is an
integration bug to fix — not a skip:
upsert records (each with a stable id + metadata), then query
with an embedding: results come back ranked by score (highest first), the
semantically closest stored item is result #1 and unrelated items rank
lower — the whole point. score is a sane similarity (bounded, ~0–1,
higher = closer) and each hit's record.id / record.metadata come back
intact.topK is honored: a query with topK: k returns AT MOST k results,
best-first — never more, never unordered.filter works: a query carrying a MetadataFilter (e.g.
{ field: 'userId', operator: 'eq', value }) returns only records matching
the filter and never leaks non-matching ones.query scoped to one collection
never returns another collection's vectors — the multi-tenant boundary that
keeps one user's private docs out of another's results. Confirm with two
collections (or two owner ids) that a scoped query returns only its own.delete removes a record: after delete({ collection, ids }) the
vector stops appearing in query results (and fetch omits it).@molecule/api-ai-embeddings (query text → embedding → query).upsert / query runs SERVER-SIDE — the provider/store key
stays on the server and never ships in the browser bundle (the package is
server-only; a client import throws by design).