Files
codex/codex-rs/tui/src/model_catalog.rs
Eric Traut 547c9a1aad Use catalog model display names throughout the TUI (#46503)
## Why

Model pickers and session details show raw model IDs even when the catalog provides a display name.

## What changed

- Use catalog display names in model and reasoning pickers, session headers, status displays, and terminal titles, retaining fallback labels for models absent from the catalog.
- Keep model IDs for selection and persistence, and preserve picker highlights by ID when display names change or are shared by multiple models.
- Remove the legacy-model instruction from the full model picker.

## Testing

Add regression tests and snapshots for custom display names, startup and resumed session headers, fallback labels, terminal titles, and picker refreshes. Verify that selecting a display name still persists the original model ID.

GitOrigin-RevId: 101fe82b20f7a8a90ceeff7999bd07ad42ca46db
2026-09-18 23:15:39 +00:00

49 lines
1.4 KiB
Rust

//! TUI model and collaboration inventories; refreshing models preserves the server mode catalog.
use codex_protocol::config_types::CollaborationModeMask;
use codex_protocol::openai_models::ModelPreset;
use std::convert::Infallible;
pub(crate) const LUNA_RESERVE_MODEL: &str = "gpt-reserve";
pub(crate) const LUNA_MODEL: &str = "gpt-5.6-luna";
pub(crate) fn model_display_name(model: &str) -> &str {
if model.eq_ignore_ascii_case(LUNA_RESERVE_MODEL) {
"Luna Reserve"
} else {
model
}
}
#[derive(Debug, Clone)]
pub(crate) struct ModelCatalog {
pub(crate) models: Vec<ModelPreset>,
pub(crate) collaboration_modes: Vec<CollaborationModeMask>,
}
impl ModelCatalog {
pub(crate) fn new(models: Vec<ModelPreset>) -> Self {
Self {
models,
collaboration_modes: Vec::new(),
}
}
pub(crate) fn with_collaboration_modes(mut self, modes: Vec<CollaborationModeMask>) -> Self {
self.collaboration_modes = modes;
self
}
pub(crate) fn try_list_models(&self) -> Result<Vec<ModelPreset>, Infallible> {
Ok(self.models.clone())
}
pub(crate) fn display_name<'a>(&'a self, model: &'a str) -> &'a str {
self.models
.iter()
.find(|preset| preset.model == model)
.map(|preset| preset.display_name.as_str())
.unwrap_or_else(|| model_display_name(model))
}
}