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                            div().max_w_32().child(
65                                Label::new(model_name)
66                                    .size(LabelSize::Small)
67                                    .color(Color::Muted)
68                                    .text_ellipsis()
69                                    .into_any_element(),
70                            ),
71                        )
72                        .child(
73                            Icon::new(IconName::ChevronDown)
74                                .color(Color::Muted)
75                                .size(IconSize::XSmall),
76                        ),
77                )
78                .tooltip(move |window, cx| {
79                    Tooltip::for_action_in(
80                        "Change Model",
81                        &ToggleModelSelector,
82                        &focus_handle,
83                        window,
84                        cx,
85                    )
86                }),
87        )
88        .with_handle(self.menu_handle.clone())
89    }
90}