feat: add one-turn situation graph update UI

This commit is contained in:
2026-08-02 09:43:42 +01:00
parent a948910ba8
commit a9bce79658
11 changed files with 901 additions and 42 deletions
+54
View File
@@ -280,6 +280,60 @@ describe("applyValidatedProposal", () => {
expect(result.updatedSituationGraph.resolvedNodeIds).toContain(
ids.complaintRateUnknown,
);
expect(
result.updatedSituationGraph.nodes.find(
(node) => node.id === ids.complaintRateUnknown,
)?.status,
).toBe("resolved");
});
it("rejects resolvedUnknownNodeIds that do not reference actual unknown nodes", () => {
const { graph, proposal, ids } = makeApplicationFixture();
const result = applyValidatedProposal({
situationGraph: graph,
proposal: {
...proposal,
resolvedUnknownNodeIds: [ids.qualityDeterioration],
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).toContain(
"Resolved unknown must reference an existing unknown node",
);
});
it("rejects a duplicate semantic node without resolution", () => {
const { graph, proposal } = makeApplicationFixture();
const result = applyValidatedProposal({
situationGraph: graph,
proposal: {
...proposal,
resolvedUnknownNodeIds: [],
updatedNodes: proposal.updatedNodes.filter(
(update) => update.nodeId !== "n-complaint-rate-unknown",
),
addedNodes: [
makeNode({
id: "n-parallel-rate",
label: "Complaint rate",
description: "Need the complaint rate per 100 units",
kind: "observation",
status: "supported",
confidence: "medium",
}),
],
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).toContain(
"duplicating unresolved unknown meaning",
);
});
it("keeps the active unknown when it remains unresolved", () => {
+7 -6
View File
@@ -13,9 +13,9 @@ function makeAnalysisResult(overrides = {}) {
return {
success: true,
validationStatus: "valid",
modelName: "llama3",
modelName: "configured-model",
responseDurationMs: 321,
rawResponse: "{}",
rawResponse: undefined,
promptVersion: "v0.3",
reconstruction: {
summary: "Revenue and complaints diverge",
@@ -164,7 +164,7 @@ describe("lib/graph/orchestrator startCase", () => {
expect(result.situationGraph.currentSummary).toContain("Nodes:");
expect(result.diagnostics).toMatchObject({
validationStatus: "valid",
modelName: "llama3",
modelName: "configured-model",
graphReferenceValidation: { valid: true, errors: [] },
});
});
@@ -208,7 +208,7 @@ describe("lib/graph/orchestrator startCase", () => {
error: "Provider unavailable",
errors: ["socket hang up"],
rawResponse: null,
modelName: "llama3",
modelName: "configured-model",
responseDurationMs: 99,
promptVersion: "v0.3",
validationStatus: "invalid",
@@ -279,8 +279,9 @@ describe("lib/graph/orchestrator startCase", () => {
diagnostics: {
promptVersion: "v0.4",
modelName: "configured",
graphNodeCount: 2,
graphEdgeCount: 0,
nodeCount: 2,
edgeCount: 0,
validationStatus: "valid",
},
});
expect(provider.generateReconstruction).toHaveBeenCalledTimes(1);