diff --git a/codex-rs/app-server-protocol/src/protocol/v2.rs b/codex-rs/app-server-protocol/src/protocol/v2.rs index ea019d3b61..d652bb5372 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2.rs @@ -30,6 +30,10 @@ use codex_protocol::config_types::ServiceTier as CoreServiceTier; use codex_protocol::config_types::Verbosity; use codex_protocol::config_types::WebSearchMode; use codex_protocol::config_types::WebSearchToolConfig; +use codex_protocol::config_types::flex_service_tier; +use codex_protocol::config_types::is_flex_service_tier; +use codex_protocol::config_types::is_priority_service_tier; +use codex_protocol::config_types::priority_service_tier; use codex_protocol::items::AgentMessageContent as CoreAgentMessageContent; use codex_protocol::items::TurnItem as CoreTurnItem; use codex_protocol::mcp::CallToolResult as CoreMcpCallToolResult; @@ -129,36 +133,26 @@ pub enum ServiceTier { Flex, } -impl ServiceTier { - pub fn fast() -> Self { - Self::Fast +pub fn service_tier_to_core(service_tier: ServiceTier) -> CoreServiceTier { + match service_tier { + ServiceTier::Fast => priority_service_tier(), + ServiceTier::Flex => flex_service_tier(), } +} - pub fn flex() -> Self { - Self::Flex - } - - pub fn to_core(self) -> CoreServiceTier { - match self { - Self::Fast => CoreServiceTier::priority(), - Self::Flex => CoreServiceTier::flex(), - } - } - - pub fn from_core(service_tier: &CoreServiceTier) -> Option { - if service_tier.is_priority() { - Some(Self::Fast) - } else if service_tier.is_flex() { - Some(Self::Flex) - } else { - None - } +pub fn service_tier_from_core(service_tier: &CoreServiceTier) -> Option { + if is_priority_service_tier(service_tier) { + Some(ServiceTier::Fast) + } else if is_flex_service_tier(service_tier) { + Some(ServiceTier::Flex) + } else { + None } } impl From for CoreServiceTier { fn from(value: ServiceTier) -> Self { - value.to_core() + service_tier_to_core(value) } } diff --git a/codex-rs/app-server/src/codex_message_processor.rs b/codex-rs/app-server/src/codex_message_processor.rs index 72dbf019d2..5bc7c30e7c 100644 --- a/codex-rs/app-server/src/codex_message_processor.rs +++ b/codex-rs/app-server/src/codex_message_processor.rs @@ -241,6 +241,8 @@ use codex_app_server_protocol::WindowsSandboxSetupMode; use codex_app_server_protocol::WindowsSandboxSetupStartParams; use codex_app_server_protocol::WindowsSandboxSetupStartResponse; use codex_app_server_protocol::build_turns_from_rollout_items; +use codex_app_server_protocol::service_tier_from_core; +use codex_app_server_protocol::service_tier_to_core; use codex_arg0::Arg0DispatchPaths; use codex_backend_client::AddCreditsNudgeCreditType as BackendAddCreditsNudgeCreditType; use codex_backend_client::Client as BackendClient; @@ -2920,7 +2922,10 @@ impl CodexMessageProcessor { thread: thread.clone(), model: config_snapshot.model, model_provider: config_snapshot.model_provider_id, - service_tier: config_snapshot.service_tier.as_ref().and_then(ServiceTier::from_core), + service_tier: config_snapshot + .service_tier + .as_ref() + .and_then(service_tier_from_core), cwd: config_snapshot.cwd, instruction_sources, approval_policy: config_snapshot.approval_policy.into(), @@ -3023,7 +3028,7 @@ impl CodexMessageProcessor { fn resolve_service_tier_override( service_tier: Option>, ) -> Option> { - service_tier.map(|service_tier| service_tier.map(ServiceTier::to_core)) + service_tier.map(|service_tier| service_tier.map(service_tier_to_core)) } async fn thread_archive(&self, request_id: ConnectionRequestId, params: ThreadArchiveParams) { @@ -4509,7 +4514,7 @@ impl CodexMessageProcessor { service_tier: session_configured .service_tier .as_ref() - .and_then(ServiceTier::from_core), + .and_then(service_tier_from_core), cwd: session_configured.cwd, instruction_sources, approval_policy: session_configured.approval_policy.into(), @@ -5147,7 +5152,7 @@ impl CodexMessageProcessor { service_tier: session_configured .service_tier .as_ref() - .and_then(ServiceTier::from_core), + .and_then(service_tier_from_core), cwd: session_configured.cwd, instruction_sources, approval_policy: session_configured.approval_policy.into(), @@ -8505,7 +8510,7 @@ async fn handle_pending_thread_resume_request( thread, model, model_provider: model_provider_id, - service_tier: service_tier.as_ref().and_then(ServiceTier::from_core), + service_tier: service_tier.as_ref().and_then(service_tier_from_core), cwd, instruction_sources, approval_policy: approval_policy.into(), @@ -8675,13 +8680,13 @@ fn collect_resume_override_mismatches( )); } if let Some(requested_service_tier) = request.service_tier.as_ref() - && requested_service_tier.map(ServiceTier::to_core).as_ref() + && requested_service_tier.map(service_tier_to_core).as_ref() != config_snapshot.service_tier.as_ref() { let active_service_tier = config_snapshot .service_tier .as_ref() - .and_then(ServiceTier::from_core); + .and_then(service_tier_from_core); mismatch_details.push(format!( "service_tier requested={requested_service_tier:?} active={active_service_tier:?}" )); @@ -10065,7 +10070,7 @@ mod tests { use codex_model_provider_info::ModelProviderInfo; use codex_model_provider_info::WireApi; use codex_protocol::ThreadId; - use codex_protocol::config_types::ServiceTier as CoreServiceTier; + use codex_protocol::config_types::flex_service_tier; use codex_protocol::openai_models::ReasoningEffort; use codex_protocol::permissions::FileSystemAccessMode; use codex_protocol::permissions::FileSystemPath; @@ -10546,7 +10551,7 @@ mod tests { path: None, model: None, model_provider: None, - service_tier: Some(Some(ServiceTier::fast())), + service_tier: Some(Some(ServiceTier::Fast)), cwd: None, approval_policy: None, approvals_reviewer: None, @@ -10562,7 +10567,7 @@ mod tests { let config_snapshot = ThreadConfigSnapshot { model: "gpt-5".to_string(), model_provider_id: "openai".to_string(), - service_tier: Some(CoreServiceTier::flex()), + service_tier: Some(flex_service_tier()), approval_policy: codex_protocol::protocol::AskForApproval::OnRequest, approvals_reviewer: codex_protocol::config_types::ApprovalsReviewer::User, permission_profile: codex_protocol::models::PermissionProfile::Disabled, diff --git a/codex-rs/app-server/src/models.rs b/codex-rs/app-server/src/models.rs index 74c4f2d066..13f8ece9ce 100644 --- a/codex-rs/app-server/src/models.rs +++ b/codex-rs/app-server/src/models.rs @@ -5,6 +5,7 @@ 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::is_priority_service_tier; use codex_protocol::openai_models::ModelPreset; use codex_protocol::openai_models::ModelServiceTier as CoreModelServiceTier; use codex_protocol::openai_models::ReasoningEffortPreset; @@ -52,7 +53,7 @@ fn model_from_preset(preset: ModelPreset) -> Model { fn legacy_additional_speed_tiers(service_tiers: &[CoreModelServiceTier]) -> Vec { service_tiers .iter() - .filter_map(|tier| tier.id.is_priority().then_some("fast".to_string())) + .filter_map(|tier| is_priority_service_tier(&tier.id).then_some("fast".to_string())) .collect() } diff --git a/codex-rs/app-server/tests/suite/v2/model_list.rs b/codex-rs/app-server/tests/suite/v2/model_list.rs index ffb360e9c6..d18c73ed48 100644 --- a/codex-rs/app-server/tests/suite/v2/model_list.rs +++ b/codex-rs/app-server/tests/suite/v2/model_list.rs @@ -12,6 +12,7 @@ use codex_app_server_protocol::ModelListResponse; use codex_app_server_protocol::ModelUpgradeInfo; use codex_app_server_protocol::ReasoningEffortOption; use codex_app_server_protocol::RequestId; +use codex_protocol::config_types::is_priority_service_tier; use codex_protocol::openai_models::ModelPreset; use codex_protocol::openai_models::ModelServiceTier as CoreModelServiceTier; use pretty_assertions::assert_eq; @@ -59,7 +60,7 @@ fn model_from_preset(preset: &ModelPreset) -> Model { fn legacy_additional_speed_tiers(service_tiers: &[CoreModelServiceTier]) -> Vec { service_tiers .iter() - .filter_map(|tier| tier.id.is_priority().then_some("fast".to_string())) + .filter_map(|tier| is_priority_service_tier(&tier.id).then_some("fast".to_string())) .collect() } diff --git a/codex-rs/app-server/tests/suite/v2/thread_start.rs b/codex-rs/app-server/tests/suite/v2/thread_start.rs index cca4d085a6..8f88943109 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_start.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_start.rs @@ -340,7 +340,7 @@ async fn thread_start_accepts_flex_service_tier() -> Result<()> { let req_id = mcp .send_thread_start_request(ThreadStartParams { - service_tier: Some(Some(ServiceTier::flex())), + service_tier: Some(Some(ServiceTier::Flex)), ..Default::default() }) .await?; @@ -352,7 +352,7 @@ async fn thread_start_accepts_flex_service_tier() -> Result<()> { .await??; let ThreadStartResponse { service_tier, .. } = to_response::(resp)?; - assert_eq!(service_tier, Some(ServiceTier::flex())); + assert_eq!(service_tier, Some(ServiceTier::Flex)); Ok(()) } diff --git a/codex-rs/core/src/client_common_tests.rs b/codex-rs/core/src/client_common_tests.rs index 732ae63e4d..e9e5dd7cfa 100644 --- a/codex-rs/core/src/client_common_tests.rs +++ b/codex-rs/core/src/client_common_tests.rs @@ -3,6 +3,7 @@ use codex_api::ResponsesApiRequest; use codex_api::TextControls; use codex_api::create_text_param_for_request; use codex_protocol::config_types::ServiceTier; +use codex_protocol::config_types::flex_service_tier; use codex_protocol::models::FunctionCallOutputPayload; use pretty_assertions::assert_eq; @@ -155,7 +156,7 @@ fn serializes_flex_service_tier_when_set() { stream: true, include: vec![], prompt_cache_key: None, - service_tier: Some(ServiceTier::flex().to_string()), + service_tier: Some(flex_service_tier().to_string()), text: None, client_metadata: None, }; diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index e6a5bf09a9..eeb5bebf1d 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -89,6 +89,7 @@ use codex_protocol::config_types::Verbosity; use codex_protocol::config_types::WebSearchConfig; use codex_protocol::config_types::WebSearchMode; use codex_protocol::config_types::WindowsSandboxLevel; +use codex_protocol::config_types::is_priority_service_tier; use codex_protocol::models::ActivePermissionProfile; use codex_protocol::models::ActivePermissionProfileModification; use codex_protocol::models::PermissionProfile; @@ -2659,7 +2660,10 @@ impl Config { None => config_profile.service_tier.or(cfg.service_tier), }; let service_tier = match service_tier { - Some(service_tier) if service_tier.is_priority() && !features.enabled(Feature::FastMode) => { + Some(service_tier) + if is_priority_service_tier(&service_tier) + && !features.enabled(Feature::FastMode) => + { None } other => other, diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 2393eab5b3..37b136a617 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -314,6 +314,7 @@ use codex_protocol::config_types::Personality; use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig; use codex_protocol::config_types::ServiceTier; use codex_protocol::config_types::WindowsSandboxLevel; +use codex_protocol::config_types::priority_service_tier; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseInputItem; use codex_protocol::models::ResponseItem; @@ -788,7 +789,7 @@ fn get_service_tier( account_plan_type .is_some_and(is_enterprise_default_service_tier_plan) - .then(ServiceTier::priority) + .then(priority_service_tier) } fn is_enterprise_default_service_tier_plan(plan_type: AccountPlanType) -> bool { diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 4b7fa855ce..9376127f52 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -34,6 +34,7 @@ use codex_protocol::ThreadId; use codex_protocol::account::PlanType as AccountPlanType; use codex_protocol::config_types::ServiceTier; use codex_protocol::config_types::TrustLevel; +use codex_protocol::config_types::priority_service_tier; use codex_protocol::exec_output::ExecToolCallOutput; use codex_protocol::models::FileSystemPermissions; use codex_protocol::models::FunctionCallOutputBody; @@ -2801,7 +2802,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() { Some(AccountPlanType::Enterprise), /*fast_mode_enabled*/ true, ), - Some(ServiceTier::priority()) + Some(priority_service_tier()) ); assert_eq!( get_service_tier( @@ -2810,7 +2811,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() { Some(AccountPlanType::EnterpriseCbpUsageBased), /*fast_mode_enabled*/ true, ), - Some(ServiceTier::priority()) + Some(priority_service_tier()) ); assert_eq!( get_service_tier( @@ -2819,7 +2820,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() { Some(AccountPlanType::Business), /*fast_mode_enabled*/ true, ), - Some(ServiceTier::priority()) + Some(priority_service_tier()) ); assert_eq!( get_service_tier( @@ -2828,7 +2829,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() { Some(AccountPlanType::Team), /*fast_mode_enabled*/ true, ), - Some(ServiceTier::priority()) + Some(priority_service_tier()) ); assert_eq!( get_service_tier( @@ -2837,7 +2838,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() { Some(AccountPlanType::SelfServeBusinessUsageBased), /*fast_mode_enabled*/ true, ), - Some(ServiceTier::priority()) + Some(priority_service_tier()) ); } diff --git a/codex-rs/core/tests/suite/agent_websocket.rs b/codex-rs/core/tests/suite/agent_websocket.rs index f765c3c137..56dae67672 100644 --- a/codex-rs/core/tests/suite/agent_websocket.rs +++ b/codex-rs/core/tests/suite/agent_websocket.rs @@ -1,6 +1,7 @@ use anyhow::Result; use codex_features::Feature; use codex_protocol::config_types::ServiceTier; +use codex_protocol::config_types::priority_service_tier; use core_test_support::responses::WebSocketConnectionConfig; use core_test_support::responses::ev_assistant_message; use core_test_support::responses::ev_completed; @@ -269,7 +270,7 @@ async fn websocket_v2_first_turn_uses_updated_fast_tier_after_startup_prewarm() assert_eq!(warmup["generate"].as_bool(), Some(false)); assert_eq!(warmup.get("service_tier"), None); - test.submit_turn_with_service_tier("hello", Some(ServiceTier::priority())) + test.submit_turn_with_service_tier("hello", Some(priority_service_tier())) .await?; assert_eq!(server.handshakes().len(), 1); @@ -313,7 +314,7 @@ async fn websocket_v2_first_turn_drops_fast_tier_after_startup_prewarm() -> Resu .features .enable(Feature::ResponsesWebsocketsV2) .expect("test config should allow feature update"); - config.service_tier = Some(ServiceTier::priority()); + config.service_tier = Some(priority_service_tier()); }); let test = builder.build_with_websocket_server(&server).await?; @@ -385,7 +386,7 @@ async fn websocket_v2_next_turn_uses_updated_service_tier() -> Result<()> { assert_eq!(warmup["generate"].as_bool(), Some(false)); assert_eq!(warmup.get("service_tier"), None); - test.submit_turn_with_service_tier("first", Some(ServiceTier::priority())) + test.submit_turn_with_service_tier("first", Some(priority_service_tier())) .await?; test.submit_turn_with_service_tier("second", /*service_tier*/ None) .await?; diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index aa8d6d8ceb..173a87ae91 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -5,6 +5,8 @@ use codex_login::CodexAuth; use codex_models_manager::manager::RefreshStrategy; use codex_protocol::config_types::ReasoningSummary; use codex_protocol::config_types::ServiceTier; +use codex_protocol::config_types::flex_service_tier; +use codex_protocol::config_types::priority_service_tier; use codex_protocol::models::PermissionProfile; use codex_protocol::openai_models::ConfigShellToolType; use codex_protocol::openai_models::InputModality; @@ -297,7 +299,7 @@ async fn service_tier_change_is_applied_on_next_http_turn() -> Result<()> { let test = test_codex().build(&server).await?; - test.submit_turn_with_service_tier("fast turn", Some(ServiceTier::priority())) + test.submit_turn_with_service_tier("fast turn", Some(priority_service_tier())) .await?; test.submit_turn_with_service_tier("standard turn", /*service_tier*/ None) .await?; @@ -323,7 +325,7 @@ async fn flex_service_tier_is_applied_to_http_turn() -> Result<()> { let test = test_codex().build(&server).await?; - test.submit_turn_with_service_tier("flex turn", Some(ServiceTier::flex())) + test.submit_turn_with_service_tier("flex turn", Some(flex_service_tier())) .await?; let request = resp_mock.single_request(); diff --git a/codex-rs/memories/write/src/startup_tests.rs b/codex-rs/memories/write/src/startup_tests.rs index 1b1053fa44..98befeee37 100644 --- a/codex-rs/memories/write/src/startup_tests.rs +++ b/codex-rs/memories/write/src/startup_tests.rs @@ -4,6 +4,7 @@ use codex_git_utils::diff_since_latest_init; use codex_git_utils::reset_git_repository; use codex_protocol::ThreadId; use codex_protocol::config_types::ServiceTier; +use codex_protocol::config_types::priority_service_tier; use codex_protocol::openai_models::ReasoningEffort; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; @@ -253,14 +254,14 @@ async fn memories_startup_phase1_uses_live_thread_service_tier() -> anyhow::Resu model: None, effort: None, summary: None, - service_tier: Some(Some(ServiceTier::priority())), + service_tier: Some(Some(priority_service_tier())), collaboration_mode: None, personality: None, }) .await?; - let config_snapshot = wait_for_service_tier(&test, Some(ServiceTier::priority())).await?; - assert_eq!(config_snapshot.service_tier, Some(ServiceTier::priority())); + let config_snapshot = wait_for_service_tier(&test, Some(priority_service_tier())).await?; + assert_eq!(config_snapshot.service_tier, Some(priority_service_tier())); let context = crate::runtime::MemoryStartupContext::new( Arc::clone(&test.thread_manager), @@ -277,7 +278,7 @@ async fn memories_startup_phase1_uses_live_thread_service_tier() -> anyhow::Resu ReasoningEffort::Low, ) .await; - assert_eq!(request_context.service_tier, Some(ServiceTier::priority())); + assert_eq!(request_context.service_tier, Some(priority_service_tier())); shutdown_test_codex(&test).await?; Ok(()) diff --git a/codex-rs/model-provider/src/amazon_bedrock/catalog.rs b/codex-rs/model-provider/src/amazon_bedrock/catalog.rs index 47d2c75619..0686bcc076 100644 --- a/codex-rs/model-provider/src/amazon_bedrock/catalog.rs +++ b/codex-rs/model-provider/src/amazon_bedrock/catalog.rs @@ -1,7 +1,7 @@ use codex_models_manager::model_info::BASE_INSTRUCTIONS; use codex_protocol::config_types::ReasoningSummary; -use codex_protocol::config_types::ServiceTier; use codex_protocol::config_types::Verbosity; +use codex_protocol::config_types::priority_service_tier; use codex_protocol::openai_models::ApplyPatchToolType; use codex_protocol::openai_models::ConfigShellToolType; use codex_protocol::openai_models::InputModality; @@ -49,7 +49,7 @@ fn gpt_5_4_cmb_bedrock_model(priority: i32) -> ModelInfo { supported_in_api: true, priority, service_tiers: vec![ModelServiceTier { - id: ServiceTier::priority(), + id: priority_service_tier(), name: "Fast".to_string(), description: "Fast tier".to_string(), }], diff --git a/codex-rs/protocol/src/config_types.rs b/codex-rs/protocol/src/config_types.rs index b4433aeae2..eb54ab8a25 100644 --- a/codex-rs/protocol/src/config_types.rs +++ b/codex-rs/protocol/src/config_types.rs @@ -355,47 +355,41 @@ pub const SERVICE_TIER_FLEX: &str = "flex"; #[ts(type = "string")] pub struct ServiceTier(String); -impl ServiceTier { - pub fn new(id: impl Into) -> Self { - Self(id.into()) - } +pub fn priority_service_tier() -> ServiceTier { + ServiceTier::from(SERVICE_TIER_PRIORITY) +} - pub fn as_str(&self) -> &str { - self.0.as_str() - } +pub fn flex_service_tier() -> ServiceTier { + ServiceTier::from(SERVICE_TIER_FLEX) +} - pub fn priority() -> Self { - Self::new(SERVICE_TIER_PRIORITY) - } +pub fn service_tier_id(service_tier: &ServiceTier) -> &str { + service_tier.as_ref() +} - pub fn flex() -> Self { - Self::new(SERVICE_TIER_FLEX) - } +pub fn is_priority_service_tier(service_tier: &ServiceTier) -> bool { + service_tier_id(service_tier) == SERVICE_TIER_PRIORITY +} - pub fn is_priority(&self) -> bool { - self.as_str() == SERVICE_TIER_PRIORITY - } - - pub fn is_flex(&self) -> bool { - self.as_str() == SERVICE_TIER_FLEX - } +pub fn is_flex_service_tier(service_tier: &ServiceTier) -> bool { + service_tier_id(service_tier) == SERVICE_TIER_FLEX } impl AsRef for ServiceTier { fn as_ref(&self) -> &str { - self.as_str() + self.0.as_str() } } impl From<&str> for ServiceTier { fn from(value: &str) -> Self { - Self::new(value) + Self(value.to_string()) } } impl From for ServiceTier { fn from(value: String) -> Self { - Self::new(value) + Self(value) } } @@ -407,7 +401,7 @@ impl From for String { impl std::fmt::Display for ServiceTier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(self.as_str()) + f.write_str(service_tier_id(self)) } } diff --git a/codex-rs/protocol/src/openai_models.rs b/codex-rs/protocol/src/openai_models.rs index 6f2daccea9..5afbee4098 100644 --- a/codex-rs/protocol/src/openai_models.rs +++ b/codex-rs/protocol/src/openai_models.rs @@ -19,6 +19,7 @@ use crate::config_types::Personality; use crate::config_types::ReasoningSummary; use crate::config_types::ServiceTier; use crate::config_types::Verbosity; +use crate::config_types::priority_service_tier; const PERSONALITY_PLACEHOLDER: &str = "{{ personality }}"; @@ -469,19 +470,24 @@ impl From for ModelPreset { } } +pub fn model_supports_service_tier(model: &ModelPreset, service_tier: &ServiceTier) -> bool { + model + .service_tiers + .iter() + .any(|tier| tier.id == *service_tier) +} + +pub fn model_service_tier<'a>( + model: &'a ModelPreset, + service_tier: &ServiceTier, +) -> Option<&'a ModelServiceTier> { + model + .service_tiers + .iter() + .find(|tier| tier.id == *service_tier) +} + impl ModelPreset { - pub fn supports_service_tier(&self, service_tier: &ServiceTier) -> bool { - self.service_tiers - .iter() - .any(|tier| tier.id == *service_tier) - } - - pub fn service_tier(&self, service_tier: &ServiceTier) -> Option<&ModelServiceTier> { - self.service_tiers - .iter() - .find(|tier| tier.id == *service_tier) - } - /// Filter models based on authentication mode. /// /// In ChatGPT mode, all models are visible. Otherwise, only API-supported models are shown. @@ -831,7 +837,7 @@ mod tests { message: "Try Spark.".to_string(), }), service_tiers: vec![ModelServiceTier { - id: ServiceTier::priority(), + id: priority_service_tier(), name: "Fast".to_string(), description: "Fast tier".to_string(), }], @@ -844,6 +850,9 @@ mod tests { message: "Try Spark.".to_string(), }) ); - assert!(preset.supports_service_tier(&ServiceTier::priority())); + assert!(model_supports_service_tier( + &preset, + &priority_service_tier() + )); } }