assistant_model_selector.rs

 1use assistant_settings::AssistantSettings;
 2use fs::Fs;
 3use gpui::{Entity, FocusHandle, SharedString};
 4use language_model::LanguageModelRegistry;
 5use language_model_selector::{LanguageModelSelector, LanguageModelSelectorPopoverMenu};
 6use settings::update_settings_file;
 7use std::sync::Arc;
 8use ui::{prelude::*, ButtonLike, PopoverMenuHandle, Tooltip};
 9
10use crate::ToggleModelSelector;
11
12pub struct AssistantModelSelector {
13    selector: Entity<LanguageModelSelector>,
14    menu_handle: PopoverMenuHandle<LanguageModelSelector>,
15    focus_handle: FocusHandle,
16}
17
18impl AssistantModelSelector {
19    pub(crate) fn new(
20        fs: Arc<dyn Fs>,
21        menu_handle: PopoverMenuHandle<LanguageModelSelector>,
22        focus_handle: FocusHandle,
23        window: &mut Window,
24        cx: &mut App,
25    ) -> Self {
26        Self {
27            selector: cx.new(|cx| {
28                let fs = fs.clone();
29                LanguageModelSelector::new(
30                    move |model, cx| {
31                        update_settings_file::<AssistantSettings>(
32                            fs.clone(),
33                            cx,
34                            move |settings, _cx| settings.set_model(model.clone()),
35                        );
36                    },
37                    window,
38                    cx,
39                )
40            }),
41            menu_handle,
42            focus_handle,
43        }
44    }
45}
46
47impl Render for AssistantModelSelector {
48    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
49        let active_model = LanguageModelRegistry::read_global(cx).active_model();
50        let focus_handle = self.focus_handle.clone();
51        let model_name = match active_model {
52            Some(model) => model.name().0,
53            _ => SharedString::from("No model selected"),
54        };
55
56        LanguageModelSelectorPopoverMenu::new(
57            self.selector.clone(),
58            ButtonLike::new("active-model")
59                .style(ButtonStyle::Subtle)
60                .child(
61                    h_flex()
62                        .gap_0p5()
63                        .child(
64                            Label::new(model_name)
65                                .size(LabelSize::Small)
66                                .color(Color::Muted),
67                        )
68                        .child(
69                            Icon::new(IconName::ChevronDown)
70                                .color(Color::Muted)
71                                .size(IconSize::XSmall),
72                        ),
73                ),
74            move |window, cx| {
75                Tooltip::for_action_in(
76                    "Change Model",
77                    &ToggleModelSelector,
78                    &focus_handle,
79                    window,
80                    cx,
81                )
82            },
83            gpui::Corner::BottomRight,
84        )
85        .with_handle(self.menu_handle.clone())
86    }
87}