@farming-labs/grag
v0.1.6
Published
TypeScript GraphRAG primitives with relational database storage.
Maintainers
Readme
@farming-labs/grag
TypeScript GraphRAG primitives for apps that want graph-backed retrieval, citations, and relational storage without leaving the TypeScript ecosystem.
Install
npm install @farming-labs/grag kyselyInstall the database driver you use separately:
npm install pg
npm install better-sqlite3
npm install mysql2What You Get
- GraphRAG artifact models for documents, chunks, entities, relationships, communities, reports, and embeddings.
- Memory storage for tests and prototypes.
- SQL/Kysely storage with migrations for relational databases.
- Optional
@farming-labs/ormadapter from@farming-labs/grag/orm. - Retrieval helpers for lexical search, graph context, local search, global search, citations, and source cards.
- A CLI Studio for previewing and querying GraphRAG snapshots.
Quick Start
import {
MemoryGraphRagStore,
chunkDocuments,
createGraphRagService,
relationalRowsToDocuments,
} from "@farming-labs/grag";
const rows = [
{ id: 1, customer: "Acme", body: "The billing export failed after migration." },
{ id: 2, customer: "Globex", body: "Password reset worked." },
];
const documents = relationalRowsToDocuments({
tableName: "support_tickets",
rows,
idColumn: "id",
titleColumn: "customer",
textColumn: "body",
});
const graph = chunkDocuments(documents);
const store = new MemoryGraphRagStore();
await store.upsertGraph(graph);
const grag = createGraphRagService({ store });
const answer = await grag.ask("What failed after the migration?");
console.log(answer.answer);
console.log(answer.citations);Database Source Adapter
Use source.database when your app should own the SQL query and GRAG should handle row-to-document conversion, row provenance, chunking, and retrieval citations:
import { DataSourceLoader, source } from "@farming-labs/grag";
const loader = new DataSourceLoader([
source.database({
label: "Production support tickets",
tableName: "support_tickets",
loadRows: () =>
db.selectFrom("support_tickets").selectAll().where("status", "!=", "spam").execute(),
idColumn: "id",
titleColumn: "subject",
textColumn: "body",
attributeColumns: ["customer", "priority", "status", "created_at"],
}),
]);
const { documents, textUnits } = await loader.load();
await store.upsertGraph({ documents, textUnits });SQL Storage
import { Kysely, PostgresDialect } from "kysely";
import { Pool } from "pg";
import {
SqlGraphRagStore,
applyGraphRagMigrations,
type GraphRagSqlDatabase,
} from "@farming-labs/grag";
const db = new Kysely<GraphRagSqlDatabase>({
dialect: new PostgresDialect({
pool: new Pool({ connectionString: process.env.DATABASE_URL }),
}),
});
await applyGraphRagMigrations(db, "postgres");
const store = new SqlGraphRagStore({ db });OpenAI Helpers
import { createGraphRagService } from "@farming-labs/grag";
import { OpenAiChatModel, OpenAiEmbeddingModel } from "@farming-labs/grag/openai";
const grag = createGraphRagService({
store,
model: new OpenAiChatModel(),
embeddingModel: new OpenAiEmbeddingModel(),
});
const result = await grag.ask("How does retrieval work?", {
responseStyle: "short answer with citations",
});CLI Studio
grag studio ./snapshot.json --port 3333 --open
grag retrieve ./snapshot.json "How does graph expansion help retrieval?"
grag repo . --ask "What does this repository do?" --snapshot repo.snapshot.jsonDocs
Development
pnpm install
pnpm --filter @farming-labs/grag check
pnpm --filter @farming-labs/grag test
pnpm --filter @farming-labs/grag buildFrom the monorepo root, pnpm build compiles the package, CLI Studio assets, and docs app.
