This commit is contained in:
Ahmed Ibrahim
2025-11-18 12:28:56 -08:00
parent c1b7e6f9a8
commit 77bc873059
4 changed files with 60 additions and 58 deletions

View File

@@ -19,7 +19,7 @@ fn model_from_preset(preset: ModelPreset) -> Model {
display_name: preset.display_name.to_string(),
description: preset.description.to_string(),
supported_reasoning_efforts: reasoning_efforts_from_preset(
&preset.supported_reasoning_efforts,
preset.supported_reasoning_efforts,
),
default_reasoning_effort: preset.default_reasoning_effort,
is_default: preset.is_default,

View File

@@ -43,7 +43,7 @@ pub struct ModelPreset {
/// Reasoning effort applied when none is explicitly chosen.
pub default_reasoning_effort: ReasoningEffort,
/// Supported reasoning effort options.
pub supported_reasoning_efforts: Vec<ReasoningEffortPreset>,
pub supported_reasoning_efforts: &'static [ReasoningEffortPreset],
/// Whether this is the default model for new users.
pub is_default: bool,
/// recommended upgrade model
@@ -58,7 +58,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
display_name: "codex-auto",
description: "Automatically chooses the best Codex model configuration for your task.",
default_reasoning_effort: ReasoningEffort::Medium,
supported_reasoning_efforts: vec![
supported_reasoning_efforts: &[
ReasoningEffortPreset {
effort: ReasoningEffort::Low,
description: "Works faster",
@@ -84,7 +84,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
display_name: "gpt-5.1-codex",
description: "Optimized for codex.",
default_reasoning_effort: ReasoningEffort::Medium,
supported_reasoning_efforts: vec![
supported_reasoning_efforts: &[
ReasoningEffortPreset {
effort: ReasoningEffort::Low,
description: "Fastest responses with limited reasoning",
@@ -110,7 +110,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
display_name: "gpt-5.1-codex-mini",
description: "Optimized for codex. Cheaper, faster, but less capable.",
default_reasoning_effort: ReasoningEffort::Medium,
supported_reasoning_efforts: vec![
supported_reasoning_efforts: &[
ReasoningEffortPreset {
effort: ReasoningEffort::Medium,
description: "Dynamically adjusts reasoning based on the task",
@@ -131,7 +131,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
display_name: "gpt-5.1",
description: "Broad world knowledge with strong general reasoning.",
default_reasoning_effort: ReasoningEffort::Medium,
supported_reasoning_efforts: vec![
supported_reasoning_efforts: &[
ReasoningEffortPreset {
effort: ReasoningEffort::Low,
description: "Balances speed with some reasoning; useful for straightforward queries and short explanations",
@@ -158,7 +158,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
display_name: "gpt-5-codex",
description: "Optimized for codex.",
default_reasoning_effort: ReasoningEffort::Medium,
supported_reasoning_efforts: vec![
supported_reasoning_efforts: &[
ReasoningEffortPreset {
effort: ReasoningEffort::Low,
description: "Fastest responses with limited reasoning",
@@ -187,7 +187,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
display_name: "gpt-5-codex-mini",
description: "Optimized for codex. Cheaper, faster, but less capable.",
default_reasoning_effort: ReasoningEffort::Medium,
supported_reasoning_efforts: vec![
supported_reasoning_efforts: &[
ReasoningEffortPreset {
effort: ReasoningEffort::Medium,
description: "Dynamically adjusts reasoning based on the task",
@@ -211,7 +211,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
display_name: "gpt-5",
description: "Broad world knowledge with strong general reasoning.",
default_reasoning_effort: ReasoningEffort::Medium,
supported_reasoning_efforts: vec![
supported_reasoning_efforts: &[
ReasoningEffortPreset {
effort: ReasoningEffort::Minimal,
description: "Fastest responses with little reasoning",

View File

@@ -2089,49 +2089,6 @@ impl ChatWidget {
});
}
fn featured_model_items(&self, preset: &ModelPreset) -> Vec<SelectionItem> {
let default_effort: ReasoningEffortConfig = preset.default_reasoning_effort;
let is_current = self.config.model == preset.model;
let current_effort = if is_current {
self.config.model_reasoning_effort.or(Some(default_effort))
} else {
None
};
let mut items = Vec::new();
let model_slug = preset.model.to_string();
for option in preset.supported_reasoning_efforts.iter() {
let effort = option.effort;
let model_for_action = model_slug.clone();
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
tx.send(AppEvent::ApplyModelAndEffort {
model: model_for_action.clone(),
effort: Some(effort),
});
})];
let mut name = option.label().to_string();
let is_current_option = current_effort == Some(effort);
if effort == default_effort && !is_current_option {
name.push_str(" (default)");
}
let description =
(!option.description.is_empty()).then(|| option.description.to_string());
items.push(SelectionItem {
name,
description,
selected_description: None,
is_current: is_current_option,
actions,
dismiss_on_select: true,
..Default::default()
});
}
items
}
/// Open a popup to choose the reasoning effort (stage 2) for the given model.
pub(crate) fn open_reasoning_popup(
&mut self,
@@ -2139,7 +2096,7 @@ impl ChatWidget {
preferred_effort: Option<ReasoningEffortConfig>,
) {
let default_effort: ReasoningEffortConfig = preset.default_reasoning_effort;
let supported = &preset.supported_reasoning_efforts;
let supported = preset.supported_reasoning_efforts;
struct EffortChoice {
stored: Option<ReasoningEffortConfig>,
@@ -2271,6 +2228,49 @@ impl ChatWidget {
});
}
fn featured_model_items(&self, preset: &ModelPreset) -> Vec<SelectionItem> {
let default_effort: ReasoningEffortConfig = preset.default_reasoning_effort;
let is_current = self.config.model == preset.model;
let current_effort = if is_current {
self.config.model_reasoning_effort.or(Some(default_effort))
} else {
None
};
let mut items = Vec::new();
let model_slug = preset.model.to_string();
for option in preset.supported_reasoning_efforts.iter() {
let effort = option.effort;
let model_for_action = model_slug.clone();
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
tx.send(AppEvent::ApplyModelAndEffort {
model: model_for_action.clone(),
effort: Some(effort),
});
})];
let mut name = option.label().to_string();
let is_current_option = current_effort == Some(effort);
if effort == default_effort && !is_current_option {
name.push_str(" (default)");
}
let description =
(!option.description.is_empty()).then(|| option.description.to_string());
items.push(SelectionItem {
name,
description,
selected_description: None,
is_current: is_current_option,
actions,
dismiss_on_select: true,
..Default::default()
});
}
items
}
pub(crate) fn apply_model_and_effort(
&self,
model: String,

View File

@@ -1573,17 +1573,19 @@ fn reasoning_popup_hides_default_label_when_option_is_current() {
fn single_reasoning_option_skips_selection() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual();
const SINGLE_HIGH_REASONING: &[ReasoningEffortPreset] = &[ReasoningEffortPreset {
effort: ReasoningEffortConfig::High,
description: "Maximizes reasoning depth for complex or ambiguous problems",
label: None,
}];
let preset = ModelPreset {
id: "model-with-single-reasoning",
model: "model-with-single-reasoning",
display_name: "model-with-single-reasoning",
description: "",
default_reasoning_effort: ReasoningEffortConfig::High,
supported_reasoning_efforts: vec![ReasoningEffortPreset {
effort: ReasoningEffortConfig::High,
description: "Maximizes reasoning depth for complex or ambiguous problems",
label: None,
}],
supported_reasoning_efforts: SINGLE_HIGH_REASONING,
is_default: false,
upgrade: None,
};