diff --git a/backend/app/main.py b/backend/app/main.py index 16b803a..d3bcceb 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -300,9 +300,13 @@ def start_session( assignment = db.query(models.StudentProgramAssignment).filter_by(student_id=student.id).first() assigned_lesson = get_lesson(assignment.lesson_id) if assignment else None if assigned_lesson: + first_asset = (assigned_lesson.get("assets") or [None])[0] + first_section = (first_asset.get("sections") or [None])[0] if first_asset else None + section_label = first_section["title"] if first_section else first_asset["title"] if first_asset else assigned_lesson["title"] message = ( f"Bonjour {student.first_name} ! Aujourd’hui, on travaille la leçon " - f"{assigned_lesson['title']}. Regarde la première fiche, puis dis-moi ce que tu remarques." + f"{assigned_lesson['title']}. Regarde la carte « {section_label} ». " + "Dis-moi si tu comprends cette partie, ou ce qui te gêne." ) previous_messages_count = db.query(models.Message).filter_by(student_id=student.id).count() if previous_messages_count: @@ -313,7 +317,13 @@ def start_session( "première consigne simple." ) if assigned_lesson: - prompt += f" La leçon active choisie par le professeur est: {assigned_lesson['title']}." + first_asset = (assigned_lesson.get("assets") or [None])[0] + first_section = (first_asset.get("sections") or [None])[0] if first_asset else None + section_label = first_section["title"] if first_section else first_asset["title"] if first_asset else assigned_lesson["title"] + prompt += ( + f" La leçon active choisie par le professeur est: {assigned_lesson['title']}. " + f"La carte affichée est: {section_label}. Parle de cette carte, pas d'une ancienne leçon." + ) message = build_llm_reply(db, student.id, prompt) db.add(models.Message(student_id=student.id, role="assistant", content=message)) db.commit() @@ -334,7 +344,19 @@ def chat( db.add(models.Message(student_id=student.id, role="user", content=payload.message)) db.commit() - reply = build_llm_reply(db, payload.student_id, payload.message) + lesson_context = "" + if payload.lesson_title or payload.section_title or payload.asset_title: + lesson_context = ( + "\n\nContexte de l’écran actuellement montré à l’élève: " + f"leçon={payload.lesson_title or 'non précisée'}, " + f"fiche={payload.asset_title or 'non précisée'}, " + f"carte affichée={payload.section_title or 'non précisée'}, " + f"avancement={payload.step_percent if payload.step_percent is not None else 'non précisé'}%. " + "Réponds uniquement à propos de cette carte. Vérifie que l’élève comprend ce qui est affiché. " + "Si l’élève dit qu’il a compris, invite-le à passer à l’étape suivante." + ) + + reply = build_llm_reply(db, payload.student_id, f"{payload.message}{lesson_context}") db.add(models.Message(student_id=student.id, role="assistant", content=reply)) db.commit() diff --git a/backend/app/schemas.py b/backend/app/schemas.py index 260446e..561ccd8 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -54,6 +54,10 @@ class StudentAccountResponse(BaseModel): class ChatRequest(BaseModel): student_id: int message: str + lesson_title: str | None = None + asset_title: str | None = None + section_title: str | None = None + step_percent: int | None = None class ChatResponse(BaseModel): diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 0e99540..58e3fb9 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -213,7 +213,6 @@ function TutorApp({ currentUser, onLogout }) { const [studentProgram, setStudentProgram] = useState(null) const [activeAssetIndex, setActiveAssetIndex] = useState(0) const [activeSectionIndex, setActiveSectionIndex] = useState(0) - const [assetFullscreenOpen, setAssetFullscreenOpen] = useState(false) const [progressPanelOpen, setProgressPanelOpen] = useState(false) const [settingsPanelOpen, setSettingsPanelOpen] = useState(false) const mediaRecorderRef = useRef(null) @@ -512,7 +511,6 @@ function TutorApp({ currentUser, onLogout }) { stopSpeechPlayback() deactivateAutoListening(false) setSessionActive(false) - setAssetFullscreenOpen(false) setProgressPanelOpen(false) setSettingsPanelOpen(false) setCurrentInstruction('') @@ -614,6 +612,22 @@ function TutorApp({ currentUser, onLogout }) { } } + function getLessonContextPayload() { + return { + lesson_title: activeLessonTitle, + asset_title: activeAsset?.title || null, + section_title: activeSection?.title || activeAsset?.title || null, + step_percent: lessonStepPercent, + } + } + + function compactInstruction(text) { + const cleanText = text.trim() + if (!cleanText) return '' + const sentences = cleanText.match(/[^.!?]+[.!?]+|[^.!?]+$/g) || [cleanText] + return sentences.slice(0, 2).join(' ').trim() + } + async function finishSpeechPlayback(debugMessage) { setSpeaking(false) if (audioPlaybackUrlRef.current) { @@ -718,7 +732,11 @@ function TutorApp({ currentUser, onLogout }) { const data = await apiFetch('/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ student_id: Number(selectedStudentId), message: text }), + body: JSON.stringify({ + student_id: Number(selectedStudentId), + message: text, + ...getLessonContextPayload(), + }), }) appendMessage('assistant', data.reply) setCurrentInstruction(data.reply) @@ -1079,7 +1097,7 @@ function TutorApp({ currentUser, onLogout }) { )} {currentInstruction ? ( -
{currentInstruction}
+{compactInstruction(currentInstruction)}
) : (Professeur TOP prépare la suite de la leçon.
)} @@ -1106,18 +1124,12 @@ function TutorApp({ currentUser, onLogout }) { -