--- title: Tipitaka emoji: πŸ“– colorFrom: indigo colorTo: blue sdk: docker pinned: false --- # πŸ“– ΰΈžΰΈ£ΰΈ°ΰΉ„ΰΈ•ΰΈ£ΰΈ›ΰΈ΄ΰΈŽΰΈ ΰΈ‰ΰΈšΰΈ±ΰΈšΰΈ‘ΰΈ«ΰΈ²ΰΈˆΰΈΈΰΈ¬ΰΈ²ΰΈ₯ΰΈ‡ΰΈΰΈ£ΰΈ“ΰΈ£ΰΈ²ΰΈŠΰΈ§ΰΈ΄ΰΈ—ΰΈ’ΰΈ²ΰΈ₯ΰΈ±ΰΈ’ **Tipitaka Web App** β€” ΰΉ€ΰΈ§ΰΉ‡ΰΈšΰΈ­ΰΉˆΰΈ²ΰΈ™ΰΈžΰΈ£ΰΈ°ΰΉ„ΰΈ•ΰΈ£ΰΈ›ΰΈ΄ΰΈŽΰΈ ΰΈ‰ΰΈšΰΈ±ΰΈš ฑจร. ΰΉΰΈšΰΈšΰΈˆΰΈ΄ΰΈ•ΰΈ§ΰΈ΄ΰΉ€ΰΈ§ΰΈ ΰΈžΰΈ£ΰΉ‰ΰΈ­ΰΈ‘ AI ΰΈœΰΈΉΰΉ‰ΰΈŠΰΉˆΰΈ§ΰΈ’ΰΈ­ΰΈ±ΰΈˆΰΈ‰ΰΈ£ΰΈ΄ΰΈ’ΰΈ° > **Stack:** React + Vite | FastAPI + Python | SQLite FTS5 | Turbovec In-Process (Primary) / Qdrant (Secondary) | ONNX Reranker | DeepSeek API --- ## ✨ Features | Feature | Description | |---------|-------------| | **πŸ“– Reader** | 45+ ΰΉ€ΰΈ₯ΰΉˆΰΈ‘ΰΈžΰΈ£ΰΈ°ΰΉ„ΰΈ•ΰΈ£ΰΈ›ΰΈ΄ΰΈŽΰΈ β€” ΰΈ«ΰΈ™ΰΉ‰ΰΈ²-ΰΈ•ΰΉˆΰΈ­-ΰΈ«ΰΈ™ΰΉ‰ΰΈ², ΰΈ›ΰΈ£ΰΈ±ΰΈšΰΈ‚ΰΈ™ΰΈ²ΰΈ”ΰΈ•ΰΈ±ΰΈ§ΰΈ­ΰΈ±ΰΈΰΈ©ΰΈ£, 3 themes (dark/light/classic) | | **πŸ” Hybrid Search** | FTS5 + Vector (Turbovec / Qdrant) + ONNX Reranker β€” ถูกต้องทั้ง keyword แΰΈ₯ΰΈ°ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈ«ΰΈ‘ΰΈ²ΰΈ’ | | **πŸ€– AI Assistant** | Floating chat ΰΈžΰΈ£ΰΉ‰ΰΈ­ΰΈ‘ RAG context, ΰΈ£ΰΈ­ΰΈ‡ΰΈ£ΰΈ±ΰΈš DeepSeek-chat / DeepSeek-reasoner | | **πŸ”— Cross-Volume RAG** | ΰΈ„ΰΉ‰ΰΈ™ΰΈ‚ΰΉ‰ΰΈ²ΰΈ‘ΰΉ€ΰΈ₯่ฑจาก Turbovec index / Qdrant + jina-embeddings-v5, rerank ΰΈ”ΰΉ‰ΰΈ§ΰΈ’ jina-reranker-v2 | | **πŸ“± Responsive** | Desktop + Mobile, swipe gesture, keyboard nav | | **🎨 Markdown Rendering** | AI ΰΈ•ΰΈ­ΰΈšΰΉ€ΰΈ›ΰΉ‡ΰΈ™ markdown ΰΈžΰΈ£ΰΉ‰ΰΈ­ΰΈ‘ prose-invert ΰΈͺำหรับ dark mode | | **↔️ Resizable Panel** | ΰΈ₯ΰΈ²ΰΈΰΈ‚ΰΈ­ΰΈšΰΈ‚ΰΈ§ΰΈ²ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΈ›ΰΈ£ΰΈ±ΰΈšΰΈ‚ΰΈ™ΰΈ²ΰΈ” AI chat β€” persist ΰΈ‚ΰΈ™ΰΈ²ΰΈ”ΰΉ„ΰΈ§ΰΉ‰ | | **🏷️ Pali Autocorrect** | ΰΉΰΈΰΉ‰ΰΈ„ΰΈ³ΰΈšΰΈ²ΰΈ₯ΰΈ΅ΰΈœΰΈ΄ΰΈ”ΰΉ€ΰΈ­ΰΈ‡ ΰΈΰΉˆΰΈ­ΰΈ™ΰΈͺΰΉˆΰΈ‡ΰΈ„ΰΉ‰ΰΈ™ΰΈ«ΰΈ² β€” PyThaiNLP + custom dict | --- ## πŸ—οΈ Architecture (Turbovec Edition) ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Frontend (Vite + React) β”‚ β”‚ AppShell β†’ NavDrawer | ReaderPanel | RightToolbar | AIPopup β”‚ β”‚ Zustand (5 stores) Β· Framer Motion Β· Tailwind CSS v4 β”‚ β”‚ react-markdown + remark-gfm Β· Lucide React β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ HTTP / SSE β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Backend (FastAPI Python 3.13) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Page β”‚ β”‚ Search β”‚ β”‚ RAG β”‚ β”‚ LLM β”‚ β”‚ β”‚ β”‚ Service β”‚ β”‚ Service β”‚ β”‚ Service β”‚ β”‚ Service β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ SQLite β”‚ β”‚ SQLite β”‚ β”‚ Turbovecβ”‚ β”‚ DeepSeek β”‚ β”‚ β”‚ β”‚ FTS5 β”‚ β”‚ LIKE β”‚ β”‚ Index / β”‚ β”‚ API β”‚ β”‚ β”‚ β”‚ (memory)β”‚ β”‚ fallback β”‚ β”‚ Qdrant β”‚ β”‚ Streamingβ”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ Services: page_service Β· search_service Β· pali_utils β”‚ β”‚ rag_service Β· onnx_reranker Β· llm_service β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### πŸ”„ Hybrid Search Pipeline ``` ΰΈ„ΰΈ³ΰΈ–ΰΈ²ΰΈ‘ β†’ Pali Autocorrect β†’ FTS5 (SQLite, 30 results) ─→ Turbovec Index (jina-embeddings-v5, 30 results) β†’ SQLite Content Enrichment β†’ Merge & Deduplicate β†’ ONNX Rerank (jina-reranker-v2) β†’ Top N β†’ AI context ``` --- ## πŸ—‚οΈ Project Structure ``` RAG/ β”œβ”€β”€ webapp/ β”‚ β”œβ”€β”€ tipitaka-api/ # FastAPI backend β”‚ β”‚ β”œβ”€β”€ app/ β”‚ β”‚ β”‚ β”œβ”€β”€ main.py # FastAPI entry + lifespan β”‚ β”‚ β”‚ β”œβ”€β”€ config.py # pydantic-settings β”‚ β”‚ β”‚ β”œβ”€β”€ schemas.py # Pydantic models β”‚ β”‚ β”‚ β”œβ”€β”€ routers/ # pages, search, ai, health β”‚ β”‚ β”‚ β”œβ”€β”€ services/ # 6 service modules β”‚ β”‚ β”‚ └── database/ # sqlite_db.py β”‚ β”‚ β”œβ”€β”€ tests/ # 35 tests β”‚ β”‚ β”œβ”€β”€ models/ # ONNX reranker β”‚ β”‚ └── startup.sh # HF Spaces entry β”‚ β”‚ β”‚ └── tipitaka-web/ # React frontend β”‚ └── src/ β”‚ β”œβ”€β”€ components/ # layout, reader, toolbar, ai β”‚ β”œβ”€β”€ stores/ # Zustand (5 stores) β”‚ β”œβ”€β”€ hooks/ # swipe, keyboard β”‚ └── lib/ # api.ts β”‚ β”œβ”€β”€ qdrant_storage/ # Local Qdrant data (optional fallback) β”œβ”€β”€ snapshots/ # Qdrant snapshot files (optional fallback) β”œβ”€β”€ Dockerfile # Multi-stage build β”œβ”€β”€ TIPITAKA_WEB_ARCHITECTURE_TURBOVEC.md # Main architecture doc (Turbovec) └── SEARCH_ARCHITECTURE_TURBOVEC.md # Search specification (Turbovec) ``` --- ## πŸš€ Quick Start ### Prerequisites - Python 3.13+ - Node.js 20+ - Ollama (for embedding β€” **jina-embeddings-v5-small-retrieval**) - DeepSeek API key ### 1. Setup Backend ```bash cd webapp/tipitaka-api python -m venv .venv .venv\Scripts\activate # Windows pip install -r requirements.txt # Copy .env.example β†’ .env and fill DEEPSEEK_API_KEY python -m app.main # starts on :8000 ``` ### 2. Setup Frontend ```bash cd webapp/tipitaka-web npm install npm run dev # starts on :5173 ``` ### 3. Setup Embedding ```bash # Download jina-embeddings-v5 GGUF ollama pull hf.co/second-state/jina-embeddings-v5-text-small-retrieval-GGUF:v5-small-retrieval-Q6_K.gguf ``` ### 4. Run Tests ```bash cd webapp/tipitaka-api python -m pytest tests/ -v # 35 tests, all passing ``` --- ## πŸ“‘ API Endpoints | Method | Path | Description | |--------|------|-------------| | `GET` | `/api/pages/volumes` | ราฒการเΰΈ₯ΰΉˆΰΈ‘ΰΈžΰΈ£ΰΈ°ΰΉ„ΰΈ•ΰΈ£ΰΈ›ΰΈ΄ΰΈŽΰΈ | | `GET` | `/api/pages/volumes/{id}/toc` | ΰΈͺารบัญ (dedup + noise filter) | | `GET` | `/api/pages/{vol}/{page}` | ΰΉ€ΰΈ™ΰΈ·ΰΉ‰ΰΈ­ΰΈ«ΰΈ²ΰΈ«ΰΈ™ΰΉ‰ΰΈ² | | `GET` | `/api/search?q=&limit=&offset=` | ΰΈ„ΰΉ‰ΰΈ™ΰΈ«ΰΈ² FTS5 + LIKE + highlight | | `GET` | `/api/search/suggestions?q=` | Autocomplete | | `POST` | `/api/ask/stream` | AI ΰΈ–ΰΈ²ΰΈ‘-ΰΈ•ΰΈ­ΰΈš (SSE streaming) | | `POST` | `/api/ask` | AI ΰΈ–ΰΈ²ΰΈ‘-ΰΈ•ΰΈ­ΰΈš (non-stream β€” Discord) | | `GET` | `/api/ask/rag-status` | ΰΈͺΰΈ–ΰΈ²ΰΈ™ΰΈ° Turbovec/Qdrant | | `GET` | `/health` | Health check | --- ## πŸ§ͺ Test Suite ``` tests/ β”œβ”€β”€ test_pali_utils.py # 90 assertions β€” autocorrect, digits, similarity β”œβ”€β”€ test_search_service.py # FTS5 + LIKE merge, suggestions └── test_rag_service.py # Embedding LRU cache Total: 35 tests βœ… ``` --- ## 🧰 Tech Stack Detail | Layer | Technology | |-------|-----------| | **Frontend** | React 18, TypeScript 5, Vite 6, Tailwind CSS v4 | | **State** | Zustand (5 stores) | | **Animation** | Framer Motion | | **Icons** | Lucide React | | **Markdown** | react-markdown + remark-gfm | | **Backend** | FastAPI, Python 3.11 | | **Database** | SQLite (FTS5, loaded to `:memory:` at startup) | | **Vector Store** | Turbovec (Primary in-process index), Qdrant (Secondary fallback) | | **Embedding** | jina-embeddings-v5-small-retrieval (GGUF via Ollama / sentence-transformers) | | **Reranker** | jina-reranker-v2-base-multilingual (ONNX, CPU) | | **AI** | DeepSeek API (OpenAI-compatible, SSE streaming) | | **CI/CD** | HF Spaces (Docker multi-stage, auto-build) | --- ## πŸ“š Documents | File | Description | |------|-------------| | `DESIGN.md` | Design system β€” colors, typography, components, themes | | `PRODUCT.md` | Product vision, users, principles | | `TIPITAKA_WEB_ARCHITECTURE_TURBOVEC.md` | Main architecture document (Turbovec Edition) | | `SEARCH_ARCHITECTURE_TURBOVEC.md` | Search Architecture Specification (Turbovec Edition) | | `Tipitaka-Web-Application-Tech-Stack-TURBOVEC-HF.md` | Tech Stack & HF Spaces Deployment (Turbovec Edition) | | `TIPITAKA_WEB_ARCHITECTURE_V2.md` | Full architecture V2 document (Legacy Qdrant version) | --- ## πŸ™ Acknowledgements - **ฑหาจุฬาΰΈ₯ΰΈ‡ΰΈΰΈ£ΰΈ“ΰΈ£ΰΈ²ΰΈŠΰΈ§ΰΈ΄ΰΈ—ΰΈ’ΰΈ²ΰΈ₯ΰΈ±ΰΈ’ (MCU)** β€” ΰΉ€ΰΈ™ΰΈ·ΰΉ‰ΰΈ­ΰΈ«ΰΈ²ΰΈžΰΈ£ΰΈ°ΰΉ„ΰΈ•ΰΈ£ΰΈ›ΰΈ΄ΰΈŽΰΈ - **Turbovec** β€” In-process vector database - **Qdrant** β€” Vector database (Legacy/Alternative) - **jina.ai** β€” Embedding + Reranker models - **Ollama** β€” Local model serving - **Hugging Face Spaces** β€” Deployment platform --- *"อุปฑาเหฑือนแΰΈͺΰΈ‡ΰΉ€ΰΈ—ΰΈ΅ΰΈ’ΰΈ™ΰΉƒΰΈ™ΰΈ«ΰΉ‰ΰΈ­ΰΈ‡ΰΈ‘ΰΈ·ΰΈ” คือปัญญาทำΰΈ₯าฒอวิชชา"*