agent_ui: Add delete button for compatible API-based LLM providers (#41739)
Discussion: https://github.com/zed-industries/zed/discussions/41736 Release Notes: - agent panel: Added the ability to remove OpenAI-compatible LLM providers directly from the UI. --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
@@ -23,16 +23,18 @@ use language::LanguageRegistry;
|
||||
use language_model::{
|
||||
LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID,
|
||||
};
|
||||
use language_models::AllLanguageModelSettings;
|
||||
use notifications::status_toast::{StatusToast, ToastIcon};
|
||||
use project::{
|
||||
agent_server_store::{AgentServerStore, CLAUDE_CODE_NAME, CODEX_NAME, GEMINI_NAME},
|
||||
context_server_store::{ContextServerConfiguration, ContextServerStatus, ContextServerStore},
|
||||
};
|
||||
use rope::Rope;
|
||||
use settings::{SettingsStore, update_settings_file};
|
||||
use settings::{Settings, SettingsStore, update_settings_file};
|
||||
use ui::{
|
||||
Chip, CommonAnimationExt, ContextMenu, Disclosure, Divider, DividerColor, ElevationIndex,
|
||||
Indicator, PopoverMenu, Switch, SwitchColor, Tooltip, WithScrollbar, prelude::*,
|
||||
Button, ButtonStyle, Chip, CommonAnimationExt, ContextMenu, Disclosure, Divider, DividerColor,
|
||||
ElevationIndex, IconName, IconPosition, IconSize, Indicator, LabelSize, PopoverMenu, Switch,
|
||||
SwitchColor, Tooltip, WithScrollbar, prelude::*,
|
||||
};
|
||||
use util::ResultExt as _;
|
||||
use workspace::{Workspace, create_and_open_local_file};
|
||||
@@ -304,10 +306,76 @@ impl AgentConfiguration {
|
||||
}
|
||||
})),
|
||||
)
|
||||
}),
|
||||
})
|
||||
.when(
|
||||
is_expanded && is_removable_provider(&provider.id(), cx),
|
||||
|this| {
|
||||
this.child(
|
||||
Button::new(
|
||||
SharedString::from(format!("delete-provider-{provider_id}")),
|
||||
"Remove Provider",
|
||||
)
|
||||
.full_width()
|
||||
.style(ButtonStyle::Outlined)
|
||||
.icon_position(IconPosition::Start)
|
||||
.icon(IconName::Trash)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(Color::Muted)
|
||||
.label_size(LabelSize::Small)
|
||||
.on_click(cx.listener({
|
||||
let provider = provider.clone();
|
||||
move |this, _event, window, cx| {
|
||||
this.delete_provider(provider.clone(), window, cx);
|
||||
}
|
||||
})),
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn delete_provider(
|
||||
&mut self,
|
||||
provider: Arc<dyn LanguageModelProvider>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let fs = self.fs.clone();
|
||||
let provider_id = provider.id();
|
||||
|
||||
cx.spawn_in(window, async move |_, cx| {
|
||||
cx.update(|_window, cx| {
|
||||
update_settings_file(fs.clone(), cx, {
|
||||
let provider_id = provider_id.clone();
|
||||
move |settings, _| {
|
||||
if let Some(ref mut openai_compatible) = settings
|
||||
.language_models
|
||||
.as_mut()
|
||||
.and_then(|lm| lm.openai_compatible.as_mut())
|
||||
{
|
||||
let key_to_remove: Arc<str> = Arc::from(provider_id.0.as_ref());
|
||||
openai_compatible.remove(&key_to_remove);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.log_err();
|
||||
|
||||
cx.update(|_window, cx| {
|
||||
LanguageModelRegistry::global(cx).update(cx, {
|
||||
let provider_id = provider_id.clone();
|
||||
move |registry, cx| {
|
||||
registry.unregister_provider(provider_id, cx);
|
||||
}
|
||||
})
|
||||
})
|
||||
.log_err();
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn render_provider_configuration_section(
|
||||
&mut self,
|
||||
cx: &mut Context<Self>,
|
||||
@@ -1225,3 +1293,14 @@ fn find_text_in_buffer(
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// OpenAI-compatible providers are user-configured and can be removed,
|
||||
// whereas built-in providers (like Anthropic, OpenAI, Google, etc.) can't.
|
||||
//
|
||||
// If in the future we have more "API-compatible-type" of providers,
|
||||
// they should be included here as removable providers.
|
||||
fn is_removable_provider(provider_id: &LanguageModelProviderId, cx: &App) -> bool {
|
||||
AllLanguageModelSettings::get_global(cx)
|
||||
.openai_compatible
|
||||
.contains_key(provider_id.0.as_ref())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user