Embed Anthropic configuration view

This commit is contained in:
Agus Zubiaga 2025-08-18 17:18:21 -03:00
parent 6c7a5c50bf
commit 21082c0aba
28 changed files with 299 additions and 187 deletions

View file

@ -15,11 +15,11 @@ use gpui::{
};
use http_client::HttpClient;
use language_model::{
AuthenticateError, LanguageModel, LanguageModelCacheConfiguration,
LanguageModelCompletionError, LanguageModelId, LanguageModelName, LanguageModelProvider,
LanguageModelProviderId, LanguageModelProviderName, LanguageModelProviderState,
LanguageModelRequest, LanguageModelToolChoice, LanguageModelToolResultContent, MessageContent,
RateLimiter, Role,
AuthenticateError, ConfigurationViewTargetAgent, LanguageModel,
LanguageModelCacheConfiguration, LanguageModelCompletionError, LanguageModelId,
LanguageModelName, LanguageModelProvider, LanguageModelProviderId, LanguageModelProviderName,
LanguageModelProviderState, LanguageModelRequest, LanguageModelToolChoice,
LanguageModelToolResultContent, MessageContent, RateLimiter, Role,
};
use language_model::{LanguageModelCompletionEvent, LanguageModelToolUse, StopReason};
use schemars::JsonSchema;
@ -223,14 +223,6 @@ impl AnthropicLanguageModelProvider {
})
}
}
pub fn observe(
&self,
mut on_notify: impl FnMut(&mut App) + 'static,
cx: &mut App,
) -> Subscription {
cx.observe(&self.state, move |_, cx| on_notify(cx))
}
}
impl LanguageModelProviderState for AnthropicLanguageModelProvider {
@ -324,8 +316,13 @@ impl LanguageModelProvider for AnthropicLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
fn configuration_view(
&self,
target_agent: ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), target_agent, window, cx))
.into()
}
@ -927,12 +924,18 @@ struct ConfigurationView {
api_key_editor: Entity<Editor>,
state: gpui::Entity<State>,
load_credentials_task: Option<Task<()>>,
target_agent: ConfigurationViewTargetAgent,
}
impl ConfigurationView {
const PLACEHOLDER_TEXT: &'static str = "sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
fn new(
state: gpui::Entity<State>,
target_agent: ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
cx.observe(&state, |_, _, cx| {
cx.notify();
})
@ -964,6 +967,7 @@ impl ConfigurationView {
}),
state,
load_credentials_task,
target_agent,
}
}
@ -1037,7 +1041,10 @@ impl Render for ConfigurationView {
v_flex()
.size_full()
.on_action(cx.listener(Self::save_api_key))
.child(Label::new("To use Zed's agent with Anthropic, you need to add an API key. Follow these steps:"))
.child(Label::new(format!("To use {}, you need to add an API key. Follow these steps:", match self.target_agent {
ConfigurationViewTargetAgent::ZedAgent => "Zed's agent with Anthropic",
ConfigurationViewTargetAgent::Other(agent) => agent,
})))
.child(
List::new()
.child(
@ -1048,7 +1055,7 @@ impl Render for ConfigurationView {
)
)
.child(
InstructionListItem::text_only("Paste your API key below and hit enter to start using the assistant")
InstructionListItem::text_only("Paste your API key below and hit enter to start using the agent")
)
)
.child(

View file

@ -348,7 +348,12 @@ impl LanguageModelProvider for BedrockLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -391,7 +391,12 @@ impl LanguageModelProvider for CloudLanguageModelProvider {
Task::ready(Ok(()))
}
fn configuration_view(&self, _: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
_: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|_| ConfigurationView::new(self.state.clone()))
.into()
}

View file

@ -176,7 +176,12 @@ impl LanguageModelProvider for CopilotChatLanguageModelProvider {
Task::ready(Err(err.into()))
}
fn configuration_view(&self, _: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
_: &mut Window,
cx: &mut App,
) -> AnyView {
let state = self.state.clone();
cx.new(|cx| ConfigurationView::new(state, cx)).into()
}

View file

@ -229,7 +229,12 @@ impl LanguageModelProvider for DeepSeekLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -277,7 +277,12 @@ impl LanguageModelProvider for GoogleLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -226,7 +226,12 @@ impl LanguageModelProvider for LmStudioLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, _window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
_window: &mut Window,
cx: &mut App,
) -> AnyView {
let state = self.state.clone();
cx.new(|cx| ConfigurationView::new(state, cx)).into()
}

View file

@ -243,7 +243,12 @@ impl LanguageModelProvider for MistralLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -255,7 +255,12 @@ impl LanguageModelProvider for OllamaLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
let state = self.state.clone();
cx.new(|cx| ConfigurationView::new(state, window, cx))
.into()

View file

@ -233,7 +233,12 @@ impl LanguageModelProvider for OpenAiLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -243,7 +243,12 @@ impl LanguageModelProvider for OpenAiCompatibleLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -306,7 +306,12 @@ impl LanguageModelProvider for OpenRouterLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -230,7 +230,12 @@ impl LanguageModelProvider for VercelLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}

View file

@ -230,7 +230,12 @@ impl LanguageModelProvider for XAiLanguageModelProvider {
self.state.update(cx, |state, cx| state.authenticate(cx))
}
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
fn configuration_view(
&self,
_target_agent: language_model::ConfigurationViewTargetAgent,
window: &mut Window,
cx: &mut App,
) -> AnyView {
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
.into()
}