Use standard service tier conversions

This commit is contained in:
Ahmed Ibrahim
2026-05-03 07:24:16 +03:00
parent 7ee21cc692
commit 93f7d42258
14 changed files with 78 additions and 89 deletions
+20 -22
View File
@@ -25,15 +25,13 @@ use codex_protocol::config_types::ForcedLoginMethod;
use codex_protocol::config_types::ModeKind;
use codex_protocol::config_types::Personality;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::config_types::SERVICE_TIER_FLEX;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
use codex_protocol::config_types::SandboxMode as CoreSandboxMode;
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;
@@ -133,26 +131,26 @@ pub enum ServiceTier {
Flex,
}
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 service_tier_from_core(service_tier: &CoreServiceTier) -> Option<ServiceTier> {
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<ServiceTier> for CoreServiceTier {
fn from(value: ServiceTier) -> Self {
service_tier_to_core(value)
match value {
ServiceTier::Fast => SERVICE_TIER_PRIORITY.into(),
ServiceTier::Flex => SERVICE_TIER_FLEX.into(),
}
}
}
impl TryFrom<&CoreServiceTier> for ServiceTier {
type Error = ();
fn try_from(value: &CoreServiceTier) -> Result<Self, Self::Error> {
if value.as_ref() == SERVICE_TIER_PRIORITY {
Ok(ServiceTier::Fast)
} else if value.as_ref() == SERVICE_TIER_FLEX {
Ok(ServiceTier::Flex)
} else {
Err(())
}
}
}
@@ -241,8 +241,6 @@ 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;
@@ -342,6 +340,7 @@ use codex_protocol::ThreadId;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::ForcedLoginMethod;
use codex_protocol::config_types::Personality;
use codex_protocol::config_types::ServiceTier as CoreServiceTier;
use codex_protocol::config_types::TrustLevel;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::dynamic_tools::DynamicToolSpec as CoreDynamicToolSpec;
@@ -2925,7 +2924,7 @@ impl CodexMessageProcessor {
service_tier: config_snapshot
.service_tier
.as_ref()
.and_then(service_tier_from_core),
.and_then(|service_tier| ServiceTier::try_from(service_tier).ok()),
cwd: config_snapshot.cwd,
instruction_sources,
approval_policy: config_snapshot.approval_policy.into(),
@@ -3027,8 +3026,8 @@ impl CodexMessageProcessor {
fn resolve_service_tier_override(
service_tier: Option<Option<ServiceTier>>,
) -> Option<Option<codex_protocol::config_types::ServiceTier>> {
service_tier.map(|service_tier| service_tier.map(service_tier_to_core))
) -> Option<Option<CoreServiceTier>> {
service_tier.map(|service_tier| service_tier.map(Into::into))
}
async fn thread_archive(&self, request_id: ConnectionRequestId, params: ThreadArchiveParams) {
@@ -4514,7 +4513,7 @@ impl CodexMessageProcessor {
service_tier: session_configured
.service_tier
.as_ref()
.and_then(service_tier_from_core),
.and_then(|service_tier| ServiceTier::try_from(service_tier).ok()),
cwd: session_configured.cwd,
instruction_sources,
approval_policy: session_configured.approval_policy.into(),
@@ -5152,7 +5151,7 @@ impl CodexMessageProcessor {
service_tier: session_configured
.service_tier
.as_ref()
.and_then(service_tier_from_core),
.and_then(|service_tier| ServiceTier::try_from(service_tier).ok()),
cwd: session_configured.cwd,
instruction_sources,
approval_policy: session_configured.approval_policy.into(),
@@ -8510,7 +8509,9 @@ async fn handle_pending_thread_resume_request(
thread,
model,
model_provider: model_provider_id,
service_tier: service_tier.as_ref().and_then(service_tier_from_core),
service_tier: service_tier
.as_ref()
.and_then(|service_tier| ServiceTier::try_from(service_tier).ok()),
cwd,
instruction_sources,
approval_policy: approval_policy.into(),
@@ -8680,13 +8681,13 @@ fn collect_resume_override_mismatches(
));
}
if let Some(requested_service_tier) = request.service_tier.as_ref()
&& requested_service_tier.map(service_tier_to_core).as_ref()
&& requested_service_tier.map(CoreServiceTier::from).as_ref()
!= config_snapshot.service_tier.as_ref()
{
let active_service_tier = config_snapshot
.service_tier
.as_ref()
.and_then(service_tier_from_core);
.and_then(|service_tier| ServiceTier::try_from(service_tier).ok());
mismatch_details.push(format!(
"service_tier requested={requested_service_tier:?} active={active_service_tier:?}"
));
@@ -10070,7 +10071,7 @@ mod tests {
use codex_model_provider_info::ModelProviderInfo;
use codex_model_provider_info::WireApi;
use codex_protocol::ThreadId;
use codex_protocol::config_types::flex_service_tier;
use codex_protocol::config_types::SERVICE_TIER_FLEX;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
@@ -10567,7 +10568,7 @@ mod tests {
let config_snapshot = ThreadConfigSnapshot {
model: "gpt-5".to_string(),
model_provider_id: "openai".to_string(),
service_tier: Some(flex_service_tier()),
service_tier: Some(SERVICE_TIER_FLEX.into()),
approval_policy: codex_protocol::protocol::AskForApproval::OnRequest,
approvals_reviewer: codex_protocol::config_types::ApprovalsReviewer::User,
permission_profile: codex_protocol::models::PermissionProfile::Disabled,
+4 -2
View File
@@ -5,7 +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::config_types::SERVICE_TIER_PRIORITY;
use codex_protocol::openai_models::ModelPreset;
use codex_protocol::openai_models::ModelServiceTier as CoreModelServiceTier;
use codex_protocol::openai_models::ReasoningEffortPreset;
@@ -53,7 +53,9 @@ fn model_from_preset(preset: ModelPreset) -> Model {
fn legacy_additional_speed_tiers(service_tiers: &[CoreModelServiceTier]) -> Vec<String> {
service_tiers
.iter()
.filter_map(|tier| is_priority_service_tier(&tier.id).then_some("fast".to_string()))
.filter_map(|tier| {
(tier.id.as_ref() == SERVICE_TIER_PRIORITY).then_some("fast".to_string())
})
.collect()
}
@@ -12,7 +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::config_types::SERVICE_TIER_PRIORITY;
use codex_protocol::openai_models::ModelPreset;
use codex_protocol::openai_models::ModelServiceTier as CoreModelServiceTier;
use pretty_assertions::assert_eq;
@@ -60,7 +60,9 @@ fn model_from_preset(preset: &ModelPreset) -> Model {
fn legacy_additional_speed_tiers(service_tiers: &[CoreModelServiceTier]) -> Vec<String> {
service_tiers
.iter()
.filter_map(|tier| is_priority_service_tier(&tier.id).then_some("fast".to_string()))
.filter_map(|tier| {
(tier.id.as_ref() == SERVICE_TIER_PRIORITY).then_some("fast".to_string())
})
.collect()
}
+2 -2
View File
@@ -2,8 +2,8 @@ use codex_api::OpenAiVerbosity;
use codex_api::ResponsesApiRequest;
use codex_api::TextControls;
use codex_api::create_text_param_for_request;
use codex_protocol::config_types::SERVICE_TIER_FLEX;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::flex_service_tier;
use codex_protocol::models::FunctionCallOutputPayload;
use pretty_assertions::assert_eq;
@@ -156,7 +156,7 @@ fn serializes_flex_service_tier_when_set() {
stream: true,
include: vec![],
prompt_cache_key: None,
service_tier: Some(flex_service_tier().to_string()),
service_tier: Some(ServiceTier::from(SERVICE_TIER_FLEX).to_string()),
text: None,
client_metadata: None,
};
+2 -2
View File
@@ -81,6 +81,7 @@ use codex_protocol::config_types::AltScreenMode;
use codex_protocol::config_types::ForcedLoginMethod;
use codex_protocol::config_types::Personality;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
use codex_protocol::config_types::SandboxMode;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::ShellEnvironmentPolicy;
@@ -89,7 +90,6 @@ 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;
@@ -2661,7 +2661,7 @@ impl Config {
};
let service_tier = match service_tier {
Some(service_tier)
if is_priority_service_tier(&service_tier)
if service_tier.as_ref() == SERVICE_TIER_PRIORITY
&& !features.enabled(Feature::FastMode) =>
{
None
+2 -2
View File
@@ -312,9 +312,9 @@ use codex_otel::TelemetryAuthMode;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::Personality;
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
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;
@@ -789,7 +789,7 @@ fn get_service_tier(
account_plan_type
.is_some_and(is_enterprise_default_service_tier_plan)
.then(priority_service_tier)
.then(|| SERVICE_TIER_PRIORITY.into())
}
fn is_enterprise_default_service_tier_plan(plan_type: AccountPlanType) -> bool {
+6 -6
View File
@@ -32,9 +32,9 @@ use codex_models_manager::test_support::get_model_offline_for_tests;
use codex_protocol::AgentPath;
use codex_protocol::ThreadId;
use codex_protocol::account::PlanType as AccountPlanType;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
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;
@@ -2802,7 +2802,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() {
Some(AccountPlanType::Enterprise),
/*fast_mode_enabled*/ true,
),
Some(priority_service_tier())
Some(SERVICE_TIER_PRIORITY.into())
);
assert_eq!(
get_service_tier(
@@ -2811,7 +2811,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() {
Some(AccountPlanType::EnterpriseCbpUsageBased),
/*fast_mode_enabled*/ true,
),
Some(priority_service_tier())
Some(SERVICE_TIER_PRIORITY.into())
);
assert_eq!(
get_service_tier(
@@ -2820,7 +2820,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() {
Some(AccountPlanType::Business),
/*fast_mode_enabled*/ true,
),
Some(priority_service_tier())
Some(SERVICE_TIER_PRIORITY.into())
);
assert_eq!(
get_service_tier(
@@ -2829,7 +2829,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() {
Some(AccountPlanType::Team),
/*fast_mode_enabled*/ true,
),
Some(priority_service_tier())
Some(SERVICE_TIER_PRIORITY.into())
);
assert_eq!(
get_service_tier(
@@ -2838,7 +2838,7 @@ fn get_service_tier_defaults_enterprise_accounts_to_fast() {
Some(AccountPlanType::SelfServeBusinessUsageBased),
/*fast_mode_enabled*/ true,
),
Some(priority_service_tier())
Some(SERVICE_TIER_PRIORITY.into())
);
}
+4 -4
View File
@@ -1,7 +1,7 @@
use anyhow::Result;
use codex_features::Feature;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
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;
@@ -270,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(priority_service_tier()))
test.submit_turn_with_service_tier("hello", Some(SERVICE_TIER_PRIORITY.into()))
.await?;
assert_eq!(server.handshakes().len(), 1);
@@ -314,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(priority_service_tier());
config.service_tier = Some(SERVICE_TIER_PRIORITY.into());
});
let test = builder.build_with_websocket_server(&server).await?;
@@ -386,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(priority_service_tier()))
test.submit_turn_with_service_tier("first", Some(SERVICE_TIER_PRIORITY.into()))
.await?;
test.submit_turn_with_service_tier("second", /*service_tier*/ None)
.await?;
+4 -4
View File
@@ -4,9 +4,9 @@ use codex_features::Feature;
use codex_login::CodexAuth;
use codex_models_manager::manager::RefreshStrategy;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::config_types::SERVICE_TIER_FLEX;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
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;
@@ -299,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(priority_service_tier()))
test.submit_turn_with_service_tier("fast turn", Some(SERVICE_TIER_PRIORITY.into()))
.await?;
test.submit_turn_with_service_tier("standard turn", /*service_tier*/ None)
.await?;
@@ -325,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(flex_service_tier()))
test.submit_turn_with_service_tier("flex turn", Some(SERVICE_TIER_FLEX.into()))
.await?;
let request = resp_mock.single_request();
+11 -5
View File
@@ -3,8 +3,8 @@ use codex_features::Feature;
use codex_git_utils::diff_since_latest_init;
use codex_git_utils::reset_git_repository;
use codex_protocol::ThreadId;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
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;
@@ -254,14 +254,17 @@ async fn memories_startup_phase1_uses_live_thread_service_tier() -> anyhow::Resu
model: None,
effort: None,
summary: None,
service_tier: Some(Some(priority_service_tier())),
service_tier: Some(Some(SERVICE_TIER_PRIORITY.into())),
collaboration_mode: None,
personality: None,
})
.await?;
let config_snapshot = wait_for_service_tier(&test, Some(priority_service_tier())).await?;
assert_eq!(config_snapshot.service_tier, Some(priority_service_tier()));
let config_snapshot = wait_for_service_tier(&test, Some(SERVICE_TIER_PRIORITY.into())).await?;
assert_eq!(
config_snapshot.service_tier,
Some(SERVICE_TIER_PRIORITY.into())
);
let context = crate::runtime::MemoryStartupContext::new(
Arc::clone(&test.thread_manager),
@@ -278,7 +281,10 @@ async fn memories_startup_phase1_uses_live_thread_service_tier() -> anyhow::Resu
ReasoningEffort::Low,
)
.await;
assert_eq!(request_context.service_tier, Some(priority_service_tier()));
assert_eq!(
request_context.service_tier,
Some(SERVICE_TIER_PRIORITY.into())
);
shutdown_test_codex(&test).await?;
Ok(())
@@ -1,7 +1,7 @@
use codex_models_manager::model_info::BASE_INSTRUCTIONS;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::config_types::SERVICE_TIER_PRIORITY;
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: priority_service_tier(),
id: SERVICE_TIER_PRIORITY.into(),
name: "Fast".to_string(),
description: "Fast tier".to_string(),
}],
+1 -21
View File
@@ -355,26 +355,6 @@ pub const SERVICE_TIER_FLEX: &str = "flex";
#[ts(type = "string")]
pub struct ServiceTier(String);
pub fn priority_service_tier() -> ServiceTier {
ServiceTier::from(SERVICE_TIER_PRIORITY)
}
pub fn flex_service_tier() -> ServiceTier {
ServiceTier::from(SERVICE_TIER_FLEX)
}
pub fn service_tier_id(service_tier: &ServiceTier) -> &str {
service_tier.as_ref()
}
pub fn is_priority_service_tier(service_tier: &ServiceTier) -> bool {
service_tier_id(service_tier) == SERVICE_TIER_PRIORITY
}
pub fn is_flex_service_tier(service_tier: &ServiceTier) -> bool {
service_tier_id(service_tier) == SERVICE_TIER_FLEX
}
impl AsRef<str> for ServiceTier {
fn as_ref(&self) -> &str {
self.0.as_str()
@@ -401,7 +381,7 @@ impl From<ServiceTier> for String {
impl std::fmt::Display for ServiceTier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(service_tier_id(self))
f.write_str(self.as_ref())
}
}
+3 -3
View File
@@ -17,9 +17,9 @@ use ts_rs::TS;
use crate::config_types::Personality;
use crate::config_types::ReasoningSummary;
use crate::config_types::SERVICE_TIER_PRIORITY;
use crate::config_types::ServiceTier;
use crate::config_types::Verbosity;
use crate::config_types::priority_service_tier;
const PERSONALITY_PLACEHOLDER: &str = "{{ personality }}";
@@ -837,7 +837,7 @@ mod tests {
message: "Try Spark.".to_string(),
}),
service_tiers: vec![ModelServiceTier {
id: priority_service_tier(),
id: SERVICE_TIER_PRIORITY.into(),
name: "Fast".to_string(),
description: "Fast tier".to_string(),
}],
@@ -852,7 +852,7 @@ mod tests {
);
assert!(model_supports_service_tier(
&preset,
&priority_service_tier()
&SERVICE_TIER_PRIORITY.into()
));
}
}