aelgendy commited on
Commit
c566217
Β·
verified Β·
1 Parent(s): efd73f6

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app/prompts.py +11 -5
  2. app/state.py +83 -74
app/prompts.py CHANGED
@@ -79,11 +79,17 @@ TASK_INSTRUCTIONS: Dict[str, str] = {
79
  "CRITICAL: The SURAH INFORMATION block is the ONLY authoritative source."
80
  ),
81
  "general": (
82
- "The user has a general Islamic question. Steps:\n"
83
- "1. Give a direct, clear answer first.\n"
84
- "2. Support with evidence from the RETRIEVED RESULTS.\n"
85
- "3. Quote relevant verses or hadiths from the results with references.\n"
86
- "4. Conclude with a brief summary."
 
 
 
 
 
 
87
  ),
88
  }
89
 
 
79
  "CRITICAL: The SURAH INFORMATION block is the ONLY authoritative source."
80
  ),
81
  "general": (
82
+ "The user may be asking a general Islamic question OR pasting text to look up. Steps:\n"
83
+ "1. Check ALL retrieved results from EVERY source (Quran AND Hadith).\n"
84
+ "2. For EACH result that matches the user's text or question, state WHERE it appears:\n"
85
+ " β€’ For Quran: Surah name (Arabic & English), Surah number, and Ayah number from the [REF] line.\n"
86
+ " β€’ For Hadith: collection name, book/chapter, hadith number, and grade.\n"
87
+ "3. If the same text appears in MULTIPLE places, list ALL of them explicitly.\n"
88
+ " Example: β€˜Ω‡Ψ°Ψ§ Ψ§Ω„Ω†Ψ΅ ذُكِر في سورة Ψ§Ω„Ψ¨Ω‚Ψ±Ψ© (ؒية Ω’Ω₯Ω₯) ΩˆΨ’Ω„ ΨΉΩ…Ψ±Ψ§Ω† (ؒية Ω’)’\n"
89
+ "4. Quote the Arabic text and English translation EXACTLY from the results.\n"
90
+ "5. Provide brief context or explanation of the text.\n"
91
+ "6. Answer the user's specific question if one was asked.\n"
92
+ "CRITICAL: Do NOT give a generic answer. Always mention the exact sources from the results."
93
  ),
94
  }
95
 
app/state.py CHANGED
@@ -41,84 +41,93 @@ logger = logging.getLogger("qmodel.state")
41
  # SURAH INFO PROGRAMMATIC FALLBACK
42
  # ═══════════════════════════════════════════════════════════════════════
43
  def _results_fallback(results: list, lang: str) -> str:
44
- """Generate a direct answer from search results when LLM returns empty."""
 
 
 
 
45
  if not results:
46
  return not_found_answer(lang)
47
 
48
- top = results[0]
49
- item_type = top.get("type", "")
50
-
51
- if item_type == "quran":
52
- ar_text = top.get("arabic", "")
53
- en_text = top.get("english", "")
54
- surah_ar = top.get("surah_name_ar", "")
55
- surah_en = top.get("surah_name_en", "")
56
- surah_num = top.get("surah_number", "")
57
- verse_num = top.get("verse_number", "")
58
- tafsir = top.get("tafsir_ar", "") if lang == "arabic" else top.get("tafsir_en", "")
59
-
60
- if lang == "arabic":
61
- lines = [
62
- f"Ω‡Ψ°Ω‡ Ψ§Ω„Ψ’ΩŠΨ© Ψ§Ω„ΩƒΨ±ΩŠΩ…Ψ© Ω…Ω† سورة {surah_ar} ({surah_en})، Ψ§Ω„Ψ’ΩŠΨ© {verse_num}.",
63
- "",
64
- f"β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”",
65
- f"β”‚ ❝ {ar_text} ❞",
66
- f"β”‚ πŸ“ Translation: {en_text}",
67
- f"β”‚ πŸ“– Source: سورة {surah_ar} ({surah_en}) | Ψ±Ω‚Ω… Ψ§Ω„Ψ³ΩˆΨ±Ψ©: {surah_num} | Ψ§Ω„Ψ’ΩŠΨ©: {verse_num}",
68
- f"β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜",
69
- ]
70
- if tafsir:
71
- lines.append(f"\n{tafsir}")
72
- lines.append("\nΩˆΨ§Ω„Ω„Ω‡ Ψ£ΨΉΩ„Ω….")
73
- return "\n".join(lines)
74
- else:
75
- lines = [
76
- f"This noble verse is from Surah {surah_en} ({surah_ar}), verse {verse_num}.",
77
- "",
78
- f"β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”",
79
- f"β”‚ ❝ {ar_text} ❞",
80
- f"β”‚ πŸ“ Translation: {en_text}",
81
- f"β”‚ πŸ“– Source: Surah {surah_en} ({surah_ar}) | Surah Number: {surah_num} | Verse: {verse_num}",
82
- f"β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜",
83
- ]
84
- if tafsir:
85
- lines.append(f"\n{tafsir}")
86
- lines.append("\nAnd Allah knows best.")
87
- return "\n".join(lines)
88
-
89
- elif item_type == "hadith":
90
- ar_text = top.get("arabic", "")
91
- en_text = top.get("english", "")
92
- source = top.get("source") or top.get("reference", "")
93
- grade = top.get("grade", "")
94
- grade_str = f" [{grade}]" if grade else ""
95
-
96
- if lang == "arabic":
97
- lines = [
98
- f"Ψ§Ω„Ψ­Ψ―ΩŠΨ« Ψ§Ω„Ψ΄Ψ±ΩŠΩ{grade_str}:",
99
- "",
100
- f"β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”",
101
- f"β”‚ ❝ {ar_text} ❞",
102
- f"β”‚ πŸ“ Translation: {en_text}",
103
- f"β”‚ πŸ“– Source: {source}",
104
- f"β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜",
105
- "\nΩˆΨ§Ω„Ω„Ω‡ Ψ£ΨΉΩ„Ω….",
106
- ]
107
- return "\n".join(lines)
108
  else:
109
- lines = [
110
- f"The Hadith{grade_str}:",
111
- "",
112
- f"β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”",
113
- f"β”‚ ❝ {ar_text} ❞",
114
- f"β”‚ πŸ“ Translation: {en_text}",
115
- f"β”‚ πŸ“– Source: {source}",
116
- f"β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜",
117
- "\nAnd Allah knows best.",
118
- ]
119
- return "\n".join(lines)
120
-
121
- return not_found_answer(lang)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
 
124
  def _surah_info_fallback(info: dict, lang: str) -> str:
 
41
  # SURAH INFO PROGRAMMATIC FALLBACK
42
  # ═══════════════════════════════════════════════════════════════════════
43
  def _results_fallback(results: list, lang: str) -> str:
44
+ """Generate a direct answer from search results when LLM returns empty.
45
+
46
+ Presents ALL high-scoring results so the user sees every place
47
+ a text is mentioned (e.g. same verse in multiple surahs).
48
+ """
49
  if not results:
50
  return not_found_answer(lang)
51
 
52
+ # Include all results whose score is at least 50% of the top score,
53
+ # or score >= 2.0 (strong match), whichever captures more.
54
+ top_score = results[0].get("_score", 0.0)
55
+ threshold = max(top_score * 0.5, 2.0) if top_score >= 2.0 else 0.0
56
+ relevant = [r for r in results if r.get("_score", 0.0) >= threshold] or results[:1]
57
+
58
+ quran_hits = [r for r in relevant if r.get("type") == "quran"]
59
+ hadith_hits = [r for r in relevant if r.get("type") == "hadith"]
60
+
61
+ lines: list[str] = []
62
+
63
+ # --- Quran results ---
64
+ if quran_hits:
65
+ if len(quran_hits) == 1:
66
+ r = quran_hits[0]
67
+ surah_ar = r.get("surah_name_ar", "")
68
+ surah_en = r.get("surah_name_en", "")
69
+ verse_num = r.get("verse_number", "")
70
+ if lang == "arabic":
71
+ lines.append(f"Ω‡Ψ°Ω‡ Ψ§Ω„Ψ’ΩŠΨ© Ψ§Ω„ΩƒΨ±ΩŠΩ…Ψ© Ω…Ω† سورة {surah_ar} ({surah_en})، Ψ§Ω„Ψ’ΩŠΨ© {verse_num}.")
72
+ else:
73
+ lines.append(f"This noble verse is from Surah {surah_en} ({surah_ar}), verse {verse_num}.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  else:
75
+ if lang == "arabic":
76
+ refs = [
77
+ f"سورة {r.get('surah_name_ar', '')} ({r.get('surah_name_en', '')})، Ψ§Ω„Ψ’ΩŠΨ© {r.get('verse_number', '')}"
78
+ for r in quran_hits
79
+ ]
80
+ lines.append(f"Ω‡Ψ°Ψ§ Ψ§Ω„Ω†Ψ΅ Ψ§Ω„ΩƒΨ±ΩŠΩ… ذُكِر في {len(quran_hits)} Ω…ΩˆΨ§ΨΆΨΉ:")
81
+ for ref in refs:
82
+ lines.append(f" β€’ {ref}")
83
+ else:
84
+ refs = [
85
+ f"Surah {r.get('surah_name_en', '')} ({r.get('surah_name_ar', '')}), verse {r.get('verse_number', '')}"
86
+ for r in quran_hits
87
+ ]
88
+ lines.append(f"This text appears in {len(quran_hits)} places:")
89
+ for ref in refs:
90
+ lines.append(f" β€’ {ref}")
91
+
92
+ for r in quran_hits:
93
+ ar_text = r.get("arabic", "")
94
+ en_text = r.get("english", "")
95
+ surah_ar = r.get("surah_name_ar", "")
96
+ surah_en = r.get("surah_name_en", "")
97
+ surah_num = r.get("surah_number", "")
98
+ verse_num = r.get("verse_number", "")
99
+ lines.append("")
100
+ lines.append("β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”")
101
+ lines.append(f"β”‚ ❝ {ar_text} ❞")
102
+ lines.append(f"β”‚ πŸ“ Translation: {en_text}")
103
+ lines.append(f"β”‚ πŸ“– Source: سورة {surah_ar} ({surah_en}) | Ψ±Ω‚Ω… Ψ§Ω„Ψ³ΩˆΨ±Ψ©: {surah_num} | Ψ§Ω„Ψ’ΩŠΨ©: {verse_num}")
104
+ lines.append("β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜")
105
+
106
+ # --- Hadith results ---
107
+ if hadith_hits:
108
+ for r in hadith_hits:
109
+ ar_text = r.get("arabic", "")
110
+ en_text = r.get("english", "")
111
+ source = r.get("source") or r.get("reference", "")
112
+ grade = r.get("grade", "")
113
+ grade_str = f" [{grade}]" if grade else ""
114
+ if lang == "arabic":
115
+ lines.append(f"\nΨ§Ω„Ψ­Ψ―ΩŠΨ« Ψ§Ω„Ψ΄Ψ±ΩŠΩ{grade_str}:")
116
+ else:
117
+ lines.append(f"\nHadith{grade_str}:")
118
+ lines.append("")
119
+ lines.append("β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”")
120
+ lines.append(f"β”‚ ❝ {ar_text} ❞")
121
+ lines.append(f"β”‚ πŸ“ Translation: {en_text}")
122
+ lines.append(f"β”‚ πŸ“– Source: {source}")
123
+ lines.append("β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜")
124
+
125
+ if lang == "arabic":
126
+ lines.append("\nΩˆΨ§Ω„Ω„Ω‡ Ψ£ΨΉΩ„Ω….")
127
+ else:
128
+ lines.append("\nAnd Allah knows best.")
129
+
130
+ return "\n".join(lines)
131
 
132
 
133
  def _surah_info_fallback(info: dict, lang: str) -> str: