Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T02:55:13.443Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

agent_model_selector.rs

145 lines · 5.2 KB · rust
1use crate::{
2    ModelUsageContext,
3    language_model_selector::{LanguageModelSelector, language_model_selector},
4    ui::ModelSelectorTooltip,
5};
6use fs::Fs;
7use gpui::{Entity, FocusHandle, SharedString};
8use language_model::IconOrSvg;
9use picker::popover_menu::PickerPopoverMenu;
10use settings::update_settings_file;
11use std::sync::Arc;
12use ui::{PopoverMenuHandle, Tooltip, prelude::*};
13
14pub struct AgentModelSelector {
15    selector: Entity<LanguageModelSelector>,
16    menu_handle: PopoverMenuHandle<LanguageModelSelector>,
17}
18
19impl AgentModelSelector {
20    pub(crate) fn new(
21        fs: Arc<dyn Fs>,
22        menu_handle: PopoverMenuHandle<LanguageModelSelector>,
23        focus_handle: FocusHandle,
24        model_usage_context: ModelUsageContext,
25        window: &mut Window,
26        cx: &mut Context<Self>,
27    ) -> Self {
28        Self {
29            selector: cx.new(move |cx| {
30                language_model_selector(
31                    {
32                        let model_context = model_usage_context.clone();
33                        move |cx| model_context.configured_model(cx)
34                    },
35                    {
36                        let fs = fs.clone();
37                        move |model, cx| {
38                            let provider = model.provider_id().0.to_string();
39                            let model_id = model.id().0.to_string();
40                            match &model_usage_context {
41                                ModelUsageContext::InlineAssistant => {
42                                    update_settings_file(fs.clone(), cx, move |settings, _cx| {
43                                        settings
44                                            .agent
45                                            .get_or_insert_default()
46                                            .set_inline_assistant_model(provider.clone(), model_id);
47                                    });
48                                }
49                            }
50                        }
51                    },
52                    {
53                        let fs = fs.clone();
54                        move |model, should_be_favorite, cx| {
55                            crate::favorite_models::toggle_in_settings(
56                                model,
57                                should_be_favorite,
58                                fs.clone(),
59                                cx,
60                            );
61                        }
62                    },
63                    true, // Use popover styles for picker
64                    focus_handle.clone(),
65                    window,
66                    cx,
67                )
68            }),
69            menu_handle,
70        }
71    }
72
73    pub fn toggle(&self, window: &mut Window, cx: &mut Context<Self>) {
74        self.menu_handle.toggle(window, cx);
75    }
76
77    pub fn active_model(&self, cx: &App) -> Option<language_model::ConfiguredModel> {
78        self.selector.read(cx).delegate.active_model(cx)
79    }
80
81    pub fn cycle_favorite_models(&self, window: &mut Window, cx: &mut Context<Self>) {
82        self.selector.update(cx, |selector, cx| {
83            selector.delegate.cycle_favorite_models(window, cx);
84        });
85    }
86}
87
88impl Render for AgentModelSelector {
89    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
90        let model = self.selector.read(cx).delegate.active_model(cx);
91        let model_name = model
92            .as_ref()
93            .map(|model| model.model.name().0)
94            .unwrap_or_else(|| SharedString::from("Select a Model"));
95
96        let provider_icon = model.as_ref().map(|model| model.provider.icon());
97        let color = if self.menu_handle.is_deployed() {
98            Color::Accent
99        } else {
100            Color::Muted
101        };
102
103        let show_cycle_row = self.selector.read(cx).delegate.favorites_count() > 1;
104
105        let tooltip = Tooltip::element({
106            move |_, _cx| {
107                ModelSelectorTooltip::new()
108                    .show_cycle_row(show_cycle_row)
109                    .into_any_element()
110            }
111        });
112
113        PickerPopoverMenu::new(
114            self.selector.clone(),
115            Button::new("active-model", model_name)
116                .label_size(LabelSize::Small)
117                .color(color)
118                .when_some(provider_icon, |this, icon| {
119                    this.start_icon(
120                        match icon {
121                            IconOrSvg::Svg(path) => Icon::from_external_svg(path),
122                            IconOrSvg::Icon(name) => Icon::new(name),
123                        }
124                        .color(color)
125                        .size(IconSize::XSmall),
126                    )
127                })
128                .end_icon(
129                    Icon::new(IconName::ChevronDown)
130                        .color(color)
131                        .size(IconSize::XSmall),
132                ),
133            tooltip,
134            gpui::Anchor::TopRight,
135            cx,
136        )
137        .with_handle(self.menu_handle.clone())
138        .offset(gpui::Point {
139            x: px(0.0),
140            y: px(2.0),
141        })
142        .render(window, cx)
143    }
144}
145
Served at tenant.openagents/omega Member data and write actions are omitted.