Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
AI Tutor
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Salma Mohammed Hamed
AI Tutor
Commits
2e568aab
Commit
2e568aab
authored
Sep 22, 2025
by
SalmaMohammedHamedMustafa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
unsafe_sensitive_bio handleing
parent
92dffa87
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
169 additions
and
84 deletions
+169
-84
query_handlers.py
..._env/voice_agent/services/agent_helpers/query_handlers.py
+109
-27
response_generator.py
.../voice_agent/services/agent_helpers/response_generator.py
+60
-57
voice_agent.tar
self_hosted_env/voice_agent/voice_agent.tar
+0
-0
No files found.
self_hosted_env/voice_agent/services/agent_helpers/query_handlers.py
View file @
2e568aab
...
@@ -7,7 +7,6 @@ from core import StudentNationality, StudyLanguage
...
@@ -7,7 +7,6 @@ from core import StudentNationality, StudyLanguage
import
logging
import
logging
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
GENERAL_CHAT_CONTEXTS
:
Dict
[
StudentNationality
,
str
]
=
{
GENERAL_CHAT_CONTEXTS
:
Dict
[
StudentNationality
,
str
]
=
{
StudentNationality
.
EGYPTIAN
:
"""
StudentNationality
.
EGYPTIAN
:
"""
مَعلومات الطِّفل:
مَعلومات الطِّفل:
...
@@ -19,9 +18,10 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = {
...
@@ -19,9 +18,10 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = {
السُّؤال: "{query}"
السُّؤال: "{query}"
خَليك بتِرُد بالعاميّة المَصري، وبطريقة بسيطة وودودة.
خَليك بتِرُد بالعاميّة المَصري، وبطريقة بسيطة وودودة.
لو الطِّفل سأل عن هُويِّتك، استخدِم الرَّد المَحدَّد في التَّعليمات.
لو سأل عن مَعلوماته الشَّخصيّة، استَخدِم البيانات اللي فوق.
لو الطِّفل سأل: "إنت مين؟" → رد بالهوية المخصصة ليك (أنا عَنان...).
مَتستَخدِمش أي مَعلومات من المَنهج أو مَحتوى تعليمي هنا.
لو الطِّفل سأل: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب اللي فوق (الاسم + الصف).
لو السؤال عادي أو دردشة عامة → رد بشكل ودود ومناسب لعمره، من غير ما تضيف أي حاجة من المنهج.
"""
,
"""
,
StudentNationality
.
SAUDI
:
"""
StudentNationality
.
SAUDI
:
"""
...
@@ -34,62 +34,73 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = {
...
@@ -34,62 +34,73 @@ GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = {
السؤال: "{query}"
السؤال: "{query}"
رد باللهجة السعوديّة الطبيعية، خلّ الرد بسيط وودود.
رد باللهجة السعوديّة الطبيعية، خلّ الرد بسيط وودود.
إذا سأل عن هويتك، استخدم الرد المحدد في التعليمات.
إذا سأل عن معلوماته الشخصية، استخدم البيانات المتوفرة أعلاه.
إذا سأل الطالب: "إنت مين؟" → رد بالهوية المخصصة لك (أنا عَنان...).
لا تستخدم أي محتوى من المنهج أو دروس تعليمية هنا.
إذا سأل الطالب: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب أعلاه (الاسم + الصف).
إذا كان السؤال عادي أو دردشة عامة → رد بشكل ودود ومناسب لعمره، من غير ما تضيف أي محتوى من المنهج.
"""
"""
}
}
UNSAFE_CONTEXTS
:
Dict
[
StudentNationality
,
Dict
[
str
,
str
]]
=
{
UNSAFE_CONTEXTS
:
Dict
[
StudentNationality
,
Dict
[
str
,
str
]]
=
{
StudentNationality
.
EGYPTIAN
:
{
StudentNationality
.
EGYPTIAN
:
{
"unsafe_religion"
:
"""
"unsafe_religion"
:
"""
الموضوع ده مش مناسب نتكلم فيه هنا. أي حاجة دينيّة الأحسن تسأل فيها بابا أو ماما أو حد كبير بتثق فيه.
الموضوع ده مش مناسب نتكلم فيه هنا. أي حاجة دينيّة الأحسن تسأل فيها بابا أو ماما أو حد كبير بتثق فيه.
تعالى نرجع لل
علوم—تحب نحكي عن الفضاء، الحيوانات، أو جسم الإنسان
؟
تعالى نرجع لل
درس—تحب نكمل في الموضوع اللي بنتعلمه سوا
؟
"""
,
"""
,
"unsafe_personal"
:
"""
"unsafe_personal"
:
"""
مينفعش تقول أسرارك أو تفاصيلك الشخصية هنا، دي حاجات تحتفظ بيها لنفسك أو تقولها لحد كبير زي بابا أو ماما.
مينفعش تقول أسرارك أو تفاصيلك الشخصية هنا، دي حاجات تحتفظ بيها لنفسك أو تقولها لحد كبير زي بابا أو ماما.
طب إيه رأيك نكمّل في ال
علوم ونتكلم عن الطاقة أو الكواكب
؟
طب إيه رأيك نكمّل في ال
درس ونشوف النقطة اللي كنا شغالين عليها
؟
"""
,
"""
,
"unsafe_harmful"
:
"""
"unsafe_harmful"
:
"""
الكلام ده خطر ومش مناسب. لو حسيت بحاجة زي دي، لازم تكلم بابا أو ماما أو حد كبير تثق فيه.
الكلام ده خطر ومش مناسب. لو حسيت بحاجة زي دي، لازم تكلم بابا أو ماما أو حد كبير تثق فيه.
تحب نغيّر الموضوع ون
شوف إزاي النباتات بتعيش أو إزاي جسمنا بيتحرك
؟
تحب نغيّر الموضوع ون
رجع للدرس بتاعنا
؟
"""
,
"""
,
"unsafe_sensitive_emotion"
:
"""
"unsafe_sensitive_emotion"
:
"""
أنا حاسس إنك زعلان، وده طبيعي. الأحسن تحكي لماما أو بابا أو حد كبير قريب منك.
أنا حاسس إنك زعلان، وده طبيعي. الأحسن تحكي لماما أو بابا أو حد كبير قريب منك.
ممكن كمان نلهي نفسنا بحاجة من العلوم—زي الفضاء أو الحيوانات.
تحب نرجع للدرس ونشغل نفسنا باللي كنا بنتعلمه؟
"""
,
"unsafe_sensitive_bio"
:
"""
الموضوع ده انت هتدرسه بعدين، بس دلوقتي أنسب إنك تسأل بابا وماما لو عندك فضول، وهم بس اللي ممكن يشرحوهولك ويردوا على سؤالك.
تحب نكمّل سوا في الدرس اللي فاتحينه دلوقتي؟
"""
,
"""
,
},
},
StudentNationality
.
SAUDI
:
{
StudentNationality
.
SAUDI
:
{
"unsafe_religion"
:
"""
"unsafe_religion"
:
"""
هذا موضوع ما نقدر نتكلم فيه هنا. أي شي يخص الدين الأفضل تسأل فيه أبوك أو أمك أو شخص كبير تثق فيه.
هذا موضوع ما نقدر نتكلم فيه هنا. أي شي يخص الدين الأفضل تسأل فيه أبوك أو أمك أو شخص كبير تثق فيه.
خلنا نرجع لل
علوم—تبغى نتكلم عن الفضاء، جسم الإنسان، أو النباتات
؟
خلنا نرجع لل
درس—تحب نكمل في الموضوع اللي ندرسه الحين
؟
"""
,
"""
,
"unsafe_personal"
:
"""
"unsafe_personal"
:
"""
ما ينفع تشارك أسرارك أو معلوماتك الشخصية هنا، هذي لازم تقولها بس لأهلك أو شخص كبير تثق فيه.
ما ينفع تشارك أسرارك أو معلوماتك الشخصية هنا، هذي لازم تقولها بس لأهلك أو شخص كبير تثق فيه.
وش رايك ن
كمل في العلوم ونتكلم عن الطاقة أو الكواكب
؟
وش رايك ن
رجع للدرس ونكمل اللي كنا نشتغل عليه
؟
"""
,
"""
,
"unsafe_harmful"
:
"""
"unsafe_harmful"
:
"""
الكلام ذا خطر وما يصلح. إذا حسيت بشي زي كذا لازم تحكي مع أبوك أو أمك أو شخص كبير تثق فيه.
الكلام ذا خطر وما يصلح. إذا حسيت بشي زي كذا لازم تحكي مع أبوك أو أمك أو شخص كبير تثق فيه.
خلنا نغيّر الموضوع
—تحب نتكلم عن النباتات أو عن كيف يتحرك جسم الإنسان
؟
خلنا نغيّر الموضوع
ونرجع للدرس
؟
"""
,
"""
,
"unsafe_sensitive_emotion"
:
"""
"unsafe_sensitive_emotion"
:
"""
واضح إنك حزين، وهذا شعور طبيعي. الأفضل تحكي مع أهلك أو شخص كبير قريب منك.
واضح إنك حزين، وهذا شعور طبيعي. الأفضل تحكي مع أهلك أو شخص كبير قريب منك.
وممكن نلهي نفسنا بشي من العلوم—زي الفضاء أو الحيوانات.
تحب نرجع للدرس ونركز فيه؟
"""
,
"unsafe_sensitive_bio"
:
"""
هذا موضوع تدرسه بعدين، لكن الآن الأفضل تسأل فيه أهلك، هم اللي يقدرون يشرحونه لك ويجاوبونك.
تحب نرجع للدرس اللي احنا فيه؟
"""
,
"""
,
}
}
}
}
class
QueryHandler
:
class
QueryHandler
:
"""Handles different types of queries and their classification"""
"""Handles different types of queries and their classification"""
...
@@ -98,27 +109,60 @@ class QueryHandler:
...
@@ -98,27 +109,60 @@ class QueryHandler:
self
.
pgvector
=
pgvector_service
self
.
pgvector
=
pgvector_service
self
.
db_service
=
db_service
self
.
db_service
=
db_service
def
classify_query_type
(
self
,
query
:
str
,
student_info
:
Dict
[
str
,
Any
])
->
str
:
def
get_recent_conversation_context
(
self
,
student_id
:
str
,
max_messages
:
int
=
5
)
->
str
:
"""Enhanced query classification using LLM with contextual keyword hints"""
"""Get recent conversation history for context"""
try
:
# Get conversation history from database
full_history
=
self
.
db_service
.
get_chat_history
(
student_id
)
# Get last max_messages messages (excluding system messages)
recent_messages
=
[]
for
msg
in
reversed
(
full_history
):
if
msg
[
'role'
]
!=
'system'
and
len
(
recent_messages
)
<
max_messages
:
recent_messages
.
insert
(
0
,
msg
)
# Insert at beginning to maintain order
elif
len
(
recent_messages
)
>=
max_messages
:
break
if
not
recent_messages
:
return
"لا توجد رسائل سابقة في المحادثة."
# Format the context
context_parts
=
[
"المحادثة الأخيرة:"
]
for
msg
in
recent_messages
:
role_label
=
"الطالب"
if
msg
[
'role'
]
==
'user'
else
"المعلم"
context_parts
.
append
(
f
"{role_label}: {msg['content'][:200]}..."
)
# Limit message length
return
"
\n
"
.
join
(
context_parts
)
except
Exception
as
e
:
logger
.
warning
(
f
"Error getting conversation context for {student_id}: {e}"
)
return
"لا يمكن الحصول على سياق المحادثة."
def
classify_query_type
(
self
,
query
:
str
,
student_info
:
Dict
[
str
,
Any
],
student_id
:
str
)
->
str
:
"""Enhanced query classification using LLM with conversation context"""
if
not
self
.
openai_service
.
is_available
():
if
not
self
.
openai_service
.
is_available
():
return
"specific_content"
return
"specific_content"
is_arabic
:
bool
=
student_info
.
get
(
'is_arabic'
,
True
)
is_arabic
:
bool
=
student_info
.
get
(
'is_arabic'
,
True
)
grade
:
int
=
student_info
.
get
(
'grade'
,
4
)
grade
:
int
=
student_info
.
get
(
'grade'
,
4
)
# Keywords grouped by category
# Get recent conversation context
conversation_context
=
self
.
get_recent_conversation_context
(
student_id
,
max_messages
=
5
)
# Keywords grouped by category for hint detection
unsafe_keywords
=
{
unsafe_keywords
=
{
"unsafe_religion"
:
[
"دين"
,
"ديانة"
,
"دينى"
,
"دينك"
,
"الله"
,
"إله"
,
"عبادة"
,
"صلوات"
,
"قرآن"
,
"إنجيل"
,
"تورا"
],
"unsafe_religion"
:
[
"دين"
,
"ديانة"
,
"دينى"
,
"دينك"
,
"الله"
,
"إله"
,
"عبادة"
,
"صلوات"
,
"قرآن"
,
"إنجيل"
,
"تورا"
],
"unsafe_personal"
:
[
"عنوان"
,
"ساكن"
,
"موبايل"
,
"رقم"
,
"تليفون"
,
"شارع"
,
"عمارة"
,
"شقة"
],
"unsafe_personal"
:
[
"عنوان"
,
"ساكن"
,
"موبايل"
,
"رقم"
,
"تليفون"
,
"شارع"
,
"عمارة"
,
"شقة"
],
"unsafe_harmful"
:
[
"مخدرات"
,
"سجاير"
,
"انتحار"
,
"اضرب"
,
"أقتل"
,
"أذى"
,
"دم"
,
"خطر"
],
"unsafe_harmful"
:
[
"مخدرات"
,
"سجاير"
,
"انتحار"
,
"اضرب"
,
"أقتل"
,
"أذى"
,
"دم"
,
"خطر"
],
"unsafe_sensitive_emotion"
:
[
"زعلان"
,
"حزين"
,
"موت"
,
"اتوفى"
,
"وَفاة"
,
"بعيط"
,
"عايط"
,
"اكتئاب"
]
"unsafe_sensitive_emotion"
:
[
"زعلان"
,
"حزين"
,
"موت"
,
"اتوفى"
,
"وَفاة"
,
"بعيط"
,
"عايط"
,
"اكتئاب"
],
"unsafe_sensitive_bio"
:
[
"جنس"
,
"جنسي"
,
"حمل"
,
"دورة شهرية"
,
"أمومة"
,
"ولادة"
]
}
}
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
)]
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" - أسئلة عن نظرة عامة على المنهج أو المحتوى الكامل
...
@@ -128,10 +172,24 @@ class QueryHandler:
...
@@ -128,10 +172,24 @@ class QueryHandler:
6. "unsafe_personal" - مشاركة أسرار أو تفاصيل شخصية حساسة
6. "unsafe_personal" - مشاركة أسرار أو تفاصيل شخصية حساسة
7. "unsafe_harmful" - كلام عن العنف، الأذى للنفس، المخدرات، الشتائم
7. "unsafe_harmful" - كلام عن العنف، الأذى للنفس، المخدرات، الشتائم
8. "unsafe_sensitive_emotion" - مواقف حزينة جداً مثل فقدان شخص أو بكاء شديد
8. "unsafe_sensitive_emotion" - مواقف حزينة جداً مثل فقدان شخص أو بكاء شديد
9. "unsafe_sensitive_bio" - أي أسئلة عن الإنجاب، الحمل، أو كيف الأطفال بييجوا للدنيا
أمثلة على unsafe_sensitive_bio:
- "ماما وبابا جابوني إزاي؟"
- "الأطفال بييجوا للدنيا إزاي؟"
- "يعني إيه حمل؟"
{conversation_context}
السؤال: "{query}"
السؤال
الحالي
: "{query}"
الطالب يدرس باللغة: {"العربية" if is_arabic else "الإنجليزية"}
الطالب يدرس باللغة: {"العربية" if is_arabic else "الإنجليزية"}
الصف: {grade}
الصف: {grade}
تعليمات مهمة:
- استخدم سياق المحادثة الأخيرة لفهم السؤال بشكل أفضل
- إذا كان الطالب يتحدث عن موضوع علمي معين وسأل سؤال متعلق به، فهو "specific_content"
- إذا كان السؤال غامض، اعتمد على السياق لتحديد القصد الحقيقي
- مثال: إذا كان يتحدث عن النباتات وسأل "كيف تأكل؟" فهو يقصد تغذية النباتات وليس الطعام العادي
"""
"""
if
keyword_flags
:
if
keyword_flags
:
...
@@ -151,11 +209,13 @@ class QueryHandler:
...
@@ -151,11 +209,13 @@ 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_religion"
,
"unsafe_personal"
,
"unsafe_harmful"
,
"unsafe_sensitive_emotion"
,
"unsafe_sensitive_bio"
}
}
if
classification
in
valid_classes
:
if
classification
in
valid_classes
:
logger
.
info
(
f
"Query classified as: {classification} for query: '{query}' (flags={keyword_flags})"
)
logger
.
info
(
f
"Query classified as: {classification} for query: '{query}' (with context, flags={keyword_flags})"
)
print
(
f
"Query classified as: {classification} for query: '{query}' (with context, flags={keyword_flags})"
)
return
classification
return
classification
else
:
else
:
logger
.
warning
(
logger
.
warning
(
...
@@ -348,3 +408,25 @@ class QueryHandler:
...
@@ -348,3 +408,25 @@ 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
()
\ No newline at end of file
self_hosted_env/voice_agent/services/agent_helpers/response_generator.py
View file @
2e568aab
...
@@ -7,10 +7,8 @@ import logging
...
@@ -7,10 +7,8 @@ import logging
sys
.
path
.
append
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'../../'
)))
sys
.
path
.
append
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'../../'
)))
from
core
import
StudentNationality
,
StudyLanguage
,
Models
from
core
import
StudentNationality
,
StudyLanguage
,
Models
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
class
ResponseGenerator
:
class
ResponseGenerator
:
"""Handles AI response generation and conversation management"""
"""Handles AI response generation and conversation management"""
...
@@ -70,8 +68,6 @@ class ResponseGenerator:
...
@@ -70,8 +68,6 @@ class ResponseGenerator:
return
formatted_base_prompt
return
formatted_base_prompt
def
generate_response
(
def
generate_response
(
self
,
self
,
user_message
:
str
,
user_message
:
str
,
...
@@ -99,38 +95,44 @@ class ResponseGenerator:
...
@@ -99,38 +95,44 @@ class ResponseGenerator:
conversation_history
=
self
.
get_conversation_history
(
student_id
)
conversation_history
=
self
.
get_conversation_history
(
student_id
)
# Classify query type
# Classify query type
query_type
=
self
.
query_handler
.
classify_query_type
(
user_message
,
student_info
)
query_type
=
self
.
query_handler
.
classify_query_type
(
user_message
,
student_info
,
student_id
)
logger
.
info
(
f
"Query type: {query_type} for student {student_name} ({study_language.value})"
)
logger
.
info
(
f
"Query type: {query_type} for student {student_name} ({study_language.value}) with conversation context"
)
# Prepare system prompt
formatted_base_prompt
=
self
.
prepare_system_prompt
(
student_info
)
# Build base messages
messages
=
[{
"role"
:
"system"
,
"content"
:
formatted_base_prompt
}]
messages
.
extend
(
conversation_history
)
messages
.
append
({
"role"
:
"user"
,
"content"
:
user_message
})
# *** HANDLE UNSAFE QUERIES IMMEDIATELY - NO SYSTEM PROMPT ***
# ==========================
# HANDLE UNSAFE QUERIES
# ==========================
if
query_type
.
startswith
(
"unsafe_"
):
if
query_type
.
startswith
(
"unsafe_"
):
if
query_type
==
"unsafe_religion"
:
if
query_type
==
"unsafe_religion"
:
unsafe_response
=
self
.
query_handler
.
handle_unsafe_religion_query
(
student_info
)
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"
:
elif
query_type
==
"unsafe_personal"
:
unsafe_
response
=
self
.
query_handler
.
handle_unsafe_personal_query
(
student_info
)
unsafe_
context
=
self
.
query_handler
.
handle_unsafe_personal_query
(
student_info
)
elif
query_type
==
"unsafe_harmful"
:
elif
query_type
==
"unsafe_harmful"
:
unsafe_response
=
self
.
query_handler
.
handle_unsafe_harmful_query
(
student_info
)
unsafe_context
=
self
.
query_handler
.
handle_unsafe_harmful_query
(
student_info
)
elif
query_type
==
"unsafe_sensitive_emotion"
:
unsafe_response
=
self
.
query_handler
.
handle_unsafe_sensitive_emotion_query
(
student_info
)
else
:
else
:
unsafe_response
=
"هذا الموضوع غير مناسب للمناقشة هنا."
unsafe_context
=
"هذا الموضوع غير مناسب للمناقشة هنا."
# Save response directly and return - NO AI MODEL CALL
self
.
add_message_to_history
(
student_id
,
unsafe_response
,
"assistant"
)
logger
.
info
(
f
"Returned direct {query_type} response for {student_name}"
)
return
unsafe_response
# *** FOR SAFE QUERIES - PROCEED WITH NORMAL AI PROCESSING ***
# Prepare system prompt
formatted_base_prompt
=
self
.
prepare_system_prompt
(
student_info
)
# Prepare messages
# نضيف التعليمات كـ system context بدل الرد المباشر
messages
=
[]
messages
.
append
({
messages
.
append
({
"role"
:
"system"
,
"content"
:
formatted_base_prompt
})
"role"
:
"system"
,
messages
.
extend
(
conversation_history
)
"content"
:
f
"التعليمات للتعامل مع الموضوع الحساس:
\n
{unsafe_context}"
messages
.
append
({
"role"
:
"user"
,
"content"
:
user_message
})
})
# Handle different safe query types
# ==========================
# 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}"
})
...
@@ -148,15 +150,16 @@ class ResponseGenerator:
...
@@ -148,15 +150,16 @@ class ResponseGenerator:
relevant_results
=
self
.
context_generator
.
search_enhanced_content
(
relevant_results
=
self
.
context_generator
.
search_enhanced_content
(
user_message
,
student_info
,
subject
,
top_k
user_message
,
student_info
,
subject
,
top_k
)
)
if
relevant_results
:
if
relevant_results
:
enhanced_context
=
self
.
context_generator
.
generate_enhanced_context
(
enhanced_context
=
self
.
context_generator
.
generate_enhanced_context
(
relevant_results
,
student_info
,
query_type
relevant_results
,
student_info
,
query_type
)
)
messages
.
append
({
"role"
:
"system"
,
"content"
:
enhanced_context
})
messages
.
append
({
"role"
:
"system"
,
"content"
:
enhanced_context
})
logger
.
info
(
f
"Added enhanced context with {len(relevant_results)} chunks
"
)
logger
.
info
(
f
"Added enhanced context with {len(relevant_results)} chunks for student {student_name}
"
)
# Generate response using AI model
# ==========================
# CALL AI MODEL
# ==========================
response
=
self
.
openai_service
.
client
.
chat
.
completions
.
create
(
response
=
self
.
openai_service
.
client
.
chat
.
completions
.
create
(
model
=
model
,
model
=
model
,
messages
=
messages
,
messages
=
messages
,
...
@@ -169,12 +172,12 @@ class ResponseGenerator:
...
@@ -169,12 +172,12 @@ class ResponseGenerator:
# Save AI response
# Save AI response
self
.
add_message_to_history
(
student_id
,
ai_response
,
"assistant"
)
self
.
add_message_to_history
(
student_id
,
ai_response
,
"assistant"
)
logger
.
info
(
f
"Generated {query_type} response for {student_name} ({study_language.value}): {len(ai_response)} characters"
)
logger
.
info
(
f
"Generated {query_type} response for {student_name} ({study_language.value})
with conversation context
: {len(ai_response)} characters"
)
return
ai_response
return
ai_response
except
HTTPException
:
except
HTTPException
:
raise
raise
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"Error generating AI response: {e}"
)
logger
.
error
(
f
"Error generating response for student {student_id}: {e}"
)
raise
HTTPException
(
status_code
=
500
,
detail
=
f
"AI response generation failed: {str(e)}"
)
raise
HTTPException
(
status_code
=
500
,
detail
=
"Error generating response"
)
\ No newline at end of file
self_hosted_env/voice_agent/voice_agent.tar
View file @
2e568aab
No preview for this file type
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment