mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-11 17:26:32 +02:00
fix: immediate AI loading feedback + auto-fallback for deprecated model
- BulkAiAnalyzer: set isAnalyzing=true immediately on click (before context fetch), so the spinner appears instantly instead of after 1-2 seconds of silence - analyze/route.ts: if configured model returns 400/404 (e.g., deprecated google/gemini-flash-1.5), automatically retry with google/gemini-2.0-flash-001 - batch-analyze/route.ts: same fallback logic Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
2aa9cbecaa
commit
bbb04a4d2a
3 files changed
+32
-9
No files matched your search
@@ -54,8 +54,22 @@ export async function POST(req: NextRequest) {
|
||||
}
|
||||
}
|
||||
|
||||
const client = new OpenRouterClient({ apiKey, model });
|
||||
const result = await client.analyzeProduct(enrichedBody);
|
||||
const FALLBACK_MODEL = "google/gemini-2.0-flash-001";
|
||||
let client = new OpenRouterClient({ apiKey, model });
|
||||
let result;
|
||||
try {
|
||||
result = await client.analyzeProduct(enrichedBody);
|
||||
} catch (modelErr) {
|
||||
// If configured model fails (e.g., deprecated), retry with fallback
|
||||
const msg = modelErr instanceof Error ? modelErr.message : "";
|
||||
if (model !== FALLBACK_MODEL && (msg.includes("400") || msg.includes("404") || msg.includes("OpenRouter error"))) {
|
||||
console.warn(`[AI] Model "${model}" failed (${msg}), retrying with fallback ${FALLBACK_MODEL}`);
|
||||
client = new OpenRouterClient({ apiKey, model: FALLBACK_MODEL });
|
||||
result = await client.analyzeProduct(enrichedBody);
|
||||
} else {
|
||||
throw modelErr;
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(result);
|
||||
} catch (err) {
|
||||
|
||||
@@ -107,14 +107,12 @@ REPONDS EN JSON VALIDE uniquement :
|
||||
const userPrompt = `${products.length} produits du rayon "${rayon}" (sur ${supplierStats?.totalProducts ?? products.length} au total).
|
||||
${JSON.stringify(products, null, 2)}`;
|
||||
|
||||
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
||||
const FALLBACK_MODEL = "google/gemini-2.0-flash-001";
|
||||
const tryModel = async (modelToTry: string) => fetch("https://openrouter.ai/api/v1/chat/completions", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${apiKey}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
model,
|
||||
model: modelToTry,
|
||||
messages: [
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: userPrompt }
|
||||
@@ -124,6 +122,14 @@ ${JSON.stringify(products, null, 2)}`;
|
||||
}),
|
||||
});
|
||||
|
||||
let response = await tryModel(model);
|
||||
|
||||
// Fallback if configured model is deprecated/not found
|
||||
if (!response.ok && response.status === 400 && model !== FALLBACK_MODEL) {
|
||||
console.warn(`[batch-analyze] Model "${model}" returned 400, retrying with fallback ${FALLBACK_MODEL}`);
|
||||
response = await tryModel(FALLBACK_MODEL);
|
||||
}
|
||||
|
||||
if (response.status === 429) {
|
||||
const retryAfter = response.headers.get("Retry-After") || response.headers.get("x-ratelimit-reset-requests");
|
||||
const waitSeconds = retryAfter ? parseInt(retryAfter, 10) : 60;
|
||||
|
||||
@@ -41,6 +41,10 @@ export function BulkAiAnalyzer() {
|
||||
const { rows } = useGridStore.getState();
|
||||
isCancelledRef.current = false;
|
||||
|
||||
// Show immediate visual feedback before any async work
|
||||
setIsAnalyzing(true);
|
||||
setProgress({ current: 0, total: 0, message: "Chargement du contexte...", errors: 0 });
|
||||
|
||||
// 1. Fetch AI Context for the Supplier
|
||||
let supplierContext = "";
|
||||
if (supplierCode) {
|
||||
@@ -166,7 +170,6 @@ export function BulkAiAnalyzer() {
|
||||
|
||||
// 2c. Context profiling en micro-batches asynchrones
|
||||
// Le score est déjà calculé par score-engine.ts (champ row.score sur chaque ProductRow).
|
||||
setIsAnalyzing(true);
|
||||
setProgress({ current: 0, total: payloadsWithSales.length, message: "Calcul du contexte...", errors: 0 });
|
||||
|
||||
const SCORING_BATCH_SIZE = 25;
|
||||
|
||||
Reference in new issue
Block a user