AUDIT / src /lib /agentLoop /earlyGuards.ts
Arypulka98's picture
feat(audit): deploy full backend cluster node (part 3)
95eb75a verified
Raw
History Blame Contribute Delete
2.13 kB
// agentLoop/earlyGuards.ts — P4-3
// Extracted from agentLoop.ts: navigator.onLine guard (S313) + token guard (S322).
// Returns true if the loop should return early (guard triggered).
// Uses raw `callbacks` (pre-onChunk-closure) to avoid dependency on render buffer.
import { liveGuidanceStore } from "@/lib/liveGuidanceStore"; // S440
interface EarlyGuardCallbacks {
onChunk?: (chunk: string) => void;
onStatus?: (status: string) => void;
}
/** S313 + S322: pre-loop guards. Returns true → caller must return immediately. */
export function checkEarlyGuards(token: string, callbacks: EarlyGuardCallbacks): boolean {
// S313-iOS: navigator.onLine guard — previene 30s timeout silenzioso su iPhone in tunnel/metro
if (typeof navigator !== "undefined" && !navigator.onLine) {
callbacks.onChunk?.("⚠️ Nessuna connessione internet. Riprova quando sei online.");
callbacks.onStatus?.("📵 Offline — loop annullato");
try { liveGuidanceStore.clear(); } catch { /* non-blocking */ } // S440
return true;
}
// S322: Early token guard — risposta immediata se nessun provider configurato.
// DEVE essere PRIMA di qualsiasi onStatus/taskStore call per evitare che l'utente
// veda "Analisi richiesta…" per 30+ secondi prima di scoprire che manca il token.
if (!token || !token.trim()) {
const _noTokenMsg =
`🔑 **Nessun token API configurato.**\n\nApri le **Impostazioni** (⚙️) e aggiungi uno di questi token gratuiti:\n\n` +
`- **OpenRouter** → [openrouter.ai/keys](https://openrouter.ai/keys) — gratuito, 13+ modelli\n` +
`- **Groq** → [console.groq.com/keys](https://console.groq.com/keys) — velocissimo, gratuito\n` +
`- **Gemini** → [aistudio.google.com/apikey](https://aistudio.google.com/apikey) — Google, gratuito\n` +
`- **HuggingFace** → [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens)`;
callbacks.onChunk?.(_noTokenMsg);
callbacks.onStatus?.("🔑 Token mancante");
try { liveGuidanceStore.clear(); } catch { /* non-blocking */ } // S440
return true;
}
return false;
}