A Next.js 15 application that parses legal PDF documents with a local parser, indexes document chunks in an in-memory vector store, and utilizes OpenRouter for AI summarization and grounded conversational Q&A.
- Local PDF Ingestion: Instant server-side PDF extraction with zero cloud OCR delays or GCP dependencies.
- Per-Document Vector Store & RAG: Semantic text chunking and cosine similarity search for pinpoint accuracy.
- AI Legal Summarization: Key obligations, rights, liabilities, deadlines, payment terms, and termination clauses powered by OpenRouter LLMs.
- Grounded Interactive Q&A: Chat interface with clickable source chunk citations showing relevance score.
- Flexible Model Selection: Configurable chat and embedding models via environment variables.
- Node.js: v18.18+ or v20+
- OpenRouter API Key: Obtain a key from openrouter.ai
git clone <repository-url>
cd verity
npm installCreate a .env.local file from .env.example:
cp .env.example .env.localAdd your OpenRouter credentials:
OR_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional model customizations (defaults shown below)
OPENROUTER_MODEL=google/gemini-2.5-flash
OPENROUTER_EMBEDDING_MODEL=openai/text-embedding-3-smallnpm run devOpen http://localhost:3000 in your browser.
verity/
├── src/
│ ├── app/
│ │ ├── api/
│ │ │ ├── extract-text/route.ts # Local PDF parse + Vector indexing
│ │ │ ├── summarize/route.ts # OpenRouter Legal Summarizer
│ │ │ └── ask/route.ts # RAG Cosine Retrieval + Grounded Q&A
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Split dashboard UI
│ ├── components/
│ │ ├── PDFUpload.tsx # Drag & Drop PDF uploader
│ │ ├── DocumentSummary.tsx # Markdown summary viewer
│ │ ├── ChatInterface.tsx # Vector-grounded Q&A with citations
│ │ └── ErrorBoundary.tsx # Global UI error boundary
│ └── lib/
│ ├── chunker.ts # Semantic paragraph & sliding window chunking
│ ├── openrouter.ts # OpenRouter API client for chat & embeddings
│ ├── pdf.ts # Server-side PDF extraction
│ ├── types.ts # Shared TypeScript definitions
│ └── vectorStore.ts # In-memory per-document vector store
├── Dockerfile # Multi-stage production container
└── package.json
POST /api/extract-text: Accepts{ fileBase64, fileName }. Extracts text, chunks paragraphs, creates vector embeddings via OpenRouter, stores them in the in-memory vector store, and returns{ documentId, text, totalPages, chunkCount }.POST /api/summarize: Accepts{ documentId, documentText }. Generates structured legal analysis using the configured OpenRouter LLM.POST /api/ask: Accepts{ documentId, question, documentText? }. Performs cosine similarity search over indexed chunks, injects relevant excerpts into the prompt, and returns{ answer, sources: [...] }.
Build and run with Docker:
docker build -t verity .
docker run -p 8080:8080 -e OR_API_KEY=your_key verityMIT License