mirror of
https://github.com/openai/codex.git
synced 2026-11-03 08:22:30 +00:00
[codex] Generalize service tier slash commands (#21745)
## Why `/fast` was wired as a one-off slash command even though model metadata now exposes service tiers as catalog data. That meant adding another tier, such as a slower/cheaper tier, would require more hardcoded TUI plumbing instead of letting the model catalog drive the available commands. This change makes service-tier commands data-driven: each advertised `service_tiers` entry becomes a `/name` command using the catalog description, while the request path sends the tier `id` only when the selected model supports it. ## What Changed - Removed the hardcoded `/fast` slash-command variant and introduced dynamic service-tier command items in the composer and command popup. - Added toggle behavior for service-tier commands: invoking `/name` selects that tier, and invoking it again clears the selection. - Preserved the existing Fast-mode keybinding/status affordances by resolving the current model tier whose name is `fast`, while still sending the tier request value such as `priority`. - Persisted service-tier selections as raw request strings so non-fast tiers can round-trip through config. - Updated the Bedrock catalog entry to advertise fast support through `service_tiers` with `id: "priority"` and `name: "fast"`. - Added defensive filtering in core so unsupported selected service tiers are omitted from `/responses` requests. ## Validation - Added/updated coverage for dynamic service-tier slash command lookup, popup descriptions, composer dispatch, TUI fast toggling, and unsupported-tier omission in core request construction. - Local tests were not run per request. --------- Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
1 parent
47f1d7b40b
commit
7c0e54bf59
24 files changed
+919
-412
No files matched your search
@@ -1274,26 +1274,21 @@ impl App {
|
||||
AppEvent::PersistServiceTierSelection { service_tier } => {
|
||||
self.refresh_status_line();
|
||||
let profile = self.active_profile.as_deref();
|
||||
self.config.service_tier =
|
||||
service_tier.map(|service_tier| service_tier.request_value().to_string());
|
||||
self.config.service_tier = service_tier.clone();
|
||||
let mut edits = ConfigEditsBuilder::new(&self.config.codex_home)
|
||||
.with_profile(profile)
|
||||
.set_service_tier(service_tier);
|
||||
.set_service_tier(service_tier.clone());
|
||||
if service_tier.is_none() {
|
||||
self.config.notices.fast_default_opt_out = Some(true);
|
||||
edits = edits.set_fast_default_opt_out(/*opted_out*/ true);
|
||||
}
|
||||
match edits.apply().await {
|
||||
Ok(()) => {
|
||||
let status = if matches!(
|
||||
service_tier,
|
||||
Some(codex_protocol::config_types::ServiceTier::Fast)
|
||||
) {
|
||||
"on"
|
||||
let mut message = if let Some(service_tier) = service_tier {
|
||||
format!("Service tier set to {service_tier}")
|
||||
} else {
|
||||
"off"
|
||||
"Service tier cleared".to_string()
|
||||
};
|
||||
let mut message = format!("Fast mode set to {status}");
|
||||
if let Some(profile) = profile {
|
||||
message.push_str(" for ");
|
||||
message.push_str(profile);
|
||||
@@ -1302,14 +1297,14 @@ impl App {
|
||||
self.chat_widget.add_info_message(message, /*hint*/ None);
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!(error = %err, "failed to persist fast mode selection");
|
||||
tracing::error!(error = %err, "failed to persist service tier selection");
|
||||
if let Some(profile) = profile {
|
||||
self.chat_widget.add_error_message(format!(
|
||||
"Failed to save Fast mode for profile `{profile}`: {err}"
|
||||
"Failed to save service tier for profile `{profile}`: {err}"
|
||||
));
|
||||
} else {
|
||||
self.chat_widget.add_error_message(format!(
|
||||
"Failed to save default Fast mode: {err}"
|
||||
"Failed to save default service tier: {err}"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,10 +617,7 @@ impl App {
|
||||
|
||||
pub(super) fn fresh_session_config(&self) -> Config {
|
||||
let mut config = self.config.clone();
|
||||
config.service_tier = self
|
||||
.chat_widget
|
||||
.configured_service_tier()
|
||||
.map(|service_tier| service_tier.request_value().to_string());
|
||||
config.service_tier = self.chat_widget.configured_service_tier();
|
||||
config.notices.fast_default_opt_out = self.chat_widget.fast_default_opt_out();
|
||||
config
|
||||
}
|
||||
|
||||
@@ -3829,8 +3829,11 @@ async fn clear_ui_header_shows_fast_status_for_fast_capable_models() {
|
||||
set_fast_mode_test_catalog(&mut app.chat_widget);
|
||||
app.chat_widget
|
||||
.set_reasoning_effort(Some(ReasoningEffortConfig::XHigh));
|
||||
app.chat_widget
|
||||
.set_service_tier(Some(codex_protocol::config_types::ServiceTier::Fast));
|
||||
app.chat_widget.set_service_tier(Some(
|
||||
codex_protocol::config_types::ServiceTier::Fast
|
||||
.request_value()
|
||||
.to_string(),
|
||||
));
|
||||
set_chatgpt_auth(&mut app.chat_widget);
|
||||
set_fast_mode_test_catalog(&mut app.chat_widget);
|
||||
|
||||
@@ -4481,8 +4484,11 @@ fn active_turn_steer_race_extracts_actual_turn_id_from_mismatch() {
|
||||
#[tokio::test]
|
||||
async fn fresh_session_config_uses_current_service_tier() {
|
||||
let mut app = make_test_app().await;
|
||||
app.chat_widget
|
||||
.set_service_tier(Some(codex_protocol::config_types::ServiceTier::Fast));
|
||||
app.chat_widget.set_service_tier(Some(
|
||||
codex_protocol::config_types::ServiceTier::Fast
|
||||
.request_value()
|
||||
.to_string(),
|
||||
));
|
||||
|
||||
let config = app.fresh_session_config();
|
||||
|
||||
|
||||
@@ -63,10 +63,7 @@ impl App {
|
||||
thread_name: None,
|
||||
model: self.chat_widget.current_model().to_string(),
|
||||
model_provider_id: self.config.model_provider_id.clone(),
|
||||
service_tier: self
|
||||
.chat_widget
|
||||
.current_service_tier()
|
||||
.map(|service_tier| service_tier.request_value().to_string()),
|
||||
service_tier: self.chat_widget.current_service_tier().map(str::to_string),
|
||||
approval_policy: AskForApproval::from(
|
||||
self.config.permissions.approval_policy.value(),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user