#!/usr/bin/env python3 """ Interactive CLI for QModel (FAISS + BM25 + Ollama/GGUF). Run directly in your terminal to query the full Islamic RAG system. """ import os import sys import json import asyncio import logging # Suppress verbose warnings os.environ.setdefault("KMP_DUPLICATE_LIB_OK", "TRUE") os.environ.setdefault("OMP_NUM_THREADS", "1") logging.basicConfig(level=logging.WARNING) from app.config import cfg from app.state import state, _build_lookup_tables, run_rag_pipeline from app.llm import get_llm_provider from sentence_transformers import SentenceTransformer import faiss async def init_qmodel(): print("⏳ Loading QModel Islamic RAG System...") print(f" • Loading metadata: {cfg.METADATA_FILE}") with open(cfg.METADATA_FILE, "r", encoding="utf-8") as f: state.dataset = json.load(f) print(" • Building BM25 & scripture lookup tables...") _build_lookup_tables(state.dataset) print(f" • Loading dense embeddings ({cfg.EMBED_MODEL})...") state.embed_model = SentenceTransformer(cfg.EMBED_MODEL) print(f" • Loading FAISS vector index ({cfg.FAISS_INDEX})...") state.faiss_index = faiss.read_index(cfg.FAISS_INDEX) print(f" • Connecting to LLM backend ({cfg.LLM_BACKEND})...") state.llm = get_llm_provider() state.ready = True print("✅ QModel is ready!\n" + "=" * 60) async def main(): await init_qmodel() print("🕌 Sheikh QModel — Islamic Knowledge Assistant (Quran, Tafsir, Hadith, Fatwa)") print("Type your question below (or 'exit' / 'quit' to exit):\n") while True: try: query = input("Q: ").strip() except (EOFError, KeyboardInterrupt): print("\nوداعاً — مع السلامة.") break if not query: continue if query.lower() in ("exit", "quit", "q"): print("مع السلامة.") break print("\n⏳ جاري البحث في الفهرس والتحقق من النصوص...") try: res = await run_rag_pipeline(query) print("\n" + res["answer"] + "\n") print("-" * 60) except Exception as exc: print(f"❌ حدث خطأ: {exc}\n") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: pass