Skip to content

Repository files navigation

DocMind

Intelligent Document Assistant powered by RAG

Next.js React TypeScript Anthropic Claude Anthropic SDK OpenAI OpenAI SDK Ollama pdf-parse Mammoth License

Upload a PDF, Word doc, or text file. Ask questions. Get answers with exact page citations — backed by semantic vector search, not just keyword matching.


Features

Multi-format upload PDF (page-aware), DOCX via Mammoth, TXT, Markdown
Semantic RAG OpenAI text-embedding-3-small embeddings → cosine similarity retrieval; falls back to keyword scoring when no key is present
Page-level citations Every answer cites exact page numbers (p. 3–5) pulled from the original document
Streaming responses Server-Sent Events deliver tokens as they arrive, with a live cursor
Web cross-check Manual toggle or automatic detection — if your question contains signals like "latest", "verify", "as of", or "compare", the web search fires automatically and Claude flags any conflicts with the document
Multi-document Upload several files; select which ones to search per query
Three LLM providers Anthropic Claude Sonnet 4, OpenAI GPT-4o, or any local Ollama model — switchable in-app
File caching Original buffers are held in memory so source passage highlighting is always available

Quick Start

1. Clone & install

git clone https://github.com/your-username/docmind.git
cd docmind
npm install

2. Configure API keys

cp .env.local.example .env.local

Then edit .env.local:

# Required for Claude (default provider)
ANTHROPIC_API_KEY=sk-ant-...

# Optional — enables semantic embeddings + GPT-4o chat
OPENAI_API_KEY=sk-...

Tip: Keys can also be entered directly in the in-app Settings panel (⚙ in the header). Browser-stored keys always take precedence over env vars.

3. Start the dev server

npm run dev

Open http://localhost:3000.


Using a Local Model (Ollama)

No API costs, fully private.

# Install Ollama
# macOS
brew install ollama
# Linux
curl -fsSL https://ollama.com/install.sh | sh

# Pull a model
ollama pull llama3.2      # ~2 GB, fast
ollama pull mistral       # ~4 GB, higher quality
ollama pull phi3:mini     # ~2 GB, fastest

Then open Settings in the app, choose Local via Ollama, set the base URL (http://localhost:11434), and enter your model name.

Note: Web cross-check requires Anthropic — it is silently skipped for OpenAI and Ollama.


How It Works

┌─────────────────────────────────────────────────────────────┐
│  UPLOAD PIPELINE                                            │
│                                                             │
│  File → extractTextWithPages() ──────────────────────────┐  │
│          (pdf-parse page hooks / Mammoth / plain UTF-8)  │  │
│                                                          ↓  │
│          chunkTextWithPages()  → [{text, pages[]}]       │  │
│          (1 500-char chunks, 200-char overlap,           │  │
│           page sentinel tracking)                        │  │
│                                                          ↓  │
│          generateEmbeddings()  → float[] per chunk       │  │
│          (OpenAI text-embedding-3-small, batched)        │  │
│                                                          ↓  │
│          In-memory store: documents, chunks, file buffer │  │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│  CHAT / RETRIEVAL LOOP                                      │
│                                                             │
│  Question → embed query (text-embedding-3-small)            │
│           → cosineSimilarity() against all chunk embeddings │
│             (falls back to keywordScore() without a key)    │
│           → top-6 chunks with page numbers                  │
│           → shouldAutoWebSearch(query)?                     │
│             yes → fetchWebResults() via Claude tool use     │
│           → buildSystemPrompt(context, webResults)          │
│           → stream response (Claude / GPT-4o / Ollama)      │
│           → SSE: { sources[], webSearchAuto, text, done }   │
└─────────────────────────────────────────────────────────────┘

Project Structure

docmind/
├── app/
│   ├── api/
│   │   ├── upload/route.ts       ← Extraction, chunking, embedding, caching
│   │   ├── chat/route.ts         ← Query embedding, RAG, auto web-search, streaming
│   │   └── documents/route.ts   ← List & delete documents
│   ├── components/
│   │   └── SettingsPanel.tsx     ← Provider / API key configuration UI
│   ├── lib/
│   │   ├── chunker.ts            ← extractTextWithPages, chunkTextWithPages, generateEmbeddings
│   │   ├── retrieval.ts          ← retrieveChunks (cosine + keyword), buildContext, buildSystemPrompt
│   │   ├── store.ts              ← In-memory documents / chunks / file buffers
│   │   └── providers.ts         ← Provider type definitions and metadata
│   ├── page.tsx                  ← Main chat UI
│   ├── layout.tsx
│   └── globals.css
├── .env.local.example
├── next.config.ts
└── package.json

Production Upgrade Path

Component Current (dev) Recommended for production
Vector store In-memory Map Pinecone · pgvector · Qdrant
File storage In-memory Buffer S3 · Cloudflare R2
Embeddings text-embedding-3-small via OpenAI Same, or self-hosted via Ollama
Database None PostgreSQL · Supabase
Auth None Clerk · NextAuth.js
Deployment npm run dev Vercel · Railway · Docker

License

MIT

About

DocMind is an AI-powered document Q&A assistant. Users upload documents (PDF, DOCX, TXT, Markdown), then ask natural language questions and receive answers with exact page-level citations, backed by semantic vector search (RAG — Retrieval-Augmented Generation).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages