refactor(disambiguation): extract F3 rewrite path (#26)
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const { createDisambiguationGate } = require("../disambiguation/index.js");
|
||||
const { createFakePi } = require("./fake_pi_runtime.js");
|
||||
|
||||
|
||||
function setupRewrite({ phase = 3, failAt } = {}) {
|
||||
const { pi, ctx, tools } = createFakePi();
|
||||
const calls = [];
|
||||
const error = (message) => ({ content: [{ type: "text", text: message }] });
|
||||
const gate = createDisambiguationGate({
|
||||
workflow: {
|
||||
activate: () => calls.push(["activate"]),
|
||||
phase: () => {
|
||||
calls.push(["phase"]);
|
||||
return { number: phase, id: `F${phase}` };
|
||||
},
|
||||
advance: (_ctx, session, current) => {
|
||||
calls.push(["advance", session, current]);
|
||||
return failAt === "advance" ? { err: error("advance failed") } : { finalized: false };
|
||||
},
|
||||
},
|
||||
session: {
|
||||
mutate: (_ctx, args) => {
|
||||
calls.push(["session", ...args]);
|
||||
return failAt === "session" ? error("question write failed") : null;
|
||||
},
|
||||
},
|
||||
ledger: {
|
||||
record: (_ctx, session, decision) => {
|
||||
calls.push(["ledger", session, decision]);
|
||||
return failAt === "ledger" ? error("ledger write failed") : null;
|
||||
},
|
||||
},
|
||||
toTextResult: (text) => ({ content: [{ type: "text", text }] }),
|
||||
});
|
||||
gate.install(pi);
|
||||
return { ctx, tools, calls };
|
||||
}
|
||||
|
||||
|
||||
for (const resumed of [false, true]) {
|
||||
test(`the Disambiguation facade rewrites and closes F3 in order (${resumed ? "resume" : "new"})`, async () => {
|
||||
const { ctx, tools, calls } = setupRewrite();
|
||||
ctx.resumed = resumed;
|
||||
|
||||
const result = await tools.get("rewrite_question").def.execute(
|
||||
`rewrite-${resumed}`,
|
||||
{
|
||||
session: "s1",
|
||||
question: "pazienti con ablazione",
|
||||
assumptions: resumed ? '["anno 2025"]' : ["anno 2025"],
|
||||
},
|
||||
null,
|
||||
null,
|
||||
ctx,
|
||||
);
|
||||
|
||||
assert.deepEqual(calls, [
|
||||
["activate"],
|
||||
["phase"],
|
||||
[
|
||||
"session", "set-question", "s1", "--question", "pazienti con ablazione",
|
||||
"--assumption", "anno 2025",
|
||||
],
|
||||
[
|
||||
"ledger", "s1", {
|
||||
type: "question_rewritten",
|
||||
subject: "domanda",
|
||||
detail: "pazienti con ablazione",
|
||||
},
|
||||
],
|
||||
["advance", "s1", 3],
|
||||
]);
|
||||
assert.match(result.content[0].text, /Fase 3 completata/);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
test("the Disambiguation facade preserves a non-JSON assumption as one item", async () => {
|
||||
const { ctx, tools, calls } = setupRewrite();
|
||||
|
||||
await tools.get("rewrite_question").def.execute(
|
||||
"rewrite-assumption",
|
||||
{ session: "s1", question: "q", assumptions: "assunzione libera" },
|
||||
null,
|
||||
null,
|
||||
ctx,
|
||||
);
|
||||
|
||||
assert.deepEqual(calls[2], [
|
||||
"session", "set-question", "s1", "--question", "q",
|
||||
"--assumption", "assunzione libera",
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
test("the Disambiguation facade refuses rewrite outside F3 before mutations", async () => {
|
||||
const { ctx, tools, calls } = setupRewrite({ phase: 4 });
|
||||
|
||||
const result = await tools.get("rewrite_question").def.execute(
|
||||
"rewrite-outside",
|
||||
{ session: "s1", question: "q" },
|
||||
null,
|
||||
null,
|
||||
ctx,
|
||||
);
|
||||
|
||||
assert.deepEqual(calls, [["activate"], ["phase"]]);
|
||||
assert.match(result.content[0].text, /solo in Fase 3/);
|
||||
});
|
||||
|
||||
|
||||
for (const [failAt, expectedCalls, errorPattern] of [
|
||||
["session", ["activate", "phase", "session"], /question write failed/],
|
||||
["ledger", ["activate", "phase", "session", "ledger"], /ledger write failed/],
|
||||
["advance", ["activate", "phase", "session", "ledger", "advance"], /advance failed/],
|
||||
]) {
|
||||
test(`the Disambiguation facade stops F3 after a ${failAt} failure`, async () => {
|
||||
const { ctx, tools, calls } = setupRewrite({ failAt });
|
||||
|
||||
const result = await tools.get("rewrite_question").def.execute(
|
||||
`rewrite-${failAt}`,
|
||||
{ session: "s1", question: "q", assumptions: [] },
|
||||
null,
|
||||
null,
|
||||
ctx,
|
||||
);
|
||||
|
||||
assert.deepEqual(calls.map(([kind]) => kind), expectedCalls);
|
||||
assert.match(result.content[0].text, errorPattern);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user