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 project::{Project, ProjectLspAdapterDelegate};
|
||||
use search::{buffer_search::DivRegistrar, BufferSearchBar};
|
||||
use settings::Settings;
|
||||
use settings::{update_settings_file, Settings};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cmp::{self, Ordering},
|
||||
|
@ -139,6 +139,7 @@ pub struct AssistantPanel {
|
|||
model_selector_menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||
model_summary_editor: View<Editor>,
|
||||
authenticate_provider_task: Option<(LanguageModelProviderId, Task<()>)>,
|
||||
configuration_subscription: Option<Subscription>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -423,6 +424,7 @@ impl AssistantPanel {
|
|||
model_selector_menu_handle,
|
||||
model_summary_editor,
|
||||
authenticate_provider_task: None,
|
||||
configuration_subscription: None,
|
||||
};
|
||||
|
||||
if LanguageModelRegistry::read_global(cx)
|
||||
|
@ -478,6 +480,17 @@ impl AssistantPanel {
|
|||
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 { .. } => {
|
||||
cx.emit(AssistantPanelEvent::ContextEdited);
|
||||
true
|
||||
|
@ -546,12 +559,7 @@ impl AssistantPanel {
|
|||
log::error!("no context found with ID: {}", context_id.to_proto());
|
||||
return;
|
||||
};
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let lsp_adapter_delegate = workspace.update(cx, |workspace, cx| {
|
||||
make_lsp_adapter_delegate(workspace.project(), cx).log_err()
|
||||
});
|
||||
let lsp_adapter_delegate = make_lsp_adapter_delegate(&self.project, cx).log_err();
|
||||
|
||||
let assistant_panel = cx.view().downgrade();
|
||||
let editor = cx.new_view(|cx| {
|
||||
|
@ -943,6 +951,27 @@ impl AssistantPanel {
|
|||
}
|
||||
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| {
|
||||
pane.add_item(Box::new(configuration), true, true, None, cx);
|
||||
});
|
||||
|
@ -1024,12 +1053,7 @@ impl AssistantPanel {
|
|||
let project = self.project.clone();
|
||||
let workspace = self.workspace.clone();
|
||||
|
||||
let lsp_adapter_delegate = workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
make_lsp_adapter_delegate(workspace.project(), cx).log_err()
|
||||
})
|
||||
.log_err()
|
||||
.flatten();
|
||||
let lsp_adapter_delegate = make_lsp_adapter_delegate(&project, cx).log_err();
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let context = context.await?;
|
||||
|
@ -1076,13 +1100,7 @@ impl AssistantPanel {
|
|||
.update(cx, |store, cx| store.open_remote_context(id, cx));
|
||||
let fs = self.fs.clone();
|
||||
let workspace = self.workspace.clone();
|
||||
|
||||
let lsp_adapter_delegate = workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
make_lsp_adapter_delegate(workspace.project(), cx).log_err()
|
||||
})
|
||||
.log_err()
|
||||
.flatten();
|
||||
let lsp_adapter_delegate = make_lsp_adapter_delegate(&self.project, cx).log_err();
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let context = context.await?;
|
||||
|
@ -3100,6 +3118,9 @@ impl ConfigurationView {
|
|||
return None;
|
||||
};
|
||||
|
||||
let provider = active_tab.provider.clone();
|
||||
let provider_name = provider.name().0.clone();
|
||||
|
||||
let show_spinner = active_tab.is_loading_credentials();
|
||||
|
||||
let content = if show_spinner {
|
||||
|
@ -3123,13 +3144,41 @@ impl ConfigurationView {
|
|||
};
|
||||
|
||||
Some(
|
||||
div()
|
||||
.p(Spacing::Large.rems(cx))
|
||||
.bg(cx.theme().colors().title_bar_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.rounded_md()
|
||||
.child(content),
|
||||
v_flex()
|
||||
.gap_4()
|
||||
.child(
|
||||
div()
|
||||
.p(Spacing::Large.rems(cx))
|
||||
.bg(cx.theme().colors().title_bar_background)
|
||||
.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 {
|
||||
fn focus_handle(&self, _: &AppContext) -> FocusHandle {
|
||||
|
@ -3230,7 +3283,7 @@ impl FocusableView for ConfigurationView {
|
|||
}
|
||||
|
||||
impl Item for ConfigurationView {
|
||||
type Event = ();
|
||||
type Event = ConfigurationViewEvent;
|
||||
|
||||
fn tab_content_text(&self, _cx: &WindowContext) -> Option<SharedString> {
|
||||
Some("Configuration".into())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue