1use assistant_settings::AssistantSettings;
2use fs::Fs;
3use gpui::{Entity, FocusHandle};
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
52 LanguageModelSelectorPopoverMenu::new(
53 self.selector.clone(),
54 ButtonLike::new("active-model")
55 .style(ButtonStyle::Subtle)
56 .child(
57 h_flex()
58 .gap_0p5()
59 .child(
60 div()
61 .overflow_x_hidden()
62 .flex_grow()
63 .whitespace_nowrap()
64 .child(match active_model {
65 Some(model) => h_flex()
66 .child(
67 Label::new(model.name().0)
68 .size(LabelSize::Small)
69 .color(Color::Muted),
70 )
71 .into_any_element(),
72 _ => Label::new("No model selected")
73 .size(LabelSize::Small)
74 .color(Color::Muted)
75 .into_any_element(),
76 }),
77 )
78 .child(
79 Icon::new(IconName::ChevronDown)
80 .color(Color::Muted)
81 .size(IconSize::XSmall),
82 ),
83 )
84 .tooltip(move |window, cx| {
85 Tooltip::for_action_in(
86 "Change Model",
87 &ToggleModelSelector,
88 &focus_handle,
89 window,
90 cx,
91 )
92 }),
93 )
94 .with_handle(self.menu_handle.clone())
95 }
96}