A conversational AI agent that ingests documentation and codebases to answer questions with source-cited responses.
Built with OpenAI Assistants API, ChromaDB, Next.js 14, and Vercel AI SDK.
graph TB
User([User]) -->|Uploads files / Asks questions| UI[Next.js UI]
UI -->|API calls| Server[Next.js API Routes]
Server -->|Store/Query| Chroma[(ChromaDB)]
Server -->|Generate| OpenAI[OpenAI API]
Server -->|File parsing| Parser[Document Parser]
sequenceDiagram
participant U as User
participant API as API Route
participant P as Parser
participant C as ChromaDB
participant O as OpenAI
U->>API: Upload document
API->>P: Extract text
P->>API: Return chunks
API->>C: Store embeddings
C->>API: Confirm storage
API->>U: Upload complete
U->>API: Ask question
API->>C: Query similar chunks
C->>API: Return context
API->>O: Generate answer with context
O->>API: Return response + citations
API->>U: Stream answer with sources
graph LR
subgraph Frontend
Chat[Chat Interface]
Upload[File Upload]
Sources[Source Viewer]
end
subgraph API Layer
ingest[/api/ingest\]
chat[/api/chat\]
search[/api/search\]
end
subgraph Core
Parser[Document Parser]
Chunker[Text Chunker]
Embedder[Embedding Service]
end
subgraph Storage
Chroma[(ChromaDB)]
end
Upload --> ingest
ingest --> Parser
Parser --> Chunker
Chunker --> Embedder
Embedder --> Chroma
Chat --> chat
chat --> search
search --> Chroma
chat --> Embedder
chat --> Sources
- Node.js 18+
- OpenAI API key
# Clone and install
git clone <repo-url>
cd rag-docs-agent
npm install
# Environment
cp .env.example .env.local
# Add your OPENAI_API_KEY to .env.local
# Run tests
npm test
# Start dev server
npm run dev| Test Type | Tool | Coverage Focus |
|---|---|---|
| Unit | Vitest | lib/ functions (parsers, etc.) |
| Integration | Vitest + MSW | API routes, mocked services |
| Component | - | React components (not tested) |
All external API calls (OpenAI, ChromaDB) are mocked for fast, deterministic tests.
# Run all tests
npm test
# Run tests once
npm test -- --run
# Run tests with coverage
npm run test:coverage
# Run tests with UI
npm run test:uiβββ app/ # Next.js App Router
β βββ api/ # API routes
β β βββ ingest/ # Document ingestion endpoint
β β βββ chat/ # Chat with RAG endpoint
β βββ components/ # React components
β β βββ ChatInterface.tsx
β β βββ FileUpload.tsx
β βββ layout.tsx # Root layout
βββ lib/ # Core logic
β βββ parser.ts # Document parsing
β βββ chunker.ts # Text chunking
β βββ embedder.ts # Embedding service
β βββ chroma.ts # ChromaDB client
βββ tests/ # Test files
β βββ unit/ # Unit tests for lib functions
β βββ integration/ # Integration tests for API routes
β βββ mocks/ # Mocked services (MSW)
β βββ setup.ts # Test setup
βββ types/ # TypeScript types
β βββ index.ts # Shared type definitions
βββ docs/ # Architecture decisions (ADR)
Ingests a markdown or text file into the vector database.
Request:
curl -X POST http://localhost:3000/api/ingest \
-F "file=@document.md"Parameters:
file(File): The markdown or text file to ingest
Response:
{
"success": true,
"chunkCount": 15
}Constraints:
- Max file size: 10MB
- Allowed extensions:
.md,.txt,.markdown,.text
Answers questions using RAG (Retrieval-Augmented Generation).
Request:
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "How do I handle errors?"}
]
}'Parameters:
messages(Array<{role: string, content: string}>): Conversation history
Response:
{
"response": "To handle errors in this code...",
"sources": [
{
"id": "chunk-42",
"content": "Error handling...",
"metadata": {
"source": "docs.md",
"startLine": 15,
"endLine": 20
}
}
]
}| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| UI | React 18 + Tailwind CSS |
| AI SDK | Vercel AI SDK |
| LLM | OpenAI GPT-4o |
| Vector DB | ChromaDB |
| Testing | Vitest + MSW |
| Deployment | Vercel |
- Push your code to GitHub
- Import the project in Vercel
- Add environment variables:
OPENAI_API_KEY: Your OpenAI API keyCHROMA_URL: (Optional) ChromaDB server URL (defaults to localhost:8000)CHROMA_COLLECTION: (Optional) Collection name (defaults to "documents")
- Deploy!
# Build image
docker build -t rag-docs-agent .
# Run container
docker run -p 3000:3000 \
-e OPENAI_API_KEY=your-key \
-e CHROMA_URL=http://chromadb:8000 \
rag-docs-agentnpm run build
npm startThe application will be available at http://localhost:3000
Problem: "Failed to connect to ChromaDB"
Solutions:
- Ensure ChromaDB server is running:
docker run -p 8000:8000 chromadb/chroma - Check the
CHROMA_URLenvironment variable - Verify network connectivity if ChromaDB is remote
Problem: "Insufficient quota" or "Invalid API key"
Solutions:
- Verify your OpenAI API key is correct
- Check your API quota at https://platform.openai.com/usage
- Add a valid
OPENAI_API_KEYto.env.local
Problem: Files aren't uploading or showing errors
Solutions:
- Ensure file is
.mdor.txtformat - Check file size is under 10MB
- Verify file encoding is UTF-8
Problem: Tests failing with "module not found" errors
Solutions:
- Run
npm installto install dependencies - Ensure all dependencies are up to date:
npm update - Clear cache:
rm -rf node_modules/.vite
Problem: Chat responses don't include relevant sources
Solutions:
- Ensure documents have been ingested via /api/ingest
- Check ChromaDB collection has data
- Try adjusting your question to match document content
MIT