fix: finalize session after memory promotion
This commit is contained in:
@@ -832,6 +832,24 @@ export default function (pi) {
|
||||
const curNum = currentPhase(ctx, session);
|
||||
const phase = phaseId(ctx, curNum);
|
||||
|
||||
// Sessione gia' finalizzata: non c'e' piu' nulla da approvare — mai
|
||||
// ripresentare il phase-gate (la form "approve") a workflow chiuso.
|
||||
if (kind === "phase" && curNum >= phaseMeta(ctx).max_phase) {
|
||||
try {
|
||||
const show = JSON.parse(tht(ctx, ["session", "show", session, "--json"]));
|
||||
if (show?.status === "finalized") {
|
||||
lockActive = false;
|
||||
return textResult(
|
||||
`La sessione ${session} e' gia' finalizzata: il workflow e' completo. ` +
|
||||
"Comunica al reviewer il riepilogo finale e termina il turno; NON " +
|
||||
"presentare altri gate reviewer_*.",
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
// show non leggibile: prosegui col gate normale
|
||||
}
|
||||
}
|
||||
|
||||
// --- v2 payload construction (WS2) -------------------------------------
|
||||
// The gate builds/validates the structured payload BEFORE showing the
|
||||
// widget, so the reviewer approves a deterministic artifact (not the raw
|
||||
@@ -948,26 +966,9 @@ export default function (pi) {
|
||||
return textResult("Il reviewer vuole uscire.");
|
||||
// outcome.kind === "approve" -> execute the privileged action via the CLI.
|
||||
if (kind === "phase") {
|
||||
// Explicit human approval: advance unconditionally except for unmet
|
||||
// prerequisites. Plain `phase advance` (no --auto) enforces advance_problems
|
||||
// and exits 6 with the missing items, which relayIfThtFails surfaces.
|
||||
const err = relayIfThtFails(
|
||||
ctx,
|
||||
["phase", "advance", "--session", session],
|
||||
PHASE_RECOVERY,
|
||||
);
|
||||
if (err) return err;
|
||||
// Auto-finalize after advancing the LAST phase: the model may not
|
||||
// follow through (token budget, turn end) leaving the session open.
|
||||
const meta = phaseMeta(ctx);
|
||||
if (curNum >= meta.max_phase) {
|
||||
const fErr = relayIfThtFails(
|
||||
ctx,
|
||||
["session", "finalize", session],
|
||||
"Fase approvata ma finalizzazione fallita: esegui manualmente " +
|
||||
`\`tht session finalize ${session}\`.`,
|
||||
);
|
||||
if (fErr) return fErr;
|
||||
const r = advancePhaseAndFinalize(ctx, session, curNum);
|
||||
if (r.err) return r.err;
|
||||
if (r.finalized) {
|
||||
lockActive = false;
|
||||
lastSteered = false;
|
||||
return textResult(
|
||||
@@ -1053,6 +1054,46 @@ export default function (pi) {
|
||||
},
|
||||
});
|
||||
|
||||
// Explicit human approval: advance unconditionally except for unmet
|
||||
// prerequisites. Plain `phase advance` (no --auto) enforces advance_problems
|
||||
// and exits 6 with the missing items, which relayIfThtFails surfaces.
|
||||
// Auto-finalize after advancing the LAST phase: the model may not follow
|
||||
// through (token budget, turn end) leaving the session open.
|
||||
function advancePhaseAndFinalize(ctx, session, curNum) {
|
||||
const err = relayIfThtFails(
|
||||
ctx,
|
||||
["phase", "advance", "--session", session],
|
||||
PHASE_RECOVERY,
|
||||
);
|
||||
if (err) return { err };
|
||||
if (curNum < phaseMeta(ctx).max_phase) return { finalized: false };
|
||||
const fErr = relayIfThtFails(
|
||||
ctx,
|
||||
["session", "finalize", session],
|
||||
"Fase approvata ma finalizzazione fallita: esegui manualmente " +
|
||||
`\`tht session finalize ${session}\`.`,
|
||||
);
|
||||
if (fErr) return { err: fErr };
|
||||
return { finalized: true };
|
||||
}
|
||||
|
||||
// La promozione memorie e' l'ultima interazione umana di F8: chiudere qui
|
||||
// (advance + finalize) evita il reviewer_confirm finale a workflow gia'
|
||||
// deciso (la form "approve" ridondante a fine sessione). Fuori dall'ultima
|
||||
// fase ritorna null e il chiamante mantiene il comportamento precedente.
|
||||
function closeAfterPromotion(ctx, session, curNum, summary) {
|
||||
if (curNum < phaseMeta(ctx).max_phase) return null;
|
||||
const r = advancePhaseAndFinalize(ctx, session, curNum);
|
||||
if (r.err) return r.err;
|
||||
lockActive = false;
|
||||
lastSteered = false;
|
||||
return textResult(
|
||||
`${summary} Fase ${curNum} approvata e sessione finalizzata (${session}): ` +
|
||||
"il workflow e' completo. Comunica al reviewer il riepilogo finale " +
|
||||
"della sessione e termina il turno; NON presentare altri gate reviewer_*.",
|
||||
);
|
||||
}
|
||||
|
||||
pi.registerTool({
|
||||
name: "reviewer_memory_promote",
|
||||
label: "Promozione memorie riusabili (reviewer)",
|
||||
@@ -1062,14 +1103,17 @@ export default function (pi) {
|
||||
"table_promoted/table_excluded, max 5, esclusi i gia' promossi/rifiutati). Le selezioni " +
|
||||
"vengono salvate nel vectordb (tht memory save-one) e registrate come memory_promoted; " +
|
||||
"le deselezioni come memory_promotion_declined (non riproposte). Nessun parametro oltre " +
|
||||
"alla sessione: i candidati sono deterministici, NON li scrivi tu.",
|
||||
"alla sessione: i candidati sono deterministici, NON li scrivi tu. Registrata la " +
|
||||
"promozione, in F8 il gate chiude la fase e finalizza la sessione da solo: NON " +
|
||||
"presentare un reviewer_confirm dopo.",
|
||||
parameters: Type.Object({
|
||||
session: Type.String(),
|
||||
}),
|
||||
async execute(_id, params, _signal, _onUpdate, ctx) {
|
||||
lockActive = true;
|
||||
const { session } = params;
|
||||
const phase = phaseId(ctx, currentPhase(ctx, session));
|
||||
const curNum = currentPhase(ctx, session);
|
||||
const phase = phaseId(ctx, curNum);
|
||||
let candidates;
|
||||
try {
|
||||
candidates = JSON.parse(
|
||||
@@ -1084,6 +1128,10 @@ export default function (pi) {
|
||||
"Nessuna decisione riusabile da promuovere in memoria per questa sessione.",
|
||||
"info",
|
||||
);
|
||||
const closed = closeAfterPromotion(
|
||||
ctx, session, curNum, "Nessun candidato di promozione.",
|
||||
);
|
||||
if (closed) return closed;
|
||||
return textResult(
|
||||
"Nessun candidato di promozione: prosegui con la chiusura della sessione.",
|
||||
);
|
||||
@@ -1128,10 +1176,12 @@ export default function (pi) {
|
||||
}), "");
|
||||
if (err) return err;
|
||||
}
|
||||
return textResult(
|
||||
const summary =
|
||||
`Promozione registrata: ${saved} memorie salvate nel vectordb, ` +
|
||||
`${decline.length} candidati scartati.`,
|
||||
);
|
||||
`${decline.length} candidati scartati.`;
|
||||
const closed = closeAfterPromotion(ctx, session, curNum, summary);
|
||||
if (closed) return closed;
|
||||
return textResult(summary);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user