Aviary
Packages

@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-core

API

ExportWhat 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.
MemoryVectorStoreIn-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.

On this page