use std::sync::Arc; use codex_app_server_protocol::Model; use codex_app_server_protocol::ModelUpgradeInfo; use codex_app_server_protocol::ReasoningEffortOption; use codex_core::ThreadManager; use codex_core::models_manager::manager::RefreshStrategy; use codex_protocol::openai_models::ModelPreset; use codex_protocol::openai_models::ReasoningEffortPreset; pub async fn supported_models( thread_manager: Arc, include_hidden: bool, ) -> Vec { thread_manager .list_models(RefreshStrategy::OnlineIfUncached) .await .into_iter() .filter(|preset| include_hidden || preset.show_in_picker) .map(model_from_preset) .collect() } fn model_from_preset(preset: ModelPreset) -> Model { Model { id: preset.id.to_string(), model: preset.model.to_string(), upgrade: preset.upgrade.as_ref().map(|upgrade| upgrade.id.clone()), upgrade_info: preset.upgrade.as_ref().map(|upgrade| ModelUpgradeInfo { model: upgrade.id.clone(), upgrade_copy: upgrade.upgrade_copy.clone(), model_link: upgrade.model_link.clone(), migration_markdown: upgrade.migration_markdown.clone(), }), availability_nux: preset.availability_nux.map(Into::into), display_name: preset.display_name.to_string(), description: preset.description.to_string(), hidden: !preset.show_in_picker, supported_reasoning_efforts: reasoning_efforts_from_preset( preset.supported_reasoning_efforts, ), default_reasoning_effort: preset.default_reasoning_effort, input_modalities: preset.input_modalities, supports_personality: preset.supports_personality, is_default: preset.is_default, } } fn reasoning_efforts_from_preset( efforts: Vec, ) -> Vec { efforts .iter() .map(|preset| ReasoningEffortOption { reasoning_effort: preset.effort, description: preset.description.to_string(), }) .collect() }