deployed version of annan voice

parent e61483ee
...@@ -11,8 +11,7 @@ SYSTEM_PROMPTS: Dict[Tuple[StudentNationality, StudyLanguage], str] = { ...@@ -11,8 +11,7 @@ SYSTEM_PROMPTS: Dict[Tuple[StudentNationality, StudyLanguage], str] = {
إنت مُدرِّس مصري لطفل في ابتدائي اسمه {student_name} في الصف {grade}. إنت مُدرِّس مصري لطفل في ابتدائي اسمه {student_name} في الصف {grade}.
لو الطفّل سأل عن هويتك بصراحة و وضوح باي طريقة (زي "إنت مين؟"، "عرّفني بنفسك"، "إنت بتعمل إيه هنا؟")، لو الطفّل سأل عن هويتك بصراحة و وضوح باي طريقة (زي "إنت مين؟"، "عرّفني بنفسك"، "إنت بتعمل إيه هنا؟")،
رُد بالرد الثابت ده: رُد بالرد الثابت ده:
"أنا عَنان مؤسِّس شارع العلوم، وإنت هنا على مَنَصّة Science Street Lab، "أنا عَنان مؤسِّس شارع العلوم، وأنا هنا عشان أَساعدك تتعلَّم أي حاجة عايز تتعلَّمها في العلوم."
وأنا هنا عشان أَساعدك تتعلَّم أي حاجة عايز تتعلَّمها في العلوم."
⚠️ مهم: النص دا استخدمه في حاله السؤال عن هويتك انت بس. ⚠️ مهم: النص دا استخدمه في حاله السؤال عن هويتك انت بس.
⚠️ مهم جدًا: مَمنوع تقول أبداً إنك AI أو برنامج أو روبوت. إنت عنان اللي جي تساعد في العلوم وبس. ⚠️ مهم جدًا: مَمنوع تقول أبداً إنك AI أو برنامج أو روبوت. إنت عنان اللي جي تساعد في العلوم وبس.
...@@ -27,6 +26,7 @@ SYSTEM_PROMPTS: Dict[Tuple[StudentNationality, StudyLanguage], str] = { ...@@ -27,6 +26,7 @@ SYSTEM_PROMPTS: Dict[Tuple[StudentNationality, StudyLanguage], str] = {
* لو السؤال عن محتوى معيّن، استخدم السياق من المنهج واربط بالوحدات والمفاهيم اللي ليها علاقة. * لو السؤال عن محتوى معيّن، استخدم السياق من المنهج واربط بالوحدات والمفاهيم اللي ليها علاقة.
* اذكر دايماً موقع الموضوع في المنهج: "الموضوع دا في الوحدة الأولى، المفهوم التاني" * اذكر دايماً موقع الموضوع في المنهج: "الموضوع دا في الوحدة الأولى، المفهوم التاني"
* وضِّح الروابط: "دا مرتبط باللي اتعلمناه عن ..." أو "دا مرتبط باللي هنتعلمه عن..." * وضِّح الروابط: "دا مرتبط باللي اتعلمناه عن ..." أو "دا مرتبط باللي هنتعلمه عن..."
* مهما كانت المعلومة مكتوبة بالعربي الفصيح أو متاخدة من كتاب المنهج، دايمًا صيّغها باللهجة المصريّة الطبيعيّة. متستخدمش لغة فصحى ابدا الا في المصطلحات العلمية اللي ملهاش بديل.
دايما رَد باللهجة المصريّة الطبيعيّة كأنّك بتكَلّم {student_name} قصادك. دايما رَد باللهجة المصريّة الطبيعيّة كأنّك بتكَلّم {student_name} قصادك.
خَلّي الكلام بسيط، واضح، وقَريب من ودنه. خَلّي الكلام بسيط، واضح، وقَريب من ودنه.
...@@ -42,7 +42,6 @@ SYSTEM_PROMPTS: Dict[Tuple[StudentNationality, StudyLanguage], str] = { ...@@ -42,7 +42,6 @@ SYSTEM_PROMPTS: Dict[Tuple[StudentNationality, StudyLanguage], str] = {
لو {student_name} مكتوب بالإنجليزي، اكتبه دايماً بالعَربي في ردودك. لو {student_name} مكتوب بالإنجليزي، اكتبه دايماً بالعَربي في ردودك.
لَمّا تُذكر الصف {grade}، قُوله بالطريقة الطبيعيّة زي ما الأطفال بيقولوها: الصف 4 = سنة رابعة ابتدائي، الصف 5 = سنة خامسة ابتدائي، وهكذا. لَمّا تُذكر الصف {grade}، قُوله بالطريقة الطبيعيّة زي ما الأطفال بيقولوها: الصف 4 = سنة رابعة ابتدائي، الصف 5 = سنة خامسة ابتدائي، وهكذا.
مهما كانت المعلومة مكتوبة بالعربي الفصيح أو متاخدة من كتاب المنهج، دايمًا صيّغها باللهجة المصريّة الطبيعيّة. متستخدمش لغة فصحى إلا في المصطلحات العلمية اللي ملهاش بديل.
""", """,
# ---------- Saudi + Arabic ---------- # ---------- Saudi + Arabic ----------
......
...@@ -24,7 +24,7 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = { ...@@ -24,7 +24,7 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = {
- لو الطِّفل سأل: "إنت مين؟" → رد بالهوية المخصصة ليك (أنا عَنان...). - لو الطِّفل سأل: "إنت مين؟" → رد بالهوية المخصصة ليك (أنا عَنان...).
- لو الطِّفل سأل: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب اللي فوق (الاسم + الصف). - لو الطِّفل سأل: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب اللي فوق (الاسم + الصف).
- لو السُّؤال له علاقة بالعلوم أو بالمنهج → جاوب عليه. - لو السُّؤال له علاقة بالعلوم أو بالمنهج → جاوب عليه.
- لو السُّؤال دردشة عامة أو خارج المنهج → رد بلطف يوضح إن الوقت دا للمذاكرة في العلوم، واسأله بطريقة ودودة لو يحب يختار موضوع في العلوم تتكلمو فيه . - لو السُّؤال دردشة عامة أو خارج المنهج والعلوم →متردش على الكلام نهائيا و قوله الرد دا "الوقت دا للمذاكرة في العلوم، انا هنا عشان اساعدك في العلوم وبس " واسأله بطريقة ودودة لو يحب يختار موضوع في العلوم تتكلمو فيه .
""", """,
StudentNationality.SAUDI: """ StudentNationality.SAUDI: """
...@@ -41,138 +41,13 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = { ...@@ -41,138 +41,13 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = {
- إذا سأل الطالب: "إنت مين؟" → رد بالهوية المخصصة لك (أنا عَنان...). - إذا سأل الطالب: "إنت مين؟" → رد بالهوية المخصصة لك (أنا عَنان...).
- إذا سأل الطالب: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب أعلاه (الاسم + الصف). - إذا سأل الطالب: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب أعلاه (الاسم + الصف).
- إذا كان السؤال له علاقة بالعلوم أو بالمنهج → جاوب عليه. - إذا كان السؤال له علاقة بالعلوم أو بالمنهج → جاوب عليه.
- إذا كان السؤال دردشة عامة أو خارج المنهج → رد بلطف يوضح إن الوقت هذا مخصّص للمذاكرة في العلوم، واسأله بطريقة ودودة لو يحب يختار موضوع في العلوم. - إذا كان السؤال دردشة عامة أو خارج المنهج → قوله الوقت هذا مخصّص للمذاكرة في العلوم، واسأله بطريقة ودودة لو يحب يختار موضوع في العلوم.
""" """
} }
UNSAFE_CONTEXTS: Dict[StudentNationality, Dict[str, str]] = {
StudentNationality.EGYPTIAN: {
"unsafe_religion": """
لو الطفل سأل عن الدين أو المواضيع الدينية:
- ممنوع تجاوب بمعلومة دينية.
- رد بطريقة ودودة: قوله إن المواضيع دي يسأل فيها بابا أو ماما أو شخص كبير يثق فيه.
- ممنوع الرغي الطويل
""",
"unsafe_personal": """
لو الطفل حاول يشارك أسرار أو تفاصيل شخصية (زي عنوان، رقم تليفون...):
- ممنوع تاخد منه بيانات.
- قول له إن المعلومات دي خاصة ويشاركها مع بابا أو ماما بس.
- ممنوع الرغي الطويل
""",
"unsafe_harmful": """
لو الطفل قال حاجة عن العنف، الأذى للنفس، أو المخدرات:
- لازم تكون حازم وتوضح إن ده خطر وغلط.
- انصحه يتكلم مع بابا أو ماما فورًا.
- ممنوع الرغي الطويل
""",
"unsafe_sensitive_emotion": """
لو الطفل بيعبّر عن زعل أو حزن شديد أو فقدان:
- طمّنه وخليه يحس إن مشاعره طبيعية.
- انصحه يتكلم مع أهله أو شخص كبير يثق فيه.
- ممنوع الرغي الطويل
""",
"unsafe_sensitive_bio": """
لو الطفل سأل عن الحمل أو الجنس أو إزاي الأطفال بيتولدوا:
- ممنوع تجاوب على تفاصيل بيولوجية حساسة.
- قوله ان الموضوع ده انت هتدرسه بعدين، بس دلوقتي أنسب إنك تسأل بابا وماما لو عندك فضول، وهم بس اللي ممكن يشرحوهولك ويردوا على سؤالك.
- ممنوع الرغي الطويل
""",
"unsafe_bullying": """
لو الطفل بيتعرض للتنمّر:
- طمّنه وقوله إن اللي يتعرض للتنمّر مش ذنبه.
- انصحه يحكي لبابا أو ماما أو مدرس كبير.
لو الطفل هو اللي بيتنمّر أو بيتريق:
- رد بشكل قصير وحازم إن ده غلط ومش مقبول.
- وضّح إن اللي بيتنمّر محدش بيحبه ولا بيصاحبه.
- قلّه إن الناس بتحب اللي يكون محترم وجدع.
ممنوع الرغي الطويل أو الشرح العلمي.
خليك بالعامية المصريّة، جُمَل قصيرة وواضحة.
""",
"unsafe_sport_activity": """
- لو الطفل بيتكلم عن رياضات ممكن يعملها الأطفال زي السباحة أو ألعاب قتالية بسيطة، وضّح له إن الأفضل يتعلمها مع مدرب أو شخص كبير يراقبه.
- لو بيتكلم عن رياضات خطيرة مش مناسبة لعمره زي ركوب الدراجات النارية أو التزلج على أماكن خطرة، قل له إن دي مش مناسبة دلوقتي ويقدر يعملها لما يكبر.
- الرياضة ممتعة، بس الأمان أهم.
- ممنوع الرغي الطويل
""",
},
StudentNationality.SAUDI: {
"unsafe_religion": """
إذا الطالب سأل عن الدين أو المواضيع الدينية:
- لا تجاوب بأي معلومة دينية.
- قل له بلطف إن المواضيع هذي يسأل فيها أهله أو شخص كبير يثق فيه.
- لا تدخل في شروحات طويلة.
""",
"unsafe_personal": """
إذا الطالب حاول يشارك معلومات شخصية (عنوان، رقم جوال...):
- لا تقبل أي بيانات منه.
- وضّح إن هذي معلومات خاصة، يقولها لأهله فقط.
- لا تدخل في شروحات طويلة.
""",
"unsafe_harmful": """
إذا الطالب تكلم عن عنف، أذى، أو مخدرات:
- لازم تكون واضح إن ذا شي خطر وغلط.
- انصحه يكلم أهله فورًا.
- لا تدخل في شروحات طويلة.
""",
"unsafe_sensitive_emotion": """
إذا الطالب عبّر عن حزن أو فقدان:
- طمّنه وخليه يحس إن مشاعره طبيعية.
- انصحه يكلم أهله أو شخص كبير يثق فيه.
- لا تدخل في شروحات طويلة.
""",
"unsafe_sensitive_bio": """
إذا الطالب سأل عن الحمل أو الجنس أو كيف يجي الأطفال:
- لا تجاوب بأي تفاصيل حساسة.
- قوله هذا موضوع تدرسه بعدين، لكن الآن الأفضل تسأل فيه أهلك، هم اللي يقدرون يشرحونه لك ويجاوبونك.
- لا تدخل في شروحات طويلة.
""",
"unsafe_bullying": """
إذا الطالب يتعرض للتنمّر:
- طمّنه وقله إن اللي يتعرض للتنمّر ما هو غلطان.
- انصحه يتكلم مع أبوه أو أمه أو معلم كبير.
إذا الطالب هو اللي يتنمّر أو يتريق:
- رد بكلام قصير وحازم إن ذا غلط وما ينفع.
- وضّح إن المتنمّر محد يحبّه ولا يبي يصاحبه.
- قلّه إن الناس تحب اللي يحترم غيره ويكون طيب.
لا تدخل في شروحات طويلة أو أمثلة علمية.
خل ردك باللهجة السعوديّة، بسيط وواضح.
""",
"unsafe_sport_activity": """
- إذا الطالب يتحدث عن رياضات مناسبة للأطفال مثل السباحة أو بعض الألعاب القتالية البسيطة، قل له من الأفضل تعلمها مع مدرب أو شخص بالغ يراقبه.
- إذا ذكر رياضات خطيرة غير مناسبة لعمره مثل ركوب الدراجات النارية أو التزلج على أماكن خطرة، وضّح له أنها غير مناسبة الآن ويمكنه تجربتها عندما يكبر.
- النشاط ممتع، لكن السلامة أهم.
- لا تدخل في شروحات طويلة
""",
}
}
class QueryHandler: class QueryHandler:
"""Handles different types of queries and their classification""" """Handles different types of queries and their classification"""
...@@ -222,43 +97,16 @@ class QueryHandler: ...@@ -222,43 +97,16 @@ class QueryHandler:
# Get recent conversation context # Get recent conversation context
conversation_context = self.get_recent_conversation_context(student_id, max_messages=5) conversation_context = self.get_recent_conversation_context(student_id, max_messages=5)
# Keywords grouped by category for hint detection
unsafe_keywords = {
"unsafe_religion": ["دين", "ديانة", "دينى", "دينك", "الله", "إله", "عبادة", "صلوات", "قرآن", "إنجيل", "تورا"],
"unsafe_personal": ["عنوان", "ساكن", "موبايل", "رقم", "تليفون", "شارع", "عمارة", "شقة"],
"unsafe_harmful": ["مخدرات", "سجاير", "انتحار", "اضرب", "أقتل", "أذى", "دم", "خطر"],
"unsafe_sensitive_emotion": ["زعلان", "حزين", "موت", "اتوفى", "وَفاة", "بعيط", "عايط", "اكتئاب"],
"unsafe_sensitive_bio": ["جنس", "جنسي", "حمل", "دورة شهرية", "أمومة", "ولادة"],
"unsafe_bullying": ["اتنمر", "بتنمر", "بتريق", "بسخر", "بشتم", "بغلط", "بضرب", "بعاير", "شكله وحش"],
"unsafe_sport_activity": ["مصارعة", "سباحة", "ركوب دراجات نارية"]
}
q_lower = query.lower() q_lower = query.lower()
keyword_flags = [cat for cat, kws in unsafe_keywords.items() if any(kw in q_lower for kw in kws)]
classification_prompt = f""" classification_prompt = f"""
صنف السؤال التالي إلى إحدى الفئات التالية، مع مراعاة سياق المحادثة الأخيرة: صنف السؤال التالي إلى إحدى الفئات التالية، مع مراعاة سياق المحادثة الأخيرة:
1. "general_chat" - أسئلة دردشة عامة وشخصية عن الطالب أو المدرس 1. "general_chat" - أسئلة دردشة عامة وشخصية عن الطالب أو المدرس او اي سؤال عن اي شئ غير مرتبط بالعلوم عموما او المنهج او الدراسة
2. "overview" - أسئلة عن نظرة عامة على المنهج أو المحتوى الكامل 2. "overview" - أسئلة عن نظرة عامة على المنهج أو المحتوى الكامل
3. "navigation" - أسئلة عن وحدة أو مفهوم معين 3. "navigation" - أسئلة عن وحدة أو مفهوم معين
4. "specific_content" - أسئلة محددة عن موضوع علمي معين 4. "specific_content" - أسئلة محددة عن موضوع علمي معين
5. "unsafe_religion" - أي كلام عن الدين أو اختراع ديانة أو عبادة
6. "unsafe_personal" - مشاركة أسرار أو تفاصيل شخصية حساسة
7. "unsafe_harmful" - كلام عن العنف، الأذى للنفس، المخدرات، الشتائم
8. "unsafe_sensitive_emotion" - مواقف حزينة جداً مثل فقدان شخص أو بكاء شديد
9. "unsafe_sensitive_bio" - أي أسئلة عن الإنجاب، الحمل، أو كيف الأطفال بييجوا للدنيا او التلقيح في البشر او الولادة
أمثلة على unsafe_sensitive_bio:
- "ماما وبابا جابوني إزاي؟"
- "الأطفال بييجوا للدنيا إزاي؟"
- "يعني إيه حمل؟"
- "إزاي الواحد يبقى أب؟"
- "إزاي بيحصل التلقيح في البشر؟"
- "إزاي الولادة بتتم؟"
10. "unsafe_bullying" - أي كلام عن التنمر (سواء كان ضحية أو متنمر) او تريقه على شكل حد او تشبيهه بحاجة تزعل
11. "unsafe_sport_activity" - كلام عن ممارسة رياضات ممكن تكون خطرة لو طفل مارسها منغير مختص زي المصارة او السباحة او رياضات خطرة عموما لطفل زي ركوب الدراجات النارية
{conversation_context} {conversation_context}
السؤال الحالي: "{query}" السؤال الحالي: "{query}"
...@@ -272,9 +120,6 @@ class QueryHandler: ...@@ -272,9 +120,6 @@ class QueryHandler:
- مثال: إذا كان يتحدث عن النباتات وسأل "كيف تأكل؟" فهو يقصد تغذية النباتات وليس الطعام العادي - مثال: إذا كان يتحدث عن النباتات وسأل "كيف تأكل؟" فهو يقصد تغذية النباتات وليس الطعام العادي
""" """
if keyword_flags:
classification_prompt += f"\n ملاحظة: السؤال يحتوي على كلمات قد تكون مرتبطة بالفئات: {', '.join(keyword_flags)}. \
تأكد من السياق جيداً قبل التصنيف."
classification_prompt += "\n\nرد فقط بكلمة واحدة من الفئات المحددة أعلاه" classification_prompt += "\n\nرد فقط بكلمة واحدة من الفئات المحددة أعلاه"
...@@ -289,14 +134,12 @@ class QueryHandler: ...@@ -289,14 +134,12 @@ class QueryHandler:
valid_classes = { valid_classes = {
"general_chat", "overview", "navigation", "specific_content", "general_chat", "overview", "navigation", "specific_content"
"unsafe_religion", "unsafe_personal", "unsafe_harmful",
"unsafe_sensitive_emotion", "unsafe_sensitive_bio", "unsafe_bullying", "unsafe_sport_activity"
} }
if classification in valid_classes: if classification in valid_classes:
logger.info(f"Query classified as: {classification} for query: '{query}' (with context, flags={keyword_flags})") logger.info(f"Query classified as: {classification} for query: '{query}'")
print(f"Query classified as: {classification} for query: '{query}' (with context, flags={keyword_flags})") print(f"Query classified as: {classification} for query: '{query}'")
return classification return classification
else: else:
logger.warning( logger.warning(
...@@ -364,93 +207,6 @@ class QueryHandler: ...@@ -364,93 +207,6 @@ class QueryHandler:
رد بطريقة ودودة وبسيطة. رد بطريقة ودودة وبسيطة.
""" """
def handle_unsafe_religion_query(self, student_info: Dict[str, Any]) -> str:
"""Handle queries about religion or religious topics"""
nationality_str: str = student_info.get('nationality', 'egyptian')
nationality_mapping = {
'egyptian': StudentNationality.EGYPTIAN,
'saudi': StudentNationality.SAUDI
}
nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
# Get the appropriate unsafe response template
unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
response_template = unsafe_responses.get("unsafe_religion")
if not response_template:
# Fallback to Egyptian template if not found
unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
response_template = unsafe_responses.get("unsafe_religion",
"هذا الموضوع غير مناسب للمناقشة هنا. يرجى التحدث مع الوالدين أو شخص بالغ موثوق.")
logger.info(f"Handled unsafe_religion query for nationality: {nationality_enum}")
return response_template.strip()
def handle_unsafe_personal_query(self, student_info: Dict[str, Any]) -> str:
"""Handle queries involving sharing personal secrets or sensitive information"""
nationality_str: str = student_info.get('nationality', 'egyptian')
nationality_mapping = {
'egyptian': StudentNationality.EGYPTIAN,
'saudi': StudentNationality.SAUDI
}
nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
# Get the appropriate unsafe response template
unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
response_template = unsafe_responses.get("unsafe_personal")
if not response_template:
# Fallback to Egyptian template if not found
unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
response_template = unsafe_responses.get("unsafe_personal",
"لا يجب مشاركة المعلومات الشخصية هنا. تحدث مع الوالدين فقط حول هذه الأمور.")
logger.info(f"Handled unsafe_personal query for nationality: {nationality_enum}")
return response_template.strip()
def handle_unsafe_harmful_query(self, student_info: Dict[str, Any]) -> str:
"""Handle queries about violence, self-harm, drugs, or inappropriate language"""
nationality_str: str = student_info.get('nationality', 'egyptian')
nationality_mapping = {
'egyptian': StudentNationality.EGYPTIAN,
'saudi': StudentNationality.SAUDI
}
nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
# Get the appropriate unsafe response template
unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
response_template = unsafe_responses.get("unsafe_harmful")
if not response_template:
# Fallback to Egyptian template if not found
unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
response_template = unsafe_responses.get("unsafe_harmful",
"هذا الموضوع غير آمن وغير مناسب. يرجى التحدث مع شخص بالغ موثوق إذا كان لديك مشاعر صعبة.")
logger.warning(f"Handled unsafe_harmful query for nationality: {nationality_enum}")
return response_template.strip()
def handle_unsafe_sensitive_emotion_query(self, student_info: Dict[str, Any]) -> str:
"""Handle queries involving very sad situations like loss or extreme sadness"""
nationality_str: str = student_info.get('nationality', 'egyptian')
nationality_mapping = {
'egyptian': StudentNationality.EGYPTIAN,
'saudi': StudentNationality.SAUDI
}
nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
# Get the appropriate unsafe response template
unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
response_template = unsafe_responses.get("unsafe_sensitive_emotion")
if not response_template:
# Fallback to Egyptian template if not found
unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
response_template = unsafe_responses.get("unsafe_sensitive_emotion",
"أشعر أنك حزين. هذه مشاعر طبيعية، ولكن من المهم التحدث مع الوالدين أو شخص بالغ موثوق.")
logger.info(f"Handled unsafe_sensitive_emotion query for nationality: {nationality_enum}")
return response_template.strip()
def handle_overview_query(self, student_info: Dict[str, Any], subject: str = "Science") -> str: def handle_overview_query(self, student_info: Dict[str, Any], subject: str = "Science") -> str:
"""Handle curriculum overview queries using JSON-based data""" """Handle curriculum overview queries using JSON-based data"""
...@@ -489,64 +245,3 @@ class QueryHandler: ...@@ -489,64 +245,3 @@ class QueryHandler:
logger.error(f"Error getting navigation response: {e}") logger.error(f"Error getting navigation response: {e}")
# Fallback to overview if navigation fails # Fallback to overview if navigation fails
return self.handle_overview_query(student_info, subject) return self.handle_overview_query(student_info, subject)
def handle_unsafe_sensitive_bio_query(self, student_info: Dict[str, Any]) -> str:
"""Handle queries about sensitive biology topics"""
nationality_str: str = student_info.get('nationality', 'egyptian')
nationality_mapping = {
'egyptian': StudentNationality.EGYPTIAN,
'saudi': StudentNationality.SAUDI
}
nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
# Get the appropriate unsafe response template
unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
response_template = unsafe_responses.get("unsafe_sensitive_bio")
if not response_template:
# Fallback to Egyptian template if not found
unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
response_template = unsafe_responses.get("unsafe_sensitive_bio",
"الموضوع ده مش مناسب هنا. الأحسن تسأل فيه بابا أو ماما.")
logger.info(f"Handled unsafe_sensitive_bio query for nationality: {nationality_enum}")
return response_template.strip()
def handle_unsafe_bullying_query(self, student_info: Dict[str, Any]) -> str:
"""Handle queries about bullying (whether victim or bully)"""
nationality_str: str = student_info.get('nationality', 'egyptian')
nationality_mapping = {
'egyptian': StudentNationality.EGYPTIAN,
'saudi': StudentNationality.SAUDI
}
nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
response_template = unsafe_responses.get("unsafe_bullying")
if not response_template:
# fallback
response_template = "لو في موضوع فيه تنمّر، لازم تتكلم مع بابا أو ماما أو شخص كبير تثق فيه. التنمّر غلط، ولازم نعامل غيرنا باحترام."
logger.info(f"Handled unsafe_bullying query for nationality: {nationality_enum}")
return response_template.strip()
def handle_unsafe_sport_activity_query(self, student_info: Dict[str, Any]) -> str:
"""Handle queries about engaging in potentially risky sports activities"""
nationality_str: str = student_info.get('nationality', 'egyptian')
nationality_mapping = {
'egyptian': StudentNationality.EGYPTIAN,
'saudi': StudentNationality.SAUDI
}
nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
response_template = unsafe_responses.get("unsafe_sport_activity")
if not response_template:
# fallback
response_template = "الرياضة ممتعة، بس لازم نكون حذرين. لو عايز تجرب رياضة جديدة، الأفضل تتعلمها مع مدرب أو شخص كبير يراقبك."
logger.info(f"Handled unsafe_sport_activity query for nationality: {nationality_enum}")
return response_template.strip()
...@@ -106,37 +106,11 @@ class ResponseGenerator: ...@@ -106,37 +106,11 @@ class ResponseGenerator:
messages.extend(conversation_history) messages.extend(conversation_history)
messages.append({"role": "user", "content": user_message}) messages.append({"role": "user", "content": user_message})
# ==========================
# HANDLE UNSAFE QUERIES
# ==========================
if query_type.startswith("unsafe_"):
if query_type == "unsafe_religion":
unsafe_context = self.query_handler.handle_unsafe_religion_query(student_info)
elif query_type == "unsafe_sensitive_emotion":
unsafe_context = self.query_handler.handle_unsafe_sensitive_emotion_query(student_info)
elif query_type == "unsafe_sensitive_bio":
unsafe_context = self.query_handler.handle_unsafe_sensitive_bio_query(student_info)
elif query_type == "unsafe_personal":
unsafe_context = self.query_handler.handle_unsafe_personal_query(student_info)
elif query_type == "unsafe_harmful":
unsafe_context = self.query_handler.handle_unsafe_harmful_query(student_info)
elif query_type == "unsafe_bullying":
unsafe_context = self.query_handler.handle_unsafe_bullying_query(student_info)
elif query_type == "unsafe_sport_activity":
unsafe_context = self.query_handler.handle_unsafe_sport_activity_query(student_info)
else:
unsafe_context = "هذا الموضوع غير مناسب للمناقشة هنا."
# نضيف التعليمات كـ system context بدل الرد المباشر
messages.append({
"role": "system",
"content": f"التعليمات للتعامل مع الموضوع الحساس:\n{unsafe_context}"
})
# ========================== # ==========================
# HANDLE SAFE QUERIES # HANDLE SAFE QUERIES
# ========================== # ==========================
else:
if query_type == "general_chat": if query_type == "general_chat":
chat_context = self.query_handler.handle_general_chat_query(user_message, student_info) chat_context = self.query_handler.handle_general_chat_query(user_message, student_info)
messages.append({"role": "system", "content": f"سياق المحادثة العامة:\n{chat_context}"}) messages.append({"role": "system", "content": f"سياق المحادثة العامة:\n{chat_context}"})
......
...@@ -88,6 +88,7 @@ custom_fixes = { ...@@ -88,6 +88,7 @@ custom_fixes = {
"عضلات": "عَضَلَات", "عضلات": "عَضَلَات",
"بنأكله": "بِنأكْلُه", "بنأكله": "بِنأكْلُه",
"الهضم": "الْهَضْم", "الهضم": "الْهَضْم",
"منصة": "مَنَصّةْ",
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment