Compare commits

...

2 Commits

Author SHA1 Message Date
Ahmed Ibrahim
da8716b9e3 Inline service tier alias normalization 2026-05-10 06:09:18 +03:00
Ahmed Ibrahim
5fb3de060b Save priority service tier as fast config value 2026-05-10 05:46:54 +03:00
5 changed files with 81 additions and 5 deletions

View File

@@ -73,6 +73,7 @@ use codex_otel::current_span_w3c_trace_context;
use codex_protocol::SessionId;
use codex_protocol::ThreadId;
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::Verbosity as VerbosityConfig;
use codex_protocol::models::ResponseItem;
use codex_protocol::openai_models::ModelInfo;
@@ -740,8 +741,14 @@ impl ModelClient {
prompt.output_schema_strict,
);
let prompt_cache_key = Some(self.state.thread_id.to_string());
let service_tier =
service_tier.filter(|service_tier| model_info.supports_service_tier(service_tier));
let service_tier = service_tier
.map(|configured_service_tier| {
match ServiceTier::from_request_value(&configured_service_tier) {
Some(service_tier) => service_tier.request_value().to_string(),
None => configured_service_tier,
}
})
.filter(|service_tier| model_info.supports_service_tier(service_tier));
let request = ResponsesApiRequest {
model: model_info.slug.clone(),
instructions: instructions.clone(),

View File

@@ -7,6 +7,7 @@ use codex_config::types::SessionPickerViewMode;
use codex_config::types::ToolSuggestDisabledTool;
use codex_features::FEATURES;
use codex_protocol::config_types::Personality;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::TrustLevel;
use codex_protocol::openai_models::ReasoningEffort;
use std::collections::BTreeMap;
@@ -535,9 +536,13 @@ impl ConfigDocument {
}),
ConfigEdit::SetServiceTier { service_tier } => Ok(self.write_profile_value(
&["service_tier"],
service_tier
.as_ref()
.map(|service_tier| value(service_tier.clone())),
service_tier.as_ref().map(|service_tier| {
let config_value = match ServiceTier::from_request_value(service_tier) {
Some(service_tier) => service_tier.config_value(),
None => service_tier,
};
value(config_value)
}),
)),
ConfigEdit::SetModelPersonality { personality } => Ok(self.write_profile_value(
&["personality"],

View File

@@ -3,6 +3,7 @@ use codex_config::types::AppToolApproval;
use codex_config::types::McpServerToolConfig;
use codex_config::types::McpServerTransportConfig;
use codex_config::types::SessionPickerViewMode;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::openai_models::ReasoningEffort;
use pretty_assertions::assert_eq;
#[cfg(unix)]
@@ -49,6 +50,38 @@ fn builder_with_edits_applies_custom_paths() {
assert_eq!(contents, "enabled = true\n");
}
#[test]
fn blocking_set_service_tier_persists_priority_alias_as_fast() {
let tmp = tempdir().expect("tmpdir");
let codex_home = tmp.path();
ConfigEditsBuilder::new(codex_home)
.set_service_tier(Some(ServiceTier::Fast.request_value().to_string()))
.apply_blocking()
.expect("persist");
let contents = std::fs::read_to_string(codex_home.join(CONFIG_TOML_FILE)).expect("read config");
let expected_service_tier = ServiceTier::Fast.config_value();
assert_eq!(
contents,
format!("service_tier = {expected_service_tier:?}\n")
);
}
#[test]
fn blocking_set_service_tier_preserves_custom_value() {
let tmp = tempdir().expect("tmpdir");
let codex_home = tmp.path();
ConfigEditsBuilder::new(codex_home)
.set_service_tier(Some("experimental-tier-id".to_string()))
.apply_blocking()
.expect("persist");
let contents = std::fs::read_to_string(codex_home.join(CONFIG_TOML_FILE)).expect("read config");
assert_eq!(contents, "service_tier = \"experimental-tier-id\"\n");
}
#[test]
fn session_picker_view_edit_writes_root_tui_setting() {
let tmp = tempdir().expect("tmpdir");

View File

@@ -356,6 +356,13 @@ pub enum ServiceTier {
}
impl ServiceTier {
pub const fn config_value(self) -> &'static str {
match self {
Self::Fast => "fast",
Self::Flex => "flex",
}
}
pub const fn request_value(self) -> &'static str {
match self {
Self::Fast => "priority",
@@ -678,6 +685,26 @@ mod tests {
}
}
#[test]
fn service_tier_aliases_have_distinct_config_and_request_values() {
let values = ["fast", "priority", "flex", "experimental-tier-id"].map(|value| {
match ServiceTier::from_request_value(value) {
Some(service_tier) => (service_tier.config_value(), service_tier.request_value()),
None => (value, value),
}
});
assert_eq!(
values,
[
("fast", "priority"),
("fast", "priority"),
("flex", "flex"),
("experimental-tier-id", "experimental-tier-id"),
]
);
}
#[test]
fn approvals_reviewer_serializes_auto_review_and_accepts_legacy_guardian_subagent() {
assert_eq!(ApprovalsReviewer::User.to_string(), "user");

View File

@@ -489,6 +489,10 @@ impl ModelPreset {
impl ModelInfo {
pub fn supports_service_tier(&self, service_tier: &str) -> bool {
let service_tier = match ServiceTier::from_request_value(service_tier) {
Some(service_tier) => service_tier.request_value(),
None => service_tier,
};
self.service_tiers
.iter()
.any(|tier| tier.id == service_tier)