feat: surface answer impact after update

This commit is contained in:
2026-08-03 19:11:32 +01:00
parent 3a83944006
commit 007f5ac286
+90 -2
View File
@@ -250,6 +250,89 @@ function LoadingOverlay({ isLoading, elapsed, currentMessage, variant }) {
);
}
// ── Update acknowledgement ────────────────────────────────────
function UpdateAcknowledgement({ answer, updateResult }) {
if (!updateResult || !answer?.trim()) return null;
const hasResolvedNodes =
updateResult.resolvedUnknownNodeIds && updateResult.resolvedUnknownNodeIds.length > 0;
const hasAffectedNodes =
updateResult.affectedNodeIds && updateResult.affectedNodeIds.length > 0;
const graph = updateResult.updatedSituationGraph;
function getNodeText(nodeId) {
if (!graph?.nodes) return String(nodeId);
const node = graph.nodes.find((n) => n.id === nodeId);
if (node) {
const parts = [node.label];
if (node.status !== "resolved") {
parts.push(node.status);
}
return parts.join(" ");
}
return String(nodeId);
}
let changedText;
if (hasResolvedNodes || hasAffectedNodes) {
const items = [];
if (hasResolvedNodes) {
for (const id of updateResult.resolvedUnknownNodeIds.slice(0, 5)) {
items.push(getNodeText(id));
}
if (updateResult.resolvedUnknownNodeIds.length > 5) {
items.push(`and ${updateResult.resolvedUnknownNodeIds.length - 5} more resolved`);
}
}
if (hasAffectedNodes && !hasResolvedNodes) {
for (const id of updateResult.affectedNodeIds.slice(0, 5)) {
items.push(getNodeText(id));
}
if (updateResult.affectedNodeIds.length > 5) {
items.push(`and ${updateResult.affectedNodeIds.length - 5} more affected`);
}
}
if (items.length === 0 && updateResult.changesApplied) {
const parts = [];
const ca = updateResult.changesApplied;
if (ca.addedNodeCount) parts.push(`${ca.addedNodeCount} node(s) added`);
if (ca.updatedNodeCount) parts.push(`${ca.updatedNodeCount} node(s) updated`);
if (ca.resolvedUnknownCount) parts.push(`${ca.resolvedUnknownCount} unknown(s) resolved`);
changedText = parts.join(", ");
} else {
changedText = items.join(". ") + ".";
}
} else if (updateResult.changesApplied) {
const ca = updateResult.changesApplied;
const parts = [];
if (ca.addedNodeCount) parts.push(`${ca.addedNodeCount} node(s) added`);
if (ca.updatedNodeCount) parts.push(`${ca.updatedNodeCount} node(s) updated`);
if (ca.addedEdgeCount) parts.push(`${ca.addedEdgeCount} edge(s) added`);
if (ca.removedEdgeCount) parts.push(`${ca.removedEdgeCount} edge(s) removed`);
changedText = parts.length > 0 ? parts.join(", ") : null;
}
const summary = updateResult.summary || null;
const displayChanged = summary || changedText || "Your answer has been added to the investigation.";
return (
<div className="rounded-lg border border-blue-200 bg-blue-50 px-5 py-4 space-y-3">
<div>
<h3 className="mb-1 text-xs font-medium uppercase tracking-wide text-blue-700">
You told us
</h3>
<p className="text-sm leading-relaxed text-blue-900">{answer}</p>
</div>
<div>
<h3 className="mb-1 text-xs font-medium uppercase tracking-wide text-blue-700">
What changed
</h3>
<p className="text-sm leading-relaxed text-blue-900">{displayChanged}</p>
</div>
</div>
);
}
// ── Developer details disclosure ──────────────────────────────
function DeveloperDetails({ graph, selectedQuestion, diagnostics, newlySurfacedNodeIds, updateResult }) {
return (
@@ -340,11 +423,16 @@ export default function ReasoningWorkspace({
</div>
) : (
<>
{/* Completion or holding state (only when there is no next question) */}
{/* ── Post-update acknowledgement ─────────────── */}
{updateStatus === "success" && graph && (
<UpdateAcknowledgement answer={answer} updateResult={result} />
)}
{/* Completion state (only when there is no next question and nothing remains) */}
{status === "success" && !canAnswer && graph && genuineCompletion && (
<InvestigationCompleteMessage noQuestionReason={noQuestionReason} />
)}
{status === "success" && !canAnswer && graph && unresolvedRemaining && (
{status === "success" && !canAnswer && graph && unresolvedRemaining && updateStatus !== "success" && (
<div className="rounded-lg border border-gray-200 bg-gray-50 px-5 py-4 text-center">
<p className="text-sm text-gray-600">There is no further question the engine can justify at the moment.</p>
<p className="mt-1 text-xs text-gray-500">More evidence may be needed before a next step is clear.</p>