fix(tui): smart auth-profile auto-switch selection + auto-resume interrupted turn#406
Merged
Merged
Conversation
andrei-hasna
force-pushed
the
fix/authswitch-smart-select-restart
branch
3 times, most recently
from
July 24, 2026 19:38
4f37742 to
b444752
Compare
…rrupted turn On rate-limit exhaustion the agent now: - resumes the interrupted turn on the newly selected profile instead of switching silently and dropping the failed request (re-queues the failed turn so the SwitchAuthProfile resume drains it on the new profile); - preserves each cached per-profile snapshot's server reset time so exhausted profiles are ranked by their real reset and skipped until they reset; - when every alternate profile is also rate-limited, reports the earliest reset time instead of switching onto an exhausted profile. Adds unit tests: best-remaining selection skips exhausted profiles; all-exhausted surfaces the earliest reset; the automatic weekly fallback re-queues and resumes the failed turn on the new profile.
- Reorder the UsageProfileSwitchOutcome import so `cargo fmt --check` passes for codex-tui/codex-core (also picks up incidental fmt on an adjacent test assertion). - Guard the "every alternate profile is also rate-limited" info message behind a per-exhaustion-window trigger key (last_no_eligible_auth_profile_trigger), mirroring the existing auto-switch trigger dedupe, so it is emitted once per window instead of on every rate-limit poll. - Add a regression test asserting the notice fires exactly once across repeated polls of the same exhausted window.
Fold the new auth-profile-switch requeue path into the existing resume_after_usage_limit_reset body as requeue_failed_turn_at_front, so both callers use one implementation and only differ in whether they send the queued turn immediately.
andrei-hasna
force-pushed
the
fix/authswitch-smart-select-restart
branch
from
July 25, 2026 04:51
b444752 to
56d6a17
Compare
Contributor
Author
Rebased onto
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On weekly/5h rate-limit exhaustion, codewith's auth-profile auto-switch had two gaps:
display_rate_limit_windowhardcodedresets_at: None), so exhausted alternates looked "reset-unknown". When no alternate had available usage the user got a vague "no alternate profile with available usage is known" with no reset info.usage_self_heal.last_submitted_turn, not the input queue, and theSwitchAuthProfile { resume_queued_input: true }handler only drains the queue. The user had to re-typego.(The healthiest-profile selection itself already worked when per-profile snapshots were fresh — see existing
exhausted_limit_auto_switches_to_profile_with_most_fresh_usage.)Changes
resets_at_unixtoRateLimitWindowDisplayand carried it through the broker so exhausted profiles report their realretry_at, are ranked/skipped by reset, and can surface the earliest reset.UsageProfileSwitchOutcome::{Switch, NoEligibleProfile { earliest_reset_at }}; when every alternate is also rate-limited the agent does not switch onto an exhausted profile and shows a clear message including the earliest reset time.SwitchAuthProfileresume re-runs it on the new profile after the profile override is applied — correct ordering, exactly once. Loop/idempotency guards (last_auth_profile_auto_switch_trigger, cooldown keyed on reset) are unchanged.Tests (Rust unit tests)
core:highest_available_picks_best_remaining_and_skips_exhausted,all_exhausted_snapshots_report_earliest_reset_gracefully.tui:all_alternate_profiles_exhausted_reports_earliest_reset_without_switching(graceful message + earliest reset, no switch),automatic_weekly_switch_requeues_failed_turn_for_resume_on_new_profile(switch re-queues the failed turn and resumes it exactly once on the new profile).Build / verify
Heavy builds are offloaded to the AWS testbox. Crates to build/test:
codex-coreandcodex-tui(cargo test -p codex-core -p codex-tui).cargo fmt --checkpasses locally.🤖 Generated with Claude Code