feat(rhema-provider): the retry ladder follows the failure

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.
This commit is contained in:
vhaudiquet committed 2026-10-31 18:56:13 +01:00
1 parent 951430e44b
commit 6e641102c6
1 file changed
+1
+1
View File
@@ -661,6 +661,7 @@ impl EventSink for HubSink {
| ModelEvent::ToolOutputDelta { .. } | ModelEvent::ToolOutputDelta { .. }
| ModelEvent::ToolStatus { .. } | ModelEvent::ToolStatus { .. }
| ModelEvent::Usage(_) | ModelEvent::Usage(_)
| ModelEvent::RetryWait { .. }
| ModelEvent::StepEnd { .. } => return, | ModelEvent::StepEnd { .. } => return,
}; };
self.hub.emit(&self.key, turn); self.hub.emit(&self.key, turn);