Cleanup
This commit is contained in:
@@ -34,8 +34,7 @@ pub struct AgentSettings {
|
||||
pub commit_message_model: Option<LanguageModelSelection>,
|
||||
pub thread_summary_model: Option<LanguageModelSelection>,
|
||||
pub inline_alternatives: Vec<LanguageModelSelection>,
|
||||
pub favorite_models_as_selections: Vec<LanguageModelSelection>,
|
||||
pub favorite_models_as_ids: Arc<HashSet<ModelId>>,
|
||||
pub favorite_models: Vec<LanguageModelSelection>,
|
||||
pub default_profile: AgentProfileId,
|
||||
pub default_view: DefaultAgentView,
|
||||
pub profiles: IndexMap<AgentProfileId, AgentProfileSettings>,
|
||||
@@ -99,6 +98,13 @@ impl AgentSettings {
|
||||
pub fn set_message_editor_max_lines(&self) -> usize {
|
||||
self.message_editor_min_lines * 2
|
||||
}
|
||||
|
||||
pub fn favorite_model_ids(&self) -> HashSet<ModelId> {
|
||||
self.favorite_models
|
||||
.iter()
|
||||
.map(|sel| ModelId::new(format!("{}/{}", sel.provider.0, sel.model)))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
|
||||
@@ -167,16 +173,7 @@ impl Settings for AgentSettings {
|
||||
commit_message_model: agent.commit_message_model,
|
||||
thread_summary_model: agent.thread_summary_model,
|
||||
inline_alternatives: agent.inline_alternatives.unwrap_or_default(),
|
||||
favorite_models_as_selections: agent.favorite_models,
|
||||
favorite_models_as_ids: Arc::new(
|
||||
content
|
||||
.agent
|
||||
.as_ref()
|
||||
.iter()
|
||||
.flat_map(|agent| &agent.favorite_models)
|
||||
.map(|sel| ModelId::new(format!("{}/{}", sel.provider.0, sel.model)))
|
||||
.collect(),
|
||||
),
|
||||
favorite_models: agent.favorite_models,
|
||||
default_profile: AgentProfileId(agent.default_profile.unwrap()),
|
||||
default_view: agent.default_view.unwrap(),
|
||||
profiles: agent
|
||||
|
||||
@@ -45,24 +45,7 @@ pub fn acp_model_selector(
|
||||
|
||||
enum AcpModelPickerEntry {
|
||||
Separator(SharedString),
|
||||
Model(AgentModelInfo, AcpModelPickerEntryAction),
|
||||
}
|
||||
|
||||
/// Corresponds to the action button shown on the model in the list.
|
||||
#[derive(Copy, Clone)]
|
||||
enum AcpModelPickerEntryAction {
|
||||
Favorite,
|
||||
Unfavorite,
|
||||
}
|
||||
|
||||
impl AcpModelPickerEntryAction {
|
||||
fn from_favorite_state(is_favorite: bool) -> Self {
|
||||
if is_favorite {
|
||||
Self::Unfavorite
|
||||
} else {
|
||||
Self::Favorite
|
||||
}
|
||||
}
|
||||
Model(AgentModelInfo, ModelSelectorFavoriteAction),
|
||||
}
|
||||
|
||||
pub struct AcpModelPickerDelegate {
|
||||
@@ -180,7 +163,7 @@ impl PickerDelegate for AcpModelPickerDelegate {
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
let favorites = if self.selector.supports_favorites() {
|
||||
AgentSettings::get_global(cx).favorite_models_as_ids.clone()
|
||||
Arc::new(AgentSettings::get_global(cx).favorite_model_ids())
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
@@ -201,7 +184,7 @@ impl PickerDelegate for AcpModelPickerDelegate {
|
||||
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
this.delegate.filtered_entries =
|
||||
info_list_to_picker_entries(filtered_models, favorites).collect();
|
||||
info_list_to_picker_entries(filtered_models, favorites);
|
||||
// Finds the currently selected model in the list
|
||||
let new_index = this
|
||||
.delegate
|
||||
@@ -279,32 +262,17 @@ impl PickerDelegate for AcpModelPickerDelegate {
|
||||
let supports_favorites = self.selector.supports_favorites();
|
||||
|
||||
let handle_action_click = {
|
||||
let action = *action;
|
||||
let is_favorite = matches!(action, ModelSelectorFavoriteAction::Unfavorite);
|
||||
let model_id = model_info.id.clone();
|
||||
let fs = self.fs.clone();
|
||||
|
||||
move |cx: &App| match action {
|
||||
AcpModelPickerEntryAction::Favorite => {
|
||||
crate::favorite_models::add_to_settings(
|
||||
model_id.clone(),
|
||||
fs.clone(),
|
||||
cx,
|
||||
)
|
||||
}
|
||||
AcpModelPickerEntryAction::Unfavorite => {
|
||||
crate::favorite_models::remove_from_settings(
|
||||
model_id.clone(),
|
||||
fs.clone(),
|
||||
cx,
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let favorite_action = match action {
|
||||
AcpModelPickerEntryAction::Favorite => ModelSelectorFavoriteAction::Favorite,
|
||||
AcpModelPickerEntryAction::Unfavorite => {
|
||||
ModelSelectorFavoriteAction::Unfavorite
|
||||
move |cx: &App| {
|
||||
crate::favorite_models::toggle_model_id_in_settings(
|
||||
model_id.clone(),
|
||||
!is_favorite,
|
||||
fs.clone(),
|
||||
cx,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -328,7 +296,7 @@ impl PickerDelegate for AcpModelPickerDelegate {
|
||||
.is_selected(is_selected)
|
||||
.is_focused(selected)
|
||||
.when(supports_favorites, |this| {
|
||||
this.favorite_action(favorite_action)
|
||||
this.favorite_action(*action)
|
||||
.on_favorite_action_click(handle_action_click)
|
||||
}),
|
||||
)
|
||||
@@ -381,58 +349,56 @@ impl PickerDelegate for AcpModelPickerDelegate {
|
||||
fn info_list_to_picker_entries(
|
||||
model_list: AgentModelList,
|
||||
favorites: Arc<HashSet<ModelId>>,
|
||||
) -> impl Iterator<Item = AcpModelPickerEntry> {
|
||||
let all_models = match &model_list {
|
||||
AgentModelList::Flat(list) => itertools::Either::Left(list.iter()),
|
||||
AgentModelList::Grouped(index_map) => {
|
||||
itertools::Either::Right(index_map.values().flatten())
|
||||
}
|
||||
) -> Vec<AcpModelPickerEntry> {
|
||||
let mut entries = Vec::new();
|
||||
|
||||
let all_models: Vec<_> = match &model_list {
|
||||
AgentModelList::Flat(list) => list.iter().collect(),
|
||||
AgentModelList::Grouped(index_map) => index_map.values().flatten().collect(),
|
||||
};
|
||||
|
||||
let favorites_entries = all_models
|
||||
.filter(|model_info| favorites.contains(&model_info.id))
|
||||
.unique_by(|model_info| &model_info.id)
|
||||
.map(|model_info| {
|
||||
AcpModelPickerEntry::Model(model_info.clone(), AcpModelPickerEntryAction::Unfavorite)
|
||||
})
|
||||
.collect_vec();
|
||||
let favorite_models: Vec<_> = all_models
|
||||
.iter()
|
||||
.filter(|m| favorites.contains(&m.id))
|
||||
.unique_by(|m| &m.id)
|
||||
.collect();
|
||||
|
||||
let model_list_is_flat = model_list.is_flat();
|
||||
|
||||
let all_models_entries = match model_list {
|
||||
AgentModelList::Flat(list) => {
|
||||
itertools::Either::Left(list.into_iter().map(move |model_info| {
|
||||
let action = AcpModelPickerEntryAction::from_favorite_state(
|
||||
favorites.contains(&model_info.id),
|
||||
);
|
||||
AcpModelPickerEntry::Model(model_info, action)
|
||||
}))
|
||||
let has_favorites = !favorite_models.is_empty();
|
||||
if has_favorites {
|
||||
entries.push(AcpModelPickerEntry::Separator("Favorite".into()));
|
||||
for model in favorite_models {
|
||||
entries.push(AcpModelPickerEntry::Model(
|
||||
(*model).clone(),
|
||||
ModelSelectorFavoriteAction::Unfavorite,
|
||||
));
|
||||
}
|
||||
AgentModelList::Grouped(index_map) => {
|
||||
itertools::Either::Right(index_map.into_iter().flat_map(move |(group_name, models)| {
|
||||
let favorites = favorites.clone();
|
||||
std::iter::once(AcpModelPickerEntry::Separator(group_name.0)).chain(
|
||||
models.into_iter().map(move |model_info| {
|
||||
let action = AcpModelPickerEntryAction::from_favorite_state(
|
||||
favorites.contains(&model_info.id),
|
||||
);
|
||||
AcpModelPickerEntry::Model(model_info, action)
|
||||
}),
|
||||
)
|
||||
}))
|
||||
}
|
||||
};
|
||||
|
||||
if favorites_entries.is_empty() {
|
||||
itertools::Either::Left(all_models_entries)
|
||||
} else {
|
||||
itertools::Either::Right(
|
||||
std::iter::once(AcpModelPickerEntry::Separator("Favorite".into()))
|
||||
.chain(favorites_entries)
|
||||
.chain(model_list_is_flat.then_some(AcpModelPickerEntry::Separator("All".into())))
|
||||
.chain(all_models_entries),
|
||||
)
|
||||
}
|
||||
|
||||
match model_list {
|
||||
AgentModelList::Flat(list) => {
|
||||
if has_favorites {
|
||||
entries.push(AcpModelPickerEntry::Separator("All".into()));
|
||||
}
|
||||
for model in list {
|
||||
let action =
|
||||
ModelSelectorFavoriteAction::from_is_favorite(favorites.contains(&model.id));
|
||||
entries.push(AcpModelPickerEntry::Model(model, action));
|
||||
}
|
||||
}
|
||||
AgentModelList::Grouped(index_map) => {
|
||||
for (group_name, models) in index_map {
|
||||
entries.push(AcpModelPickerEntry::Separator(group_name.0));
|
||||
for model in models {
|
||||
let action = ModelSelectorFavoriteAction::from_is_favorite(
|
||||
favorites.contains(&model.id),
|
||||
);
|
||||
entries.push(AcpModelPickerEntry::Model(model, action));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entries
|
||||
}
|
||||
|
||||
async fn fuzzy_search(
|
||||
@@ -591,7 +557,7 @@ mod tests {
|
||||
]);
|
||||
let favorites = create_favorites(vec!["zed/gemini"]);
|
||||
|
||||
let entries = info_list_to_picker_entries(models, favorites).collect_vec();
|
||||
let entries = info_list_to_picker_entries(models, favorites);
|
||||
|
||||
assert!(matches!(
|
||||
entries.first(),
|
||||
@@ -607,7 +573,7 @@ mod tests {
|
||||
let models = create_model_list(vec![("zed", vec!["zed/claude", "zed/gemini"])]);
|
||||
let favorites = create_favorites(vec![]);
|
||||
|
||||
let entries = info_list_to_picker_entries(models, favorites).collect_vec();
|
||||
let entries = info_list_to_picker_entries(models, favorites);
|
||||
|
||||
assert!(matches!(
|
||||
entries.first(),
|
||||
@@ -623,16 +589,16 @@ mod tests {
|
||||
]);
|
||||
let favorites = create_favorites(vec!["zed/claude"]);
|
||||
|
||||
let entries = info_list_to_picker_entries(models, favorites).collect_vec();
|
||||
let entries = info_list_to_picker_entries(models, favorites);
|
||||
|
||||
for entry in &entries {
|
||||
match entry {
|
||||
AcpModelPickerEntry::Separator(_) => {}
|
||||
AcpModelPickerEntry::Model(info, action) if info.id.0.as_ref() == "zed/claude" => {
|
||||
assert!(matches!(action, AcpModelPickerEntryAction::Unfavorite));
|
||||
assert!(matches!(action, ModelSelectorFavoriteAction::Unfavorite));
|
||||
}
|
||||
AcpModelPickerEntry::Model(_, action) => {
|
||||
assert!(matches!(action, AcpModelPickerEntryAction::Favorite));
|
||||
assert!(matches!(action, ModelSelectorFavoriteAction::Favorite));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -646,7 +612,7 @@ mod tests {
|
||||
]);
|
||||
let favorites = create_favorites(vec!["zed/gemini", "openai/gpt-5"]);
|
||||
|
||||
let entries = info_list_to_picker_entries(models, favorites).collect_vec();
|
||||
let entries = info_list_to_picker_entries(models, favorites);
|
||||
let model_ids = get_entry_model_ids(&entries);
|
||||
|
||||
assert_eq!(model_ids[0], "zed/gemini");
|
||||
@@ -667,7 +633,7 @@ mod tests {
|
||||
|
||||
let favorites = create_favorites(vec!["zed/claude"]);
|
||||
|
||||
let entries = info_list_to_picker_entries(models, favorites).collect_vec();
|
||||
let entries = info_list_to_picker_entries(models, favorites);
|
||||
let labels = get_entry_labels(&entries);
|
||||
|
||||
assert_eq!(
|
||||
@@ -707,7 +673,7 @@ mod tests {
|
||||
]);
|
||||
let favorites = create_favorites(vec!["zed/gemini"]);
|
||||
|
||||
let entries = info_list_to_picker_entries(models, favorites).collect_vec();
|
||||
let entries = info_list_to_picker_entries(models, favorites);
|
||||
|
||||
assert!(matches!(
|
||||
entries.first(),
|
||||
|
||||
@@ -271,13 +271,15 @@ impl ManageProfilesModal {
|
||||
},
|
||||
{
|
||||
let fs = fs.clone();
|
||||
move |model, cx| {
|
||||
crate::favorite_models::add_to_settings(model, fs.clone(), cx);
|
||||
move |model, should_be_favorite, cx| {
|
||||
crate::favorite_models::toggle_in_settings(
|
||||
model,
|
||||
should_be_favorite,
|
||||
fs.clone(),
|
||||
cx,
|
||||
);
|
||||
}
|
||||
},
|
||||
move |model, cx| {
|
||||
crate::favorite_models::remove_from_settings(model, fs.clone(), cx);
|
||||
},
|
||||
false, // Do not use popover styles for the model picker
|
||||
self.focus_handle.clone(),
|
||||
window,
|
||||
|
||||
@@ -53,13 +53,15 @@ impl AgentModelSelector {
|
||||
},
|
||||
{
|
||||
let fs = fs.clone();
|
||||
move |model, cx| {
|
||||
crate::favorite_models::add_to_settings(model, fs.clone(), cx);
|
||||
move |model, should_be_favorite, cx| {
|
||||
crate::favorite_models::toggle_in_settings(
|
||||
model,
|
||||
should_be_favorite,
|
||||
fs.clone(),
|
||||
cx,
|
||||
);
|
||||
}
|
||||
},
|
||||
move |model, cx| {
|
||||
crate::favorite_models::remove_from_settings(model, fs.clone(), cx);
|
||||
},
|
||||
true, // Use popover styles for picker
|
||||
focus_handle_clone,
|
||||
window,
|
||||
|
||||
@@ -458,8 +458,7 @@ mod tests {
|
||||
commit_message_model: None,
|
||||
thread_summary_model: None,
|
||||
inline_alternatives: vec![],
|
||||
favorite_models_as_selections: vec![],
|
||||
favorite_models_as_ids: Arc::new(Default::default()),
|
||||
favorite_models: vec![],
|
||||
default_profile: AgentProfileId::default(),
|
||||
default_view: DefaultAgentView::Thread,
|
||||
profiles: Default::default(),
|
||||
|
||||
@@ -6,52 +6,52 @@ use language_model::LanguageModel;
|
||||
use settings::{LanguageModelSelection, update_settings_file};
|
||||
use ui::App;
|
||||
|
||||
pub trait IntoLanguageModelSelection {
|
||||
fn into_language_model_selection(self) -> LanguageModelSelection;
|
||||
}
|
||||
|
||||
impl IntoLanguageModelSelection for Arc<dyn LanguageModel> {
|
||||
fn into_language_model_selection(self) -> LanguageModelSelection {
|
||||
LanguageModelSelection {
|
||||
provider: self.provider_id().to_string().into(),
|
||||
model: self.id().0.to_string(),
|
||||
}
|
||||
fn language_model_to_selection(model: &Arc<dyn LanguageModel>) -> LanguageModelSelection {
|
||||
LanguageModelSelection {
|
||||
provider: model.provider_id().to_string().into(),
|
||||
model: model.id().0.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLanguageModelSelection for ModelId {
|
||||
fn into_language_model_selection(self) -> LanguageModelSelection {
|
||||
let model_id = self.0.as_ref();
|
||||
let (provider, model) = model_id.split_once('/').unwrap_or(("", model_id));
|
||||
|
||||
LanguageModelSelection {
|
||||
provider: provider.to_owned().into(),
|
||||
model: model.to_owned(),
|
||||
}
|
||||
fn model_id_to_selection(model_id: &ModelId) -> LanguageModelSelection {
|
||||
let id = model_id.0.as_ref();
|
||||
let (provider, model) = id.split_once('/').unwrap_or(("", id));
|
||||
LanguageModelSelection {
|
||||
provider: provider.to_owned().into(),
|
||||
model: model.to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_to_settings(
|
||||
model: impl IntoLanguageModelSelection + Send + 'static,
|
||||
pub fn toggle_in_settings(
|
||||
model: Arc<dyn LanguageModel>,
|
||||
should_be_favorite: bool,
|
||||
fs: Arc<dyn Fs>,
|
||||
cx: &App,
|
||||
) {
|
||||
update_settings_file(fs, cx, |settings, _| {
|
||||
settings
|
||||
.agent
|
||||
.get_or_insert_default()
|
||||
.add_favorite_model(model.into_language_model_selection())
|
||||
});
|
||||
}
|
||||
|
||||
pub fn remove_from_settings(
|
||||
model: impl IntoLanguageModelSelection + Send + 'static,
|
||||
fs: Arc<dyn Fs>,
|
||||
cx: &App,
|
||||
) {
|
||||
update_settings_file(fs, cx, |settings, _| {
|
||||
if let Some(ref mut agent_settings) = settings.agent {
|
||||
agent_settings.remove_favorite_model(&model.into_language_model_selection())
|
||||
let selection = language_model_to_selection(&model);
|
||||
update_settings_file(fs, cx, move |settings, _| {
|
||||
let agent = settings.agent.get_or_insert_default();
|
||||
if should_be_favorite {
|
||||
agent.add_favorite_model(selection.clone());
|
||||
} else {
|
||||
agent.remove_favorite_model(&selection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn toggle_model_id_in_settings(
|
||||
model_id: ModelId,
|
||||
should_be_favorite: bool,
|
||||
fs: Arc<dyn Fs>,
|
||||
cx: &App,
|
||||
) {
|
||||
let selection = model_id_to_selection(&model_id);
|
||||
update_settings_file(fs, cx, move |settings, _| {
|
||||
let agent = settings.agent.get_or_insert_default();
|
||||
if should_be_favorite {
|
||||
agent.add_favorite_model(selection.clone());
|
||||
} else {
|
||||
agent.remove_favorite_model(&selection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@ use crate::ui::{
|
||||
|
||||
type OnModelChanged = Arc<dyn Fn(Arc<dyn LanguageModel>, &mut App) + 'static>;
|
||||
type GetActiveModel = Arc<dyn Fn(&App) -> Option<ConfiguredModel> + 'static>;
|
||||
type OnToggleFavorite = Arc<dyn Fn(Arc<dyn LanguageModel>, bool, &App) + 'static>;
|
||||
|
||||
pub type LanguageModelSelector = Picker<LanguageModelPickerDelegate>;
|
||||
|
||||
pub fn language_model_selector(
|
||||
get_active_model: impl Fn(&App) -> Option<ConfiguredModel> + 'static,
|
||||
on_model_changed: impl Fn(Arc<dyn LanguageModel>, &mut App) + 'static,
|
||||
on_add_favorite_model: impl Fn(Arc<dyn LanguageModel>, &App) + 'static,
|
||||
on_remove_favorite_model: impl Fn(Arc<dyn LanguageModel>, &App) + 'static,
|
||||
on_toggle_favorite: impl Fn(Arc<dyn LanguageModel>, bool, &App) + 'static,
|
||||
popover_styles: bool,
|
||||
focus_handle: FocusHandle,
|
||||
window: &mut Window,
|
||||
@@ -38,8 +38,7 @@ pub fn language_model_selector(
|
||||
let delegate = LanguageModelPickerDelegate::new(
|
||||
get_active_model,
|
||||
on_model_changed,
|
||||
on_add_favorite_model,
|
||||
on_remove_favorite_model,
|
||||
on_toggle_favorite,
|
||||
popover_styles,
|
||||
focus_handle,
|
||||
window,
|
||||
@@ -62,7 +61,7 @@ fn all_models(cx: &App) -> GroupedModels {
|
||||
|
||||
let mut favorites_index = FavoritesIndex::default();
|
||||
|
||||
for sel in &AgentSettings::get_global(cx).favorite_models_as_selections {
|
||||
for sel in &AgentSettings::get_global(cx).favorite_models {
|
||||
favorites_index
|
||||
.entry(sel.provider.0.clone().into())
|
||||
.or_default()
|
||||
@@ -122,8 +121,7 @@ impl ModelInfo {
|
||||
pub struct LanguageModelPickerDelegate {
|
||||
on_model_changed: OnModelChanged,
|
||||
get_active_model: GetActiveModel,
|
||||
on_add_favorite_model: Arc<dyn Fn(Arc<dyn LanguageModel>, &App)>,
|
||||
on_remove_favorite_model: Arc<dyn Fn(Arc<dyn LanguageModel>, &App)>,
|
||||
on_toggle_favorite: OnToggleFavorite,
|
||||
all_models: Arc<GroupedModels>,
|
||||
filtered_entries: Vec<LanguageModelPickerEntry>,
|
||||
selected_index: usize,
|
||||
@@ -137,8 +135,7 @@ impl LanguageModelPickerDelegate {
|
||||
fn new(
|
||||
get_active_model: impl Fn(&App) -> Option<ConfiguredModel> + 'static,
|
||||
on_model_changed: impl Fn(Arc<dyn LanguageModel>, &mut App) + 'static,
|
||||
on_add_favorite_model: impl Fn(Arc<dyn LanguageModel>, &App) + 'static,
|
||||
on_remove_favorite_model: impl Fn(Arc<dyn LanguageModel>, &App) + 'static,
|
||||
on_toggle_favorite: impl Fn(Arc<dyn LanguageModel>, bool, &App) + 'static,
|
||||
popover_styles: bool,
|
||||
focus_handle: FocusHandle,
|
||||
window: &mut Window,
|
||||
@@ -154,8 +151,7 @@ impl LanguageModelPickerDelegate {
|
||||
selected_index: Self::get_active_model_index(&entries, get_active_model(cx)),
|
||||
filtered_entries: entries,
|
||||
get_active_model: Arc::new(get_active_model),
|
||||
on_add_favorite_model: Arc::new(on_add_favorite_model),
|
||||
on_remove_favorite_model: Arc::new(on_remove_favorite_model),
|
||||
on_toggle_favorite: Arc::new(on_toggle_favorite),
|
||||
_authenticate_all_providers_task: Self::authenticate_all_providers(cx),
|
||||
_subscriptions: vec![cx.subscribe_in(
|
||||
&LanguageModelRegistry::global(cx),
|
||||
@@ -296,7 +292,7 @@ impl GroupedModels {
|
||||
entries.extend(self.favorites.iter().map(|info| {
|
||||
LanguageModelPickerEntry::Model(
|
||||
info.clone(),
|
||||
LanguageModelPickerEntryAction::Unfavorite,
|
||||
ModelSelectorFavoriteAction::Unfavorite,
|
||||
)
|
||||
}));
|
||||
}
|
||||
@@ -306,7 +302,7 @@ impl GroupedModels {
|
||||
entries.extend(self.recommended.iter().map(|info| {
|
||||
LanguageModelPickerEntry::Model(
|
||||
info.clone(),
|
||||
LanguageModelPickerEntryAction::from_favorite_state(info.is_favorite),
|
||||
ModelSelectorFavoriteAction::from_is_favorite(info.is_favorite),
|
||||
)
|
||||
}));
|
||||
}
|
||||
@@ -321,7 +317,7 @@ impl GroupedModels {
|
||||
entries.extend(models.iter().map(|info| {
|
||||
LanguageModelPickerEntry::Model(
|
||||
info.clone(),
|
||||
LanguageModelPickerEntryAction::from_favorite_state(info.is_favorite),
|
||||
ModelSelectorFavoriteAction::from_is_favorite(info.is_favorite),
|
||||
)
|
||||
}));
|
||||
}
|
||||
@@ -330,27 +326,10 @@ impl GroupedModels {
|
||||
}
|
||||
|
||||
enum LanguageModelPickerEntry {
|
||||
Model(ModelInfo, LanguageModelPickerEntryAction),
|
||||
Model(ModelInfo, ModelSelectorFavoriteAction),
|
||||
Separator(SharedString),
|
||||
}
|
||||
|
||||
/// Corresponds to the action button shown on the model in the list.
|
||||
#[derive(Copy, Clone)]
|
||||
enum LanguageModelPickerEntryAction {
|
||||
Favorite,
|
||||
Unfavorite,
|
||||
}
|
||||
|
||||
impl LanguageModelPickerEntryAction {
|
||||
fn from_favorite_state(is_favorite: bool) -> Self {
|
||||
if is_favorite {
|
||||
Self::Unfavorite
|
||||
} else {
|
||||
Self::Favorite
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ModelMatcher {
|
||||
models: Vec<ModelInfo>,
|
||||
bg_executor: BackgroundExecutor,
|
||||
@@ -554,27 +533,10 @@ impl PickerDelegate for LanguageModelPickerDelegate {
|
||||
&& Some(model_info.model.id()) == active_model_id;
|
||||
|
||||
let handle_action_click = {
|
||||
let action = *action;
|
||||
let is_favorite = model_info.is_favorite;
|
||||
let model = model_info.model.clone();
|
||||
let on_add_favorite_model = self.on_add_favorite_model.clone();
|
||||
let on_remove_favorite_model = self.on_remove_favorite_model.clone();
|
||||
move |cx: &App| match action {
|
||||
LanguageModelPickerEntryAction::Favorite => {
|
||||
on_add_favorite_model(model.clone(), cx)
|
||||
}
|
||||
LanguageModelPickerEntryAction::Unfavorite => {
|
||||
on_remove_favorite_model(model.clone(), cx)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let favorite_action = match action {
|
||||
LanguageModelPickerEntryAction::Favorite => {
|
||||
ModelSelectorFavoriteAction::Favorite
|
||||
}
|
||||
LanguageModelPickerEntryAction::Unfavorite => {
|
||||
ModelSelectorFavoriteAction::Unfavorite
|
||||
}
|
||||
let on_toggle_favorite = self.on_toggle_favorite.clone();
|
||||
move |cx: &App| on_toggle_favorite(model.clone(), !is_favorite, cx)
|
||||
};
|
||||
|
||||
Some(
|
||||
@@ -582,7 +544,7 @@ impl PickerDelegate for LanguageModelPickerDelegate {
|
||||
.icon(model_info.icon)
|
||||
.is_selected(is_selected)
|
||||
.is_focused(selected)
|
||||
.favorite_action(favorite_action)
|
||||
.favorite_action(*action)
|
||||
.on_favorite_action_click(handle_action_click)
|
||||
.into_any_element(),
|
||||
)
|
||||
@@ -915,13 +877,13 @@ mod tests {
|
||||
LanguageModelPickerEntry::Model(info, action)
|
||||
if !in_favorites_section && info.model.telemetry_id() == "zed/claude" =>
|
||||
{
|
||||
assert!(matches!(action, LanguageModelPickerEntryAction::Unfavorite));
|
||||
assert!(matches!(action, ModelSelectorFavoriteAction::Unfavorite));
|
||||
}
|
||||
LanguageModelPickerEntry::Model(info, action) => {
|
||||
if info.is_favorite {
|
||||
assert!(matches!(action, LanguageModelPickerEntryAction::Unfavorite));
|
||||
assert!(matches!(action, ModelSelectorFavoriteAction::Unfavorite));
|
||||
} else {
|
||||
assert!(matches!(action, LanguageModelPickerEntryAction::Favorite));
|
||||
assert!(matches!(action, ModelSelectorFavoriteAction::Favorite));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,13 +321,15 @@ impl TextThreadEditor {
|
||||
},
|
||||
{
|
||||
let fs = fs.clone();
|
||||
move |model, cx| {
|
||||
crate::favorite_models::add_to_settings(model, fs.clone(), cx);
|
||||
move |model, should_be_favorite, cx| {
|
||||
crate::favorite_models::toggle_in_settings(
|
||||
model,
|
||||
should_be_favorite,
|
||||
fs.clone(),
|
||||
cx,
|
||||
);
|
||||
}
|
||||
},
|
||||
move |model, cx| {
|
||||
crate::favorite_models::remove_from_settings(model, fs.clone(), cx);
|
||||
},
|
||||
true, // Use popover styles for picker
|
||||
focus_handle,
|
||||
window,
|
||||
|
||||
@@ -42,6 +42,14 @@ pub enum ModelSelectorFavoriteAction {
|
||||
}
|
||||
|
||||
impl ModelSelectorFavoriteAction {
|
||||
pub fn from_is_favorite(is_favorite: bool) -> Self {
|
||||
if is_favorite {
|
||||
Self::Unfavorite
|
||||
} else {
|
||||
Self::Favorite
|
||||
}
|
||||
}
|
||||
|
||||
pub fn icon_name(&self) -> IconName {
|
||||
match self {
|
||||
Self::Favorite => IconName::Star,
|
||||
|
||||
Reference in New Issue
Block a user