mirror of
https://github.com/openai/codex.git
synced 2026-11-05 08:28:29 +00:00
[codex] Support model-defined reasoning efforts (#26444)
## Summary - accept non-empty model-defined reasoning effort values while preserving built-in effort behavior - propagate the non-Copy effort type through core, app-server, TUI, telemetry, and persistence call sites - preserve string wire encoding and expose an open-string schema for clients - update model selection and shortcut behavior for model-advertised effort values ## Root cause `ReasoningEffort` gained a string-backed custom variant, so it could no longer implement `Copy` or rely on derived closed-enum serialization. Existing consumers still moved effort values from shared references and assumed a fixed built-in value set. ## Validation - `just fmt` - Local tests and compilation were not run per request; relying on CI.
This commit is contained in:
1 parent
4a70e0ac1b
commit
8ac304c299
97 files changed
+685
-581
No files matched your search
@@ -712,21 +712,17 @@ impl App {
|
||||
.add_info_message("Reset local memories.".to_string(), /*hint*/ None);
|
||||
}
|
||||
|
||||
pub(super) fn reasoning_label(reasoning_effort: Option<ReasoningEffortConfig>) -> &'static str {
|
||||
pub(super) fn reasoning_label(reasoning_effort: Option<&ReasoningEffortConfig>) -> String {
|
||||
match reasoning_effort {
|
||||
Some(ReasoningEffortConfig::Minimal) => "minimal",
|
||||
Some(ReasoningEffortConfig::Low) => "low",
|
||||
Some(ReasoningEffortConfig::Medium) => "medium",
|
||||
Some(ReasoningEffortConfig::High) => "high",
|
||||
Some(ReasoningEffortConfig::XHigh) => "xhigh",
|
||||
None | Some(ReasoningEffortConfig::None) => "default",
|
||||
None | Some(ReasoningEffortConfig::None) => "default".to_string(),
|
||||
Some(reasoning_effort) => reasoning_effort.as_str().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn reasoning_label_for(
|
||||
model: &str,
|
||||
reasoning_effort: Option<ReasoningEffortConfig>,
|
||||
) -> Option<&'static str> {
|
||||
reasoning_effort: Option<&ReasoningEffortConfig>,
|
||||
) -> Option<String> {
|
||||
(!model.starts_with("codex-auto-")).then(|| Self::reasoning_label(reasoning_effort))
|
||||
}
|
||||
|
||||
@@ -737,7 +733,7 @@ impl App {
|
||||
pub(super) fn on_update_reasoning_effort(&mut self, effort: Option<ReasoningEffortConfig>) {
|
||||
// TODO(aibrahim): Remove this and don't use config as a state object.
|
||||
// Instead, explicitly pass the stored collaboration mode's effort into new sessions.
|
||||
self.config.model_reasoning_effort = effort;
|
||||
self.config.model_reasoning_effort = effort.clone();
|
||||
self.chat_widget.set_reasoning_effort(effort);
|
||||
}
|
||||
|
||||
|
||||
@@ -750,7 +750,7 @@ impl App {
|
||||
self.chat_widget.on_connectors_loaded(result, is_final);
|
||||
}
|
||||
AppEvent::UpdateReasoningEffort(effort) => {
|
||||
self.on_update_reasoning_effort(effort);
|
||||
self.on_update_reasoning_effort(effort.clone());
|
||||
self.sync_active_thread_reasoning_setting(app_server, effort)
|
||||
.await;
|
||||
}
|
||||
@@ -1300,19 +1300,23 @@ impl App {
|
||||
AppEvent::PersistModelSelection { model, effort } => {
|
||||
match crate::config_update::write_config_batch(
|
||||
app_server.request_handle(),
|
||||
crate::config_update::build_model_selection_edits(model.as_str(), effort),
|
||||
crate::config_update::build_model_selection_edits(
|
||||
model.as_str(),
|
||||
effort.as_ref(),
|
||||
),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => {
|
||||
let effort_label = effort
|
||||
.map(|selected_effort| selected_effort.to_string())
|
||||
.as_ref()
|
||||
.map(std::string::ToString::to_string)
|
||||
.unwrap_or_else(|| "default".to_string());
|
||||
tracing::info!("Selected model: {model}, Selected effort: {effort_label}");
|
||||
let mut message = format!("Model changed to {model}");
|
||||
if let Some(label) = Self::reasoning_label_for(&model, effort) {
|
||||
if let Some(label) = Self::reasoning_label_for(&model, effort.as_ref()) {
|
||||
message.push(' ');
|
||||
message.push_str(label);
|
||||
message.push_str(&label);
|
||||
}
|
||||
self.chat_widget.add_info_message(message, /*hint*/ None);
|
||||
}
|
||||
@@ -1607,7 +1611,7 @@ impl App {
|
||||
self.chat_widget.set_rate_limit_switch_prompt_hidden(hidden);
|
||||
}
|
||||
AppEvent::UpdatePlanModeReasoningEffort(effort) => {
|
||||
self.config.plan_mode_reasoning_effort = effort;
|
||||
self.config.plan_mode_reasoning_effort = effort.clone();
|
||||
self.chat_widget.set_plan_mode_reasoning_effort(effort);
|
||||
self.sync_active_thread_plan_mode_reasoning_setting(app_server)
|
||||
.await;
|
||||
|
||||
@@ -152,9 +152,11 @@ pub(super) fn apply_accepted_model_migration(
|
||||
});
|
||||
|
||||
config.model = Some(target_model.clone());
|
||||
config.model_reasoning_effort = Some(target_default_effort);
|
||||
config.model_reasoning_effort = Some(target_default_effort.clone());
|
||||
app_event_tx.send(AppEvent::UpdateModel(target_model.clone()));
|
||||
app_event_tx.send(AppEvent::UpdateReasoningEffort(Some(target_default_effort)));
|
||||
app_event_tx.send(AppEvent::UpdateReasoningEffort(Some(
|
||||
target_default_effort.clone(),
|
||||
)));
|
||||
app_event_tx.send(AppEvent::PersistModelSelection {
|
||||
model: target_model,
|
||||
effort: Some(target_default_effort),
|
||||
@@ -290,7 +292,7 @@ pub(super) async fn handle_model_migration_prompt_if_needed(
|
||||
app_event_tx,
|
||||
model.to_string(),
|
||||
target_model.clone(),
|
||||
target_preset.default_reasoning_effort,
|
||||
target_preset.default_reasoning_effort.clone(),
|
||||
);
|
||||
}
|
||||
ModelMigrationOutcome::Rejected => {
|
||||
|
||||
@@ -5241,7 +5241,7 @@ async fn override_turn_context_sends_thread_settings_update() {
|
||||
.expect("thread/start should succeed");
|
||||
let thread_id = started.session.thread_id;
|
||||
let initial_model = started.session.model.clone();
|
||||
let initial_effort = started.session.reasoning_effort;
|
||||
let initial_effort = started.session.reasoning_effort.clone();
|
||||
app.enqueue_primary_thread_session(started.session, started.turns)
|
||||
.await
|
||||
.expect("primary thread should be registered");
|
||||
@@ -5466,7 +5466,7 @@ async fn inactive_thread_settings_notification_updates_cached_collaboration_mode
|
||||
model: "gpt-plan".to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
effort: collaboration_mode.settings.reasoning_effort,
|
||||
effort: collaboration_mode.settings.reasoning_effort.clone(),
|
||||
summary: None,
|
||||
collaboration_mode: collaboration_mode.clone(),
|
||||
personality: Some(Personality::Pragmatic),
|
||||
|
||||
@@ -606,7 +606,7 @@ impl App {
|
||||
permissions_override,
|
||||
config.permissions.user_visible_workspace_roots(),
|
||||
model.to_string(),
|
||||
*effort,
|
||||
effort.clone(),
|
||||
*summary,
|
||||
service_tier.clone(),
|
||||
collaboration_mode.clone(),
|
||||
|
||||
@@ -124,7 +124,7 @@ impl App {
|
||||
.as_ref()
|
||||
.map(|profile| profile.id.clone()),
|
||||
model: model.clone(),
|
||||
effort: effort.unwrap_or_default(),
|
||||
effort: effort.clone().unwrap_or_default(),
|
||||
summary: *summary,
|
||||
service_tier: service_tier.clone(),
|
||||
collaboration_mode: collaboration_mode.clone(),
|
||||
@@ -172,7 +172,7 @@ impl App {
|
||||
fn apply_thread_settings_to_session(session: &mut ThreadSessionState, settings: &ThreadSettings) {
|
||||
if settings.collaboration_mode.mode == ModeKind::Default {
|
||||
session.model = settings.model.clone();
|
||||
session.reasoning_effort = settings.effort;
|
||||
session.reasoning_effort = settings.effort.clone();
|
||||
}
|
||||
session.model_provider_id = settings.model_provider.clone();
|
||||
session.service_tier = settings.service_tier.clone();
|
||||
@@ -190,7 +190,7 @@ fn apply_thread_settings_to_session(session: &mut ThreadSessionState, settings:
|
||||
.settings
|
||||
.model
|
||||
.clone_from(&settings.model);
|
||||
collaboration_mode.settings.reasoning_effort = settings.effort;
|
||||
collaboration_mode.settings.reasoning_effort = settings.effort.clone();
|
||||
session.collaboration_mode = Some(Box::new(collaboration_mode));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user