@forgedevstack/forge-ai
v1.0.0
Published
Thin RAG toolkit: text chunking, provider-agnostic embeddings, pgvector SQL helpers, and document extraction types.
Maintainers
Readme
@forgedevstack/forge-ai
Thin RAG toolkit for TypeScript: text chunking, provider-agnostic embeddings, pgvector SQL helpers, and document extraction types. Zero runtime dependencies — the embedding client uses the global fetch.
Part of the ForgeStack ecosystem.
Install
npm install @forgedevstack/forge-aiQuick Example
Chunk a document, embed the chunks, and store/query them with pgvector:
import {
chunkText,
createOpenAiEmbeddingProvider,
buildCreateTableSql,
buildSimilarityQuerySql,
formatVectorLiteral,
} from '@forgedevstack/forge-ai';
const chunks = chunkText(documentText, {
strategy: 'sentence',
chunkSize: 512,
overlap: 64,
});
const provider = createOpenAiEmbeddingProvider({
baseUrl: 'https://api.openai.com/v1',
apiKey: process.env.OPENAI_API_KEY ?? '',
});
const embeddings = await provider.embed(chunks.map((chunk) => chunk.text));
await db.query(buildCreateTableSql({ table: 'documents', dimensions: provider.dimensions }));
for (const [position, chunk] of chunks.entries()) {
await db.query(
'INSERT INTO documents (content, embedding) VALUES ($1, $2)',
[chunk.text, formatVectorLiteral(embeddings[position])],
);
}
const [queryEmbedding] = await provider.embed(['What is ForgeStack?']);
const results = await db.query(
buildSimilarityQuerySql({ table: 'documents', topK: 5 }),
[formatVectorLiteral(queryEmbedding)],
);The similarity query uses a $1 placeholder for the query vector — pass the output of formatVectorLiteral as the query parameter.
API Overview
Chunking
chunkText(text, options?)— dispatches onoptions.strategy('fixed'default, or'sentence').chunkFixedSize(text, options?)— sliding character window ofchunkSizesteppingchunkSize - overlap, with correctstartOffset/endOffseton every chunk.chunkBySentence(text, options?)— splits on sentence boundaries (.,!,?followed by whitespace), packs sentences up tochunkSizecharacters, and carries trailing sentences up tooverlapcharacters into the next chunk.
Both throw when overlap >= chunkSize. Defaults: chunkSize 512, overlap 64.
Embeddings
createOpenAiEmbeddingProvider(options)— returns anEmbeddingProvidertargeting any OpenAI-compatible embeddings endpoint (POST {baseUrl}/embeddings). Supports custommodel,dimensions,headers, andfetchImplfor testing or non-global fetch. Results are sorted by responseindex. Non-ok responses throw with status and body.- Implement the
EmbeddingProviderinterface to plug in any other provider.
pgvector
buildCreateTableSql(options)—CREATE EXTENSION IF NOT EXISTS vector;plus aCREATE TABLE IF NOT EXISTSstatement with id (bigserial), text,vector(dimensions), and JSONB metadata columns. Column names are configurable.buildSimilarityQuerySql(options)— cosine distance (<=>) query with configurable select columns, optionalWHEREclause, andLIMIT topK(default 5).formatVectorLiteral(embedding)— formats anumber[]as a pgvector literal like[0.1,0.2,0.3].
Document Extraction
Extractor,ExtractorInput,ExtractedDocument, andSupportedDocumentFormat('pdf' | 'docx' | 'xlsx') types describe the extraction contract.createExtractorRegistry(initial?)— registry withregister,get, andhas;getthrows for unregistered formats.createStubExtractor(format)— placeholder whoseextractrejects, naming the optional peer dependency to install.
pdf-parse, mammoth, and xlsx are optional peer dependencies. v0.1.0 ships only the Extractor interface and stubs — install a parser and register your own Extractor implementation to extract real documents.
License
MIT © John Yaghobieh
