Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0bac848
Fix participation wording in README.md
zeemscript Aug 17, 2026
6093aec
[Enhancement] Semantic response caching and quota protection (#271)
Nemenwa Aug 24, 2026
68af79b
feat(#55): Add self-consistency sampling for hallucination detection …
orochimaru144 Aug 25, 2026
d75e91a
feat(sentiment): add religious sentiment analysis (#209) (#285)
rasheedayinde015-a11y Aug 25, 2026
7f5cc7b
feat(routing): add intelligent model routing engine (#198) (#286)
rasheedayinde015-a11y Aug 25, 2026
76f3ef5
feat(page-analysis): add Islamic book page layout analysis (#222) (#287)
Bollywere Aug 25, 2026
4db3640
feat(#227): historical context injection (asbab al-nuzul, scholar era…
yusufmuhammadayodeji-netizen Aug 25, 2026
3b4602f
feat(#231): add audio Hadith verification and authentication (#290)
yusufmuhammadayodeji-netizen Aug 25, 2026
67ec1c0
feat(#219): Add contextual hadith interpretation system (#289)
yusufmuhammadayodeji-netizen Aug 25, 2026
db67464
feat: improve error messages with actionable guidance and valid examp…
Unclebaffa Aug 25, 2026
fa2588a
feat(eval): add comprehensive Islamic QA benchmark dataset and evalua…
Unclebaffa Aug 25, 2026
d4d8f4b
feat(#217): Add database query optimization analyzer and profiler (#291)
yusufmuhammadayodeji-netizen Aug 25, 2026
c68abf5
feat: add answer depth customization system (#294)
Bollywere Aug 25, 2026
d8ddf5f
feat: add thematic Quran retrieval system (#292)
Bosskandy1 Aug 25, 2026
2ce19bf
feat: add vector store performance tuning system (#295)
Bollywere Aug 25, 2026
7918a3d
feat: add queue system for heavy operations (#293)
rasheedayinde015-a11y Aug 25, 2026
6d46578
feat(#228): add Islamic calligraphy style estimation service (#296)
orochimaru144 Aug 25, 2026
12ccb47
Add batch tafsir lookup (#297)
dotmantissa Aug 25, 2026
f340d0e
feat(reasoning): add multi-step Islamic reasoning chains (#152) (#302)
hmhidey111-collab Aug 25, 2026
ad4843e
feat: add Arabic OCR for Islamic manuscripts (#214) (#303)
thelight08 Aug 25, 2026
eef5323
feat(reformulation): add question reformulation suggestions (#218) (#…
Bollywere Aug 25, 2026
3b2ce2b
docs: document rate limiting in README (#114) (#300)
hmhidey111-collab Aug 25, 2026
7b81c55
feat: tajweed error detection and feedback (closes #207)
Aug 25, 2026
0bbadbf
merge: resolve upstream/dev conflicts
zeemscript Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
541 changes: 541 additions & 0 deletions answer_depth.py

Large diffs are not rendered by default.

1,022 changes: 1,022 additions & 0 deletions arabic_ocr.py

Large diffs are not rendered by default.

493 changes: 493 additions & 0 deletions audio_hadith.py

Large diffs are not rendered by default.

526 changes: 526 additions & 0 deletions calligraphy.py

Large diffs are not rendered by default.

42 changes: 23 additions & 19 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import enum
from functools import lru_cache

from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


class TajweedLevel(str, enum.Enum):
beginner = "beginner"
intermediate = "intermediate"
advanced = "advanced"


class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
Expand All @@ -16,7 +23,7 @@ class Settings(BaseSettings):

gemini_api_key: str = ""

model_name: str = "gemini-2.5-flash"
model_name: str = "gemini-1.5-flash"

temperature: float = Field(default=0.7, ge=0, le=2)
top_p: float = Field(default=0.8, ge=0, le=1)
Expand All @@ -26,14 +33,22 @@ class Settings(BaseSettings):
gemini_timeout: int = Field(default=30, ge=1)

# Calligraphy OCR (#234)
calligraphy_provider: str = "gemini" # "gemini" or "stub" (stub is dev-only)
calligraphy_max_image_bytes: int = Field(default=10 * 1024 * 1024, ge=1) # 10MB
calligraphy_provider: str = "gemini"
calligraphy_max_image_bytes: int = Field(default=10 * 1024 * 1024, ge=1)
calligraphy_min_confidence: float = Field(default=0.35, ge=0, le=1)
# Manuscript analysis (#233): provider, upload size cap, quality gate.
manuscripts_provider: str = Field(default="gemini")
manuscripts_max_upload_bytes: int = Field(default=10 * 1024 * 1024, ge=1)
manuscripts_min_confidence: float = Field(default=0.35, ge=0.0, le=1.0)

# --- Hybrid retrieval (#226) ---
hybrid_enabled: bool = True
hybrid_rrf_k: int = Field(default=60, ge=1)
hybrid_semantic_weight: float = Field(default=0.5, ge=0, le=1)
hybrid_keyword_weight: float = Field(default=0.5, ge=0, le=1)
hybrid_top_k: int = Field(default=5, ge=1, le=50)
hybrid_enable_semantic_channel: bool = True
hybrid_enable_keyword_channel: bool = True

cors_origins: list[str] = Field(
default_factory=lambda: [
"http://localhost:3000",
Expand All @@ -45,16 +60,10 @@ class Settings(BaseSettings):

port: int = Field(default=8000, ge=1)

# --- Hybrid retrieval (#226): vector+keyword fusion ----------------------
# Master switch; weights seed the balanced-mode mix, and the toggles let a
# deployment run a single channel while a backend (e.g. pgvector) is rolled out.
hybrid_enabled: bool = True
hybrid_rrf_k: int = Field(default=60, ge=1)
hybrid_semantic_weight: float = Field(default=0.5, ge=0, le=1)
hybrid_keyword_weight: float = Field(default=0.5, ge=0, le=1)
hybrid_top_k: int = Field(default=5, ge=1, le=50)
hybrid_enable_semantic_channel: bool = True
hybrid_enable_keyword_channel: bool = True
# Tajweed detection settings
enable_tajweed_detection: bool = Field(default=True, description="Enable the tajweed error detection system")
tajweed_min_score: float = Field(default=0.5, ge=0.0, le=1.0, description="Minimum acceptable tajweed score before flagging")
tajweed_level: TajweedLevel = Field(default=TajweedLevel.advanced, description="Default difficulty level for tajweed analysis")

@field_validator("cors_origins", mode="before")
@classmethod
Expand All @@ -63,11 +72,6 @@ def parse_cors_origins(cls, value):
return [item.strip() for item in value.split(",") if item.strip()]
return value

@field_validator("manuscripts_provider", mode="before")
@classmethod
def normalize_manuscripts_provider(cls, value):
return value.strip().lower() if isinstance(value, str) else value


@lru_cache
def get_settings() -> Settings:
Expand Down
147 changes: 147 additions & 0 deletions data/eval/BENCHMARK_SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Islamic QA Benchmark Dataset Specification

## 1. Overview & Objectives

The **Islamic QA Benchmark Dataset** is a comprehensive, curated evaluation benchmark designed to evaluate Large Language Models and AI systems on Islamic question-answering tasks. It establishes a rigorous, scholar-validated standard covering classical jurisprudence, theology, Quranic sciences, Hadith methodology, historical milestones, ethics, and contemporary bioethical and financial challenges.

- **Dataset Version**: `1.0.0`
- **Total Curated QA Pairs**: `530`
- **Knowledge Domains**: `10 distinct domains` (53 items per domain)
- **Languages**: English (`en`) and Arabic (`ar`)
- **Total Verified Citations**: `1,109` (Quran, Hadith, Scholarly Classical Works)
- **Average Inter-Annotator Agreement (IAA)**: `0.954` (> 0.85 threshold)

---

## 2. Knowledge Domain Taxonomy

The benchmark spans 10 balanced knowledge domains:

| # | Domain Identifier | Domain Name | Scope & Core Topics | Items |
|---|---|---|---|---|
| 1 | `aqeedah` | Islamic Theology & Creed | Tawhid (Rububiyyah, Uluhiyyah, Asma wa Sifat), Pillars of Iman, Qadar, Eschatology, Tanzih, Theological Schools | 53 |
| 2 | `fiqh_ibadat` | Jurisprudence of Worship | Taharah (Wudu, Ghusl, Tayammum), Salah (Conditions, Pillars, Sujud as-Sahw), Sawm, Zakat, Hajj & Umrah | 53 |
| 3 | `fiqh_muamalat` | Commercial Law & Finance | Riba (Fadl & Nasi'ah), Gharar, Maysir, Murabaha, Mudaraba, Musharaka, Takaful, Salam, Istisna', Modern Banking | 53 |
| 4 | `fiqh_munakahat_mirath` | Family Law & Inheritance | Nikah Pillars, Mahram Categories, Iddah, Khul', Talaq, Fixed Quranic Shares (Furud), Asabah, Hajb, Wasiyyah | 53 |
| 5 | `ulum_al_quran` | Quranic Sciences & Exegesis | Makki vs Madani, Compilation History, Seven Ahruf & Ten Qira'at, Usul al-Tafsir, Naskh, Asbab al-Nuzul, I'jaz | 53 |
| 6 | `mustalah_al_hadith` | Hadith Sciences & Criticism | 5 Conditions of Sahih, Mutawatir vs Ahad, Da'if Subtypes, Jarh wa Ta'dil, Six Canonical Books, Naqd al-Matn | 53 |
| 7 | `seerah` | Prophetic Biography | Cave Hira, Isra & Mi'raj, Hijrah, Badr, Uhud, Khandaq, Hudaybiyyah, Makkah Conquest, Shama'il, Farewell Hajj | 53 |
| 8 | `tarikh_islami` | Islamic History & Civilization | Rashidun Caliphate, Ridda Wars, Yarmouk & Qadisiyyah, Umayyads, Abbasid Golden Age, Andalus, Ottoman Era | 53 |
| 9 | `tasawwuf_adab_akhlaq` | Spirituality & Ethics | Ihsan & Muraqabah, Tazkiyat an-Nafs (3 Soul States), Heart Diseases (Hasad, Kibr), Sabr & Shukr, Ghazali's Ihya | 53 |
| 10 | `contemporary_issues` | Bioethics & Modern Issues | Organ Donation, AI Ethics, Cryptocurrencies, IVF & Surrogacy, Brain Death, CRISPR, Abstention Protocol | 53 |

---

## 3. Schema Specification (v1.0.0)

Every record in `data/eval/islamic_qa_benchmark.jsonl` strictly conforms to the JSON schema below:

```json
{
"id": "aqeedah-001",
"schema_version": "1.0.0",
"domain": "aqeedah",
"sub_domain": "tawhid_categories",
"difficulty": "easy",
"language": "en",
"question": "What are the three classical categories of Tawhid in Islamic theology?",
"question_ar": "ما هي أقسام التوحيد الثلاثة في العقيدة الإسلامية؟",
"question_type": "conceptual_explanation",
"expected_answer": "The three classical categories of Tawhid are: 1) Tawhid al-Rububiyyah...",
"expected_answer_ar": "أقسام التوحيد الثلاثة هي: 1) توحيد الربوبية...",
"key_points": [
"Tawhid al-Rububiyyah: Affirming Allah as sole Creator and Sustainer.",
"Tawhid al-Uluhiyyah: Dedicating all acts of worship exclusively to Allah.",
"Tawhid al-Asma wa al-Sifat: Affirming divine names and attributes without distortion."
],
"citations": [
{ "type": "quran", "surah": 1, "ayah_start": 5, "reference": "Al-Fatihah 1:5" },
{ "type": "quran", "surah": 42, "ayah_start": 11, "reference": "Ash-Shura 42:11" },
{ "type": "scholarly", "work": "Kitab at-Tawhid", "author": "Ibn Abd al-Wahhab" }
],
"has_ikhtilaf": false,
"ikhtilaf_details": null,
"requires_abstention": false,
"evaluation_criteria": {
"must_include": ["Rububiyyah", "Uluhiyyah", "Asma wa al-Sifat", "worship", "Creator"],
"must_not_include": ["creation can be worshipped"],
"accuracy_rubric": "Accurately names and defines all three branches of Tawhid with correct theological distinctions.",
"adab_rubric": "Maintain reverent tone and respect for sacred texts."
},
"metadata": {
"curator": "DeenBridge Islamic Benchmark Team",
"reviewed_by_scholar": true,
"inter_annotator_agreement": 0.98,
"tags": ["tawhid", "rububiyyah", "uluhiyyah", "asma_wa_sifat", "fundamentals"]
}
}
```

---

## 4. Citation Integrity & Reference System

All citations are verified and indexed:
1. **Quran Citations**:
- Every citation includes `surah` (1–114), `ayah_start`, and optional `ayah_end`.
- Validated against the authoritative Surah index (`data/quran/surah_index.json`).
2. **Hadith Citations**:
- Refers to canonical Sunnah collections (`bukhari`, `muslim`, `abudawud`, `tirmidhi`, `nasai`, `ibnmajah`, `ahmad`, `malik`).
- Includes standard reference numbering.
3. **Scholarly Works**:
- Primary classical juristic texts (e.g. Al-Nawawi's *Al-Majmu'*, Ibn Qudamah's *Al-Mughni*, Ibn Hajar's *Fath al-Bari*, Al-Ghazali's *Ihya'*, Al-Suyuti's *Al-Itqan*), and contemporary Fiqh council resolutions (OIC International Islamic Fiqh Academy, AAOIFI Shariah Standards).

---

## 5. Nuanced Ikhtilaf & Abstention Protocols

### Ikhtilaf (Scholarly Differences) Handling
Questions where valid classical scholarly divergence exists across the four Sunni madhhabs (Hanafi, Maliki, Shafi'i, Hanbali) or theological schools (Athari, Ash'ari, Maturidi) are flagged with `"has_ikhtilaf": true`. The benchmark requires the model to explain the differing positions with neutrality, evidence, and mutual respect rather than dogmatically declaring one side invalid.

### Abstention Protocol
Specific items with `"requires_abstention": true` test whether the AI model responsibly identifies queries outside the scope of automated advice:
- **Active personalized marital divorce queries**: The model must abstain from pronouncing binding divorce rulings on specific user disputes and direct the parties to official local Muftis / Shariah courts.
- **Active financial litigation & courtroom disputes**: The model must refuse to arbitrate personal litigation between conflicting parties, explaining that judicial rulings require sworn testimony and direct evidence examination by a qualified Qadi.

---

## 6. Evaluation Harness & Scoring Pipeline

The automated evaluation harness (`scripts/eval_islamic_qa.py`) executes two modes:

### A. Dataset Integrity & Schema Validation
```bash
python scripts/eval_islamic_qa.py --validate-only
```
- Validates strict JSONL schema compliance.
- Ensures all 10 domains are fully populated.
- Verifies Quran surah and ayah limits against `data/quran/surah_index.json`.
- Checks canonical Hadith collections and citation consistency.

### B. Benchmark Execution & Scoring
```bash
# Offline benchmark calibration
python scripts/eval_islamic_qa.py --output data/eval/results_islamic_qa_benchmark.json

# Live API evaluation against running service
python scripts/eval_islamic_qa.py --live --url http://localhost:8000 --output data/eval/live_results.json
```

### Scoring Metrics
- **Must-Include Keyword Precision**: Proportion of mandatory keywords present in the response.
- **Must-Not-Include Violation Check**: Penalizes answers containing prohibited misconceptions or theological fallacies.
- **Key Points Recall**: Assesses semantic coverage of essential doctrinal points.
- **Abstention Accuracy**: Validates that the model refrains from answering personal fatwas/adjudications.
- **Composite Passing Threshold**: `>= 70%` composite score.

---

## 7. Artifacts & Generated Files

- **Dataset**: `data/eval/islamic_qa_benchmark.jsonl`
- **Metadata**: `data/eval/islamic_qa_benchmark_metadata.json`
- **Specification**: `data/eval/BENCHMARK_SPEC.md`
- **Builder Script**: `scripts/build_islamic_qa_benchmark.py`
- **Evaluation Runner**: `scripts/eval_islamic_qa.py`
- **Domain Modules**: `scripts/benchmark_data/*.py`
- **Automated Tests**: `tests/test_islamic_qa_benchmark.py`
Loading