fix(ai): server-side retry-with-backoff on 429, reads Retry-After header, up to 3 attempts

This commit is contained in:
Michael committed 2026-02-21 21:58:25 +01:00
1 parent 163d80dfe2
commit 41c3ab34b6
1 file changed
+31 -19
+31 -19
View File
@@ -62,27 +62,39 @@ Format attendu:
const userPrompt = `Analyse cette liste de produits :\n${JSON.stringify(products, null, 2)}`; const userPrompt = `Analyse cette liste de produits :\n${JSON.stringify(products, null, 2)}`;
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", { // Retry loop for 429 rate limiting — reads Retry-After header
method: "POST", let response: Response | null = null;
headers: { const MAX_RETRIES = 3;
"Authorization": `Bearer ${apiKey}`, for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
"Content-Type": "application/json", response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
}, method: "POST",
body: JSON.stringify({ headers: {
model: "meta-llama/llama-3.3-70b-instruct:free", "Authorization": `Bearer ${apiKey}`,
messages: [ "Content-Type": "application/json",
{ role: "system", content: systemPrompt }, },
{ role: "user", content: userPrompt } body: JSON.stringify({
], model,
response_format: { type: "json_object" }, // Force JSON messages: [
temperature: 0.1, // Low temp for analytical consistency { role: "system", content: systemPrompt },
}), { role: "user", content: userPrompt }
}); ],
response_format: { type: "json_object" },
temperature: 0.1,
}),
});
if (!response.ok) { if (response.status !== 429) break; // Success or non-retryable error
const err = await response.text();
const retryAfterHeader = response.headers.get("Retry-After") || response.headers.get("x-ratelimit-reset-requests");
const waitSeconds = retryAfterHeader ? Math.min(parseInt(retryAfterHeader, 10), 90) : 30 * attempt;
console.warn(`[batch-analyze] 429 on attempt ${attempt}/${MAX_RETRIES}. Waiting ${waitSeconds}s...`);
await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
}
if (!response || !response.ok) {
const err = response ? await response.text() : "No response";
console.error("OpenRouter API Error:", err); console.error("OpenRouter API Error:", err);
return NextResponse.json({ error: "Erreur lors de l'appel à OpenRouter." }, { status: response.status }); return NextResponse.json({ error: "Erreur lors de l'appel à OpenRouter." }, { status: response?.status ?? 500 });
} }
const data = await response.json(); const data = await response.json();