feat: apply validated graph update proposals
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { validateGraphReferences } from "@/lib/graph/utils.js";
|
||||
import { makeGraph, makeNode } from "@/lib/graph/schema.js";
|
||||
|
||||
const mockAnalyseScenario = vi.fn();
|
||||
@@ -526,4 +527,123 @@ describe("lib/graph/orchestrator startCase", () => {
|
||||
expect(result.nextQuestion).toBeUndefined();
|
||||
expect(result.proposal.nextQuestion).toBeUndefined();
|
||||
});
|
||||
|
||||
it("defaults to proposal-only mode", async () => {
|
||||
const { updateCase } = await import("@/lib/graph/orchestrator.js");
|
||||
const applyValidatedProposal = vi.fn();
|
||||
const provider = {
|
||||
generateReconstruction: vi.fn().mockResolvedValue(makeProposal()),
|
||||
};
|
||||
|
||||
const result = await updateCase(makeUpdateRequest(), {
|
||||
provider,
|
||||
config: MOCK_CONFIG,
|
||||
applyValidatedProposal,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.stage).toBe("proposal_ready");
|
||||
expect(applyValidatedProposal).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("applies the proposal only when explicitly enabled", async () => {
|
||||
const { updateCase } = await import("@/lib/graph/orchestrator.js");
|
||||
const request = makeUpdateRequest({
|
||||
situationGraph: makeGraph({
|
||||
centralStatement:
|
||||
"Complaint counts increased while production also increased.",
|
||||
nodes: [
|
||||
makeNode({
|
||||
id: "n-rate",
|
||||
label: "Complaint rate",
|
||||
description: "Need complaint rate",
|
||||
kind: "unknown",
|
||||
status: "unknown",
|
||||
confidence: "high",
|
||||
affects: ["n-conclusion"],
|
||||
}),
|
||||
makeNode({
|
||||
id: "n-other-unknown",
|
||||
label: "Other unknown",
|
||||
description: "Another unresolved unknown",
|
||||
kind: "unknown",
|
||||
status: "unknown",
|
||||
confidence: "medium",
|
||||
}),
|
||||
makeNode({
|
||||
id: "n-conclusion",
|
||||
label: "Quality deterioration",
|
||||
description: "Quality conclusion",
|
||||
kind: "conclusion",
|
||||
status: "supported",
|
||||
confidence: "medium",
|
||||
dependsOn: ["n-rate"],
|
||||
}),
|
||||
],
|
||||
edges: [],
|
||||
activeUnknownNodeId: "n-rate",
|
||||
resolvedNodeIds: [],
|
||||
currentSummary: "Initial summary",
|
||||
}),
|
||||
});
|
||||
const provider = {
|
||||
generateReconstruction: vi.fn().mockResolvedValue({
|
||||
addedNodes: [],
|
||||
updatedNodes: [
|
||||
{
|
||||
nodeId: "n-rate",
|
||||
previousStatus: "unknown",
|
||||
newStatus: "resolved",
|
||||
previousValue: "2.0 complaints per 100 units",
|
||||
newValue: "1.9 complaints per 100 units",
|
||||
reason: "The answer provides the updated rate.",
|
||||
},
|
||||
{
|
||||
nodeId: "n-conclusion",
|
||||
previousStatus: "supported",
|
||||
newStatus: "weakened",
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
reason: "The updated rate weakens the conclusion.",
|
||||
},
|
||||
],
|
||||
addedEdges: [],
|
||||
removedEdgeIds: [],
|
||||
resolvedUnknownNodeIds: ["n-rate"],
|
||||
affectedNodeIds: ["n-conclusion"],
|
||||
}),
|
||||
};
|
||||
|
||||
const result = await updateCase(request, {
|
||||
provider,
|
||||
config: MOCK_CONFIG,
|
||||
applyProposal: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
success: true,
|
||||
stage: "update_applied",
|
||||
affectedNodeIds: expect.arrayContaining(["n-rate", "n-conclusion"]),
|
||||
resolvedUnknownNodeIds: ["n-rate"],
|
||||
previousActiveUnknownNodeId: "n-rate",
|
||||
newActiveUnknownNodeId: "n-other-unknown",
|
||||
});
|
||||
expect(validateGraphReferences(result.updatedSituationGraph)).toEqual({
|
||||
valid: true,
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it("startCase behaviour remains unchanged", async () => {
|
||||
mockAnalyseScenario.mockResolvedValue(makeAnalysisResult());
|
||||
const { startCase } = await import("@/lib/graph/orchestrator.js");
|
||||
|
||||
const result = await startCase({ scenario: "Scenario text" });
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.selectedQuestion).toEqual({
|
||||
id: "q-1",
|
||||
question: "What denominator is being used for the complaint rate?",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user