cmux NEXT: Settings > Retry After Errors sets the automatic retry loop (on/off, seconds between tries, tries per error)
Leo-ask: ask-082cdbe456
Leo, passing on Lawrence's notes (2026-10-28): "leo make sure font size everywhere (like text input area) is customizable", "should have retry button + configurable timer loop retry", "needs more left padding".
This PR builds the one part that was still missing: the configurable timer loop retry. Where the other parts stand:
- Font size in the text input area: done in #26523 (merged 2026-10-28), which makes the composer follow Settings > Agent Chat > Chat Font Size (
agentPane.display.font.size). - Retry button: done in 9e836df4 (2026-10-29). Continue or Retry leads the rate-limit and capacity error card.
- Left padding on the prompt rail: handled in its own small PR.
What changes
acpmux already retries a turn that a rate limit, a capacity error or a lost connection ended (#25232, #27924), waiting 10 s, 1 min, 5 min and 20 min. Until now, only acpmux's own config.json (autoResumeDelaysMs) could change that loop. Three new settings under Settings > General > Retry After Errors now set it:
| key | default | meaning |
|---|---|---|
agents.autoRetry.enabled | true | Off: no automatic retry. The card's Retry still works. |
agents.autoRetry.intervalSeconds | 0 (0ā3600) | 0 keeps today's growing waits. N waits N seconds before every try. |
agents.autoRetry.attempts | 4 (1ā12) | Tries per failed turn. |
- acpmux reads them from the settings file at each retry (
hub/auto_resume/settings.rs, throughuser_settings, as Sub-sessions does), so a change applies to the next failed turn.autoResumeDelaysMsin config.json, when set, still comes first, so the dev slot's[]keeps working. The defaults give exactly today's waits, and a test pins the section JSON's defaults and ranges to the daemon's constants. - Every reader of the loop goes through
effective_delays: the turn retry, a restored wait, a chain of restarts, held agent messages and subagent retries. - The schema source is
schemas/settings/source/agent-retry.json, generated into Swift bygen-settings-sources.py. Through the schema, the settings appear in Settings, the palette,cmux settingsand MCP. MCP refuses all three as user-only (SettingsSchema+AgentPolicy), likesessions.resumeAgents.settings-schema.jsonand the settings reference are regenerated by base autofix. - Strings: 7 new keys in the CmuxNextSettings catalog, translated into all 21 locales.
- The phone parity row is in
cmux-next-ios/verify/parity-mac.md: the loop runs in acpmux, so phone chats get it, but the keys can only be edited on the Mac.
Timers: no new timer. The existing per-attempt sleep reads its wait from these settings, and Stop or close still ends it (auto_resume.rs).
risk: normal (a settings row plus where the daemon reads its existing waits).
Changelog
- Added: Settings > Retry After Errors: turn automatic retries after a rate limit or lost connection on or off, and set the seconds between tries and how many run.
Observed / Not run
- Ran:
gen-settings-sources.py(writes the generated Swift), rustfmt, the pre-push gate. Thesettings.rsunit tests and the acpmux auto_resume tests run through cmux-ci; their result is posted below. - Not run yet: a tagged-build check of the palette row,
cmux settings get|set agents.autoRetry.intervalSecondsand the MCP refusal.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Makes acpmux's automatic retry loop after rate limits, capacity errors, or lost connections configurable from Settings > Retry After Errors, instead of only via the daemon's config.json.
- Adds three
agents.autoRetry.*keys:enabled(on/off),intervalSeconds(0 keeps today's growing waits), andattempts(1ā12 per failed turn), read from the settings file at each retry. autoResumeDelaysMsinconfig.jsonstill takes precedence when set, so the dev slot's[](retry off) keeps working.- Disabling auto-retry still leaves the error card's Retry button working; changes apply to the next failed turn, and Stop or closing the chat still ends the loop.
- All three keys are user-only in MCP, appearing in Settings, the palette, and
cmux settings; the phone gets the retry behavior but has no editor for the keys. - The schema source in
schemas/settings/source/agent-retry.jsongenerates the Swift descriptors, with settings strings translated into all 21 locales.
Migration
- No action needed; defaults reproduce exactly today's waits (10 s, 1 min, 5 min, then 20 min, 4 attempts).