Skip to content

Automatic account switching as a mode of --live, with pluggable trigger and selection policies #176

Open

Description

@Loongphy

Summary

Make automatic account switching a mode of the existing live views (list --live, switch --live) instead of a separate long-running command, and design the trigger and selection rules as explicit policies rather than hardcoded arithmetic.

Why --live is the right home

  • --live already implements periodic quota refresh: a refresh timer, async refresh rounds, fresh-vs-cached rendering, and it already reaches the same account-activation path used by manual switching.
  • A foreground auto monitor has the same process model as --live: it blocks the terminal, must be kept alive, and stops on Ctrl-C. The only capability it adds is that nobody has to press Enter — that is a mode flag on the live view, not a new top-level command.
  • Keeping both means two independent implementations of poll → select → switch, plus a second "best remaining account" ranking next to the one already used when the active account is removed. Those will drift.

Design questions to settle before implementation

A single fixed rule does not cover the requests we already have.

  1. Trigger rule. Used-quota percentage: per window separately (5h vs weekly) or the maximum of both? Proactive percentage alone is not enough: when an account really is rate limited, the usage endpoint commonly answers 429, which is exactly the moment switching is wanted. A rule that only trusts HTTP 200 does nothing then.
  2. Selection rule. Callers want different targets: most remaining headroom, the account whose weekly window resets soonest (Auto-select account with closest weekly usage limit reset #143), earliest 5h reset (Add one-shot automatic switch #148). This must be one named, reusable policy with room for alternatives, not inline arithmetic inside a command.
  3. Anti-flapping. Cooldown after activation, behavior when every account is at or over the threshold, and behavior when a candidate's data is stale or its only window has expired.
  4. Safety. Only fresh, successful data may justify a mutation; API-key accounts must stay excluded. See Allowance percentages seem wrong and my accounts got suspended #121 (accounts permanently suspended for a ToS breach): unattended switching churns accounts invisibly, so every decision has to be logged, and switching must be rate-limited, not opportunistic.
  5. Does the switch actually take effect? Updating auth.json does not reach a running client or the shared app-server daemon (switch on remote server does not take effect using codex app until remote connection is restarted #85, docs/commands/switch.md). The live view must say so at the moment it switches, and restarting clients must stay opt-in.
  6. Manual takeover. An arm/disarm affordance inside the live view; all existing manual keys keep working; the last decision and its reason stay on screen.
  7. Observability. Output must explain why it held, blocked, or switched (window percentages, candidates considered, rejection reasons) without printing credentials.
  8. Non-TTY and automation callers. Serve them with a one-shot selector (switch --auto-style, Feature request: one-shot automatic account switch #147/Add one-shot automatic switch #148) that composes with --json, exit codes, and cron — not with a headless monitor.
  9. One interval setting. config live --interval already exists; do not introduce a second polling-interval surface with different bounds.
  10. Concurrency and long runs. Manual switch / import / remove, a second live session, or another armed monitor must not race the automated mutation. Decide explicitly what a long run does when registry.json needs a schema migration: self-heal or stop.
  11. JSON contract. docs/json-api.md promises exactly one JSON document per invocation. Either restrict machine-readable output to one-shot mode or document the streaming exception and its exit-code behavior.

Non-goals

  • No background services, daemons, or installed schedulers (the stance taken in v0.3).
  • Never restarting clients on the user's behalf.

Related

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions