fix: clarify terminal investigation states

This commit is contained in:
2026-08-04 18:10:06 +01:00
parent 55ed4da69a
commit f703fdc842
2 changed files with 82 additions and 83 deletions
+53 -44
View File
@@ -25,11 +25,35 @@ function isTechnicalSummary(summary) {
return false;
}
// ── Current understanding card ────────────────────────────────
// Evidence-limit text that must not appear inside Current understanding
// when the terminal outcome already communicates that state.
const EVIDENCE_LIMIT_PHRASES = [
"The available evidence has reached its current limit",
"evidence has reached its current limit",
"evidence limit reached",
"has reached its current limit",
];
function resolveCurrentSummary(currentSummary) {
if (isTechnicalSummary(currentSummary)) {
return null;
if (!currentSummary || typeof currentSummary !== "string") return null;
const trimmed = currentSummary.trim();
if (!trimmed) return null;
// Filter out technical graph summaries
for (const p of TECHNICAL_PATTERNS) {
if (p.test(trimmed)) return null;
}
return currentSummary || null;
// Don't show evidence-limit text in Current understanding when
// the terminal outcome card already communicates that state.
const lower = trimmed.toLowerCase();
for (const phrase of EVIDENCE_LIMIT_PHRASES) {
if (lower.includes(phrase)) return null;
}
return trimmed;
}
// ── Status message pools for loading feedback ────────────────
@@ -139,24 +163,17 @@ function CompletionCard() {
return (
<div className="rounded-lg border border-green-300 bg-green-50 px-5 py-6 text-center">
<h2 className="mb-1 text-sm font-bold uppercase tracking-wide text-green-700">Investigation complete</h2>
<p className="text-base text-gray-800">You have provided enough information. The situation has been fully investigated.</p>
<p className="text-base text-gray-800">The current investigation has reached a justified conclusion.</p>
</div>
);
}
// ── Evidence exhaustion card (terminal state) ─────────────────
function EvidenceExhaustedCard({ noQuestionReason }) {
let message = "There is not yet enough evidence to guide the next step.";
if (noQuestionReason) {
const reason = String(noQuestionReason);
if (reason.toLowerCase().includes("insufficient")) {
message = reason;
}
}
// ── Evidence-limit card (terminal state: no next question) ───────
function EvidenceLimitCard() {
return (
<div className="rounded-lg border border-gray-200 bg-gray-50 px-5 py-6 text-center">
<h2 className="mb-1 text-sm font-bold uppercase tracking-wide text-gray-500">Further investigation needed</h2>
<p className="text-base text-gray-700">{message}</p>
<h2 className="mb-1 text-sm font-bold uppercase tracking-wide text-gray-500">Current evidence limit reached</h2>
<p className="text-base text-gray-700">Further progress requires additional evidence.</p>
</div>
);
}
@@ -432,8 +449,6 @@ export default function ReasoningWorkspace({
const graph = result?.situationGraph ?? null;
const diagnostics = result?.diagnostics ?? null;
const newlySurfacedNodeIds = result?.newlySurfacedNodeIds || [];
const noQuestionReason = diagnostics?.noQuestionReason ?? null;
const genuineCompletion = hasGenuineCompletion(graph);
return (
@@ -457,28 +472,34 @@ export default function ReasoningWorkspace({
{/* ── No graph produced after initial analysis ───────── */}
{(status === "success" || status === "error") && !graph ? (
<div className="rounded-lg border border-yellow-300 bg-yellow-50 px-4 py-3 text-sm text-yellow-800">
{noQuestionReason
{diagnostics?.noQuestionReason
? "Validation failed — no structured graph output was produced."
: "The analysis completed but did not produce a structured result."}
</div>
) : (
<>
{/* ── 1. Current investigation (or terminal state) ─ */}
{canAnswer && <CurrentInvestigationCard selectedQuestion={selectedQ} graph={graph} />}
{/* ── 1. Terminal state: outcome card (no active question) ─ */}
{status === "success" && !canAnswer && graph && !isUpdating && genuineCompletion && <CompletionCard />}
{status === "success" && !canAnswer && graph && !isUpdating && !genuineCompletion && <EvidenceLimitCard />}
{/* Terminal states occupy the hero position when no question */}
{status === "success" && !canAnswer && graph && genuineCompletion && (
<CompletionCard />
)}
{status === "success" && !canAnswer && graph && !genuineCompletion && updateStatus !== "success" && (
<EvidenceExhaustedCard noQuestionReason={noQuestionReason} />
)}
{/* ── 2. Current understanding (when meaningful) ─ */}
{(graph?.currentSummary || (status === "success" && !canAnswer)) && <CurrentUnderstandingCard currentSummary={graph.currentSummary} />}
{/* ── 2. Post-update acknowledgement ─────────────── */}
{updateStatus === "success" && canAnswer && <UpdateAcknowledgement updateResult={result} />}
{/* ── 3. Original situation (always-visible reference) ─ */}
<OriginalSituation scenario={scenario} centralStatement={graph?.centralStatement} />
{/* ── 3. Response form ───────────────────────────── */}
{/* ── 4. Investigation history ───────────────────── */}
{investigationHistory.length > 0 && <InvestigationHistory turns={investigationHistory} />}
{/* ── Active investigation: question + form + acknowledgement ─ */}
{canAnswer && (
<>
<CurrentInvestigationCard selectedQuestion={selectedQ} graph={graph} />
{/* Post-update acknowledgement */}
{updateStatus === "success" && <UpdateAcknowledgement updateResult={result} />}
{/* Response form */}
<form onSubmit={handleUpdateCaptureAndSubmit} className="space-y-4 rounded-lg border border-gray-200 bg-white p-5">
<div>
<label htmlFor="rw-answer" className="mb-2 block text-sm font-medium text-gray-700">
@@ -507,18 +528,10 @@ export default function ReasoningWorkspace({
</button>
</div>
</form>
</>
)}
{/* ── 4. Current understanding ───────────────────── */}
{canAnswer && graph && <CurrentUnderstandingCard currentSummary={graph.currentSummary} />}
{/* ── 5. Original situation (always-visible reference) ─ */}
<OriginalSituation scenario={scenario} centralStatement={graph?.centralStatement} />
{/* ── 6. Investigation history ───────────────────── */}
<InvestigationHistory turns={investigationHistory} />
{/* ── 7. Developer details (collapsed by default) ── */}
{/* ── 5. Developer details (collapsed by default) ── */}
{(status === "success" || status === "error") && graph && (
<DeveloperDetails
graph={graph}
@@ -528,10 +541,6 @@ export default function ReasoningWorkspace({
updateResult={updateStatus === "success" ? result : null}
/>
)}
{/* ── Terminal state with understanding (when no active question) ─ */}
{status === "success" && !canAnswer && graph && genuineCompletion && <CurrentUnderstandingCard currentSummary={graph.currentSummary} />}
{status === "success" && !canAnswer && graph && !genuineCompletion && updateStatus !== "success" && <CurrentUnderstandingCard currentSummary={graph.currentSummary} />}
</>
)}
-10
View File
@@ -3,8 +3,6 @@
import React, { useEffect } from "react";
import { useState, useRef, useMemo } from "react";
import DiagnosticsView from "@/components/diagnostics-view";
import GraphUpdateView from "@/components/graph-update-view";
import SituationGraphView from "@/components/situation-graph-view";
import ReasoningWorkspace, { LoadingOverlay } from "@/components/reasoning-workspace";
import { mockFetch } from "@/lib/mocks/confidence-engine/mock-client";
@@ -103,14 +101,6 @@ export function ScenarioResultPanels({ status, result }) {
</div>
)}
{(status === "success" || hasGraph || hasQuestion) && (
<SituationGraphView
situationGraph={result.situationGraph}
selectedQuestion={result.selectedQuestion}
newlySurfacedNodeIds={result.newlySurfacedNodeIds}
/>
)}
{hasDiagnostics && <DiagnosticsView result={result} />}
</>
);