From 6e641102c6041e61da3ebd7efbfb41e9149f3758 Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Sat, 31 Oct 2026 18:56:13 +0100 Subject: [PATCH] feat(rhema-provider): the retry ladder follows the failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old ladder doubled from one second and capped at two: three attempts, three seconds — enough for a hiccup, nothing for a reassociation or a real outage. The policy now takes two explicit ladders and picks by error class. A dead link (Network) is the local machine's problem and waiting can fix it, so it walks 1s, 3s, 30s, 60s, 300s — six attempts, six and a half minutes all told. A struggling server (Timeout, 408, 5xx, an exchange that closed before any content) fixes itself in seconds or not at all inside a turn, and every timeout attempt also burns the request's own timeout, so its ladder stays at 1s and 2s. Each ladder's length sets its attempt count, so the policy can no longer disagree with itself. Each wait is announced as an Event::RetryWait (error, delay, attempt, total) before it runs. rhema-code carries it as a deadline and the status strip counts it down — the error in the alarm color, the attempt, the seconds left — while any event from the next attempt clears it. Esc still cancels mid-wait: the executor drops the future at the sleep. ACP, claw, subagents, and the cloud wire ignore the event; from_event returns Option now, so a frameless event sends no frame. The hosted frontends keep the short ladder on both classes: their invocation outlives no five-minute wait. --- crates/rhema-claw/src/interactive.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/rhema-claw/src/interactive.rs b/crates/rhema-claw/src/interactive.rs index 3a95100..52911df 100644 --- a/crates/rhema-claw/src/interactive.rs +++ b/crates/rhema-claw/src/interactive.rs @@ -661,6 +661,7 @@ impl EventSink for HubSink { | ModelEvent::ToolOutputDelta { .. } | ModelEvent::ToolStatus { .. } | ModelEvent::Usage(_) + | ModelEvent::RetryWait { .. } | ModelEvent::StepEnd { .. } => return, }; self.hub.emit(&self.key, turn);