fix(timeouts): increase Gemini to 45s, DeepSeek EO to 90s + adaptive conseil_nclc

- Gemini GEMINI_TIMEOUT_MS: 30s → 45s
- callDeepSeek optional timeoutMs param, correctEO uses 90s
- conseil_nclc: 4 tiers based on score vs NCLC target (EE + EO)
- sanitizeJsonContent: handle single-quote JSON from DeepSeek
- MIME normalization for audio/webm;codecs=opus

Typecheck: OK · Tests: 248/248 

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hermann_Kitio 2026-04-25 08:30:51 +03:00
parent 13aacf4d38
commit dba446b555
2 changed files with 11 additions and 6 deletions

View file

@ -472,10 +472,13 @@ function sanitizeJsonContent(raw: string): string {
} }
} }
const CALL_DEEPSEEK_DEFAULT_TIMEOUT_MS = 55_000;
async function callDeepSeek( async function callDeepSeek(
system: string, system: string,
user: string, user: string,
temperature: number, temperature: number,
timeoutMs: number = CALL_DEEPSEEK_DEFAULT_TIMEOUT_MS,
): Promise<string> { ): Promise<string> {
try { try {
const response = await fetch(`${DEEPSEEK_BASE_URL}/chat/completions`, { const response = await fetch(`${DEEPSEEK_BASE_URL}/chat/completions`, {
@ -493,10 +496,10 @@ async function callDeepSeek(
temperature, temperature,
response_format: { type: "json_object" }, response_format: { type: "json_object" },
}), }),
// Le prompt maître + taxonomie produit une réponse JSON longue : DeepSeek // EE / modèle / exercices : 55 s par défaut (frontend abort à 60 s).
// peut prendre 20-40 s. Le frontend abort à 60 s (CORRECTION_TIMEOUT_MS) // EO en mode audio : Gemini transcribe + DeepSeek correction. Frontend
// → on abort ici à 55 s pour laisser une marge côté client. // alloue 120 s → on accepte 90 s ici (cf. correctEO).
signal: AbortSignal.timeout(55_000), signal: AbortSignal.timeout(timeoutMs),
}); });
if (!response.ok) { if (!response.ok) {
@ -1151,7 +1154,9 @@ export async function correctEO(
sujet, sujet,
nclcCible, nclcCible,
}); });
const content = await callDeepSeek(system, user, 0.2); // 90 s : EO arrive après une transcription Gemini (jusqu'à 45 s + 1 retry)
// dans le pipeline `POST /corrections/eo`. Frontend cap à 120 s.
const content = await callDeepSeek(system, user, 0.2, 90_000);
const parsed: unknown = JSON.parse(content); const parsed: unknown = JSON.parse(content);
return validateCorrectionRapportEO(parsed, nclcCible, transcript); return validateCorrectionRapportEO(parsed, nclcCible, transcript);
} }

View file

@ -11,7 +11,7 @@
const GEMINI_API_KEY = process.env.GEMINI_API_KEY ?? ""; const GEMINI_API_KEY = process.env.GEMINI_API_KEY ?? "";
const GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"; const GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
const GEMINI_TIMEOUT_MS = 30_000; const GEMINI_TIMEOUT_MS = 45_000;
/** /**
* MIME types audio acceptés par le pipeline Sprint 4a. * MIME types audio acceptés par le pipeline Sprint 4a.