Agent pane: a turn whose model can't be reached says so, not Thinking (acpmux turn_retrying)
Summary
Leo, 2026-11-03, on a chat that read "Thinking 7m 49s": "i feel like this mac session just keeps "thinking" but idk if tool calls are somehow being hidden or if that workspace itself/session itself under acpmux is kinda weird".
The chat was not thinking. Its model gateway was down, and Claude Code was retrying the request (system/api_retry, attempt 1..10, error_status, error, about 75 s apart). acpmux logged those lines but nothing the pane reads said so, so the live line kept reading "Thinking" with a clock that counted the retries.
- acpmux (
hub/turn_retry.rs): each harness retry of a failed model request logs a mux recordturn_retrying{turnId, attempt, maxRetries, error, errorStatus, retryDelayMs, source}. Sources: Claude Code'ssystem/api_retryline and Codex'ssession_info_update._meta.codex.errorwithwillRetry("Reconnecting... 2/5", HTTP status fromcodexErrorInfo). It is in thetranscriptcategory, so clients get it with no new subscription. The turn is marked silent, so the model's next sign logsturn_heard, which ends the retry. Documented in the README anddocs/acpmux-schema.json. - Agent pane:
direct.tskeeps the retry on a client-onlyTURN_RETRYrow (kindtyping, drawn by nothing).turns.tswithRetryputs it on the live line, andThinking.tsxthen reads "Can't reach the model 路 retrying (7 of 10) 路 503 server error", or "The model is busy" for 429/529 and rate-limit or overload errors. It is calm: no shimmer, no clock, the cause in text ink and the count and error muted, with the error the part that truncates. It uses the same.cv-workedbox, so nothing moves when it starts or ends. Once the model answers, the retries' time comes off the "Thinking" clock (before the first output, the clock times the turn from its prompt). - Given up: a retry that runs out still ends the turn failed, shown on the existing turn error card with Retry ("API Error: Connection error." reads as unreachable). That needed no change; the gallery shows it.
- The iPhone app already reads
claude.system.api_retry("Retrying (2 of 10, error 503)"), so this adds no parity gap.
Gallery: agent-pane.turn-retry, with variants retrying, retrying-with-error, retrying-busy and given-up. The mock daemon has the live scene at ?mock&session=mock-model-retry (seven turn_retrying records).
Testing
- acpmux, on fleet
cmux-ci test(Linux):cargo clippy -p acpmux --all-targets -D warningsis clean.cargo test -p acpmux --lib turn_retry(3 unit tests) passes.--test claude_stream_timingpasses; its newa_claude_api_retry_logs_turn_retrying_until_the_model_answersuses fake Claude'sapi-retry-probe.--test hub_integration -- retry silentpasses 44 tests, including the Codex retry test, which now assertsturn_retryingcomes beforeturn_heard, which comes before the redelivered answer.cargo fmtwas fixed in the second commit. - Webviews:
turnRetry.live.test.tsfeeds real records throughAcpmuxDirectClientover the mock socket and checks the retry row, the retry time, and the cleanup at turn end. It also coverswithRetryandretryParts.test/transcript-turn-retry.test.tsxrenders the gallery snapshots throughturnViewandThinking.
Observed / Not run
- Observed: the Rust results above. The webview run's results are posted as a comment.
- Not run: a tagged DEV build against a real failing gateway.
Changelog
Fixed: A chat whose model can't be reached now says "Can't reach the model 路 retrying (N of M)" instead of "Thinking".
Proof
No capture: webview UI. See gallery agent-pane.turn-retry.
Agent session: agent session
馃 Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith 路 Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Shows when a chat's model can't be reached instead of reading "Thinking" while the harness retries the request.
Previously a turn whose model gateway was down kept its "Thinking" live line with a clock counting the retries. Now acpmux logs each retry, and the agent pane's live line reads "Can't reach the model 路 retrying (7 of 10) 路 503 server error" (or "The model is busy" for 429/529 and rate-limit or overload errors, including status-less codes like rate_limit_error), calmly, with no sweep and no clock. When the model answers, the line returns to "Thinking" minus the time the retries took. Once a retry runs out, the turn still ends failed on the existing error card with Retry.
acpmux
- Each harness retry of a failed model request logs a
turn_retryingmux record (transcript category), sourced from Claude Code'ssystem/api_retryand Codex's_meta.codex.errorwithwillRetry. - The retry marks the turn silent, so the model's next sign logs
turn_heard, ending the retry.
Agent pane
- The live line carries a client-only
TURN_RETRYrow, drawn in the same.cv-workedbox so nothing moves when retries start or end. - No new subscription needed; existing transcript clients receive the records.