mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Reasoning level update (#6586)
Automatically update reasoning levels when migrating between models
This commit is contained in:
1 parent
305fe73d83
commit
e3dd362c94
11 files changed
+234
-190
No files matched your search
Generated
+1
@@ -1048,6 +1048,7 @@ dependencies = [
|
|||||||
"codex-app-server-protocol",
|
"codex-app-server-protocol",
|
||||||
"codex-core",
|
"codex-core",
|
||||||
"codex-protocol",
|
"codex-protocol",
|
||||||
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|||||||
+3
-2
@@ -122,8 +122,8 @@ eventsource-stream = "0.2.3"
|
|||||||
futures = { version = "0.3", default-features = false }
|
futures = { version = "0.3", default-features = false }
|
||||||
http = "1.3.1"
|
http = "1.3.1"
|
||||||
icu_decimal = "2.1"
|
icu_decimal = "2.1"
|
||||||
icu_provider = { version = "2.1", features = ["sync"] }
|
|
||||||
icu_locale_core = "2.1"
|
icu_locale_core = "2.1"
|
||||||
|
icu_provider = { version = "2.1", features = ["sync"] }
|
||||||
ignore = "0.4.23"
|
ignore = "0.4.23"
|
||||||
image = { version = "^0.25.8", default-features = false }
|
image = { version = "^0.25.8", default-features = false }
|
||||||
indexmap = "2.12.0"
|
indexmap = "2.12.0"
|
||||||
@@ -140,6 +140,7 @@ mime_guess = "2.0.5"
|
|||||||
multimap = "0.10.0"
|
multimap = "0.10.0"
|
||||||
notify = "8.2.0"
|
notify = "8.2.0"
|
||||||
nucleo-matcher = "0.3.1"
|
nucleo-matcher = "0.3.1"
|
||||||
|
once_cell = "1"
|
||||||
openssl-sys = "*"
|
openssl-sys = "*"
|
||||||
opentelemetry = "0.30.0"
|
opentelemetry = "0.30.0"
|
||||||
opentelemetry-appender-tracing = "0.30.0"
|
opentelemetry-appender-tracing = "0.30.0"
|
||||||
@@ -278,8 +279,8 @@ opt-level = 0
|
|||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
# Uncomment to debug local changes.
|
# Uncomment to debug local changes.
|
||||||
# ratatui = { path = "../../ratatui" }
|
# ratatui = { path = "../../ratatui" }
|
||||||
ratatui = { git = "https://github.com/nornagon/ratatui", branch = "nornagon-v0.29.0-patch" }
|
|
||||||
crossterm = { git = "https://github.com/nornagon/crossterm", branch = "nornagon/color-query" }
|
crossterm = { git = "https://github.com/nornagon/crossterm", branch = "nornagon/color-query" }
|
||||||
|
ratatui = { git = "https://github.com/nornagon/ratatui", branch = "nornagon-v0.29.0-patch" }
|
||||||
|
|
||||||
# Uncomment to debug local changes.
|
# Uncomment to debug local changes.
|
||||||
# rmcp = { path = "../../rust-sdk/crates/rmcp" }
|
# rmcp = { path = "../../rust-sdk/crates/rmcp" }
|
||||||
@@ -93,10 +93,6 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
|
|||||||
display_name: "gpt-5.1".to_string(),
|
display_name: "gpt-5.1".to_string(),
|
||||||
description: "Broad world knowledge with strong general reasoning.".to_string(),
|
description: "Broad world knowledge with strong general reasoning.".to_string(),
|
||||||
supported_reasoning_efforts: vec![
|
supported_reasoning_efforts: vec![
|
||||||
ReasoningEffortOption {
|
|
||||||
reasoning_effort: ReasoningEffort::Minimal,
|
|
||||||
description: "Fastest responses with little reasoning".to_string(),
|
|
||||||
},
|
|
||||||
ReasoningEffortOption {
|
ReasoningEffortOption {
|
||||||
reasoning_effort: ReasoningEffort::Low,
|
reasoning_effort: ReasoningEffort::Low,
|
||||||
description: "Balances speed with some reasoning; useful for straightforward \
|
description: "Balances speed with some reasoning; useful for straightforward \
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { workspace = true, features = ["derive", "wrap_help"], optional = true }
|
clap = { workspace = true, features = ["derive", "wrap_help"], optional = true }
|
||||||
|
codex-app-server-protocol = { workspace = true }
|
||||||
codex-core = { workspace = true }
|
codex-core = { workspace = true }
|
||||||
codex-protocol = { workspace = true }
|
codex-protocol = { workspace = true }
|
||||||
codex-app-server-protocol = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
toml = { workspace = true, optional = true }
|
toml = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use codex_app_server_protocol::AuthMode;
|
use codex_app_server_protocol::AuthMode;
|
||||||
use codex_core::protocol_config_types::ReasoningEffort;
|
use codex_core::protocol_config_types::ReasoningEffort;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
/// A reasoning effort option that can be surfaced for a model.
|
/// A reasoning effort option that can be surfaced for a model.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@@ -10,8 +13,14 @@ pub struct ReasoningEffortPreset {
|
|||||||
pub description: &'static str,
|
pub description: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ModelUpgrade {
|
||||||
|
pub id: &'static str,
|
||||||
|
pub reasoning_effort_mapping: Option<HashMap<ReasoningEffort, ReasoningEffort>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Metadata describing a Codex-supported model.
|
/// Metadata describing a Codex-supported model.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ModelPreset {
|
pub struct ModelPreset {
|
||||||
/// Stable identifier for the preset.
|
/// Stable identifier for the preset.
|
||||||
pub id: &'static str,
|
pub id: &'static str,
|
||||||
@@ -28,162 +37,172 @@ pub struct ModelPreset {
|
|||||||
/// Whether this is the default model for new users.
|
/// Whether this is the default model for new users.
|
||||||
pub is_default: bool,
|
pub is_default: bool,
|
||||||
/// recommended upgrade model
|
/// recommended upgrade model
|
||||||
pub recommended_upgrade_model: Option<&'static str>,
|
pub upgrade: Option<ModelUpgrade>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const PRESETS: &[ModelPreset] = &[
|
static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
|
||||||
ModelPreset {
|
vec![
|
||||||
id: "gpt-5.1-codex",
|
ModelPreset {
|
||||||
model: "gpt-5.1-codex",
|
id: "gpt-5.1-codex",
|
||||||
display_name: "gpt-5.1-codex",
|
model: "gpt-5.1-codex",
|
||||||
description: "Optimized for codex.",
|
display_name: "gpt-5.1-codex",
|
||||||
default_reasoning_effort: ReasoningEffort::Medium,
|
description: "Optimized for codex.",
|
||||||
supported_reasoning_efforts: &[
|
default_reasoning_effort: ReasoningEffort::Medium,
|
||||||
ReasoningEffortPreset {
|
supported_reasoning_efforts: &[
|
||||||
effort: ReasoningEffort::Low,
|
ReasoningEffortPreset {
|
||||||
description: "Fastest responses with limited reasoning",
|
effort: ReasoningEffort::Low,
|
||||||
},
|
description: "Fastest responses with limited reasoning",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::Medium,
|
ReasoningEffortPreset {
|
||||||
description: "Dynamically adjusts reasoning based on the task",
|
effort: ReasoningEffort::Medium,
|
||||||
},
|
description: "Dynamically adjusts reasoning based on the task",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::High,
|
ReasoningEffortPreset {
|
||||||
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
effort: ReasoningEffort::High,
|
||||||
},
|
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
||||||
],
|
},
|
||||||
is_default: true,
|
],
|
||||||
recommended_upgrade_model: None,
|
is_default: true,
|
||||||
},
|
upgrade: None,
|
||||||
ModelPreset {
|
},
|
||||||
id: "gpt-5.1-codex-mini",
|
ModelPreset {
|
||||||
model: "gpt-5.1-codex-mini",
|
id: "gpt-5.1-codex-mini",
|
||||||
display_name: "gpt-5.1-codex-mini",
|
model: "gpt-5.1-codex-mini",
|
||||||
description: "Optimized for codex. Cheaper, faster, but less capable.",
|
display_name: "gpt-5.1-codex-mini",
|
||||||
default_reasoning_effort: ReasoningEffort::Medium,
|
description: "Optimized for codex. Cheaper, faster, but less capable.",
|
||||||
supported_reasoning_efforts: &[
|
default_reasoning_effort: ReasoningEffort::Medium,
|
||||||
ReasoningEffortPreset {
|
supported_reasoning_efforts: &[
|
||||||
effort: ReasoningEffort::Medium,
|
ReasoningEffortPreset {
|
||||||
description: "Dynamically adjusts reasoning based on the task",
|
effort: ReasoningEffort::Medium,
|
||||||
},
|
description: "Dynamically adjusts reasoning based on the task",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::High,
|
ReasoningEffortPreset {
|
||||||
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
effort: ReasoningEffort::High,
|
||||||
},
|
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
||||||
],
|
},
|
||||||
is_default: false,
|
],
|
||||||
recommended_upgrade_model: None,
|
is_default: false,
|
||||||
},
|
upgrade: None,
|
||||||
ModelPreset {
|
},
|
||||||
id: "gpt-5.1",
|
ModelPreset {
|
||||||
model: "gpt-5.1",
|
id: "gpt-5.1",
|
||||||
display_name: "gpt-5.1",
|
model: "gpt-5.1",
|
||||||
description: "Broad world knowledge with strong general reasoning.",
|
display_name: "gpt-5.1",
|
||||||
default_reasoning_effort: ReasoningEffort::Medium,
|
description: "Broad world knowledge with strong general reasoning.",
|
||||||
supported_reasoning_efforts: &[
|
default_reasoning_effort: ReasoningEffort::Medium,
|
||||||
ReasoningEffortPreset {
|
supported_reasoning_efforts: &[
|
||||||
effort: ReasoningEffort::Minimal,
|
ReasoningEffortPreset {
|
||||||
description: "Fastest responses with little reasoning",
|
effort: ReasoningEffort::Low,
|
||||||
},
|
description: "Balances speed with some reasoning; useful for straightforward queries and short explanations",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::Low,
|
ReasoningEffortPreset {
|
||||||
description: "Balances speed with some reasoning; useful for straightforward queries and short explanations",
|
effort: ReasoningEffort::Medium,
|
||||||
},
|
description: "Provides a solid balance of reasoning depth and latency for general-purpose tasks",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::Medium,
|
ReasoningEffortPreset {
|
||||||
description: "Provides a solid balance of reasoning depth and latency for general-purpose tasks",
|
effort: ReasoningEffort::High,
|
||||||
},
|
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::High,
|
],
|
||||||
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
is_default: false,
|
||||||
},
|
upgrade: None,
|
||||||
],
|
},
|
||||||
is_default: false,
|
// Deprecated models.
|
||||||
recommended_upgrade_model: None,
|
ModelPreset {
|
||||||
},
|
id: "gpt-5-codex",
|
||||||
// Deprecated models.
|
model: "gpt-5-codex",
|
||||||
ModelPreset {
|
display_name: "gpt-5-codex",
|
||||||
id: "gpt-5-codex",
|
description: "Optimized for codex.",
|
||||||
model: "gpt-5-codex",
|
default_reasoning_effort: ReasoningEffort::Medium,
|
||||||
display_name: "gpt-5-codex",
|
supported_reasoning_efforts: &[
|
||||||
description: "Optimized for codex.",
|
ReasoningEffortPreset {
|
||||||
default_reasoning_effort: ReasoningEffort::Medium,
|
effort: ReasoningEffort::Low,
|
||||||
supported_reasoning_efforts: &[
|
description: "Fastest responses with limited reasoning",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::Low,
|
ReasoningEffortPreset {
|
||||||
description: "Fastest responses with limited reasoning",
|
effort: ReasoningEffort::Medium,
|
||||||
},
|
description: "Dynamically adjusts reasoning based on the task",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::Medium,
|
ReasoningEffortPreset {
|
||||||
description: "Dynamically adjusts reasoning based on the task",
|
effort: ReasoningEffort::High,
|
||||||
},
|
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
||||||
ReasoningEffortPreset {
|
},
|
||||||
effort: ReasoningEffort::High,
|
],
|
||||||
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
is_default: false,
|
||||||
},
|
upgrade: Some(ModelUpgrade {
|
||||||
],
|
id: "gpt-5.1-codex",
|
||||||
is_default: false,
|
reasoning_effort_mapping: None,
|
||||||
recommended_upgrade_model: Some("gpt-5.1-codex"),
|
}),
|
||||||
},
|
},
|
||||||
ModelPreset {
|
ModelPreset {
|
||||||
id: "gpt-5-codex-mini",
|
id: "gpt-5-codex-mini",
|
||||||
model: "gpt-5-codex-mini",
|
model: "gpt-5-codex-mini",
|
||||||
display_name: "gpt-5-codex-mini",
|
display_name: "gpt-5-codex-mini",
|
||||||
description: "Optimized for codex. Cheaper, faster, but less capable.",
|
description: "Optimized for codex. Cheaper, faster, but less capable.",
|
||||||
default_reasoning_effort: ReasoningEffort::Medium,
|
default_reasoning_effort: ReasoningEffort::Medium,
|
||||||
supported_reasoning_efforts: &[
|
supported_reasoning_efforts: &[
|
||||||
ReasoningEffortPreset {
|
ReasoningEffortPreset {
|
||||||
effort: ReasoningEffort::Medium,
|
effort: ReasoningEffort::Medium,
|
||||||
description: "Dynamically adjusts reasoning based on the task",
|
description: "Dynamically adjusts reasoning based on the task",
|
||||||
},
|
},
|
||||||
ReasoningEffortPreset {
|
ReasoningEffortPreset {
|
||||||
effort: ReasoningEffort::High,
|
effort: ReasoningEffort::High,
|
||||||
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
is_default: false,
|
is_default: false,
|
||||||
recommended_upgrade_model: Some("gpt-5.1-codex-mini"),
|
upgrade: Some(ModelUpgrade {
|
||||||
},
|
id: "gpt-5.1-codex-mini",
|
||||||
ModelPreset {
|
reasoning_effort_mapping: None,
|
||||||
id: "gpt-5",
|
}),
|
||||||
model: "gpt-5",
|
},
|
||||||
display_name: "gpt-5",
|
ModelPreset {
|
||||||
description: "Broad world knowledge with strong general reasoning.",
|
id: "gpt-5",
|
||||||
default_reasoning_effort: ReasoningEffort::Medium,
|
model: "gpt-5",
|
||||||
supported_reasoning_efforts: &[
|
display_name: "gpt-5",
|
||||||
ReasoningEffortPreset {
|
description: "Broad world knowledge with strong general reasoning.",
|
||||||
effort: ReasoningEffort::Minimal,
|
default_reasoning_effort: ReasoningEffort::Medium,
|
||||||
description: "Fastest responses with little reasoning",
|
supported_reasoning_efforts: &[
|
||||||
},
|
ReasoningEffortPreset {
|
||||||
ReasoningEffortPreset {
|
effort: ReasoningEffort::Minimal,
|
||||||
effort: ReasoningEffort::Low,
|
description: "Fastest responses with little reasoning",
|
||||||
description: "Balances speed with some reasoning; useful for straightforward queries and short explanations",
|
},
|
||||||
},
|
ReasoningEffortPreset {
|
||||||
ReasoningEffortPreset {
|
effort: ReasoningEffort::Low,
|
||||||
effort: ReasoningEffort::Medium,
|
description: "Balances speed with some reasoning; useful for straightforward queries and short explanations",
|
||||||
description: "Provides a solid balance of reasoning depth and latency for general-purpose tasks",
|
},
|
||||||
},
|
ReasoningEffortPreset {
|
||||||
ReasoningEffortPreset {
|
effort: ReasoningEffort::Medium,
|
||||||
effort: ReasoningEffort::High,
|
description: "Provides a solid balance of reasoning depth and latency for general-purpose tasks",
|
||||||
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
},
|
||||||
},
|
ReasoningEffortPreset {
|
||||||
],
|
effort: ReasoningEffort::High,
|
||||||
is_default: false,
|
description: "Maximizes reasoning depth for complex or ambiguous problems",
|
||||||
recommended_upgrade_model: Some("gpt-5.1"),
|
},
|
||||||
},
|
],
|
||||||
];
|
is_default: false,
|
||||||
|
upgrade: Some(ModelUpgrade {
|
||||||
|
id: "gpt-5.1",
|
||||||
|
reasoning_effort_mapping: Some(HashMap::from([(
|
||||||
|
ReasoningEffort::Minimal,
|
||||||
|
ReasoningEffort::Low,
|
||||||
|
)])),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
pub fn builtin_model_presets(_auth_mode: Option<AuthMode>) -> Vec<ModelPreset> {
|
pub fn builtin_model_presets(_auth_mode: Option<AuthMode>) -> Vec<ModelPreset> {
|
||||||
// leave auth mode for later use
|
// leave auth mode for later use
|
||||||
PRESETS
|
PRESETS
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|preset| preset.recommended_upgrade_model.is_none())
|
.filter(|preset| preset.upgrade.is_none())
|
||||||
.copied()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_model_presets() -> &'static [ModelPreset] {
|
pub fn all_model_presets() -> &'static Vec<ModelPreset> {
|
||||||
PRESETS
|
&PRESETS
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ use ts_rs::TS;
|
|||||||
JsonSchema,
|
JsonSchema,
|
||||||
TS,
|
TS,
|
||||||
EnumIter,
|
EnumIter,
|
||||||
|
Hash,
|
||||||
)]
|
)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
#[strum(serialize_all = "lowercase")]
|
#[strum(serialize_all = "lowercase")]
|
||||||
pub enum ReasoningEffort {
|
pub enum ReasoningEffort {
|
||||||
|
None,
|
||||||
Minimal,
|
Minimal,
|
||||||
Low,
|
Low,
|
||||||
#[default]
|
#[default]
|
||||||
|
|||||||
+51
-29
@@ -17,6 +17,7 @@ use crate::tui;
|
|||||||
use crate::tui::TuiEvent;
|
use crate::tui::TuiEvent;
|
||||||
use crate::update_action::UpdateAction;
|
use crate::update_action::UpdateAction;
|
||||||
use codex_ansi_escape::ansi_escape_line;
|
use codex_ansi_escape::ansi_escape_line;
|
||||||
|
use codex_common::model_presets::ModelUpgrade;
|
||||||
use codex_common::model_presets::all_model_presets;
|
use codex_common::model_presets::all_model_presets;
|
||||||
use codex_core::AuthManager;
|
use codex_core::AuthManager;
|
||||||
use codex_core::ConversationManager;
|
use codex_core::ConversationManager;
|
||||||
@@ -64,7 +65,7 @@ fn should_show_model_migration_prompt(
|
|||||||
|
|
||||||
all_model_presets()
|
all_model_presets()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|preset| preset.recommended_upgrade_model.is_some())
|
.filter(|preset| preset.upgrade.is_some())
|
||||||
.any(|preset| preset.model == current_model)
|
.any(|preset| preset.model == current_model)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,38 +74,59 @@ async fn handle_model_migration_prompt_if_needed(
|
|||||||
config: &mut Config,
|
config: &mut Config,
|
||||||
app_event_tx: &AppEventSender,
|
app_event_tx: &AppEventSender,
|
||||||
) -> Option<AppExitInfo> {
|
) -> Option<AppExitInfo> {
|
||||||
let target_model = all_model_presets()
|
let upgrade = all_model_presets()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|preset| preset.model == config.model)
|
.find(|preset| preset.model == config.model)
|
||||||
.and_then(|preset| preset.recommended_upgrade_model)
|
.and_then(|preset| preset.upgrade.as_ref());
|
||||||
.unwrap_or(&config.model)
|
|
||||||
.to_string();
|
|
||||||
let hide_prompt_flag = config.notices.hide_gpt5_1_migration_prompt;
|
|
||||||
if !should_show_model_migration_prompt(&config.model, &target_model, hide_prompt_flag) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
match run_model_migration_prompt(tui).await {
|
if let Some(ModelUpgrade {
|
||||||
ModelMigrationOutcome::Accepted => {
|
id: target_model,
|
||||||
app_event_tx.send(AppEvent::PersistModelMigrationPromptAcknowledged {
|
reasoning_effort_mapping,
|
||||||
migration_config: "hide_gpt5_1_migration_prompt".to_string(),
|
}) = upgrade
|
||||||
});
|
{
|
||||||
config.model = target_model.clone();
|
let target_model = target_model.to_string();
|
||||||
if let Some(family) = find_family_for_model(&target_model) {
|
let hide_prompt_flag = config.notices.hide_gpt5_1_migration_prompt;
|
||||||
config.model_family = family;
|
if !should_show_model_migration_prompt(&config.model, &target_model, hide_prompt_flag) {
|
||||||
}
|
return None;
|
||||||
app_event_tx.send(AppEvent::UpdateModel(target_model.clone()));
|
|
||||||
app_event_tx.send(AppEvent::PersistModelSelection {
|
|
||||||
model: target_model,
|
|
||||||
effort: config.model_reasoning_effort,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
ModelMigrationOutcome::Exit => {
|
|
||||||
return Some(AppExitInfo {
|
match run_model_migration_prompt(tui).await {
|
||||||
token_usage: TokenUsage::default(),
|
ModelMigrationOutcome::Accepted => {
|
||||||
conversation_id: None,
|
app_event_tx.send(AppEvent::PersistModelMigrationPromptAcknowledged {
|
||||||
update_action: None,
|
migration_config: "hide_gpt5_1_migration_prompt".to_string(),
|
||||||
});
|
});
|
||||||
|
config.model = target_model.to_string();
|
||||||
|
if let Some(family) = find_family_for_model(&target_model) {
|
||||||
|
config.model_family = family;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mapped_effort = if let Some(reasoning_effort_mapping) = reasoning_effort_mapping
|
||||||
|
&& let Some(reasoning_effort) = config.model_reasoning_effort
|
||||||
|
{
|
||||||
|
reasoning_effort_mapping
|
||||||
|
.get(&reasoning_effort)
|
||||||
|
.cloned()
|
||||||
|
.or(config.model_reasoning_effort)
|
||||||
|
} else {
|
||||||
|
config.model_reasoning_effort
|
||||||
|
};
|
||||||
|
|
||||||
|
config.model_reasoning_effort = mapped_effort;
|
||||||
|
|
||||||
|
app_event_tx.send(AppEvent::UpdateModel(target_model.clone()));
|
||||||
|
app_event_tx.send(AppEvent::UpdateReasoningEffort(mapped_effort));
|
||||||
|
app_event_tx.send(AppEvent::PersistModelSelection {
|
||||||
|
model: target_model.clone(),
|
||||||
|
effort: mapped_effort,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ModelMigrationOutcome::Exit => {
|
||||||
|
return Some(AppExitInfo {
|
||||||
|
token_usage: TokenUsage::default(),
|
||||||
|
conversation_id: None,
|
||||||
|
update_action: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1836,11 +1836,12 @@ impl ChatWidget {
|
|||||||
Some(preset.description.to_string())
|
Some(preset.description.to_string())
|
||||||
};
|
};
|
||||||
let is_current = preset.model == current_model;
|
let is_current = preset.model == current_model;
|
||||||
let preset_for_action = preset;
|
let single_supported_effort = preset.supported_reasoning_efforts.len() == 1;
|
||||||
let single_supported_effort = preset_for_action.supported_reasoning_efforts.len() == 1;
|
let preset_for_action = preset.clone();
|
||||||
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
|
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
|
||||||
|
let preset_for_event = preset_for_action.clone();
|
||||||
tx.send(AppEvent::OpenReasoningPopup {
|
tx.send(AppEvent::OpenReasoningPopup {
|
||||||
model: preset_for_action,
|
model: preset_for_event,
|
||||||
});
|
});
|
||||||
})];
|
})];
|
||||||
items.push(SelectionItem {
|
items.push(SelectionItem {
|
||||||
|
|||||||
@@ -1533,7 +1533,7 @@ fn single_reasoning_option_skips_selection() {
|
|||||||
default_reasoning_effort: ReasoningEffortConfig::High,
|
default_reasoning_effort: ReasoningEffortConfig::High,
|
||||||
supported_reasoning_efforts: &SINGLE_EFFORT,
|
supported_reasoning_efforts: &SINGLE_EFFORT,
|
||||||
is_default: false,
|
is_default: false,
|
||||||
recommended_upgrade_model: None,
|
upgrade: None,
|
||||||
};
|
};
|
||||||
chat.open_reasoning_popup(preset);
|
chat.open_reasoning_popup(preset);
|
||||||
|
|
||||||
|
|||||||
@@ -712,6 +712,7 @@ impl SessionHeaderHistoryCell {
|
|||||||
ReasoningEffortConfig::Low => "low",
|
ReasoningEffortConfig::Low => "low",
|
||||||
ReasoningEffortConfig::Medium => "medium",
|
ReasoningEffortConfig::Medium => "medium",
|
||||||
ReasoningEffortConfig::High => "high",
|
ReasoningEffortConfig::High => "high",
|
||||||
|
ReasoningEffortConfig::None => "none",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "codex-git"
|
|
||||||
version.workspace = true
|
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
name = "codex-git"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
version.workspace = true
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
once_cell = "1"
|
once_cell = { workspace = true }
|
||||||
regex = "1"
|
regex = "1"
|
||||||
schemars = { workspace = true }
|
schemars = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
|||||||
Reference in new issue
Block a user