Spaces:
Sleeping
Sleeping
File size: 2,717 Bytes
95eb75a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | /**
* execReinjectBlock.ts — S496: extracted from agentLoop.ts
*
* S83: Exec loop closure gate — quando il tool di esecuzione dell'iterazione
* precedente ha prodotto output (exec/run_code/shell), riinietta l'output nel
* contesto per far analizzare al modello il risultato prima di procedere.
*
* Limita il numero di re-inject a MAX_EXEC_REINJECT per evitare loop infiniti
* su task di debug che non convergono.
*
* Restituisce { shouldContinue, newReinjectCount }:
* - shouldContinue=true → caller deve fare `continue` nel loop
* - shouldContinue=false → caller procede normalmente
*
* Muta loopMessages direttamente (by reference).
*
* @module execReinjectBlock
*/
import type { ApiMsg } from "./networkTools";
import { MAX_EXEC_REINJECT } from "./toolGate";
import { buildExecReinjectMessage } from "./execLoopGate"; // S501: usa modulo estratto invece di inline
export interface ExecReinjectCtx {
lastExecResultIter: number;
execReinjectCount: number;
iter: number;
candidateText: string;
lastExecTool: string;
lastExecOutput: string;
loopMessages: ApiMsg[];
onStatus: (msg: string) => void;
/** eventRuntime.emit — passato come callback per evitare import circolare */
emitEvent: (evt: Record<string, unknown>) => void;
}
export interface ExecReinjectResult {
shouldContinue: boolean;
newReinjectCount: number;
}
export function processExecReinject(ctx: ExecReinjectCtx): ExecReinjectResult {
const {
lastExecResultIter, execReinjectCount, iter, candidateText,
lastExecTool, lastExecOutput, loopMessages, onStatus, emitEvent,
} = ctx;
// Gate: solo se il tool di exec è stato chiamato nell'iterazione precedente
if (
lastExecResultIter !== iter - 1 ||
execReinjectCount >= MAX_EXEC_REINJECT ||
candidateText.includes("RISULTATO FINALE") ||
candidateText.toLowerCase().includes("task completat") ||
candidateText.toLowerCase().includes("compito completat")
) {
return { shouldContinue: false, newReinjectCount: execReinjectCount };
}
const newCount = execReinjectCount + 1;
onStatus(`Analisi output esecuzione... (loop ${newCount}/${MAX_EXEC_REINJECT})`);
// S501: usa buildExecReinjectMessage da execLoopGate.ts (modulo estratto, ora wired)
loopMessages.push({ role: "user", content: buildExecReinjectMessage(lastExecTool, lastExecOutput) } as ApiMsg);
emitEvent({
kind: "exec_loop_reinject",
taskId: `loop-${iter}-${newCount}`,
tool: lastExecTool,
reinjectCount: newCount,
outputSnippet: lastExecOutput.slice(0, 120),
});
return { shouldContinue: true, newReinjectCount: newCount };
}
|