@dudousxd/nestjs-agent-rag
Retrieval-Augmented Generation — chunking, ingestion, an embedding-backed Retriever, and in-memory + pgvector stores. Framework-agnostic, core-only dep.
RAG for the agent. It's framework-agnostic (depends only on -core): you bring an embedding model
and, for pgvector, a Postgres driver. Ships chunking, ingestion, an embedding-backed Retriever,
and two VectorStore adapters — in-memory and pgvector.
For the full walkthrough (agentic vs inject mode, citations, how it plugs into the loop) see the RAG guide. This page is the package reference.
Install
pnpm add @dudousxd/nestjs-agent-rag @dudousxd/nestjs-agent-coreAPI
| Export | What it is |
|---|---|
chunkText(text, { chunkSize?, overlap? }) | Overlapping, boundary-aware chunks (defaults 800 / 100). |
chunkDocuments(docs, { chunkSize?, overlap? }) | Documents → ChunkRecord[] (ids ${doc.id}#${n}). Feed the same array to a vector store and a keyword index. |
ingestChunks(chunks, { embedder, store }) | Embed pre-chunked records (batched) → upsert. |
ingestDocuments(docs, { embedder, store, chunkSize?, overlap? }) | chunkDocuments + ingestChunks in one call. Returns the chunk count. |
EmbeddingRetriever(embedder, store) | The core Retriever from an EmbeddingProvider + VectorStore. |
KeywordRetriever({ k1?, b? }) | In-memory BM25 lexical Retriever (the keyword half of hybrid). add(chunks) to index. |
HybridRetriever(retrievers, { k?, fetchTopK?, weights? }) | Fuses retrievers with Reciprocal Rank Fusion. |
RerankingRetriever(base, reranker, { fetchTopK? }) | Over-fetch from base, reorder with a Reranker, truncate to topK. |
FilteredRetriever(base, filter) | ANDs a fixed metadata filter into every query — the owner/tenant-scoping primitive ({ ownerId }). Fixed filter wins, so a caller can't widen the scope. |
MemoryVectorStore | In-JS cosine VectorStore — tests + small/embedded corpora. |
PgVectorStore(client, { table?, dimensions? }) | pgvector VectorStore over an injected PgClient. ensureSchema() creates the extension, table, and HNSW cosine index. |
RedisVectorStore(client, { index?, prefix?, dimensions?, filterableFields? }) | RediSearch VectorStore over an injected RedisSearchClient (sendCommand). HNSW + cosine; ensureSchema() runs FT.CREATE. |
createRetrievalTool(retriever, { name?, description?, topK? }) | The agentic-retrieval tool ({ spec, handler }) — pass to provideAgentTool. |
Building blocks
import {
EmbeddingRetriever,
MemoryVectorStore,
ingestDocuments,
} from '@dudousxd/nestjs-agent-rag';
import { aiSdkEmbedding } from '@dudousxd/nestjs-agent-ai-sdk';
import { openai } from '@ai-sdk/openai';
const embedder = aiSdkEmbedding(openai.embedding('text-embedding-3-small'));
const store = new MemoryVectorStore();
await ingestDocuments(
[{ id: 'refund-policy', text: '…', source: 'docs/refunds' }],
{ embedder, store, chunkSize: 800 },
);
const retriever = new EmbeddingRetriever(embedder, store);pgvector
PgVectorStore takes an injected PgClient — adapt your own pg / postgres.js, so the package
pulls in no driver of its own (the same "bring your own client" shape as -transport-redis and the
store adapters).
import { Pool } from 'pg';
import { PgVectorStore } from '@dudousxd/nestjs-agent-rag';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const store = new PgVectorStore(
{ query: (sql, params) => pool.query(sql, params).then((r) => r.rows) },
{ dimensions: 1536 },
);
await store.ensureSchema();Custom vector stores
VectorStore (upsert / search / remove / listDocuments) is the extension point —
implement it over Qdrant, Pinecone, Weaviate, or your own -data SQL seam, and pair it with any
EmbeddingProvider via EmbeddingRetriever. remove(documentId) deletes a document's chunks
(delete-sync, and avoiding an orphaned tail when a re-ingest produces fewer chunks);
listDocuments(filter?) enumerates the indexed documents (id + metadata) — the seam
rag-media's reconciler diffs against.
@dudousxd/nestjs-agent-data
createExecuteSqlTool — governed, read-only SQL as a prebuilt tool. AST-validated single SELECTs, a fail-closed table allowlist, tenant scoping, and a row cap.
@dudousxd/nestjs-agent-rag-media
Auto-ingest nestjs-media uploads into agent RAG — extract, chunk, embed, index, owner-scoped, delete-synced. Couples via the diagnostics channel, no hard media dependency.