use assistant_settings::AssistantSettings; use fs::Fs; use gpui::{Entity, FocusHandle, SharedString}; use language_model::LanguageModelRegistry; use language_model_selector::{ LanguageModelSelector, LanguageModelSelectorPopoverMenu, ToggleModelSelector, }; use settings::update_settings_file; use std::sync::Arc; use ui::{ButtonLike, PopoverMenuHandle, Tooltip, prelude::*}; #[derive(Clone, Copy)] pub enum ModelType { Default, InlineAssistant, } pub struct AssistantModelSelector { selector: Entity, menu_handle: PopoverMenuHandle, focus_handle: FocusHandle, model_type: ModelType, } impl AssistantModelSelector { pub(crate) fn new( fs: Arc, menu_handle: PopoverMenuHandle, focus_handle: FocusHandle, model_type: ModelType, window: &mut Window, cx: &mut App, ) -> Self { Self { selector: cx.new(|cx| { let fs = fs.clone(); LanguageModelSelector::new( move |model, cx| { let provider = model.provider_id().0.to_string(); let model_id = model.id().0.to_string(); match model_type { ModelType::Default => { update_settings_file::( fs.clone(), cx, move |settings, _cx| { settings.set_model(model.clone()); }, ); } ModelType::InlineAssistant => { update_settings_file::( fs.clone(), cx, move |settings, _cx| { settings.set_inline_assistant_model( provider.clone(), model_id.clone(), ); }, ); } } }, window, cx, ) }), menu_handle, focus_handle, model_type, } } pub fn toggle(&self, window: &mut Window, cx: &mut Context) { self.menu_handle.toggle(window, cx); } } impl Render for AssistantModelSelector { fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { let model_registry = LanguageModelRegistry::read_global(cx); let model = match self.model_type { ModelType::Default => model_registry.default_model(), ModelType::InlineAssistant => model_registry.inline_assistant_model(), }; let focus_handle = self.focus_handle.clone(); let model_name = match model { Some(model) => model.model.name().0, _ => SharedString::from("No model selected"), }; LanguageModelSelectorPopoverMenu::new( self.selector.clone(), ButtonLike::new("active-model") .style(ButtonStyle::Subtle) .child( h_flex() .gap_0p5() .child( Label::new(model_name) .size(LabelSize::Small) .color(Color::Muted), ) .child( Icon::new(IconName::ChevronDown) .color(Color::Muted) .size(IconSize::XSmall), ), ), move |window, cx| { Tooltip::for_action_in( "Change Model", &ToggleModelSelector, &focus_handle, window, cx, ) }, gpui::Corner::BottomRight, ) .with_handle(self.menu_handle.clone()) } }