mirror of
https://github.com/openai/codex.git
synced 2026-11-07 08:34:29 +00:00
Allow string service tiers in config TOML (#21697)
## Why `service_tier` in `config.toml` and profile config was still modeled as an enum, which blocked newer or experimental service tier IDs even though the runtime paths already carry string IDs. This change makes the TOML-facing config accept string service tier IDs directly while keeping the legacy `fast` alias behavior by normalizing it to the request value `priority`. ## What Changed - change the TOML-facing `service_tier` fields in global and profile config to `Option<String>` - keep config-load normalization so legacy `fast` still resolves to `priority` - persist resolved service tier strings directly in config locks so arbitrary IDs round-trip cleanly - regenerate the config schema and add config coverage for arbitrary string IDs plus legacy `fast` normalization ## Verification - added config tests for arbitrary string service tiers and legacy `fast` normalization - ran `just write-config-schema` - CI --------- Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
1 parent
d9feaffffb
commit
317213fd33
6 files changed
+60
-33
No files matched your search
@@ -41,7 +41,6 @@ use codex_protocol::config_types::ForcedLoginMethod;
|
|||||||
use codex_protocol::config_types::Personality;
|
use codex_protocol::config_types::Personality;
|
||||||
use codex_protocol::config_types::ReasoningSummary;
|
use codex_protocol::config_types::ReasoningSummary;
|
||||||
use codex_protocol::config_types::SandboxMode;
|
use codex_protocol::config_types::SandboxMode;
|
||||||
use codex_protocol::config_types::ServiceTier;
|
|
||||||
use codex_protocol::config_types::TrustLevel;
|
use codex_protocol::config_types::TrustLevel;
|
||||||
use codex_protocol::config_types::Verbosity;
|
use codex_protocol::config_types::Verbosity;
|
||||||
use codex_protocol::config_types::WebSearchMode;
|
use codex_protocol::config_types::WebSearchMode;
|
||||||
@@ -307,8 +306,9 @@ pub struct ConfigToml {
|
|||||||
/// Optionally specify a personality for the model
|
/// Optionally specify a personality for the model
|
||||||
pub personality: Option<Personality>,
|
pub personality: Option<Personality>,
|
||||||
|
|
||||||
/// Optional explicit service tier preference for new turns (`fast` or `flex`).
|
/// Optional explicit service tier request id for new turns (for example
|
||||||
pub service_tier: Option<ServiceTier>,
|
/// `priority` or `flex`; legacy `fast` also works).
|
||||||
|
pub service_tier: Option<String>,
|
||||||
|
|
||||||
/// Base URL for requests to ChatGPT (as opposed to the OpenAI API).
|
/// Base URL for requests to ChatGPT (as opposed to the OpenAI API).
|
||||||
pub chatgpt_base_url: Option<String>,
|
pub chatgpt_base_url: Option<String>,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ use crate::types::WindowsToml;
|
|||||||
use codex_features::FeaturesToml;
|
use codex_features::FeaturesToml;
|
||||||
use codex_protocol::config_types::ReasoningSummary;
|
use codex_protocol::config_types::ReasoningSummary;
|
||||||
use codex_protocol::config_types::SandboxMode;
|
use codex_protocol::config_types::SandboxMode;
|
||||||
use codex_protocol::config_types::ServiceTier;
|
|
||||||
use codex_protocol::config_types::Verbosity;
|
use codex_protocol::config_types::Verbosity;
|
||||||
use codex_protocol::config_types::WebSearchMode;
|
use codex_protocol::config_types::WebSearchMode;
|
||||||
use codex_protocol::openai_models::ReasoningEffort;
|
use codex_protocol::openai_models::ReasoningEffort;
|
||||||
@@ -24,8 +23,9 @@ use codex_protocol::protocol::AskForApproval;
|
|||||||
#[schemars(deny_unknown_fields)]
|
#[schemars(deny_unknown_fields)]
|
||||||
pub struct ConfigProfile {
|
pub struct ConfigProfile {
|
||||||
pub model: Option<String>,
|
pub model: Option<String>,
|
||||||
/// Optional explicit service tier preference for new turns (`fast` or `flex`).
|
/// Optional explicit service tier request id for new turns (for example
|
||||||
pub service_tier: Option<ServiceTier>,
|
/// `priority` or `flex`; legacy `fast` also works).
|
||||||
|
pub service_tier: Option<String>,
|
||||||
/// The key in the `model_providers` map identifying the
|
/// The key in the `model_providers` map identifying the
|
||||||
/// [`ModelProviderInfo`] to use.
|
/// [`ModelProviderInfo`] to use.
|
||||||
pub model_provider: Option<String>,
|
pub model_provider: Option<String>,
|
||||||
|
|||||||
@@ -670,12 +670,8 @@
|
|||||||
"$ref": "#/definitions/SandboxMode"
|
"$ref": "#/definitions/SandboxMode"
|
||||||
},
|
},
|
||||||
"service_tier": {
|
"service_tier": {
|
||||||
"allOf": [
|
"description": "Optional explicit service tier request id for new turns (for example `priority` or `flex`; legacy `fast` also works).",
|
||||||
{
|
"type": "string"
|
||||||
"$ref": "#/definitions/ServiceTier"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Optional explicit service tier preference for new turns (`fast` or `flex`)."
|
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"$ref": "#/definitions/ToolsToml"
|
"$ref": "#/definitions/ToolsToml"
|
||||||
@@ -2221,13 +2217,6 @@
|
|||||||
},
|
},
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"ServiceTier": {
|
|
||||||
"enum": [
|
|
||||||
"fast",
|
|
||||||
"flex"
|
|
||||||
],
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"SessionPickerViewMode": {
|
"SessionPickerViewMode": {
|
||||||
"description": "Preferred layout for the resume/fork session picker.",
|
"description": "Preferred layout for the resume/fork session picker.",
|
||||||
"enum": [
|
"enum": [
|
||||||
@@ -4502,12 +4491,8 @@
|
|||||||
"description": "Sandbox configuration to apply if `sandbox` is `WorkspaceWrite`."
|
"description": "Sandbox configuration to apply if `sandbox` is `WorkspaceWrite`."
|
||||||
},
|
},
|
||||||
"service_tier": {
|
"service_tier": {
|
||||||
"allOf": [
|
"description": "Optional explicit service tier request id for new turns (for example `priority` or `flex`; legacy `fast` also works).",
|
||||||
{
|
"type": "string"
|
||||||
"$ref": "#/definitions/ServiceTier"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Optional explicit service tier preference for new turns (`fast` or `flex`)."
|
|
||||||
},
|
},
|
||||||
"shell_environment_policy": {
|
"shell_environment_policy": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
|
|||||||
@@ -7297,6 +7297,54 @@ async fn legacy_fast_service_tier_override_uses_priority_request_value() -> std:
|
|||||||
Ok(())
|
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]
|
#[tokio::test]
|
||||||
async fn fast_default_opt_out_notice_config_is_respected() -> std::io::Result<()> {
|
async fn fast_default_opt_out_notice_config_is_respected() -> std::io::Result<()> {
|
||||||
let fixture = create_test_fixture()?;
|
let fixture = create_test_fixture()?;
|
||||||
|
|||||||
@@ -2734,10 +2734,7 @@ impl Config {
|
|||||||
notices.fast_default_opt_out = Some(true);
|
notices.fast_default_opt_out = Some(true);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
None => config_profile
|
None => config_profile.service_tier.or(cfg.service_tier),
|
||||||
.service_tier
|
|
||||||
.or(cfg.service_tier)
|
|
||||||
.map(|service_tier| service_tier.request_value().to_string()),
|
|
||||||
};
|
};
|
||||||
let service_tier = service_tier.and_then(|service_tier| {
|
let service_tier = service_tier.and_then(|service_tier| {
|
||||||
match ServiceTier::from_request_value(&service_tier) {
|
match ServiceTier::from_request_value(&service_tier) {
|
||||||
|
|||||||
@@ -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 = Some(sc.collaboration_mode.model().to_string());
|
||||||
lock_config.model_reasoning_effort = sc.collaboration_mode.reasoning_effort();
|
lock_config.model_reasoning_effort = sc.collaboration_mode.reasoning_effort();
|
||||||
lock_config.model_reasoning_summary = sc.model_reasoning_summary;
|
lock_config.model_reasoning_summary = sc.model_reasoning_summary;
|
||||||
lock_config.service_tier = sc
|
lock_config.service_tier = sc.service_tier.clone();
|
||||||
.service_tier
|
|
||||||
.as_deref()
|
|
||||||
.and_then(codex_protocol::config_types::ServiceTier::from_request_value);
|
|
||||||
lock_config.instructions = Some(sc.base_instructions.clone());
|
lock_config.instructions = Some(sc.base_instructions.clone());
|
||||||
lock_config.developer_instructions = sc.developer_instructions.clone();
|
lock_config.developer_instructions = sc.developer_instructions.clone();
|
||||||
lock_config.compact_prompt = sc.compact_prompt.clone();
|
lock_config.compact_prompt = sc.compact_prompt.clone();
|
||||||
|
|||||||
Reference in new issue
Block a user