assistant panel: Add button to open new context to configuration page (#15628)
This adds a button to the `Configuration` page for providers so it's easy to start a new context _with the given provider_ selected.  Obviously not the most beautiful form this button can have, but works! cc @iamnbutler Release Notes: - N/A Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
parent
70b2da78f8
commit
5afa799f37
1 changed files with 82 additions and 29 deletions
|
@ -46,7 +46,7 @@ use multi_buffer::MultiBufferRow;
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
use project::{Project, ProjectLspAdapterDelegate};
|
use project::{Project, ProjectLspAdapterDelegate};
|
||||||
use search::{buffer_search::DivRegistrar, BufferSearchBar};
|
use search::{buffer_search::DivRegistrar, BufferSearchBar};
|
||||||
use settings::Settings;
|
use settings::{update_settings_file, Settings};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cmp::{self, Ordering},
|
cmp::{self, Ordering},
|
||||||
|
@ -139,6 +139,7 @@ pub struct AssistantPanel {
|
||||||
model_selector_menu_handle: PopoverMenuHandle<ContextMenu>,
|
model_selector_menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||||
model_summary_editor: View<Editor>,
|
model_summary_editor: View<Editor>,
|
||||||
authenticate_provider_task: Option<(LanguageModelProviderId, Task<()>)>,
|
authenticate_provider_task: Option<(LanguageModelProviderId, Task<()>)>,
|
||||||
|
configuration_subscription: Option<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -423,6 +424,7 @@ impl AssistantPanel {
|
||||||
model_selector_menu_handle,
|
model_selector_menu_handle,
|
||||||
model_summary_editor,
|
model_summary_editor,
|
||||||
authenticate_provider_task: None,
|
authenticate_provider_task: None,
|
||||||
|
configuration_subscription: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if LanguageModelRegistry::read_global(cx)
|
if LanguageModelRegistry::read_global(cx)
|
||||||
|
@ -478,6 +480,17 @@ impl AssistantPanel {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pane::Event::RemoveItem { idx } => {
|
||||||
|
if self
|
||||||
|
.pane
|
||||||
|
.read(cx)
|
||||||
|
.item_for_index(*idx)
|
||||||
|
.map_or(false, |item| item.downcast::<ConfigurationView>().is_some())
|
||||||
|
{
|
||||||
|
self.configuration_subscription = None;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
pane::Event::RemovedItem { .. } => {
|
pane::Event::RemovedItem { .. } => {
|
||||||
cx.emit(AssistantPanelEvent::ContextEdited);
|
cx.emit(AssistantPanelEvent::ContextEdited);
|
||||||
true
|
true
|
||||||
|
@ -546,12 +559,7 @@ impl AssistantPanel {
|
||||||
log::error!("no context found with ID: {}", context_id.to_proto());
|
log::error!("no context found with ID: {}", context_id.to_proto());
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(workspace) = self.workspace.upgrade() else {
|
let lsp_adapter_delegate = make_lsp_adapter_delegate(&self.project, cx).log_err();
|
||||||
return;
|
|
||||||
};
|
|
||||||
let lsp_adapter_delegate = workspace.update(cx, |workspace, cx| {
|
|
||||||
make_lsp_adapter_delegate(workspace.project(), cx).log_err()
|
|
||||||
});
|
|
||||||
|
|
||||||
let assistant_panel = cx.view().downgrade();
|
let assistant_panel = cx.view().downgrade();
|
||||||
let editor = cx.new_view(|cx| {
|
let editor = cx.new_view(|cx| {
|
||||||
|
@ -943,6 +951,27 @@ impl AssistantPanel {
|
||||||
}
|
}
|
||||||
view
|
view
|
||||||
});
|
});
|
||||||
|
self.configuration_subscription = Some(cx.subscribe(
|
||||||
|
&configuration,
|
||||||
|
|this, _, event: &ConfigurationViewEvent, cx| match event {
|
||||||
|
ConfigurationViewEvent::NewProviderContextEditor(provider) => {
|
||||||
|
if LanguageModelRegistry::read_global(cx)
|
||||||
|
.active_provider()
|
||||||
|
.map_or(true, |p| p.id() != provider.id())
|
||||||
|
{
|
||||||
|
if let Some(model) = provider.provided_models(cx).first().cloned() {
|
||||||
|
update_settings_file::<AssistantSettings>(
|
||||||
|
this.fs.clone(),
|
||||||
|
cx,
|
||||||
|
move |settings, _| settings.set_model(model),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.new_context(cx);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
));
|
||||||
self.pane.update(cx, |pane, cx| {
|
self.pane.update(cx, |pane, cx| {
|
||||||
pane.add_item(Box::new(configuration), true, true, None, cx);
|
pane.add_item(Box::new(configuration), true, true, None, cx);
|
||||||
});
|
});
|
||||||
|
@ -1024,12 +1053,7 @@ impl AssistantPanel {
|
||||||
let project = self.project.clone();
|
let project = self.project.clone();
|
||||||
let workspace = self.workspace.clone();
|
let workspace = self.workspace.clone();
|
||||||
|
|
||||||
let lsp_adapter_delegate = workspace
|
let lsp_adapter_delegate = make_lsp_adapter_delegate(&project, cx).log_err();
|
||||||
.update(cx, |workspace, cx| {
|
|
||||||
make_lsp_adapter_delegate(workspace.project(), cx).log_err()
|
|
||||||
})
|
|
||||||
.log_err()
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
let context = context.await?;
|
let context = context.await?;
|
||||||
|
@ -1076,13 +1100,7 @@ impl AssistantPanel {
|
||||||
.update(cx, |store, cx| store.open_remote_context(id, cx));
|
.update(cx, |store, cx| store.open_remote_context(id, cx));
|
||||||
let fs = self.fs.clone();
|
let fs = self.fs.clone();
|
||||||
let workspace = self.workspace.clone();
|
let workspace = self.workspace.clone();
|
||||||
|
let lsp_adapter_delegate = make_lsp_adapter_delegate(&self.project, cx).log_err();
|
||||||
let lsp_adapter_delegate = workspace
|
|
||||||
.update(cx, |workspace, cx| {
|
|
||||||
make_lsp_adapter_delegate(workspace.project(), cx).log_err()
|
|
||||||
})
|
|
||||||
.log_err()
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
let context = context.await?;
|
let context = context.await?;
|
||||||
|
@ -3100,6 +3118,9 @@ impl ConfigurationView {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let provider = active_tab.provider.clone();
|
||||||
|
let provider_name = provider.name().0.clone();
|
||||||
|
|
||||||
let show_spinner = active_tab.is_loading_credentials();
|
let show_spinner = active_tab.is_loading_credentials();
|
||||||
|
|
||||||
let content = if show_spinner {
|
let content = if show_spinner {
|
||||||
|
@ -3123,13 +3144,41 @@ impl ConfigurationView {
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
div()
|
v_flex()
|
||||||
.p(Spacing::Large.rems(cx))
|
.gap_4()
|
||||||
.bg(cx.theme().colors().title_bar_background)
|
.child(
|
||||||
.border_1()
|
div()
|
||||||
.border_color(cx.theme().colors().border_variant)
|
.p(Spacing::Large.rems(cx))
|
||||||
.rounded_md()
|
.bg(cx.theme().colors().title_bar_background)
|
||||||
.child(content),
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border_variant)
|
||||||
|
.rounded_md()
|
||||||
|
.child(content),
|
||||||
|
)
|
||||||
|
.when(
|
||||||
|
!show_spinner && provider.is_authenticated(cx),
|
||||||
|
move |this| {
|
||||||
|
this.child(
|
||||||
|
h_flex().justify_end().child(
|
||||||
|
Button::new(
|
||||||
|
"new-context",
|
||||||
|
format!("Open new context using {}", provider_name),
|
||||||
|
)
|
||||||
|
.icon_position(IconPosition::Start)
|
||||||
|
.icon(IconName::Plus)
|
||||||
|
.style(ButtonStyle::Filled)
|
||||||
|
.layer(ElevationIndex::ModalSurface)
|
||||||
|
.on_click(cx.listener(
|
||||||
|
move |_, _, cx| {
|
||||||
|
cx.emit(ConfigurationViewEvent::NewProviderContextEditor(
|
||||||
|
provider.clone(),
|
||||||
|
))
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3218,7 +3267,11 @@ impl Render for ConfigurationView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter<()> for ConfigurationView {}
|
pub enum ConfigurationViewEvent {
|
||||||
|
NewProviderContextEditor(Arc<dyn LanguageModelProvider>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventEmitter<ConfigurationViewEvent> for ConfigurationView {}
|
||||||
|
|
||||||
impl FocusableView for ConfigurationView {
|
impl FocusableView for ConfigurationView {
|
||||||
fn focus_handle(&self, _: &AppContext) -> FocusHandle {
|
fn focus_handle(&self, _: &AppContext) -> FocusHandle {
|
||||||
|
@ -3230,7 +3283,7 @@ impl FocusableView for ConfigurationView {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item for ConfigurationView {
|
impl Item for ConfigurationView {
|
||||||
type Event = ();
|
type Event = ConfigurationViewEvent;
|
||||||
|
|
||||||
fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
|
fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
|
||||||
Some("Configuration".into())
|
Some("Configuration".into())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue