Problem
When the ChatGPT/Codex subscription is rate limited, codex exec returns an error and the agent sibling icon turns red — no result, no spoken feedback. There's currently no fallback.
Expected behaviour
When Codex is rate limited (or unavailable), agent tasks should fall back gracefully instead of silently failing.
Proposed solution
Add a two-tier fallback in AgentSessionManager.launchAgent():
- Tier 1 — Codex (primary): runs
codex exec --json as today
- Tier 2 — Claude fallback: if Codex throws a rate-limit error, re-route the task to
ClaudeCodeCLIClient. Claude can't build real files or run code, but handles research/summarization/planning tasks well.
The spoken response should tell the user which tier handled the task:
- Codex: speak result as-is
- Claude fallback: prefix with "Codex is rate limited, here's what I can tell you: ..."
Detection
Codex rate-limit errors come through as CodexCLIError.agentError(message) where message contains "rate" or "429". Check for this before deciding to fall back vs surface the error directly.
Files to change
AgentSessionManager.swift — add fallback logic in the catch block
CodexCLIClient.swift — expose a helper to detect rate-limit errors from the error message
Context
- Rate limits are on the ChatGPT subscription (not API credits), reset hourly
- Codex binary:
~/.local/bin/codex-clicky (v0.124.0)
- Claude fallback:
ClaudeCodeCLIClient already available in CompanionManager
Blocked until rate limit resets — implement tomorrow.
Problem
When the ChatGPT/Codex subscription is rate limited,
codex execreturns an error and the agent sibling icon turns red — no result, no spoken feedback. There's currently no fallback.Expected behaviour
When Codex is rate limited (or unavailable), agent tasks should fall back gracefully instead of silently failing.
Proposed solution
Add a two-tier fallback in
AgentSessionManager.launchAgent():codex exec --jsonas todayClaudeCodeCLIClient. Claude can't build real files or run code, but handles research/summarization/planning tasks well.The spoken response should tell the user which tier handled the task:
Detection
Codex rate-limit errors come through as
CodexCLIError.agentError(message)wheremessagecontains "rate" or "429". Check for this before deciding to fall back vs surface the error directly.Files to change
AgentSessionManager.swift— add fallback logic in thecatchblockCodexCLIClient.swift— expose a helper to detect rate-limit errors from the error messageContext
~/.local/bin/codex-clicky(v0.124.0)ClaudeCodeCLIClientalready available inCompanionManagerBlocked until rate limit resets — implement tomorrow.