From 41c550cbe169cb16aae4f0909809e5c5dbc65211 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Tue, 30 Jul 2024 14:25:02 +0200 Subject: [PATCH] assistant panel: Avoid auth prompt on provider switch (#15478) Previously, the following lead to a bug: 1. Set OpenAI key 2. Switch to Anthropic 3. Restart Zed 4. Switch provider to OpenAI -> get prompted for authentication prompt With this change, you won't get prompted for the OpenAI key again. Release Notes: - N/A Co-authored-by: Bennet --- crates/assistant/src/assistant_panel.rs | 46 +++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index c7df8bc548..ad3616c459 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -43,7 +43,7 @@ use language::{ language_settings::SoftWrap, Buffer, Capability, LanguageRegistry, LspAdapterDelegate, Point, ToOffset, }; -use language_model::Role; +use language_model::{LanguageModelProviderId, Role}; use multi_buffer::MultiBufferRow; use picker::{Picker, PickerDelegate}; use project::{Project, ProjectLspAdapterDelegate}; @@ -139,6 +139,7 @@ pub struct AssistantPanel { authentication_prompt: Option, model_selector_menu_handle: PopoverMenuHandle, model_summary_editor: View, + authentificate_provider_task: Option<(LanguageModelProviderId, Task<()>)>, } #[derive(Clone)] @@ -412,6 +413,7 @@ impl AssistantPanel { authentication_prompt: None, model_selector_menu_handle, model_summary_editor, + authentificate_provider_task: None, } } @@ -558,18 +560,42 @@ impl AssistantPanel { }) } - if self.active_context_editor(cx).is_none() { - self.new_context(cx); - } + let Some(new_provider_id) = LanguageModelCompletionProvider::read_global(cx) + .active_provider() + .map(|p| p.id()) + else { + return; + }; - let authentication_prompt = Self::authentication_prompt(cx); - for context_editor in self.context_editors(cx) { - context_editor.update(cx, |editor, cx| { - editor.set_authentication_prompt(authentication_prompt.clone(), cx); + if self + .authentificate_provider_task + .as_ref() + .map_or(true, |(old_provider_id, _)| { + *old_provider_id != new_provider_id + }) + { + let load_credentials = self.authenticate(cx); + let task = cx.spawn(|this, mut cx| async move { + let _ = load_credentials.await; + this.update(&mut cx, |this, cx| { + if this.active_context_editor(cx).is_none() { + this.new_context(cx); + } + + let authentication_prompt = Self::authentication_prompt(cx); + for context_editor in this.context_editors(cx) { + context_editor.update(cx, |editor, cx| { + editor.set_authentication_prompt(authentication_prompt.clone(), cx); + }); + } + + cx.notify(); + }) + .log_err(); }); - } - cx.notify(); + self.authentificate_provider_task = Some((new_provider_id, task)); + } } fn authentication_prompt(cx: &mut WindowContext) -> Option {