assistant_model_selector.rs

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