Files
codex/codex-rs/app-server/src/models.rs
2026-05-04 01:02:20 +03:00

74 lines
2.6 KiB
Rust

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_models_manager::manager::RefreshStrategy;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
use codex_protocol::openai_models::ModelPreset;
use codex_protocol::openai_models::ModelServiceTier;
use codex_protocol::openai_models::ReasoningEffortPreset;
pub async fn supported_models(
thread_manager: Arc<ThreadManager>,
include_hidden: bool,
) -> Vec<Model> {
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 {
let additional_speed_tiers = legacy_additional_speed_tiers(&preset.service_tiers);
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,
additional_speed_tiers,
service_tiers: preset.service_tiers,
is_default: preset.is_default,
}
}
fn legacy_additional_speed_tiers(service_tiers: &[ModelServiceTier]) -> Vec<String> {
service_tiers
.iter()
.filter_map(|tier| {
(tier.id.as_ref() == SERVICE_TIER_PRIORITY).then_some("fast".to_string())
})
.collect()
}
fn reasoning_efforts_from_preset(
efforts: Vec<ReasoningEffortPreset>,
) -> Vec<ReasoningEffortOption> {
efforts
.iter()
.map(|preset| ReasoningEffortOption {
reasoning_effort: preset.effort,
description: preset.description.to_string(),
})
.collect()
}