diff --git a/codex-rs/config/src/config_toml.rs b/codex-rs/config/src/config_toml.rs index 0a82eaf53..989aab169 100644 --- a/codex-rs/config/src/config_toml.rs +++ b/codex-rs/config/src/config_toml.rs @@ -41,7 +41,6 @@ use codex_protocol::config_types::ForcedLoginMethod; use codex_protocol::config_types::Personality; use codex_protocol::config_types::ReasoningSummary; use codex_protocol::config_types::SandboxMode; -use codex_protocol::config_types::ServiceTier; use codex_protocol::config_types::TrustLevel; use codex_protocol::config_types::Verbosity; use codex_protocol::config_types::WebSearchMode; @@ -307,8 +306,9 @@ pub struct ConfigToml { /// Optionally specify a personality for the model pub personality: Option, - /// Optional explicit service tier preference for new turns (`fast` or `flex`). - pub service_tier: Option, + /// Optional explicit service tier request id for new turns (for example + /// `priority` or `flex`; legacy `fast` also works). + pub service_tier: Option, /// Base URL for requests to ChatGPT (as opposed to the OpenAI API). pub chatgpt_base_url: Option, diff --git a/codex-rs/config/src/profile_toml.rs b/codex-rs/config/src/profile_toml.rs index fab78a128..420eb4614 100644 --- a/codex-rs/config/src/profile_toml.rs +++ b/codex-rs/config/src/profile_toml.rs @@ -12,7 +12,6 @@ use crate::types::WindowsToml; use codex_features::FeaturesToml; use codex_protocol::config_types::ReasoningSummary; use codex_protocol::config_types::SandboxMode; -use codex_protocol::config_types::ServiceTier; use codex_protocol::config_types::Verbosity; use codex_protocol::config_types::WebSearchMode; use codex_protocol::openai_models::ReasoningEffort; @@ -24,8 +23,9 @@ use codex_protocol::protocol::AskForApproval; #[schemars(deny_unknown_fields)] pub struct ConfigProfile { pub model: Option, - /// Optional explicit service tier preference for new turns (`fast` or `flex`). - pub service_tier: Option, + /// Optional explicit service tier request id for new turns (for example + /// `priority` or `flex`; legacy `fast` also works). + pub service_tier: Option, /// The key in the `model_providers` map identifying the /// [`ModelProviderInfo`] to use. pub model_provider: Option, diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index ecbd73093..edbf45694 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -670,12 +670,8 @@ "$ref": "#/definitions/SandboxMode" }, "service_tier": { - "allOf": [ - { - "$ref": "#/definitions/ServiceTier" - } - ], - "description": "Optional explicit service tier preference for new turns (`fast` or `flex`)." + "description": "Optional explicit service tier request id for new turns (for example `priority` or `flex`; legacy `fast` also works).", + "type": "string" }, "tools": { "$ref": "#/definitions/ToolsToml" @@ -2221,13 +2217,6 @@ }, "type": "object" }, - "ServiceTier": { - "enum": [ - "fast", - "flex" - ], - "type": "string" - }, "SessionPickerViewMode": { "description": "Preferred layout for the resume/fork session picker.", "enum": [ @@ -4502,12 +4491,8 @@ "description": "Sandbox configuration to apply if `sandbox` is `WorkspaceWrite`." }, "service_tier": { - "allOf": [ - { - "$ref": "#/definitions/ServiceTier" - } - ], - "description": "Optional explicit service tier preference for new turns (`fast` or `flex`)." + "description": "Optional explicit service tier request id for new turns (for example `priority` or `flex`; legacy `fast` also works).", + "type": "string" }, "shell_environment_policy": { "allOf": [ diff --git a/codex-rs/core/src/config/config_tests.rs b/codex-rs/core/src/config/config_tests.rs index 25f6697c7..3059bd530 100644 --- a/codex-rs/core/src/config/config_tests.rs +++ b/codex-rs/core/src/config/config_tests.rs @@ -7297,6 +7297,54 @@ async fn legacy_fast_service_tier_override_uses_priority_request_value() -> std: Ok(()) } +#[tokio::test] +async fn config_toml_service_tier_accepts_arbitrary_string() -> std::io::Result<()> { + let mut fixture = create_test_fixture()?; + fixture.cfg.service_tier = Some("experimental-tier-id".to_string()); + let cwd = fixture.cwd_path(); + let codex_home = fixture.codex_home(); + + let config = Config::load_from_base_config_with_overrides( + fixture.cfg, + ConfigOverrides { + cwd: Some(cwd), + ..Default::default() + }, + codex_home, + ) + .await?; + + assert_eq!( + config.service_tier, + Some("experimental-tier-id".to_string()) + ); + Ok(()) +} + +#[tokio::test] +async fn config_toml_legacy_fast_service_tier_uses_priority_request_value() -> std::io::Result<()> { + let mut fixture = create_test_fixture()?; + fixture.cfg.service_tier = Some("fast".to_string()); + let cwd = fixture.cwd_path(); + let codex_home = fixture.codex_home(); + + let config = Config::load_from_base_config_with_overrides( + fixture.cfg, + ConfigOverrides { + cwd: Some(cwd), + ..Default::default() + }, + codex_home, + ) + .await?; + + assert_eq!( + config.service_tier, + Some(ServiceTier::Fast.request_value().to_string()) + ); + Ok(()) +} + #[tokio::test] async fn fast_default_opt_out_notice_config_is_respected() -> std::io::Result<()> { let fixture = create_test_fixture()?; diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index e27002aef..b1277eda4 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -2734,10 +2734,7 @@ impl Config { notices.fast_default_opt_out = Some(true); None } - None => config_profile - .service_tier - .or(cfg.service_tier) - .map(|service_tier| service_tier.request_value().to_string()), + None => config_profile.service_tier.or(cfg.service_tier), }; let service_tier = service_tier.and_then(|service_tier| { match ServiceTier::from_request_value(&service_tier) { diff --git a/codex-rs/core/src/session/config_lock.rs b/codex-rs/core/src/session/config_lock.rs index 10f224264..3e8c36734 100644 --- a/codex-rs/core/src/session/config_lock.rs +++ b/codex-rs/core/src/session/config_lock.rs @@ -109,10 +109,7 @@ fn save_session_resolved_fields(sc: &SessionConfiguration, lock_config: &mut Con lock_config.model = Some(sc.collaboration_mode.model().to_string()); lock_config.model_reasoning_effort = sc.collaboration_mode.reasoning_effort(); lock_config.model_reasoning_summary = sc.model_reasoning_summary; - lock_config.service_tier = sc - .service_tier - .as_deref() - .and_then(codex_protocol::config_types::ServiceTier::from_request_value); + lock_config.service_tier = sc.service_tier.clone(); lock_config.instructions = Some(sc.base_instructions.clone()); lock_config.developer_instructions = sc.developer_instructions.clone(); lock_config.compact_prompt = sc.compact_prompt.clone();