refactor(disambiguation): own F1 clarification policy (#27)
This commit is contained in:
@@ -14,6 +14,108 @@ function normalizedAssumptions(assumptions) {
|
||||
}
|
||||
|
||||
|
||||
function prepareClarificationArguments(input) {
|
||||
if (!input || typeof input !== "object") return input;
|
||||
const args = { ...input };
|
||||
if (typeof args.options === "string") {
|
||||
try {
|
||||
const parsed = JSON.parse(args.options);
|
||||
if (Array.isArray(parsed)) args.options = parsed;
|
||||
} catch {
|
||||
// Preserve non-JSON input for the TypeBox/tool validation path.
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
function decisionRecordedText(decision, option) {
|
||||
return (
|
||||
`Decisione registrata (${decision.type}): ${option.label}. ` +
|
||||
"Ora rileggi lo stato persistito con `tht session show` e invoca immediatamente " +
|
||||
"il prossimo tool reviewer_ richiesto dal workflow. " +
|
||||
"Non scrivere analisi o spiegazioni visibili."
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function validateClarificationOptions(ctx, options, session, workflow) {
|
||||
const known = workflow.decisionTypes(ctx);
|
||||
if (!known) return null;
|
||||
for (const option of options) {
|
||||
if (option.decision && !known.has(option.decision.type)) {
|
||||
return (
|
||||
`Tipo di decisione '${option.decision.type}' non valido. Tipi ammessi: ` +
|
||||
`${[...known].join(", ")}. Correggi e riprova.`
|
||||
);
|
||||
}
|
||||
}
|
||||
const current = workflow.phase(ctx, session).number;
|
||||
const minimumPhases = workflow.decisionMinimumPhases(ctx);
|
||||
for (const option of options) {
|
||||
const type = option.decision?.type;
|
||||
if (type && minimumPhases[type] && minimumPhases[type] > current) {
|
||||
return (
|
||||
`Tipo '${type}' ammesso dalla Fase ${minimumPhases[type]}, ` +
|
||||
`sessione alla Fase ${current}. Chiudi prima la fase corrente.`
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function prepareClarification(
|
||||
ctx,
|
||||
params,
|
||||
id,
|
||||
{ workflow, reviewer, toTextResult },
|
||||
) {
|
||||
const { session, title, options, intro, advance } = params;
|
||||
const validationError = validateClarificationOptions(ctx, options, session, workflow);
|
||||
if (validationError) return { result: toTextResult(validationError) };
|
||||
const phase = workflow.describe(ctx, session);
|
||||
const recommended = options.find((option) => option.recommended)?.id ?? null;
|
||||
return {
|
||||
session,
|
||||
options,
|
||||
advance,
|
||||
widget: reviewer.buildSelect({
|
||||
id,
|
||||
phase,
|
||||
title,
|
||||
intro: intro ?? null,
|
||||
recommended,
|
||||
options: options
|
||||
.filter((option) => !reviewer.isReserved(option.label))
|
||||
.map((option) => ({ id: option.id, label: option.label })),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function resolveClarification(prepared, response) {
|
||||
if (response?.control === "freetext") {
|
||||
return { text: `Altro (reviewer): ${response.text}` };
|
||||
}
|
||||
if (response?.control === "back") {
|
||||
return { text: "Il reviewer vuole tornare indietro." };
|
||||
}
|
||||
if (response?.control === "exit") {
|
||||
return { text: "Il reviewer vuole uscire." };
|
||||
}
|
||||
const choice = Array.isArray(response?.choices) ? response.choices[0] : response?.choice;
|
||||
const option = (prepared.options || []).find((candidate) => candidate.id === choice) || null;
|
||||
if (option?.decision) {
|
||||
return {
|
||||
decision: option.decision,
|
||||
text: decisionRecordedText(option.decision, option),
|
||||
};
|
||||
}
|
||||
return { text: `Scelta del reviewer: ${option ? option.label : choice}` };
|
||||
}
|
||||
|
||||
|
||||
function installDisambiguationGate(
|
||||
pi,
|
||||
{ workflow, session, ledger, toTextResult },
|
||||
@@ -73,5 +175,9 @@ function installDisambiguationGate(
|
||||
export function createDisambiguationGate(dependencies) {
|
||||
return {
|
||||
install: (pi) => installDisambiguationGate(pi, dependencies),
|
||||
prepareClarificationArguments,
|
||||
prepareClarification: (ctx, params, id) =>
|
||||
prepareClarification(ctx, params, id, dependencies),
|
||||
resolveClarification,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user