| --- |
| title: Lectio |
| emoji: π |
| colorFrom: yellow |
| colorTo: gray |
| sdk: docker |
| app_port: 7860 |
| pinned: false |
| license: mit |
| short_description: Denomination-aware Christian AI assistant |
| --- |
| |
| # Lectio β Scripture Companion |
|
|
| Grounded, denomination-aware Christianity AI assistant built for the SoluLab technical assessment. |
|
|
| ## Live Demo |
|
|
| | Service | URL | |
| | :-- | :-- | |
| | Frontend | [lectio-neon.vercel.app](https://lectio-neon.vercel.app) | |
| | Backend API | [adesh01-lectio.hf.space](https://adesh01-lectio.hf.space) | |
| | API Docs | [adesh01-lectio.hf.space/docs](https://adesh01-lectio.hf.space/docs) | |
| | Source | [github.com/adeshboudh/lectio](https://github.com/adeshboudh/lectio) | |
|
|
| ## Architecture at a Glance |
|
|
| ``` |
| User β FastAPI β LangGraph Agent β pgvector RAG β Gemini Pro (grounded) |
| β |
| Safety Router (regex + Gemini Flash) |
| β |
| Citation Validator + Semantic Drift Check |
| β |
| Image Generator (FLUX.1-dev via NVIDIA) β if image intent |
| β |
| Conversation Memory (window/semantic) |
| ``` |
|
|
| Full design: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | HLD: [`docs/HLD.md`](docs/HLD.md) |
|
|
| ## Features |
|
|
| | Feature | Implementation | |
| | :-- | :-- | |
| | Scripture RAG | pgvector HNSW cosine, bge-base-en-v1.5 embeddings, KJV corpus | |
| | Denomination awareness | Protestant / Catholic / Orthodox canon filtering via `@>` SQL | |
| | Hallucination prevention | Citation validator (regex β `verse_exists()`) + semantic drift check | |
| | Safety moderation | Two-stage: regex (0ms) + Gemini Flash classifier | |
| | Image generation | FLUX.1-dev (NVIDIA) with prompt rewrite to Renaissance art style | |
| | Conversation memory | Window (β€10 turns) or semantic (>20 turns), denomination-switch guard | |
| | Evaluation harness | 20-case PASS/PARTIAL/FAIL suite with category grouping | |
|
|
| ## Stack |
|
|
| | Concern | Choice | |
| | :-- | :-- | |
| | Backend | Python 3.12, FastAPI, uvicorn | |
| | Agent | LangGraph StateGraph | |
| | LLM | `gemini-3.1-flash-lite` (grounded gen) + `gemma-4-31b-it` (safety/router) | |
| | Embeddings | `BAAI/bge-base-en-v1.5` (local, sentence-transformers) | |
| | Data | PostgreSQL 16 + pgvector (NeonDB cloud) | |
| | Images | FLUX.1-dev via NVIDIA AI API | |
| | Frontend | Next.js 16, pure CSS (Lectio design system) | |
| | Logging | structlog | |
| | Package mgr | uv | |
|
|
| ## Deployment |
|
|
| | Layer | Platform | Notes | |
| | :-- | :-- | :-- | |
| | Frontend | Vercel | Auto-deploy from `master`, `NEXT_PUBLIC_API_URL` points to HF Space | |
| | Backend | HuggingFace Spaces (Docker) | Port 7860, env secrets set in Space settings | |
| | Database | NeonDB (ap-southeast-1) | pgvector enabled, 31,102 KJV verses + 1,406 history chunks ingested | |
|
|
| ## Quick Start |
|
|
| ### Prerequisites |
|
|
| - Docker + Docker Compose |
| - Python 3.12 (via `uv`) |
| - Node 20+ |
| - API keys in `backend/.env` (see `.env.example`) |
|
|
| ### 1. Start the database |
|
|
| ```bash |
| make db-up |
| ``` |
|
|
| ### 2. Backend setup |
|
|
| ```bash |
| make backend-install # uv sync β creates .venv, installs all deps |
| make backend-init # DB schema migration |
| make backend-ingest # embed KJV verses + church history (~30 min first run) |
| make dev # start API on :8000 |
| ``` |
|
|
| ### 3. Frontend |
|
|
| ```bash |
| make frontend-install # npm install |
| make frontend-dev # Next.js on :3000 |
| ``` |
|
|
| Open `http://localhost:3000`. |
|
|
| ### 4. Run evaluation |
|
|
| ```bash |
| make eval |
| ``` |
|
|
| Expected: β₯18/20 PASS/PARTIAL. |
|
|
| ### Environment variables |
|
|
| ```bash |
| # backend/.env |
| GEMINI_API_KEY=... |
| NVIDIA_API_KEY=... # FLUX.1-dev image generation |
| DATABASE_URL=postgresql://postgres:postgres@localhost:5433/christianity_ai |
| ``` |
|
|
| ## Project Structure |
|
|
| ``` |
| . |
| βββ backend/ |
| β βββ app/ |
| β β βββ agent/ # LangGraph graph, nodes, state |
| β β βββ api/ # FastAPI routes |
| β β βββ core/ # db, embeddings, llm, retrieval, safety, memory, image |
| β βββ scripts/ |
| β βββ init_db.py # schema init |
| β βββ ingest_bible.py # KJV verse embeddings |
| β βββ ingest_history.py # creed/council document embeddings |
| βββ eval/ |
| β βββ dataset.json # 20 eval cases |
| β βββ run_eval.py # harness with PASS/PARTIAL/FAIL scoring |
| βββ frontend/ |
| β βββ app/ # Next.js app router (page.tsx, layout.tsx, globals.css) |
| β βββ components/ # Composer, DenominationSelector, MessageBubble, |
| β # VerseBlock, EmptyState, Icons, Loading |
| βββ docs/ |
| β βββ ARCHITECTURE.md |
| β βββ HLD.md |
| β βββ PHASES.md |
| β βββ SYSTEM_DESIGN.md |
| βββ Makefile |
| βββ docker-compose.yml |
| ``` |
|
|
| ## Evaluation Categories |
|
|
| | Category | Cases | What it tests | |
| | :-- | :-- | :-- | |
| | adversarial | 5 | Jailbreak, rewrite, extremism β must be flagged + blocked | |
| | fake_verse | 2 | Non-existent references β must detect, not hallucinate | |
| | hallucination | 2 | Common misquotes + topics not in scripture | |
| | image_safety | 3 | Safety pre/post rewrite + policy block | |
| | historical | 3 | Council dates, creed attribution | |
| | denomination | 2 | Catholic vs Protestant framing (purgatory, papal infallibility) | |
| | theology | 2 | Predestination paradox, resurrection significance | |
| | scripture | 1 | Normal retrieval with citation verification | |
|
|
| ## Key Design Decisions |
|
|
| **Retrieval-first grounding** β System prompt forbids citing anything outside the injected context block. Hallucinated refs are detected post-generation and flagged in the UI with strikethrough. |
|
|
| **Two-stage safety** β Regex catches obvious violations in <1ms. Gemini Flash handles nuanced manipulation attempts. Either stage can block. |
|
|
| **Public-domain corpus only** β KJV translation avoids copyright. NIV/ESV are not used. |
|
|
| **Denomination filtering** β Each denomination has an associated canon list. Queries filter `denomination_canon @> ARRAY[denomination]` so Orthodox/Catholic users see deuterocanon results. |
|
|
| **Image prompt rewriting** β User requests are rewritten by the LLM into safe Renaissance fine-art style before hitting FLUX.1-dev. Post-generation safety check runs on the rewritten prompt too. |
|
|