AUDIT / src /lib /agent /retryEngine.ts
Arypulka98's picture
feat(audit): deploy full backend cluster node (part 2)
cc11e77 verified
Raw
History Blame Contribute Delete
3.09 kB
// ─── Retry engine ─────────────────────────────────────────────────────────────
// Decides if and how to retry a failed/poor LLM response.
// S-RETRY-WIRE: usa validateGate invece di validateOutput raw.
// validateGate unifica normalize/sanitize/repair/quality/antiRewriteGuard
// e produce un retryHint chirurgico quando referenceCode è fornito.
import { validateGate } from "./validationGate";
export interface RetryDecision {
shouldRetry: boolean;
reason: string;
augmentedPrompt?: string;
priority: "immediate" | "deferred" | "skip";
}
export interface RetryContext {
task: string;
output: string;
iter: number;
maxIter: number;
toolResults?: string[];
/**
* S-RETRY-WIRE: snapshot "noto buono" del codice per antiRewriteGuard.
* Se fornito, validateGate rileva rewrite/incompletezza/import injection
* e inietta il retryHint chirurgico nel prompt del retry.
*/
referenceCode?: string;
}
export function decideRetry(ctx: RetryContext): RetryDecision {
// Never retry near the iteration ceiling
if (ctx.iter >= ctx.maxIter - 2) {
return { shouldRetry: false, reason: "limite iterazioni raggiunto", priority: "skip" };
}
// S-RETRY-WIRE: validateGate sostituisce validateOutput.
// referenceCode attiva auditOutput() → hint chirurgico anti-rewrite/incompletezza/injection.
const gate = validateGate(ctx.output, {
taskHint: ctx.task,
referenceCode: ctx.referenceCode,
});
// "accept" e "repaired" → nessun retry necessario
if (gate.verdict === "accept" || gate.verdict === "repaired") {
return { shouldRetry: false, reason: "output valido", priority: "skip" };
}
const issueStr = gate.issues.join(", ");
// S-RETRY-WIRE: retryHint del gate contiene già i constraint chirurgici
// (NON riscrivere / Includi tutte le classi / Non introdurre deps esterne).
// IMPORTANT: non menzionare mai "la risposta precedente" — istruzione interna pura.
let augmentedPrompt = gate.retryHint
? gate.retryHint + " Rispondi in modo preciso e completo. Fornisci direttamente la risposta corretta senza meta-commenti."
: "Rispondi alla domanda dell'utente in modo preciso e completo. Non commentare eventuali problemi precedenti.";
if (ctx.toolResults && ctx.toolResults.length > 0) {
const dataStr = ctx.toolResults.slice(0, 3).join("\n\n");
augmentedPrompt += ` Usa questi dati reali già disponibili:\n${dataStr}`;
} else {
augmentedPrompt += " Sii accurato, completo e in italiano.";
}
const shouldRetry = gate.verdict === "retry" || gate.verdict === "reject";
return {
shouldRetry,
reason: issueStr,
augmentedPrompt,
priority: gate.quality < 2 ? "immediate" : "deferred",
};
}
/** Quick check: should this output trigger a retry? */
export function shouldRetry(output: string, task?: string): boolean {
const gate = validateGate(output, { taskHint: task });
return gate.verdict === "retry" || gate.verdict === "reject";
}