phone screen

This commit is contained in:
2026-05-01 19:04:28 +02:00
parent 243bfd6563
commit 4b3194d207
2 changed files with 177 additions and 1 deletions

View File

@@ -100,6 +100,82 @@ Ce projet est un POC de professeur virtuel pour enfants, avec:
- Lors d'un prochain demarrage, penser a installer les dependances frontend avant validation finale.
- La TTS OpenAI suppose une `OPENAI_API_KEY` valide cote backend.
## Notes de Session 2026-04-25 - Auth, UI Eleve, Audio
- Authentification ajoutee:
- table `users`
- roles `student`, `teacher`, `maintenance`
- login via `/auth/login`
- session via cookie HTTP-only `professeur_top_session`
- compte admin/prof seede depuis `.env`
- Acces eleve/admin:
- un compte eleve est rattache a un `student_id`
- un eleve ne peut acceder qu'a sa propre fiche/seance
- prof/maintenance gardent l'acces global
- creation d'un compte eleve via `POST /admin/student-accounts`
- UI eleve:
- page login active
- l'eleve ne voit plus la creation ni le choix d'eleves
- l'ecran de cours ne montre plus la conversation complete
- le cours courant remplace la consigne precedente au centre
- la zone de reponse eleve reste en bas
- card "Transmis au prof" ajoutee pour afficher le dernier texte envoye/capte
- bouton principal `Demarrer la seance` / `Fin de la seance`
- colonne gauche eleve limitee aux themes du jour, pas au bilan global
- Conversation et analyse:
- les messages restent stockes en base
- `GET /students/{student_id}/messages` permet de relire l'historique
- le chat complet sera surtout utile aux rapports admin
- Voix/TTS:
- les voix visibles sont libellees `Voix Douce`, `Voix Rigolote`, etc.
- la mention "Voix IA non humaine..." est deplacee en tooltip
- Professeur TOP a maintenant une consigne backend de tours de parole courts
- Transcription:
- `language="fr"` force dans la transcription OpenAI
- prompt de transcription ajoute pour phrases scolaires courtes
- correction faite apres erreur type langue asiatique sur une phrase simple comme "nous chantons"
- Deploiement serveur:
- `.env` du compose doit etre dans `/root/.env` ou passe via `--env-file`
- rebuild backend necessaire pour changements backend
- rebuild frontend necessaire pour changements UI
## Idee Technique - Interruptions Trop Frequentes
Objectif: permettre a l'enfant de couper Professeur TOP sans perdre le fil, tout en evitant les faux positifs.
Approche progressive recommandee:
1. Barge-in simple avec TTS MP3 actuel:
- garder l'analyse micro active pendant la lecture audio
- si volume/parole detectee pendant que `speaking=true`, mettre l'audio en pause ou l'arreter
- enregistrer un court segment jusqu'au silence
- transcrire en francais
- envoyer au backend avec un marqueur du type `interruption=true`
- demander au LLM de classer implicitement: pertinent, question, correction, bruit/accident
- si pertinent: repondre a l'enfant puis reprendre la lecon
- si accidentel: repondre tres court puis continuer la consigne
2. Anti-faux positifs:
- imposer un seuil plus haut pendant la lecture TTS
- ignorer les segments tres courts, par exemple moins de 600 ms
- ignorer les transcriptions vides ou tres faibles
- utiliser une courte fenetre de cooldown apres chaque interruption
- afficher dans "Transmis au prof" uniquement ce qui est vraiment envoye
3. Meilleure solution moyen terme:
- passer sur OpenAI Realtime/WebRTC
- gerer interruption, VAD, tour-taking et streaming audio nativement
- envoyer des evenements de session avec contexte pedagogique
- conserver en base les transcriptions et messages comme aujourd'hui
4. Donnees a stocker plus tard:
- `session_id`
- `message_type`: text, image, audio, interruption
- `source`: keyboard, microphone, system
- `interruption_of_message_id`
- timestamp debut/fin de parole
- confiance transcription
## Points de Vigilance
- Les erreurs WebSocket Vite/HMR sur `wss://prof.open-squared.tech/...` sont du bruit de dev tant que le frontend tourne via Vite derriere nginx.

View File

@@ -276,7 +276,36 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
}
@media (max-width: 920px) {
.layout { grid-template-columns: 1fr; }
body {
overflow: auto;
}
.layout {
grid-template-columns: 1fr;
height: auto;
min-height: 100dvh;
overflow: visible;
padding: 0.75rem;
}
.sidebar,
.main {
min-height: auto;
overflow: visible;
}
.student-layout .sidebar {
order: 1;
}
.student-layout .main {
order: 2;
}
.card {
border-radius: 18px;
}
.composer { grid-template-columns: 1fr; }
.hero { align-items: flex-start; }
.session-user {
@@ -284,4 +313,75 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
margin-left: 0;
justify-content: space-between;
}
.instruction-stage {
flex: 0 0 auto;
justify-content: flex-start;
min-height: 220px;
}
.instruction-stage p {
max-height: none;
overflow: visible;
font-size: 1.1rem;
}
}
@media (max-width: 560px) {
.layout {
gap: 0.75rem;
padding: 0.5rem;
}
.card {
padding: 0.85rem;
border-radius: 16px;
}
.sidebar,
.main,
.today-panel {
gap: 0.85rem;
}
.sidebar h2,
.main h1 {
margin: 0;
}
.main h1 {
font-size: 1.85rem;
}
.hero {
gap: 0.75rem;
}
.avatar {
width: 112px;
height: 112px;
border-radius: 22px;
}
.session-user {
align-items: stretch;
flex-direction: column;
gap: 0.5rem;
}
.today-card-head {
align-items: flex-start;
flex-direction: column;
gap: 0.25rem;
}
.student-transmission p {
white-space: normal;
}
button,
input,
select {
width: 100%;
}
}