Bug cards

This commit is contained in:
2026-05-02 20:09:23 +02:00
parent 8b024bf0f3
commit 3167f35d58
2 changed files with 41 additions and 2 deletions

View File

@@ -184,6 +184,7 @@ def build_lesson_reply(db: Session, student_id: int, user_message: str, lesson_c
"Si un nombre n'est pas affiché ou autorisé dans ce contexte, tu n'en parles pas. "
"Ne propose jamais 'un autre nombre' si le contexte ne donne pas cet autre nombre. "
"Si l'élève veut continuer mais que la card courante est terminée, mets `advance_lesson_step` à true. "
"Si l'élève dit qu'il comprend, ou donne une réponse correcte attendue par le contexte, mets `advance_lesson_step` à true. "
"Quand `advance_lesson_step` vaut true, ta réponse doit seulement dire: "
"`Très bien, on passe à la suite.` Ne répète pas le nombre de la card terminée. "
"N'utilise pas l'historique des séances précédentes pour choisir le thème de ta réponse. "

View File

@@ -218,6 +218,7 @@ function TutorApp({ currentUser, onLogout }) {
const [sessionCardStates, setSessionCardStates] = useState({})
const [sessionLogs, setSessionLogs] = useState([])
const [selectedSessionLog, setSelectedSessionLog] = useState(null)
const [sessionMessageStartIndex, setSessionMessageStartIndex] = useState(0)
const [progressPanelOpen, setProgressPanelOpen] = useState(false)
const [settingsPanelOpen, setSettingsPanelOpen] = useState(false)
const mediaRecorderRef = useRef(null)
@@ -430,6 +431,8 @@ function TutorApp({ currentUser, onLogout }) {
if (!selectedStudentId) return
try {
setErrorMessage('')
setSessionMessageStartIndex(messages.length)
setSessionCardStates({})
const data = await apiFetch(`/session/start?student_id=${selectedStudentId}`, { method: 'POST' })
appendMessage('assistant', data.reply)
setCurrentInstruction(data.reply)
@@ -523,7 +526,8 @@ function TutorApp({ currentUser, onLogout }) {
async function saveLessonSession() {
if (!selectedStudentId || !studentProgram) return
const currentCardState = getActiveCardState(40, false)
const conversation = messages.map((message) => ({
const sessionMessages = messages.slice(sessionMessageStartIndex)
const conversation = sessionMessages.map((message) => ({
id: message.id,
role: message.role,
content: message.content,
@@ -766,6 +770,39 @@ function TutorApp({ currentUser, onLogout }) {
return `Très bien, on passe à ${title}. Regarde cette card.`
}
function normalizeAnswer(text) {
return text
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/[']/g, ' ')
}
function answerValidatesCurrentCard(text) {
const answer = normalizeAnswer(text)
const key = activeSection?.context_key || ''
if (/\b(oui|ok|d accord)\b/.test(answer) && /compr/.test(answer)) return true
if (key === 'Fiche1Card1') {
return /compr/.test(answer) || (answer.includes('345') && answer.includes('208'))
}
if (key === 'Fiche1Card2') {
return answer.includes('trois') && answer.includes('quarante') && answer.includes('mille') && answer.includes('huit')
}
if (key === 'Fiche1Card3') {
return answer.includes('milliers') && (answer.includes('unites') || answer.includes('simples'))
}
if (key === 'Fiche1Card4') {
return answer.includes('sept') && answer.includes('mille') && answer.includes('vingt') && answer.includes('cinq')
}
if (key === 'Fiche1Card5') {
return answer.includes('trente') && answer.includes('huit') && answer.includes('mille') && answer.includes('quatre') && answer.includes('dix')
}
if (key === 'Fiche1Card6') {
return answer.includes('cinq') && answer.includes('six') && answer.includes('mille') && answer.includes('douze')
}
return false
}
function getSectionKey(asset, section) {
return section?.context_key || `${asset?.path || 'asset'}:${section?.index ?? 0}`
}
@@ -951,7 +988,8 @@ function TutorApp({ currentUser, onLogout }) {
...getLessonContextPayload(),
}),
})
if (data.advance_lesson_step) {
const shouldAdvance = data.advance_lesson_step || answerValidatesCurrentCard(text)
if (shouldAdvance) {
rememberActiveCard({ score: 100, validated: true })
const nextStep = getNextLessonStep()
const transitionReply = nextStep