feat: prioritise follow-up questions by information value

This commit is contained in:
2026-08-02 11:11:55 +01:00
parent 72ef175971
commit 392564ed61
7 changed files with 902 additions and 235 deletions
+80 -5
View File
@@ -582,14 +582,89 @@ describe("lib/graph/orchestrator startCase", () => {
});
expect(result.success).toBe(true);
expect(result.selectedQuestion).toEqual({
nodeId: "n-commercial-value",
question: "How should commercial value be defined for this decision?",
reason: "Consequential unresolved uncertainty remains.",
});
expect(result.selectedQuestion?.nodeId).toBe("n-commercial-value");
expect(result.newActiveUnknownNodeId).toBe("n-commercial-value");
});
it("deterministically prioritises customer value over pricing follow-up", async () => {
const { updateCase } = await import("@/lib/graph/orchestrator.js");
const provider = {
generateReconstruction: vi.fn().mockResolvedValue(
makeProposal({
addedNodes: [
makeNode({
id: "n-value",
label: "Customer value",
description:
"Need customer value because purchase decisions depend on it.",
kind: "unknown",
status: "unknown",
confidence: "high",
}),
makeNode({
id: "n-price",
label: "Target price point",
description:
"Need a target price point because revenue assumptions depend on it.",
kind: "unknown",
status: "unknown",
confidence: "medium",
dependsOn: ["n-value"],
}),
makeNode({
id: "n-decision",
label: "Build Confidence Engine decision",
description: "Decision introduced by the answer.",
kind: "state",
status: "supported",
confidence: "medium",
}),
],
addedEdges: [
{
id: "e-decision-value",
fromNodeId: "n-decision",
toNodeId: "n-value",
relationship: "depends_on",
confidence: "medium",
description: "The decision depends on customer value.",
},
{
id: "e-value-price",
fromNodeId: "n-value",
toNodeId: "n-price",
relationship: "depends_on",
confidence: "medium",
description: "Pricing depends on customer value.",
},
{
id: "e-decision-price",
fromNodeId: "n-decision",
toNodeId: "n-price",
relationship: "depends_on",
confidence: "low",
description: "The decision references pricing assumptions.",
},
],
selectedQuestion: {
nodeId: "n-price",
question: "What is the price point?",
reason: "Model chose pricing.",
},
}),
),
};
const result = await updateCase(makeUpdateRequest(), {
provider,
config: MOCK_CONFIG,
applyProposal: true,
});
expect(result.success).toBe(true);
expect(result.selectedQuestion?.nodeId).toBe("n-value");
});
it("defaults to proposal-only mode", async () => {
const { updateCase } = await import("@/lib/graph/orchestrator.js");
const applyValidatedProposal = vi.fn();