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

Resolved 💬 4 comments Opened Oct 7, 2025 by prabhu-mannu Closed Dec 14, 2025

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<String>
  • available_efforts_for(&self, model: &str) -> Vec<ReasoningEffort>
  • 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.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗