Persist error/interrupt markers in history; add Retry on failed turns

Engine appends a display-only notice message on error/interrupted; providers never see it.
New retry frame re-runs a failed turn with no new user message, guarded on the error tail.
GUI renders persisted notices on reload and a Retry button on the trailing error.
This commit is contained in:
Rohit C Prasad
2026-07-22 13:45:43 -07:00
committed by Rohit P
parent d8903bc927
commit 878b858ece
12 changed files with 242 additions and 13 deletions
+9 -1
View File
@@ -280,9 +280,12 @@ interface Props {
running?: boolean;
// Sub-threshold streamed text (streamGate mode "quiet") — handed to the live turn group.
streamingText?: string;
// Re-run the failed turn (no new user message). Offered only on a retriable notice that
// is the transcript tail of an idle session — anywhere else the error is history.
onRetry?: () => void;
}
export function Transcript({ items, running, streamingText }: Props) {
export function Transcript({ items, running, streamingText, onRetry }: Props) {
// §33 grouping: a turn = the maximal run of assistant/tool/resolved-approval items between
// breakers (user, connector, notices, plan/dir requests…). Trailing assistant texts are the
// ANSWER and render as bubbles after the group; interior assistant texts are narration and
@@ -396,6 +399,11 @@ export function Transcript({ items, running, streamingText }: Props) {
return (
<div className={"notice " + (item.tone === "warn" ? "warn" : "")} key={bi}>
{item.text}
{item.retriable && !running && onRetry && block.i === items.length - 1 && (
<button className="btn ml-2" data-testid="notice-retry" onClick={onRetry}>
Retry
</button>
)}
</div>
);
default: