Skip to content

RFC: TUI shortcuts to cycle model and reasoning effort (Alt+M / Alt+E) #4879

@prabhu-mannu

Description

@prabhu-mannu

RFC: TUI keyboard shortcuts to cycle model and reasoning effort (Alt+M / Alt+E)

Summary

  • Add two TUI shortcuts to quickly switch the active model and the reasoning effort without opening popups.
  • Model: Alt+M cycles through available model slugs; Alt+Shift+M cycles backward (optional).
  • Effort: Alt+E cycles through allowed reasoning levels for the current model; Alt+Shift+E cycles backward (optional).
  • Changes are applied immediately to the running session, persisted to config.toml, and announced in the transcript.

Motivation

  • Switching between models/effort is currently a multi-step popup flow (/model).
  • Fast iteration in codebases often requires hopping between lightweight and deeper reasoning. This proposes a one-keystroke workflow.
  • Aligns with existing keyboard-first UX (Esc backtrack, @ search, ? shortcuts).

User Experience

  • Shortcuts
    • “Alt+M” → next model (wrap-around). Optional “Alt+Shift+M” → previous.
    • “Alt+E” → next reasoning effort for the current model (wrap-around). Optional “Alt+Shift+E” → previous.
  • Disabled during active task (consistent with /model). Pressing a shortcut while a task is running shows a one‑line error cell.
  • On change, append an info line to the transcript, e.g.
    • “Model changed to gpt-5 with medium reasoning”
    • “Reasoning effort set to high”
  • The “?” overlay gains two entries: “alt + m to cycle model” and “alt + e to cycle reasoning”.

Behavioral Details

  • Model list: derive from builtin presets (codex_common::model_presets::builtin_model_presets(auth_mode)), grouped by preset.model → unique, stable order.
  • Efforts per model: use ReasoningEffort values present in that model’s presets; if a model has no explicit effort variants, fall back to ReasoningEffort::iter().
  • Preserving effort across model changes:
    • If next model supports the current effort, keep it.
    • Else if next model supports ReasoningEffort::default(), use that.
    • Else pick the first available effort for that model.
  • Persistence and session updates: send existing AppEvents/Op sequence used by /model flow, then persist to config.toml via persist_model_selection.

Proposed Implementation

  • TUI keyboard handling — codex-rs/tui/src/chatwidget.rs
    • In handle_key_event, add branches for Alt+M/E (and optional Alt+Shift+M/E for reverse).
    • Guard: if bottom_pane.is_task_running() → emit error cell and return.
    • Helpers:
      • available_models(&self) -> Vec
      • available_efforts_for(&self, model: &str) -> Vec
      • cycle_next<T: Eq + Copy>(list: &[T], current: T, reverse: bool) -> T
    • Model cycle: compute next model + resolved effort, then send:
      • Op::OverrideTurnContext { model: Some(next), effort: Some(resolved), .. }
      • AppEvent::UpdateModel(next)
      • AppEvent::UpdateReasoningEffort(resolved)
      • AppEvent::PersistModelSelection { model: next, effort: resolved }
    • Effort cycle: compute next effort for current model, then send:
      • Op::OverrideTurnContext { effort: Some(Some(next_effort)), .. }
      • AppEvent::UpdateReasoningEffort(Some(next_effort))
      • AppEvent::PersistModelSelection { model: current_model, effort: Some(next_effort) }
  • Footer overlay — codex-rs/tui/src/bottom_pane/footer.rs
    • Add ShortcutId::{SwitchModel, SwitchEffort} and associated ShortcutDescriptor entries using key_hint::alt.
    • Ensure they render in ShortcutOverlay.
  • App wiring
    • AppEvent::{UpdateModel, UpdateReasoningEffort, PersistModelSelection} already handled in codex-rs/tui/src/app.rs; reuse existing behavior.

Tests & Validation

  • Unit tests — codex-rs/tui/src/chatwidget/tests.rs
    • Alt+M cycles model; assert emitted Op::OverrideTurnContext + AppEvents and info line.
    • Alt+E cycles effort; assert emitted events and info line.
    • When set_task_running(true), both shortcuts emit an error cell (mirrors disabled /model test).
  • Snapshot updates
    • Update footer overlay snapshots to include the two new entries.
  • Manual validation
    • just fmt, just fix -p codex-tui, cargo test -p codex-tui
    • Run TUI and verify cycling in practice.

Docs

  • docs/getting-started.md: add bullets in “Tips & shortcuts” for Alt+M / Alt+E.
  • In-TUI “?” overlay already shows the shortcuts after the footer change.

Non-Goals

  • Configurable keybindings (could be a follow-up).
  • Extending beyond presets/model family logic already present in code.

Constraints & Conventions

  • Follow TUI styling (ratatui Stylize helpers) and clippy rules (uninlined_format_args, collapsible_if, method-references).
  • Do not modify any CODEX_SANDBOX_* behavior.

Open Questions

  • Do we want reverse cycling by default (Alt+Shift+M/E), or add later?
  • Any conflict concerns with common terminal Alt+key mappings for macOS/Linux?

Request for Approval

  • Per docs/contributing.md, submitting this issue to request maintainer approval for the feature before coding.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions