Skip to content

Add keyboard based fast switching between agents in TUI#13923

Merged
gabec-openai merged 5 commits into
mainfrom
codex/tui-agent-navigation-footer-pr
Mar 11, 2026
Merged

Add keyboard based fast switching between agents in TUI#13923
gabec-openai merged 5 commits into
mainfrom
codex/tui-agent-navigation-footer-pr

Conversation

@gabec-openai
Copy link
Copy Markdown
Contributor

@gabec-openai gabec-openai commented Mar 8, 2026

Summary

  • add next/previous agent navigation with OS-specific shortcuts and wraparound in spawn order
  • advertise the navigation shortcuts in the /agent picker and add snapshot/regression coverage
  • show the active agent label in the TUI footer when multiple threads are present

Testing

  • just fix -p codex-tui
  • just fmt
  • cargo test -p codex-tui

Add multi-agent footer labels, spawn-ordered agent cycling, and OS-specific next/previous shortcuts in the TUI.

Co-authored-by: Codex <noreply@openai.com>
@gabec-openai gabec-openai changed the title Improve TUI agent navigation and footer labels Add keyboard based fast switching between agents Mar 8, 2026
@gabec-openai gabec-openai changed the title Add keyboard based fast switching between agents Add keyboard based fast switching between agents in TUI Mar 8, 2026
@etraut-openai etraut-openai added the oai PRs contributed by OpenAI employees label Mar 9, 2026
gabec-openai and others added 2 commits March 9, 2026 13:31
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
joshka-oai and others added 2 commits March 10, 2026 18:42
Clarify the footer terminology introduced by the multi-agent navigation
change so reviewers can read the touched code in isolation. Define the
status line, instructional footer, and contextual footer locally and
explain how the active agent label fits into that model.

Co-authored-by: Codex <noreply@openai.com>
refactor: extract agent navigation state from App

Move the multi-agent picker ordering, adjacent-thread navigation, and
active-agent label derivation into a dedicated app::agent_navigation
module so App no longer owns another chunk of pure state-management
logic.

This code previously landed in app.rs, which is already large enough
that adding more stateful UI logic there makes review and maintenance
harder. Pulling the pure navigation rules into a small module gives
those invariants a tighter home, keeps the tests next to the behavior,
and makes App call into the logic instead of continuing to grow as a
god class.

The new module keeps the stable first-seen thread order, exposes the
picker and footer label helpers, and carries focused tests next to the
implementation. App now delegates to that module and keeps the UI side
effects and backend coordination.

Add repo guidance to prefer extracting new modules once Rust files grow
large, with concrete examples from the high-touch TUI orchestration
files that tend to accumulate unrelated behavior.

Co-authored-by: Codex <noreply@openai.com>
@joshka-oai
Copy link
Copy Markdown
Contributor

joshka-oai commented Mar 11, 2026

Problem

Multi-agent sessions in the TUI already let users spawn and inspect parallel
threads, but switching between them still depended on opening the picker and
manually choosing an entry. The picker also did not explain the keyboard
navigation model, and the footer gave no persistent indication of which agent
transcript was currently on screen once more than one thread existed.

The implementation also added more state-management logic to
codex-rs/tui/src/app.rs, which is already a large, high-touch orchestration
module. That made the new behavior harder to review in isolation and continued
the pattern of growing app.rs as a god module.

What This Delivers

This PR adds direct keyboard navigation between agent threads in the TUI,
surfaces the currently viewed agent in the footer, and then follows up with a
small refactor and documentation pass to make the resulting behavior easier to
maintain.

Users can now:

  • move to the previous or next agent with Alt+Left and Alt+Right
  • use the macOS word-motion fallbacks when enhanced Option+arrow events are not
    available and the composer is empty
  • see those navigation shortcuts advertised in the /agent picker
  • see the active agent label in the footer when multiple threads exist

The PR also:

  • extracts the pure picker-ordering and active-label logic into
    codex-rs/tui/src/app/agent_navigation.rs
  • adds docs that define the contextual-footer terminology at the point of use
  • adds repo guidance in AGENTS.md to prefer extracting new modules instead of
    continuing to grow large high-touch Rust files

Mental model

The app now tracks two closely related ideas for multi-agent sessions:

  • the set of known picker entries and their latest metadata
  • the stable first-seen order in which those threads entered the session

Fast switching uses that stable first-seen order, not thread-id sorting, so
“next” and “previous” feel like stepping through the order users saw agents
appear.

The footer follows the thread whose transcript is actually being displayed, not
merely whichever thread bookkeeping most recently marked active. That matters
during transitions, because the visible transcript can briefly lag behind the
latest internal thread switch state.

The footer itself now has a clearer model:

  • instructional footer states tell the user what to do next
  • contextual footer states show ambient information instead
  • the active agent label participates in that contextual row, either by itself
    or appended to the configured status line

Non-goals

This PR does not change how agent threads are created, resumed, or closed. It
does not add richer thread-management UI beyond fast switching and labeling. It
does not change the single-thread footer behavior beyond documentation cleanup,
and it does not attempt to advertise every platform-specific fallback binding
in the picker copy.

The AGENTS.md change is guidance for future work; it does not enforce module
size mechanically.

Tradeoffs

Using stable spawn order makes navigation predictable and preserves muscle
memory, but it also means closed agents keep their place in the cycle instead
of being re-sorted around currently live threads.

Extracting the pure navigation logic into a sibling module slightly increases
the number of files involved, but that is intentional. The tradeoff is a
smaller App surface, tests that live next to the logic they validate, and a
clearer boundary between orchestration code and pure state-management rules.

The active-agent label only appears when the footer is showing contextual
information and there is more than one tracked thread. That avoids spending
footer space on redundant single-thread labeling, but it means the label is not
visible in every footer mode.

Architecture

codex-rs/tui/src/multi_agents.rs continues to own the shared presentation and
shortcut-matching helpers for multi-agent UI.

codex-rs/tui/src/app/agent_navigation.rs now owns the pure navigation state:

  • cached picker entries
  • stable first-seen traversal order
  • adjacent-thread lookup
  • active-agent footer label derivation
  • picker subtitle derivation
  • focused tests for those invariants

codex-rs/tui/src/app.rs now delegates to that module and keeps the imperative
parts:

  • thread discovery and metadata refresh
  • deciding which thread is currently displayed
  • selecting/switching threads
  • wiring the derived label into the widget tree

ChatWidget, BottomPane, ChatComposer, and footer.rs now carry and
document the active-agent label through the footer pipeline so the contextual
footer row is explained where it is rendered.

Observability

There is no new runtime logging. The behavior is covered through unit tests and
snapshots, and the follow-up documentation pass makes the important contracts
explicit in code.

The main invariants exercised here are:

  • picker traversal follows stable first-seen spawn order with wraparound
  • picker subtitle stays derived from the canonical shortcut helpers
  • the active agent label follows the currently displayed thread
  • the footer combines contextual status text and active agent label
    consistently

Tests

  • just fix -p codex-tui
  • just fmt
  • cargo test -p codex-tui

@joshka-oai
Copy link
Copy Markdown
Contributor

Follow-up updates in this PR:

  • Added a documentation pass over the multi-agent navigation/footer changes so
    the new concepts are understandable in isolation. This includes module, type,
    and method docs for the extracted navigation logic, plus clarifying comments
    in the App and footer plumbing about which thread is considered "currently
    displayed" and how the active agent label flows into the contextual footer.

  • Reworked the footer docs to define the terminology locally instead of assuming
    prior context. In particular, the touched code now distinguishes between the
    configured status line, instructional footer states, and contextual footer
    states, and explains how the active agent label participates in that model.

  • Refactored the new multi-agent picker ordering, adjacent-thread navigation,
    and active-agent label derivation out of app.rs into a focused
    app/agent_navigation.rs module. App now delegates to that module for the
    pure state-management rules while keeping backend coordination and UI side
    effects.

  • Moved the focused tests for picker ordering, wraparound navigation, picker
    subtitle text, and active-agent label behavior next to the extracted module,
    so the invariants live closer to the implementation they validate.

  • Added repo guidance in AGENTS.md to prefer extracting new modules instead of
    continuing to grow large, high-touch Rust files such as app.rs and related
    TUI orchestration modules.

@gabec-openai gabec-openai merged commit 052ec62 into main Mar 11, 2026
31 checks passed
@gabec-openai gabec-openai deleted the codex/tui-agent-navigation-footer-pr branch March 11, 2026 02:41
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

oai PRs contributed by OpenAI employees

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants