diff --git a/src/lib/deepseek.ts b/src/lib/deepseek.ts index 1a65946..630aa26 100644 --- a/src/lib/deepseek.ts +++ b/src/lib/deepseek.ts @@ -169,6 +169,40 @@ const TASK_DESCRIPTIONS: Record = { "T3 — Expression d'un point de vue spontané (4 minutes 30) : exprimer et défendre un point de vue sur une question, illustrer par des exemples concrets, organiser l'argumentation, conclure. Registre courant à standard.", }; +/** + * Bloc de règles pour `conseil_nclc` — Sprint 4b.3. + * + * Sans ce bloc, DeepSeek génère un conseil_nclc identique quel que soit le + * score (ex. un 18/20 reçoit « vous pouvez atteindre NCLC 9 » alors qu'il + * l'a déjà dépassé). On force 4 paliers basés sur l'écart score / minScore + * de la cible pour différencier les cas. + * + * `quoteStyle` : 'double' pour les prompts EE (qui utilisent ") ; + * 'single' pour les prompts EO (qui utilisent ' pour le JSON strict — + * cf. consigne Sprint 4a). + */ +function buildConseilNclcRulesBlock( + nclcCible: NclcCible, + minScore: number, + quoteStyle: "single" | "double", +): string { + const q = quoteStyle === "single" ? "'" : '"'; + const upper = Math.min(nclcCible + 1, 10); + return `RÈGLES DE GÉNÉRATION DE ${q}conseil_nclc${q} (à respecter strictement) : +- Si ${q}score${q} >= ${minScore + 2}/20 (objectif NCLC ${nclcCible} largement dépassé) : + ${q}ecart${q} = ${q}objectif dépassé : tu vises plutôt NCLC ${upper}${q} + ${q}action_prioritaire${q} = félicitations + ce qu'il faut maintenir pour viser un cran au-dessus. +- Si ${q}score${q} >= ${minScore}/20 (NCLC ${nclcCible} atteint) : + ${q}ecart${q} = ${q}objectif NCLC ${nclcCible} atteint${q} + ${q}action_prioritaire${q} = félicitations + 1 point ciblé à consolider pour stabiliser. +- Si ${q}score${q} >= ${minScore - 2}/20 (proche de la cible) : + ${q}ecart${q} = ${q}manque X points pour atteindre NCLC ${nclcCible}${q} (X = ${minScore} − score réel) + ${q}action_prioritaire${q} = encouragement + 1-2 leviers prioritaires concrets. +- Si ${q}score${q} < ${minScore - 2}/20 (loin de la cible) : + ${q}ecart${q} = ${q}manque significatif (cible NCLC ${nclcCible} = ${minScore}/20)${q} + ${q}action_prioritaire${q} = plan d'action prioritaire en 2-3 étapes, ton bienveillant.`; +} + // ── Prompts builders ───────────────────────────────────────────────────── /** @@ -201,6 +235,8 @@ CRITÈRES OFFICIELS TCF (chacun noté de 0 à 5) : ${taxonomySection} +${buildConseilNclcRulesBlock(nclcCible, minScore, "double")} + FORMAT DE RÉPONSE (JSON strict, aucun autre texte) : { "score": , @@ -928,6 +964,8 @@ CRITÈRES OFFICIELS TCF Canada — Expression Orale (chacun noté 0 à 5) : ${taxonomySection} +${buildConseilNclcRulesBlock(nclcCible, minScore, "single")} + FORMAT DE RÉPONSE (JSON strict, aucun autre texte) : { 'score': ,