AbsoluteJS

Retrieval & Context

One createRAGCollection() call wires embedding, query transforms, retrieval routing, hybrid lexical + vector fusion, and reranking over any backend that implements the RAGVectorStore contract — in-memory in core, Postgres (pgvector), SQLite (vec0), and Pinecone as published adapters.

#Collections

A collection binds a store to a retrieval pipeline. It exposes search / searchWithTrace (results plus a full retrieval trace), ingest, ingestSource / removeSource (tracked, deletable source sets), and pass-through clear / getStatus / getCapabilities. Free-function wrappers — searchDocuments, ingestRAGDocuments, ingestRAGSource, removeRAGSource — mirror the methods.

OptionType / defaultPurpose
storeRAGVectorStorerequiredThe backend. In-memory ships in core; SQLite, Postgres, and Pinecone are separate packages.
embeddingRAGEmbeddingProviderLikeA provider object or bare embed function. Falls back to the store embed() when omitted.
defaultTopK6defaultResult count when a search omits topK.
defaultCandidateMultiplier4defaultCandidate over-fetch factor (topK x multiplier) when reranking, transforms, or hybrid modes are active.
defaultModelstringEmbedding model used when neither the call nor the provider names one.
queryTransformRAGQueryTransformProviderLikeRewrites the query and adds variant queries before retrieval.
retrievalStrategyRAGRetrievalStrategyProviderLikeRoutes each query to vector, lexical, or hybrid retrieval per decision.
rerankRAGRerankerProviderLikeRe-orders the fused candidate set before the final topK slice.
TS
import {
  buildRAGContext,
  createHeuristicRAGReranker,
  createRAGCollection,
  ingestRAGDocuments,
  openaiEmbeddings,
  searchDocuments
} from '@absolutejs/rag';
import { createSQLiteRAGStore } from '@absolutejs/rag-sqlite';

const collection = createRAGCollection({
  embedding: openaiEmbeddings({
    apiKey: process.env.OPENAI_API_KEY ?? '',
    defaultModel: 'text-embedding-3-small',
    dimensions: 1536
  }),
  rerank: createHeuristicRAGReranker(),
  store: createSQLiteRAGStore({ dimensions: 1536, path: './rag.sqlite' })
});

await ingestRAGDocuments(collection, {
  documents: [
    {
      id: 'release-notes',
      source: 'docs/releases.md',
      text: 'Hybrid retrieval fuses lexical and vector results...',
      title: 'Release Notes'
    }
  ]
});

// topK defaults to 6. Candidates over-fetch at topK * 4 whenever a
// reranker, query transform, or non-vector mode is active.
const hits = await searchDocuments(collection, {
  query: 'What changed in the latest release?',
  retrieval: 'hybrid',
  topK: 5
});

// Numbered "[1] Release Notes (docs/releases.md)" context blocks
// plus citation guidance, ready to drop into a prompt.
const context = buildRAGContext(hits);

buildRAGContext(hits) renders results into a prompt-ready block: numbered [1] Title (source) headers, location labels for pages, sheets, slides, and timestamps, provenance cues for OCR and transcripts, then citation guidance. An empty hit list returns an empty string.

Every search accepts retrieval — a mode string or a full RAGHybridSearchOptions object. In hybrid mode the store's vector results and BM25-style lexical results (via queryLexical where the backend supports it) are fused, de-duplicated, diversity-filtered, and only then reranked.

OptionDefaultBehavior
mode'vector'default'vector' | 'lexical' | 'hybrid' — a bare mode string is accepted anywhere RAGHybridSearchOptions is.
fusion'rrf'defaultReciprocal rank fusion, or 'max' for weighted max-score.
fusionConstant60defaultThe k in weight / (k + rank); higher flattens rank differences.
lexicalWeight / vectorWeight2 / 1defaultsPer-signal weights applied during fusion.
lexicalTopKunsetCaps the lexical candidate list independently of topK.
diversityStrategy'none'default'mmr' enables maximal-marginal-relevance de-duplication.
mmrLambda0.7defaultMMR relevance-vs-diversity balance, clamped to 0..1.
sourceBalanceStrategy'cap'defaultWith maxResultsPerSource: 'cap' truncates per source, 'round_robin' interleaves sources.
TS
import { fuseRAGQueryResults, searchDocuments } from '@absolutejs/rag';

// A mode string picks the defaults; an options object tunes fusion.
const results = await searchDocuments(collection, {
  query: 'quarterly revenue by region',
  retrieval: {
    diversityStrategy: 'mmr', // default 'none'
    fusion: 'rrf', // 'rrf' | 'max'
    fusionConstant: 60, // default 60
    lexicalWeight: 2, // default 2
    mmrLambda: 0.7, // default 0.7
    mode: 'hybrid', // 'vector' | 'lexical' | 'hybrid'
    sourceBalanceStrategy: 'round_robin', // default 'cap'
    vectorWeight: 1 // default 1
  },
  topK: 8
});

// The fusion primitive is exported for custom pipelines : reciprocal
// rank fusion (weight / (constant + rank)) or weighted max-score.
const fused = fuseRAGQueryResults({
  fusion: 'rrf',
  lexical: lexicalResults,
  lexicalWeight: 2,
  vector: vectorResults,
  vectorWeight: 1
});

The pieces are exported for custom pipelines: buildRAGLexicalHaystack and scoreRAGLexicalMatch for lexical scoring, fuseRAGQueryResults for fusion, and resolveRAGHybridSearchOptions to expand a mode string into the fully-defaulted options object. Fused results carry their per-signal ranks in metadata.retrievalSignals.

#Reranking & Transforms

Rerankers receive the over-fetched candidate set (topK x defaultCandidateMultiplier) and return the final ordering. Query transforms run first — createHeuristicRAGQueryTransform() expands domain terms into variant queries, or wrap a model call with createRAGQueryTransform. A retrieval strategy (createHeuristicRAGRetrievalStrategy) can override the mode per query: scoped filters go straight to vector, support-style queries to lexical, exact phrases to hybrid.

RerankerDefault modelNotes
createHeuristicRAGReranker()absolute-heuristic-rerankerNo network calls — BM25-style lexical re-scoring. A solid default.
createCohereRAGReranker({ apiKey })rerank-v3.5Cohere /v2/rerank cross-encoder.
createVoyageRAGReranker({ apiKey })rerank-2Voyage /v1/rerank cross-encoder.
createJinaRAGReranker({ apiKey })jina-reranker-v2-base-multilingualJina /v1/rerank cross-encoder.
createRAGReranker({ rerank })yoursWrap any (input) => results function — an LLM judge, a local cross-encoder, anything.
TS
import {
  createCohereRAGReranker,
  createHeuristicRAGQueryTransform,
  createHeuristicRAGRetrievalStrategy,
  createRAGCollection,
  createVoyageRAGReranker
} from '@absolutejs/rag';

const collection = createRAGCollection({
  embedding,
  // Heuristic variant expansion runs before retrieval; bring your own
  // model-backed transform via createRAGQueryTransform({ transform }).
  queryTransform: createHeuristicRAGQueryTransform(),
  // Hosted cross-encoders : Cohere rerank-v3.5, Voyage rerank-2, or
  // Jina jina-reranker-v2-base-multilingual by default.
  rerank: createCohereRAGReranker({
    apiKey: process.env.COHERE_API_KEY ?? ''
  }),
  // Routes scoped queries to vector, support-style queries to
  // lexical, and exact-phrase / source-native queries to hybrid.
  retrievalStrategy: createHeuristicRAGRetrievalStrategy(),
  store
});

// Per-search overrides win over the collection defaults.
await collection.search({
  query: 'refund policy for enterprise contracts',
  rerank: createVoyageRAGReranker({
    apiKey: process.env.VOYAGE_API_KEY ?? ''
  }),
  topK: 6
});

applyRAGReranking and resolveRAGReranker are exported for standalone use — no reranker configured means results pass through unchanged.

#The RAGVectorStore Contract

Three required methods make a working store; everything else is a capability the pipeline detects and uses when present — queryLexical unlocks backend-side lexical retrieval, delete / count unlock source removal, analyze and rebuildNativeIndex unlock maintenance actions. The @absolutejs/rag/adapter-kit subpath re-exports the contract types plus the vector helpers, metadata filter matcher, lexical ranker, and native query planners adapter packages build on.

TS
// The contract every backend implements (@absolutejs/rag/adapter-kit).
// embed, query, and upsert are required; every optional member
// unlocks a capability when present.
type RAGVectorStore = {
  embed: (input: RAGEmbeddingInput) => Promise<number[]>;
  query: (input: RAGQueryInput) => Promise<RAGQueryResult[]>;
  queryLexical?: (input: RAGLexicalQueryInput) => Promise<RAGQueryResult[]>;
  count?: (input?: RAGVectorCountInput) => Promise<number>;
  delete?: (input?: RAGVectorDeleteInput) => Promise<number>;
  analyze?: () => Promise<void> | void;
  rebuildNativeIndex?: () => Promise<void> | void;
  upsert: (input: RAGUpsertInput) => Promise<void>;
  clear?: () => Promise<void> | void;
  close?: () => Promise<void> | void;
  getStatus?: () => RAGVectorStoreStatus;
  getCapabilities?: () => RAGBackendCapabilities;
};

// A minimal custom store built on the adapter-kit vector helpers.
import {
  createRAGVector,
  normalizeVector,
  querySimilarity
} from '@absolutejs/rag/adapter-kit';

const memory = new Map<string, { embedding: number[]; text: string }>();

const demoStore: RAGVectorStore = {
  embed: async ({ text }) => normalizeVector(createRAGVector(text, 24)),
  query: async ({ queryVector, topK }) =>
    [...memory.entries()]
      .map(([chunkId, row]) => ({
        chunkId,
        chunkText: row.text,
        score: querySimilarity(queryVector, row.embedding)
      }))
      .sort((left, right) => right.score - left.score)
      .slice(0, topK),
  upsert: async ({ chunks }) => {
    for (const chunk of chunks) {
      memory.set(chunk.chunkId, {
        embedding: chunk.embedding ?? [],
        text: chunk.text
      });
    }
  }
};
Status is a discriminated union
getStatus() reports the backend and its vector mode — in_memory, SQLite json_fallback / native_vec0, or Postgres native_pgvector — with native diagnostics (index type, row counts, last query plan) when available.

#Stores & Adapters

Two stores ship in core and three adapters are published as standalone packages, so the heavy backend dependencies stay out of your bundle until you opt in. Each adapter also exports a create*RAGCollection and a bundled create*RAG (store + collection + status accessors).

createInMemoryRAGStorebuilt in
@absolutejs/rag

Zero-dependency store for tests, demos, and small corpora. JS filtering and lexical ranking included.

createSyncRAGStorebuilt in
@absolutejs/rag

Backs retrieval with a live @absolutejs/sync engine collection — search results update reactively.

Postgresv0.0.12
@absolutejs/rag-postgres

pgvector-native store: vector(n) column, cosine / l2 / inner_product, hnsw or ivfflat indexes.

SQLitev0.0.12
@absolutejs/rag-sqlite

Embedded store on bun:sqlite. JSON fallback everywhere; native vec0 acceleration via platform packages.

Pineconev0.0.13
@absolutejs/rag-pinecone

Serverless Pinecone indexes with filter translation, batched upserts, and index provisioning helpers.

FactoryKey defaultNotes
createPostgresRAG(options?)rag_chunksdefault tableConnection from options.sql, connectionString, RAG_POSTGRES_URL, or DATABASE_URL. Status reports native_pgvector with index diagnostics.
createSQLiteRAG(options?):memory:default pathnative: { mode: "vec0" } loads the sqlite-vec extension resolved from @absolutejs/absolute-rag-sqlite-* platform packages; getNativeSupport() explains the outcome.
createPineconeRAG({ vector })1536default dimscosine / euclidean / dotproduct metrics, $eq..$containsAll filters, 100-record upsert batches. ensurePineconeIndex() provisions serverless indexes.
TS
// Postgres (pgvector) : table rag_chunks, hnsw index by default
import { createPostgresRAG } from '@absolutejs/rag-postgres';

const { collection, store } = createPostgresRAG({
  storeOptions: {
    connectionString: process.env.DATABASE_URL,
    dimensions: 1536,
    distanceMetric: 'cosine', // 'cosine' | 'l2' | 'inner_product'
    indexType: 'hnsw' // 'none' | 'hnsw' | 'ivfflat'
  }
});

// SQLite : JSON fallback everywhere, native vec0 when available
import { createSQLiteRAG } from '@absolutejs/rag-sqlite';

const sqlite = createSQLiteRAG({
  storeOptions: {
    dimensions: 1536,
    native: { mode: 'vec0' }, // loads the platform vec0 extension
    path: './rag.sqlite'
  }
});
sqlite.getNativeSupport(); // resolution, nativeActive, actionableMessage

// Pinecone : serverless index, provision + connect
import {
  createPineconeRAG,
  ensurePineconeIndex
} from '@absolutejs/rag-pinecone';

await ensurePineconeIndex({
  dimensions: 1536,
  indexName: 'docs',
  waitUntilReady: true
});

const pinecone = createPineconeRAG({
  indexName: 'docs', // apiKey falls back to PINECONE_API_KEY
  namespace: 'production',
  vector: { dimensions: 1536, distanceMetric: 'cosine', provider: 'pinecone' }
});