devsite/app/utils/askAI.js
2026-04-22 20:11:16 +02:00

52 lines
1.6 KiB
JavaScript

/**
* Appelle l'API GrasBot via le proxy Next (/api/proxy).
*
* Historique :
* - v1 : retournait juste `data.response` (string). Compatibilité ascendante
* assurée côté API (le champ `response` existe toujours).
* - v3 (2026-04-22) : retourne maintenant l'objet complet pour que `ChatBot.js`
* puisse afficher les sources citées, le badge `grounded`, etc. Ajoute un
* timeout (45 s) via `AbortController` pour éviter les spinners infinis.
*
* @param {string} question
* @returns {Promise<{
* response: string,
* sources?: Array<{slug: string, title: string, type: string, score: number, url?: string}>,
* grounded?: boolean,
* model?: string,
* vault_size?: number,
* }>}
*/
export async function askAI(question) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 45_000);
try {
const response = await fetch(`/api/proxy?q=${encodeURIComponent(question)}`, {
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
// Rétrocompatibilité : même si l'API ne renvoyait que `response`, on
// retourne l'objet tel quel.
return data;
} catch (error) {
clearTimeout(timeoutId);
if (error.name === "AbortError") {
return {
response:
"La réponse a mis trop de temps. Le modèle est peut-être occupé, réessayez dans un instant.",
sources: [],
grounded: false,
_timeout: true,
};
}
throw error;
}
}