Repository navigation
Conversation
Claude Code retries a failed API request itself (dropped connection, rate limit, overload) and prints system/api_retry for each attempt. The adapter dropped those lines, so a network outage looked like a turn that froze on "working" for minutes. Show one keyed status row naming the cause and the attempt, updated in place, and remove it once the request produces output, the turn ends, the session stops, or the process exits.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Refs #852 (one of the ways a long turn looks stuck).
What changed
apiRetryStatusTextinclaudeProtocol.tsmaps Claude Code'ssystem/api_retryline to a short status:Connection error · retrying (7/10)…,API overloaded · …,Rate limited · …,No response from the API · …orAPI error 500 · ….claude-api-retry), so each retry updates the same row instead of adding new ones, and removes the row as soon as the request produces output, the turn ends, the session stops, or the process exits. It uses the existing keyed-status support inapply.ts, where empty text removes the row.Why
When an API request fails, Claude Code retries it on its own (up to
max_retries, with backoff) and reports every attempt on stdout as{"type":"system","subtype":"api_retry","attempt":7,"max_retries":10,"error_status":null,…}. The adapter ignored these lines, so a dropped connection or an overloaded API showed nothing but the "working" timer for minutes, which looks the same as a hung turn. That is part of what #852 describes ("working vs stuck is impossible to tell"). The Claude Code terminal shows these retries; this shows them in the session too.UI
One system row in the turn while retries are happening, for example
Connection error · retrying (2/10)…. It updates in place and disappears once the reply starts streaming. Nothing changes when there are no retries.Validation
apiRetryStatusTextcases inclaudeProtocol.test.ts, and aclaudeLive.test.tscase where two retries are followed by output. It checks that the row is shown, updated, and then cleared exactly once. All three fail onmain.npm run check:web: vitest (5287 passed, 13 skipped) andtsc --noEmit. No Rust changes.Checklist
npm run check(check:web; no Rust files changed)Summary by CodeRabbit