From c75634e3e1dd6beae9215d85987a0e3b7e024874 Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Sat, 25 Apr 2026 21:38:17 +0200 Subject: [PATCH] transmis au prof --- MEMORY.md | 3 +++ backend/app/services.py | 10 ++++++++++ frontend/src/App.jsx | 11 +++++++++++ frontend/src/styles.css | 22 ++++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/MEMORY.md b/MEMORY.md index 993ffc5..a7afdd3 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -37,6 +37,9 @@ Ce projet est un POC de professeur virtuel pour enfants, avec: - Les options TTS visibles doivent etre libellees `Voix Douce`, `Voix Rigolote`, etc.; la mention "Voix IA non humaine..." est portee par un tooltip. - Le declenchement manuel de mini-test/exercice doit disparaitre de l'interface eleve; le programme doit etre determine par Professeur TOP. - A prevoir cote admin: tableau par eleve et prompts/instructions personnalises pour guider Professeur TOP par eleve. +- L'ecran eleve affiche une petite card "Transmis au prof" au-dessus de la zone de saisie pour montrer le texte capte/envoye. +- Le backend ajoute une consigne de tours de parole courts pour que Professeur TOP laisse le temps a l'enfant de repondre. +- Gestion interruption a prevoir: detection de parole pendant TTS, pause audio, transcription, classification pertinent/accidentel, puis reprise courte. - Le vrai `docker-compose.yml` de production n'est pas dans ce repo. Il est situe un niveau au-dessus sur le serveur. - La conf nginx reelle route: - `/api/` vers `tutor-backend:8000` diff --git a/backend/app/services.py b/backend/app/services.py index 9007c5f..c68e681 100644 --- a/backend/app/services.py +++ b/backend/app/services.py @@ -20,6 +20,15 @@ Règles : - Tu enseignes principalement le programme national français niveau primaire/cycle 3. """.strip() +TURN_TAKING_PROMPT = """ +Consignes de rythme oral: +- Fais des tours de parole courts: 1 a 3 phrases maximum, sauf demande explicite. +- Termine souvent par une question ou une consigne courte pour laisser l'enfant parler. +- Ne fais pas de longs monologues: une idee a la fois. +- Si l'eleve t'interrompt, arrete-toi, ecoute son message, puis reprends seulement si c'est utile. +- Si l'interruption semble accidentelle ou hors sujet, reponds tres brievement puis continue. +""".strip() + TTS_PROFILES = [ { "id": "rigolote", @@ -130,6 +139,7 @@ def build_llm_reply(db: Session, student_id: int, user_message: str) -> str: model="gpt-4.1-mini", input=[ {"role": "system", "content": SYSTEM_PROMPT}, + {"role": "system", "content": TURN_TAKING_PROMPT}, { "role": "user", "content": f"Contexte pédagogique:\n{context}\n\nMessage de l'élève:\n{user_message}", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e87ab18..e8cc8fe 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -190,6 +190,7 @@ function TutorApp({ currentUser, onLogout }) { }) const [messages, setMessages] = useState([]) const [currentInstruction, setCurrentInstruction] = useState('') + const [lastStudentTransmission, setLastStudentTransmission] = useState('') const [sessionActive, setSessionActive] = useState(false) const [currentFocusSkill, setCurrentFocusSkill] = useState(null) const [exerciseStatus, setExerciseStatus] = useState('not-started') @@ -288,6 +289,7 @@ function TutorApp({ currentUser, onLogout }) { setSessionActive(false) setAssessment(null) setAssessmentAnswer('') + setLastStudentTransmission('') setCurrentFocusSkill(null) setExerciseStatus('not-started') if (selectedStudentId) { @@ -459,6 +461,7 @@ function TutorApp({ currentUser, onLogout }) { }), }) appendMessage('user', `Reponse au mini-test: ${assessmentAnswer}`) + setLastStudentTransmission(assessmentAnswer) appendMessage('assistant', data.feedback) setCurrentInstruction(data.feedback) setExerciseStatus(data.correct ? 'resolved' : 'needs-review') @@ -492,6 +495,7 @@ function TutorApp({ currentUser, onLogout }) { setAssessment(null) setAssessmentAnswer('') setInput('') + setLastStudentTransmission('') } async function toggleSession() { @@ -617,6 +621,7 @@ function TutorApp({ currentUser, onLogout }) { throw new Error('Choisis un élève avant d’envoyer un message.') } appendMessage('user', text) + setLastStudentTransmission(text) setInput('') setErrorMessage('') const data = await apiFetch('/chat', { @@ -652,6 +657,7 @@ function TutorApp({ currentUser, onLogout }) { return } + setLastStudentTransmission(transcript) if (autoSend && selectedStudentId) { setVoiceStatus('Texte reconnu, envoi automatique...') pushAudioDebug('Envoi automatique du message transcrit') @@ -1008,6 +1014,11 @@ function TutorApp({ currentUser, onLogout }) { )} +
+ Transmis au prof +

{lastStudentTransmission || 'Le texte reconnu par le micro ou envoye au clavier apparaitra ici.'}

+
+