context aware retireval

parent 9be6da83
{
"Grade 4 Arabic curriculum": {
"الوحدة الأولى: الأنظمة الحية": {
"مقدمة": [
9,
12
],
"المفاهيم": {
"المفهوم 1.1: التكيف والبقاء": {},
"المفهوم 2.1: كيف تعمل الحواس؟": {},
"المفهوم 3.1: الضوء وحاسة البصر": {}
},
"مشروع الوحدة": [
63,
64
],
"المشروع بيني التخصصات": [
65,
72
],
"قيم تعلمك": [
73,
74
]
},
"الوحدة الثانية: الحركة والطاقة": {
"مقدمة": [
75,
78
],
"المفاهيم": {
"المفهوم 1.2: الحركة والتوقف": {},
"المفهوم 2.2: الطاقة والحركة": {},
"المفهوم 3.2: الطاقة والتصادم": {}
},
"مشروع الوحدة": [
121,
122
],
"قيم تعلمك": [
123,
124
],
"السلامة في فصول العلوم": [
125,
126
]
}
},
"Grade 5 English curriculum": {
"Unit 1: Interactions of Organisms": {
"Get Started": [
10,
13
],
"Concepts": {
"Concept 1.1 Plant Needs": {},
"Concept 1.2 Energy Flow in Ecosystems": {},
"Concept 1.3 Changes in Food Webs": {}
},
"Unit Project": [
59,
59
],
"Interdisciplinary project": [
60,
67
],
"Assess your learning": [
68,
69
]
},
"Unit 2: Particles in Motion": {
"Get Started": [
70,
73
],
"Concepts": {
"Concept 2.1 Matter in the World around Us": {},
"Concept 2.2 Describing and Measuring Matter": {},
"Concept 2.3 Comparing Changes in Matter": {}
},
"Unit Project": [
124,
125
],
"Assess your learning": [
126,
127
]
}
},
"Grade 6 Arabic curriculum": {
"الوحدة الأولى: ما النظام؟": {
"مقدمة": [
8,
11
],
"المفاهيم": {
"المفهوم 1.1: الخليه كنظام": {},
"المفهوم 2.1: الجسم كنظام": {},
"المفهوم 3.1: الطاقة كنظام": {}
},
"مشروع الوحدة": [
73,
75
],
"تقييم الوحدة": [
76,
79
]
},
"الوحدة الثانية: الحصول على الطاقة": {
"مقدمة": [
80,
83
],
"المفاهيم": {
"المفهوم 1.2: الطاقة الحرارية وحالات المادة": {},
"المفهوم 2.2: انتقال الحرارة": {}
},
"مشروع الوحدة": [
120,
121
],
"المشروع بيني التخصصات": [
122,
130
],
"تقييم الوحدة": [
131,
134
]
}
},
"Grade 6 English curriculum": {
"Unit 1: What is system": {
"Get Started": [
9,
12
],
"Concepts": {
"Concept 1.1 The cell as a system": {},
"Concept 1.2 The body as a system": {},
"Concept 1.3 Energy as a system": {}
},
"Unit Project": [
74,
76
],
"Unit assessment": [
77,
80
]
},
"Unit 2: Getting energy": {
"Get Started": [
81,
84
],
"Concepts": {
"Concept 2.1 Thermal energy and states of matter": {},
"Concept 2.2 Heat transfer": {}
},
"Unit Project": [
121,
122
],
"Interdisciplinary project": [
123,
131
],
"Unit assessment": [
132,
135
]
}
}
}
\ No newline at end of file
from .enums import MessageType, ResponseStatus, StudentNationality, Models from .enums import MessageType, ResponseStatus, StudentNationality, Models, StudyLanguage
from .config import AppConfig from .config import AppConfig
\ No newline at end of file
...@@ -21,3 +21,8 @@ class Models(str, Enum): ...@@ -21,3 +21,8 @@ class Models(str, Enum):
tts = "gpt-4o-mini-tts" tts = "gpt-4o-mini-tts"
embedding = "text-embedding-3-small" embedding = "text-embedding-3-small"
transcription = "gpt-4o-transcribe" transcription = "gpt-4o-transcribe"
class StudyLanguage(Enum):
ARABIC = "ARABIC"
ENGLISH = "ENGLISH"
\ No newline at end of file
This diff is collapsed.
...@@ -4,11 +4,15 @@ from psycopg2.extras import RealDictCursor ...@@ -4,11 +4,15 @@ from psycopg2.extras import RealDictCursor
from typing import List, Dict, Optional, Tuple from typing import List, Dict, Optional, Tuple
import logging import logging
from services.connection_pool import ConnectionPool from services.connection_pool import ConnectionPool
from enum import Enum
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from core import StudyLanguage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ChatDatabaseService: class ChatDatabaseService:
"""Service for managing chat history using a shared, robust connection pool""" """Service for managing chat history using a shared, robust connection pool"""
...@@ -27,7 +31,7 @@ class ChatDatabaseService: ...@@ -27,7 +31,7 @@ class ChatDatabaseService:
return result["nationality"] if result else None return result["nationality"] if result else None
def get_student_info(self, student_id: str) -> Optional[Dict]: def get_student_info(self, student_id: str) -> Optional[Dict]:
"""Get complete student information from database""" """Get complete student information with explicit language awareness"""
with self.pool_handler.get_connection() as conn: with self.pool_handler.get_connection() as conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur: with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute( cur.execute(
...@@ -40,17 +44,20 @@ class ChatDatabaseService: ...@@ -40,17 +44,20 @@ class ChatDatabaseService:
) )
result = cur.fetchone() result = cur.fetchone()
if result: if result:
# Convert boolean to explicit language enum
study_language = StudyLanguage.ARABIC if result['language'] else StudyLanguage.ENGLISH
return { return {
'student_id': result['student_id'], 'student_id': result['student_id'],
'student_name': result['student_name'], 'student_name': result['student_name'],
'grade': result['grade'], 'grade': result['grade'],
'is_arabic': result['language'], 'study_language': study_language, # Explicit language enum
'is_arabic': result['language'], # Keep for backward compatibility
'nationality': result['nationality'] 'nationality': result['nationality']
} }
return None return None
def get_student_grade_and_language(self, student_id: str) -> Optional[Tuple[int, bool]]: def get_student_grade_and_language(self, student_id: str) -> Optional[Tuple[int, bool, StudyLanguage]]:
"""Get student grade and language preference""" """Get student grade, language preference, and explicit study language"""
with self.pool_handler.get_connection() as conn: with self.pool_handler.get_connection() as conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur: with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute( cur.execute(
...@@ -59,7 +66,8 @@ class ChatDatabaseService: ...@@ -59,7 +66,8 @@ class ChatDatabaseService:
) )
result = cur.fetchone() result = cur.fetchone()
if result: if result:
return (result["grade"], result["language"]) study_language = StudyLanguage.ARABIC if result['language'] else StudyLanguage.ENGLISH
return (result["grade"], result["language"], study_language)
return None return None
def get_chat_history(self, student_id: str, limit: int = 20) -> List[Dict[str, str]]: def get_chat_history(self, student_id: str, limit: int = 20) -> List[Dict[str, str]]:
...@@ -154,6 +162,11 @@ class ChatDatabaseService: ...@@ -154,6 +162,11 @@ class ChatDatabaseService:
) )
conn.commit() conn.commit()
# Log the language update explicitly
if language is not None:
study_language = StudyLanguage.ARABIC if language else StudyLanguage.ENGLISH
logger.info(f"Updated student {student_id} language to {study_language.value}")
def create_student(self, student_id: str, student_name: str, grade: int, def create_student(self, student_id: str, student_name: str, grade: int,
language: bool, nationality: str = 'EGYPTIAN'): language: bool, nationality: str = 'EGYPTIAN'):
"""Create a new student record""" """Create a new student record"""
...@@ -168,3 +181,52 @@ class ChatDatabaseService: ...@@ -168,3 +181,52 @@ class ChatDatabaseService:
(student_id, student_name, grade, language, nationality) (student_id, student_name, grade, language, nationality)
) )
conn.commit() conn.commit()
# Log the explicit language information
study_language = StudyLanguage.ARABIC if language else StudyLanguage.ENGLISH
logger.info(f"Created student {student_id} ({student_name}) - Grade: {grade}, Language: {study_language.value}, Nationality: {nationality}")
def get_student_language_summary(self, student_id: str) -> Optional[Dict[str, str]]:
"""Get a human-readable summary of student's language settings"""
student_info = self.get_student_info(student_id)
if not student_info:
return None
nationality_desc = "مصري" if student_info['nationality'].lower() == "egyptian" else "سعودي"
language_desc = "بالعربي" if student_info['study_language'] == StudyLanguage.ARABIC else "بالإنجليزي"
return {
"student_id": student_id,
"student_name": student_info['student_name'],
"study_language": student_info['study_language'].value,
"nationality": student_info['nationality'],
"grade": str(student_info['grade']),
"description": f"طالب {nationality_desc} في الصف {student_info['grade']} يدرس {language_desc}"
}
def get_students_by_language(self, study_language: StudyLanguage) -> List[Dict]:
"""Get all students who study in a specific language"""
language_bool = True if study_language == StudyLanguage.ARABIC else False
with self.pool_handler.get_connection() as conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute(
"""
SELECT student_id, student_name, grade, nationality
FROM students
WHERE language = %s
ORDER BY grade, student_name
""",
(language_bool,)
)
results = cur.fetchall()
return [
{
'student_id': row['student_id'],
'student_name': row['student_name'],
'grade': row['grade'],
'nationality': row['nationality'],
'study_language': study_language.value
}
for row in results
]
\ No newline at end of file
...@@ -8,6 +8,8 @@ echo "Setting up schema and inserting data..." ...@@ -8,6 +8,8 @@ echo "Setting up schema and inserting data..."
python apply_test_schema.py python apply_test_schema.py
python insert_csv_embeddings.py python insert_csv_embeddings.py
echo "Database setup complete." echo "Database setup complete."
python curriculum_structure.py
echo "Curriculum structure setup complete."
sleep 5 sleep 5
# Start the web server and keep it as the main process # Start the web server and keep it as the main process
......
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