You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every prompt gets the identical treatment: "Assalamu alaikum" and a three-part inheritance question both run through the same fixed generation config with the same 2048-token allowance and the same prompt guidance — so greetings get essays, complex questions get whatever fits, and ambiguous questions get a confident guess at one of their possible meanings. This issue adds a question-understanding stage to /chat: classify the intent of each message, calibrate answer shape and length per intent, ask a clarifying question instead of guessing when the question is genuinely ambiguous, and return 2–3 suggested follow-up questions so the frontend can keep students exploring. This is answer-shape quality, complementing the campaign issues that cover grounding (#24), citations (#15), and formatting of Arabic content (#14).
Current state
The /chat handler (main.py, lines 118–184) sends every prompt through one path with hardcoded generation config — temperature: 0.7, top_p: 0.8, top_k: 40, max_output_tokens: 2048 (lines 145–150) — regardless of what kind of message it is.
ISLAMIC_CONTEXT (lines 57–71) contains no guidance on answer length, structure, or when to ask for clarification; rule 5 ("Acknowledge when a question is beyond your scope") is the only shape-related instruction.
ChatResponse (lines 85–88) is response / chat_id / history — no field exists for follow-up suggestions or any signal about what kind of answer this is, so the frontend renders every reply identically.
Nothing detects ambiguity: "Is music haram?" (a classic it-depends question with multiple scholarly framings) and "what breaks the fast?" (underspecified: eating? fasting person's doubts? which acts?) both get single-shot guesses today.
What to build
Intent taxonomy + classifier — a small enum of intents, e.g.: greeting_smalltalk, factual_knowledge (aqeedah/seerah/definitions), fiqh_ruling, personal_guidance (emotional/spiritual support, du'a requests), platform_question (DeenBridge/courses/zakat features), out_of_scope. Implement classification in a new module (e.g. intent.py) as a single cheap structured-output Gemini call with a deterministic short-circuit for trivial cases (very short greetings, salam variants) so the common case adds no latency. Measure and report the added latency in the PR.
Per-intent answer shaping — map each intent to generation parameters and a per-intent instruction snippet appended to the prompt context: greetings → warm, 1–2 sentences, return the salam properly, invite a question; factual → structured, thorough, sourced; personal guidance → compassionate tone, du'a where fitting, gentle scholar referral for serious matters; platform questions → concise and practical; out-of-scope → polite deflection per the existing rule 5. Replace the hardcoded generation-config dict with the per-intent table (env-overridable defaults).
Clarify-before-answering — extend the classifier to also emit an ambiguity judgment with a proposed clarifying question. When a question is genuinely underspecified, the assistant asks one targeted clarifying question instead of answering, and the response carries a flag (e.g. needs_clarification: true) so the frontend can style it. Guard against over-triggering: default threshold conservative, env-tunable, and never clarify twice in a row for the same session.
Suggested follow-ups — the answer generation emits 2–3 natural next questions (e.g. after an answer about wudu: "What invalidates wudu?", "How is tayammum performed?") in a delimited machine-readable block after the prose, parsed and stripped server-side into suggested_followups: List[str] on ChatResponse. Use the same defensive parse-or-degrade pattern as the structured-citations issue ([Enhancement] Return structured Quran/Hadith citations alongside answers #15): a malformed block yields an empty list, never an error, and never leaks into response.
Response metadata — echo the classified intent in the response so the frontend can adapt rendering, and so logs let the maintainer see the intent distribution of real traffic.
Eval + tests — contribute per-intent cases to the evaluation-harness ([Enhancement] Evaluation harness for Islamic answer quality #16) dataset format: greetings must be short (length assertion), ambiguous fixtures must trigger clarification, follow-ups must parse. Unit tests with a mocked Gemini client cover the classifier short-circuit, per-intent config selection, follow-up parsing (well-formed, malformed, missing), and the no-double-clarification guard.
Acceptance criteria
"Assalamu alaikum" gets a warm ≤2-sentence reply returning the greeting; a substantive aqeedah question gets a structured, full-length answer — both verifiable via committed eval cases.
Classification adds at most one lightweight model call, with the deterministic short-circuit covering trivial messages (asserted in tests) and measured latency reported in the PR.
An underspecified fixture question yields exactly one clarifying question with needs_clarification: true; the follow-up user reply then gets a real answer (no clarification loops).
suggested_followups contains 2–3 relevant questions for knowledge answers, is empty on parse failure, and the raw block never appears in response.
intent is present in the response and logged; hardcoded generation config is replaced by the per-intent table with env-overridable defaults.
Existing clients that read only response/chat_id/history are unaffected.
New modules are linted, tested offline with mocks, and CI stays green.
CI (.github/workflows/ci.yml) lints only main.py (flake8 main.py --max-line-length=120 --ignore=E501,W503) and has no pytest step — extend flake8 to new modules and add pytest.
PRs target the dev branch (see CONTRIBUTING.md).
Difficulty
Medium — no new infrastructure, but it touches the heart of the chat path: a classifier that must be fast and rarely wrong, calibration tables, defensive parsing, and an ambiguity heuristic that is genuinely useful without becoming an annoying "what do you mean?" bot.
🏆 GrantFox OSS — Official Campaign | FWC26. Apply for this issue through the GrantFox campaign page. The maintainer assigns one contributor before work starts; unassigned PRs may not be reviewed. PRs target the dev branch. Quality bar: CI must stay green.
💬 Questions or need help? Reach the maintainers and other contributors on the DeenBridge Telegram: https://t.me/+nst9lXNj1wc4ZDE0
Summary
Every prompt gets the identical treatment: "Assalamu alaikum" and a three-part inheritance question both run through the same fixed generation config with the same 2048-token allowance and the same prompt guidance — so greetings get essays, complex questions get whatever fits, and ambiguous questions get a confident guess at one of their possible meanings. This issue adds a question-understanding stage to
/chat: classify the intent of each message, calibrate answer shape and length per intent, ask a clarifying question instead of guessing when the question is genuinely ambiguous, and return 2–3 suggested follow-up questions so the frontend can keep students exploring. This is answer-shape quality, complementing the campaign issues that cover grounding (#24), citations (#15), and formatting of Arabic content (#14).Current state
/chathandler (main.py, lines 118–184) sends every prompt through one path with hardcoded generation config —temperature: 0.7,top_p: 0.8,top_k: 40,max_output_tokens: 2048(lines 145–150) — regardless of what kind of message it is.ISLAMIC_CONTEXT(lines 57–71) contains no guidance on answer length, structure, or when to ask for clarification; rule 5 ("Acknowledge when a question is beyond your scope") is the only shape-related instruction.ChatResponse(lines 85–88) isresponse/chat_id/history— no field exists for follow-up suggestions or any signal about what kind of answer this is, so the frontend renders every reply identically.What to build
greeting_smalltalk,factual_knowledge(aqeedah/seerah/definitions),fiqh_ruling,personal_guidance(emotional/spiritual support, du'a requests),platform_question(DeenBridge/courses/zakat features),out_of_scope. Implement classification in a new module (e.g.intent.py) as a single cheap structured-output Gemini call with a deterministic short-circuit for trivial cases (very short greetings, salam variants) so the common case adds no latency. Measure and report the added latency in the PR.ambiguityjudgment with a proposed clarifying question. When a question is genuinely underspecified, the assistant asks one targeted clarifying question instead of answering, and the response carries a flag (e.g.needs_clarification: true) so the frontend can style it. Guard against over-triggering: default threshold conservative, env-tunable, and never clarify twice in a row for the same session.suggested_followups: List[str]onChatResponse. Use the same defensive parse-or-degrade pattern as the structured-citations issue ([Enhancement] Return structured Quran/Hadith citations alongside answers #15): a malformed block yields an empty list, never an error, and never leaks intoresponse.intentin the response so the frontend can adapt rendering, and so logs let the maintainer see the intent distribution of real traffic.Acceptance criteria
needs_clarification: true; the follow-up user reply then gets a real answer (no clarification loops).suggested_followupscontains 2–3 relevant questions for knowledge answers, is empty on parse failure, and the raw block never appears inresponse.intentis present in the response and logged; hardcoded generation config is replaced by the per-intent table with env-overridable defaults.response/chat_id/historyare unaffected.Pointers
main.py— the/chathandler (lines 118–184), hardcoded generation config (lines 145–150),ISLAMIC_CONTEXT(lines 57–71),ChatResponse(lines 85–88).fiqh_rulingintent) rather than building two; [Enhancement] Return structured Quran/Hadith citations alongside answers #15 owns the citation block format (reuse its delimited-block parsing conventions for follow-ups); [Enhancement] First-class Arabic and multilingual support #14 owns language/Arabic formatting rules; [Enhancement] Stream chat responses with Server-Sent Events #8 owns SSE streaming (if it lands, follow-ups belong in the terminal event — same coordination [Enhancement] Return structured Quran/Hadith citations alongside answers #15's body describes); [Enhancement] Layered content-safety pipeline with policy enforcement and red-team suite in CI #31's safety pipeline runs regardless of intent — don't route around it..github/workflows/ci.yml) lints onlymain.py(flake8 main.py --max-line-length=120 --ignore=E501,W503) and has no pytest step — extend flake8 to new modules and add pytest.devbranch (seeCONTRIBUTING.md).Difficulty
Medium — no new infrastructure, but it touches the heart of the chat path: a classifier that must be fast and rarely wrong, calibration tables, defensive parsing, and an ambiguity heuristic that is genuinely useful without becoming an annoying "what do you mean?" bot.
🏆 GrantFox OSS — Official Campaign | FWC26. Apply for this issue through the GrantFox campaign page. The maintainer assigns one contributor before work starts; unassigned PRs may not be reviewed. PRs target the
devbranch. Quality bar: CI must stay green.💬 Questions or need help? Reach the maintainers and other contributors on the DeenBridge Telegram: https://t.me/+nst9lXNj1wc4ZDE0