Spaces:
Sleeping
Sleeping
| # GeminiRAG β Project Context | |
| **For use by the next chat session to resume work without losing any context.** | |
| --- | |
| ## What This Project Is | |
| GeminiRAG is a **production-ready Multimodal RAG (Retrieval-Augmented Generation) pipeline** built for MasterCRM Internal Engineering. It allows users to upload any document (PDF, Word, Excel, CSV, image, audio, video), have it processed by Google Gemini, chunked and embedded into a ChromaDB vector store, and then queried in natural language. The system returns answers with citations and RAGAS quality scores. | |
| **Delivered by:** Dhrumil Parikh | |
| **Delivery date:** 3 June 2026 | |
| **GitHub repo:** https://github.com/Dhrumilparikh2806/yaya (branch: master) | |
| --- | |
| ## Tech Stack | |
| | Layer | Technology | | |
| |---|---| | |
| | LLM / Embeddings | Google Gemini (`gemini-2.5-flash`, `models/gemini-embedding-001`) via `google-genai` SDK | | |
| | Agent | Google ADK (`google-adk`) with 5 MCP tools | | |
| | API | FastAPI 0.111 + uvicorn, Python 3.11 | | |
| | Task Queue | Celery 5.6 + Redis broker, PostgreSQL result backend | | |
| | Vector Store | ChromaDB (HTTP client, cosine similarity) | | |
| | Database | PostgreSQL 18 (native, NOT Docker) β SQLModel + Alembic | | |
| | RAG Evaluation | RAGAS (faithfulness, answer_relevancy, context_precision, context_recall, answer_correctness) | | |
| | Frontend | React 18 + TypeScript + Vite + TailwindCSS + Recharts | | |
| | Observability | structlog (JSON), OpenTelemetry (stdout exporter), UsageLog DB table | | |
| | Auth | JWT (HS256, python-jose) + bcrypt passwords | | |
| | Rate Limiting | slowapi (10/min on /auth/login) | | |
| --- | |
| ## Environment (Local, No Docker) | |
| **Important:** Docker is NOT installed on this machine. All services run natively. | |
| | Service | Port | Status | Notes | | |
| |---|---|---|---| | |
| | PostgreSQL 18 | 5432 | Running natively | DB: `geminirag`, user: `geminirag`, pass: `geminirag` | | |
| | Redis | 6379 | Running natively | | | |
| | ChromaDB | 8001 | Running natively | | | |
| | FastAPI (uvicorn) | 8000 | Must be started manually | See "How to Start" below | | |
| | Celery worker | β | Must be started manually | Uses `--pool=solo` on Windows | | |
| | React (Vite) | 5173 | Must be started manually | | | |
| ### How to Start Everything | |
| Open 3 separate cmd windows (or use PowerShell `Start-Process`): | |
| **Window 1 β API Server:** | |
| ``` | |
| cd "c:\Users\Dhrumil.parikh\OneDrive - Taazaa Tech Pvt Ltd\Desktop\playbook_final\geminirag" | |
| py -m uvicorn app.main:app --reload --port 8000 | |
| ``` | |
| **Window 2 β Celery Worker:** | |
| ``` | |
| cd "c:\Users\Dhrumil.parikh\OneDrive - Taazaa Tech Pvt Ltd\Desktop\playbook_final\geminirag" | |
| py -m celery -A app.workers.celery_app worker --loglevel=info --concurrency=2 --pool=solo | |
| ``` | |
| **Window 3 β Frontend:** | |
| ``` | |
| cd "c:\Users\Dhrumil.parikh\OneDrive - Taazaa Tech Pvt Ltd\Desktop\playbook_final\geminirag\frontend" | |
| npm run dev | |
| ``` | |
| Or via PowerShell (each in its own visible cmd window that stays alive): | |
| ```powershell | |
| Start-Process cmd.exe -ArgumentList "/k", "cd /d `"...\geminirag`" && py -m uvicorn app.main:app --reload --port 8000" | |
| Start-Process cmd.exe -ArgumentList "/k", "cd /d `"...\geminirag\frontend`" && npm run dev" | |
| ``` | |
| ### Verification | |
| ```powershell | |
| # Check health (should return {"status":"ok","database":"ok","chromadb":"ok"}) | |
| Invoke-WebRequest http://localhost:8000/health -UseBasicParsing | Select -Expand Content | |
| ``` | |
| --- | |
| ## .env File Location and Contents | |
| Path: `c:\Users\Dhrumil.parikh\OneDrive - Taazaa Tech Pvt Ltd\Desktop\playbook_final\geminirag\.env` | |
| ``` | |
| GEMINI_API_KEY=AIzaSyD-0xYBLCksuwdk0oo1SO3S_gdFXW3DFNs | |
| DATABASE_URL=postgresql://geminirag:geminirag@localhost:5432/geminirag | |
| REDIS_URL=redis://localhost:6379/0 | |
| SECRET_KEY=geminirag_secret_key_minimum_32_chars_long_secure | |
| UPLOAD_DIR=C:/tmp/geminirag_uploads | |
| GEMINI_MODEL=gemini-2.5-flash | |
| GEMINI_EMBEDDING_MODEL=models/gemini-embedding-001 | |
| ``` | |
| `.env` is gitignored β never commit it. | |
| --- | |
| ## Database | |
| - **Engine:** PostgreSQL 18, running on localhost:5432 | |
| - **Database:** `geminirag` | |
| - **Tables:** `users`, `jobs`, `usage_logs`, `query_history` | |
| - **Migrations:** Alembic (`alembic upgrade head`) | |
| - **Connection pooling:** pool_size=10, max_overflow=20, pool_pre_ping=True (in `app/models/db.py`) | |
| To view in PgAdmin: connect to localhost:5432, user=geminirag, password=geminirag, DB=geminirag. | |
| --- | |
| ## Admin Credentials | |
| ``` | |
| Email: admin@test.com | |
| Password: Admin1234! | |
| Role: admin | |
| ``` | |
| To recreate: `py scripts/seed_admin.py --email admin@test.com --password Admin1234!` | |
| --- | |
| ## API Overview | |
| Base URL: `http://localhost:8000` | |
| Docs: `http://localhost:8000/docs` | |
| | Method | Path | Auth | Description | | |
| |---|---|---|---| | |
| | POST | /auth/register | No | Register user | | |
| | POST | /auth/login | No | Login β JWT token | | |
| | POST | /v1/files/upload | JWT | Upload file β returns job_id (async) | | |
| | GET | /v1/jobs/{id} | JWT | Get job status | | |
| | GET | /v1/jobs | JWT | List all user's jobs (admin sees all) | | |
| | POST | /v1/jobs/{id}/reprocess | JWT | Re-queue failed job | | |
| | GET | /v1/documents | JWT | List completed documents | | |
| | GET | /v1/documents/{id}/summary | JWT | Get document AI summary | | |
| | POST | /v1/query | JWT | RAG query β answer + citations | | |
| | POST | /v1/query/stream | JWT | Streaming RAG via SSE | | |
| | POST | /v1/agent/chat | JWT | ADK agent chat | | |
| | GET | /v1/admin/usage | Admin | Usage stats | | |
| | GET | /v1/admin/ragas | Admin | RAGAS metric averages | | |
| | GET | /v1/admin/users | Admin | User list with stats | | |
| | PATCH | /v1/admin/users/{id} | Admin | Toggle user is_active | | |
| | GET | /health | No | DB + ChromaDB health check | | |
| **Login format** (JSON body): | |
| ```json | |
| {"email": "admin@test.com", "password": "Admin1234!"} | |
| ``` | |
| --- | |
| ## File Processing Pipeline | |
| ``` | |
| User uploads file β POST /v1/files/upload | |
| β creates Job (PENDING) in PostgreSQL | |
| β saves file to C:/tmp/geminirag_uploads/{job_id}/ | |
| β enqueues process_file.delay(job_id) in Celery via Redis | |
| Celery worker picks up task β process_file(job_id): | |
| 1. EXTRACTING β dispatch to processor by file_type | |
| (PDFProcessor / DOCXProcessor / XLSXProcessor / | |
| ImageProcessor / VideoAudioProcessor) | |
| β processor.extract() β raw text | |
| β processor.summarise() β Gemini JSON summary | |
| β stores summary in job.result | |
| 2. CHUNKING β chunk_text() or chunk_video_segments() | |
| 800 words/chunk, 100-word overlap, min 50 words | |
| 3. EMBEDDING β embed_chunks() β Gemini embedding API (768-dim) | |
| batched 100 at a time, retry on 429 | |
| 4. INDEXING β add_chunks() β ChromaDB upsert with 3x retry | |
| 5. COMPLETED β job.status = COMPLETED, job.chunk_count = N | |
| ``` | |
| **Supported file types:** PDF, DOCX, XLSX, CSV, PNG, JPG, JPEG, WEBP, MP4, MOV, MP3, WAV, M4A | |
| **Max file size:** 500 MB | |
| --- | |
| ## RAG Query Flow | |
| ``` | |
| POST /v1/query {question, job_ids?} | |
| 1. Embed question β 768-dim vector (Gemini) | |
| 2. Search ChromaDB β top_k=5 chunks (cosine similarity) | |
| 3. Confidence gate: avg_score >= 0.65 | |
| β If fails: return "I don't have enough information..." | |
| 4. Format context from chunks | |
| 5. Call Gemini (gemini-2.5-flash) with RAG system prompt | |
| β Answer must only use provided context, must cite [1][2]... | |
| 6. Log to UsageLog + QueryHistory | |
| 7. Enqueue compute_ragas.delay() async (adds ~15-60s, runs in background) | |
| 8. Return: {answer, citations, confidence_gate_passed, avg_similarity_score} | |
| RAGAS scores appear later in QueryHistory (populated by background Celery task) | |
| ``` | |
| Streaming variant: `POST /v1/query/stream` uses `StreamingResponse` with `text/event-stream`. | |
| Frontend uses Fetch API (not EventSource) because SSE doesn't support POST/auth headers. | |
| --- | |
| ## Celery Tasks | |
| | Task | Trigger | Purpose | | |
| |---|---|---| | |
| | `process_file` | File upload | Full extraction β chunk β embed β index pipeline | | |
| | `compute_ragas` | After each query | Async RAGAS score computation | | |
| | `cleanup_old_uploads` | Daily (beat schedule) | Delete upload files for 7-day-old completed jobs | | |
| **Retry strategy:** max_retries=3, exponential backoff (CELERY_RETRY_BACKOFF * 2^retry). | |
| **Dead letter queue:** FAILED_PERMANENT jobs pushed to Redis list `geminirag:dead_letter`. | |
| **Windows note:** Must use `--pool=solo` flag on Windows. | |
| --- | |
| ## ADK Agent | |
| The agent has 5 tools and can hold multi-turn conversations: | |
| | Tool | What it does | | |
| |---|---| | |
| | `ingest_file` | Upload a file by path β creates job, queues processing | | |
| | `get_job_status` | Check processing status of a job | | |
| | `query_rag` | Ask a question against uploaded documents | | |
| | `list_documents` | List all completed documents | | |
| | `summarize_document` | Get AI summary of a specific document | | |
| **Session service:** InMemorySessionService β conversation history resets on server restart. | |
| **Production note:** Should be replaced with Redis/PostgreSQL-backed session service. | |
| --- | |
| ## RAGAS Evaluation | |
| **Target scores (from spec):** | |
| - Faithfulness β₯ 0.80 | |
| - Context Precision β₯ 0.60 | |
| **Running baseline offline:** | |
| 1. Ensure documents are uploaded and COMPLETED | |
| 2. Create test set JSON: `C:/tmp/ragas_test_set.json` | |
| ```json | |
| [{"question": "...", "ground_truth": "...", "job_id": "uuid-here"}] | |
| ``` | |
| 3. Run: `py scripts/ragas_baseline.py --test-set C:/tmp/ragas_test_set.json` | |
| 4. Results saved to: `C:/tmp/ragas_baseline.json` | |
| **Pre-downloaded sample datasets** (50 Q&A pairs each, no job_id yet): | |
| - `Data set/ragas_eval/ms_marco_samples.json` β MS MARCO v1.1 validation | |
| - `Data set/ragas_eval/natural_questions_samples.json` β Natural Questions dev | |
| To use these, upload relevant documents first, then add the returned `job_id` to the JSON entries. | |
| --- | |
| ## Frontend Pages | |
| | URL | Page | What it does | | |
| |---|---|---| | |
| | `/login` | LoginPage | Email/password login, stores JWT | | |
| | `/register` | RegisterPage | New user registration | | |
| | `/upload` | UploadPage | Drag-drop upload, job polling, summary drawer | | |
| | `/query` | QueryPage | Select docs, ask question, streaming mode, citation links | | |
| | `/agent` | AgentPage | Chat with ADK agent, tool call log sidebar | | |
| | `/jobs` | JobsPage | Full jobs table, re-process button | | |
| | `/admin` | AdminPage | Usage/RAGAS/user management tabs (admin only) | | |
| **All pages lazy-loaded** (React.lazy + Suspense) β main bundle ~211KB after code splitting. | |
| --- | |
| ## Key Design Decisions (for context) | |
| 1. **`google-genai` not `google-generativeai`** β The old SDK (`google-generativeai`) is deprecated. Always use `google-genai>=1.0.0` with `from google import genai`. | |
| 2. **SSE streaming uses Fetch not EventSource** β EventSource API doesn't support POST requests or custom headers. The frontend uses `fetch()` with `ReadableStream` reader to stream answers with auth. | |
| 3. **ChromaDB 3x retry** β `add_chunks()` retries 3 times with 5s backoff because ChromaDB can have transient write failures. | |
| 4. **RAGAS is async** β Computing RAGAS after every query adds 15-60s latency. It runs in a background Celery task (`compute_ragas`). The query response returns immediately; RAGAS scores appear in QueryHistory later. | |
| 5. **ALLOWED_ORIGINS is env-driven** β Set `ALLOWED_ORIGINS=https://your-domain.com` in .env for production. In dev it defaults to `http://localhost:5173`. | |
| 6. **No Docker** β All infrastructure runs natively on this machine. PostgreSQL (v18), Redis, ChromaDB are already running as system services. | |
| 7. **Windows Celery** β Must use `--pool=solo` flag. Celery's default prefork pool doesn't work on Windows. | |
| --- | |
| ## Known Limitations | |
| 1. **Speaker diarization accuracy** β depends on audio quality. Mono recordings work best. | |
| 2. **Large video files** β >500 MB rejected. Close-to-limit files may hit Gemini context window. | |
| 3. **RAGAS cost** β ~15-60s and token cost per query. Disable by removing `compute_ragas.delay()` from `app/rag/engine.py`. | |
| 4. **In-memory agent sessions** β ADK InMemorySessionService resets on server restart. | |
| 5. **ChromaDB not backed up** β Lives in Docker named volume. If deleted, re-upload all documents. | |
| 6. **No email notifications** β No notification when long jobs complete. Planned future feature. | |
| --- | |
| ## Adding a New File Type | |
| 1. Create `app/processors/newtype.py` extending `BaseProcessor` β implement `extract()` and `summarise()` | |
| 2. Add extension to `EXTENSION_MAP` in `app/api/files.py` | |
| 3. Add extension to `EXT_TO_TYPE` in `frontend/src/pages/UploadPage.tsx` | |
| 4. Add dispatch case in `process_file()` in `app/workers/tasks.py` | |
| 5. Write a test in `tests/test_processors.py` | |
| --- | |
| ## Git History (recent) | |
| ``` | |
| 5965edb feat: day 8-10 + buffer β frontend, security hardening, streaming, delivery docs | |
| 636fd39 fix: phase-1 checklist gaps β otel spans, from_status logging, user_id in http middleware | |
| 48f3cfa day-7: ragas evaluation, observability audit, baseline | |
| 39c873f day-6: rag engine, citations, confidence gate, admin api | |
| a8fbf32 day-4: image and video/audio processors, diarization, 14 tests pass | |
| 3f24a13 day-3: migrate to google.genai SDK, verify processors end-to-end | |
| ``` | |
| --- | |
| ## Project Directory | |
| ``` | |
| playbook_final/ | |
| βββ geminirag/ β main project root | |
| βββ app/ β FastAPI backend | |
| β βββ main.py | |
| β βββ config.py | |
| β βββ deps.py | |
| β βββ security.py | |
| β βββ limiter.py | |
| β βββ api/ β route handlers | |
| β βββ models/ β SQLModel ORM | |
| β βββ processors/ β file type processors | |
| β βββ rag/ β chunker, embedder, vectorstore, engine | |
| β βββ workers/ β Celery tasks | |
| β βββ agent/ β ADK agent + tools | |
| β βββ evaluation/ β RAGAS eval | |
| β βββ observability/ β logging + tracing | |
| βββ frontend/ β React + TypeScript | |
| β βββ src/ | |
| β βββ pages/ β 7 pages | |
| β βββ context/ β Auth + Toast contexts | |
| β βββ components/ β NavBar, PrivateRoute | |
| β βββ hooks/ β useToast | |
| β βββ api/ β Axios client | |
| βββ scripts/ β seed_admin, ragas_baseline, download_datasets | |
| βββ tests/ β pytest test suite | |
| βββ migrations/ β Alembic migration files | |
| βββ Data set/ β test datasets | |
| β βββ ragas_eval/ β ms_marco_samples.json, natural_questions_samples.json | |
| βββ .env β secrets (gitignored) | |
| βββ .env.example β template | |
| βββ pyproject.toml β Python deps | |
| βββ docker-compose.yml β dev (not used locally) | |
| βββ docker-compose.prod.yml | |
| βββ Dockerfile | |
| βββ alembic.ini | |
| βββ README.md | |
| βββ HANDOVER.md | |
| βββ DEMO_SCRIPT.md | |
| ``` | |