-
Couldn't load subscription status.
- Fork 6k
Open
Labels
enhancementNew feature or requestNew feature or request
Description
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
Labels
enhancementNew feature or requestNew feature or request