fix: let the learner retry a turn whose model call failed

This commit is contained in:
Evangelos Stavropoulos
2026-10-26 14:31:51 +02:00
parent 3dc88472ee
commit a572675900
4 changed files with 330 additions and 2 deletions
+15 -2
View File
@@ -65,9 +65,11 @@ import {
type CompactionDividerData,
} from "@/components/compaction-divider";
import { CoverageRing } from "@/components/extraction-coverage";
import { Button } from "@/components/ui/button";
import {
activeProblemOf,
dismissedAnswer,
endsInFailedTurn,
findPendingToolCall,
phaseAt3,
phaseTimeline,
@@ -458,6 +460,12 @@ export function Chat({
const busy = localStream || turnInFlight;
const busyRef = useRef(busy);
busyRef.current = busy;
// A failed model call (issue #110): the banner offers Retry, which
// re-runs the turn from the saved input — the only path back, since an
// answered question cannot be answered again. Offered from "error" too:
// a dropped stream leaves the model there, and send() recovers from it.
const retryable = (status === "ready" || status === "error") && !busy && endsInFailedTurn(nativeMessages);
const retryFailedTurn = () => void send({ type: "retry" });
// The attach handoff (stream-reattach wave): the moment a resumed
// stream takes over the rendering — the SDK left "ready", so
@@ -1577,8 +1585,13 @@ export function Chat({
</span>
)}
{error && (
<div className="rounded-lg border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm">
Something went wrong: {error.message}
<div className="flex items-center justify-between gap-3 rounded-lg border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm">
<span>Something went wrong: {error.message}</span>
{retryable && (
<Button variant="outline" size="xs" data-testid="retry-failed-turn" onClick={retryFailedTurn}>
Retry
</Button>
)}
</div>
)}
</div>