Skip to repository content146 lines · 5.2 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T03:03:30.235Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
agent_api_keys_onboarding.rs
1use gpui::{Action, IntoElement, ParentElement, RenderOnce};
2use language_model::{IconOrSvg, LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID};
3use ui::{Divider, List, ListBulletItem, prelude::*};
4
5pub struct ApiKeysWithProviders {
6 configured_providers: Vec<(IconOrSvg, SharedString)>,
7}
8
9impl ApiKeysWithProviders {
10 pub fn new(cx: &mut Context<Self>) -> Self {
11 cx.subscribe(
12 &LanguageModelRegistry::global(cx),
13 |this: &mut Self, _registry, event: &language_model::Event, cx| match event {
14 language_model::Event::ProviderStateChanged(_)
15 | language_model::Event::AddedProvider(_)
16 | language_model::Event::RemovedProvider(_)
17 | language_model::Event::ProvidersChanged => {
18 this.configured_providers = Self::compute_configured_providers(cx);
19 cx.notify();
20 }
21 _ => {}
22 },
23 )
24 .detach();
25
26 Self {
27 configured_providers: Self::compute_configured_providers(cx),
28 }
29 }
30
31 fn compute_configured_providers(cx: &App) -> Vec<(IconOrSvg, SharedString)> {
32 LanguageModelRegistry::read_global(cx)
33 .visible_providers()
34 .iter()
35 .filter(|provider| {
36 provider.is_authenticated(cx) && provider.id() != ZED_CLOUD_PROVIDER_ID
37 })
38 .map(|provider| (provider.icon(), provider.name().0))
39 .collect()
40 }
41}
42
43impl Render for ApiKeysWithProviders {
44 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
45 let configured_providers_list =
46 self.configured_providers
47 .iter()
48 .cloned()
49 .map(|(icon, name)| {
50 h_flex()
51 .gap_1p5()
52 .child(
53 match icon {
54 IconOrSvg::Icon(icon_name) => Icon::new(icon_name),
55 IconOrSvg::Svg(icon_path) => Icon::from_external_svg(icon_path),
56 }
57 .size(IconSize::XSmall)
58 .color(Color::Muted),
59 )
60 .child(Label::new(name))
61 });
62 div()
63 .mx_2p5()
64 .p_1()
65 .pb_0()
66 .gap_2()
67 .rounded_t_lg()
68 .border_t_1()
69 .border_x_1()
70 .border_color(cx.theme().colors().border.opacity(0.5))
71 .bg(cx.theme().colors().background.alpha(0.5))
72 .shadow(vec![
73 gpui::BoxShadow::new(px(1.), px(-1.), gpui::black().opacity(0.15))
74 .blur_radius(px(3.)),
75 ])
76 .child(
77 h_flex()
78 .px_2p5()
79 .py_1p5()
80 .gap_2()
81 .flex_wrap()
82 .rounded_t(px(5.))
83 .overflow_hidden()
84 .border_t_1()
85 .border_x_1()
86 .border_color(cx.theme().colors().border)
87 .bg(cx.theme().colors().panel_background)
88 .child(
89 h_flex()
90 .min_w_0()
91 .gap_2()
92 .child(
93 Icon::new(IconName::Info)
94 .size(IconSize::XSmall)
95 .color(Color::Muted),
96 )
97 .child(
98 div().w_full().child(
99 Label::new("Configured AI providers:").color(Color::Muted),
100 ),
101 ),
102 )
103 .children(configured_providers_list),
104 )
105 }
106}
107
108#[derive(IntoElement)]
109pub struct ApiKeysWithoutProviders;
110
111impl ApiKeysWithoutProviders {
112 pub fn new() -> Self {
113 Self
114 }
115}
116
117impl RenderOnce for ApiKeysWithoutProviders {
118 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
119 v_flex()
120 .mt_2()
121 .gap_1()
122 .child(
123 h_flex()
124 .gap_2()
125 .child(
126 Label::new("API Keys")
127 .size(LabelSize::Small)
128 .color(Color::Muted)
129 .buffer_font(cx),
130 )
131 .child(Divider::horizontal()),
132 )
133 .child(List::new().child(ListBulletItem::new(
134 "Configure a provider or API key directly in Omega.",
135 )))
136 .child(
137 Button::new("configure-providers", "Configure Providers")
138 .full_width()
139 .style(ButtonStyle::Outlined)
140 .on_click(move |_, window, cx| {
141 window.dispatch_action(zed_actions::agent::OpenSettings.boxed_clone(), cx);
142 }),
143 )
144 }
145}
146