mirror of
https://github.com/zed-industries/zed.git
synced 2026-07-09 16:00:35 +00:00
agent_ui: Defer spawning agents until the agent panel has been opened (#47355)
Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
parent
2be94ce893
commit
8db954a492
3 changed files with 41 additions and 111 deletions
|
|
@ -413,7 +413,6 @@ impl AcpThreadView {
|
|||
thread_store: Option<Entity<ThreadStore>>,
|
||||
prompt_store: Option<Entity<PromptStore>>,
|
||||
history: Entity<AcpThreadHistory>,
|
||||
track_load_event: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
|
|
@ -559,7 +558,6 @@ impl AcpThreadView {
|
|||
resume_thread.clone(),
|
||||
workspace.clone(),
|
||||
project.clone(),
|
||||
track_load_event,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
|
|
@ -570,7 +568,7 @@ impl AcpThreadView {
|
|||
profile_selector: None,
|
||||
notifications: Vec::new(),
|
||||
notification_subscriptions: HashMap::default(),
|
||||
list_state: list_state,
|
||||
list_state,
|
||||
thread_retry_status: None,
|
||||
thread_error: None,
|
||||
thread_error_markdown: None,
|
||||
|
|
@ -630,7 +628,6 @@ impl AcpThreadView {
|
|||
self.resume_thread_metadata.clone(),
|
||||
self.workspace.clone(),
|
||||
self.project.clone(),
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
|
@ -651,7 +648,6 @@ impl AcpThreadView {
|
|||
resume_thread: Option<AgentSessionInfo>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
project: Entity<Project>,
|
||||
track_load_event: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> ThreadState {
|
||||
|
|
@ -713,9 +709,7 @@ impl AcpThreadView {
|
|||
}
|
||||
};
|
||||
|
||||
if track_load_event {
|
||||
telemetry::event!("Agent Thread Started", agent = connection.telemetry_id());
|
||||
}
|
||||
telemetry::event!("Agent Thread Started", agent = connection.telemetry_id());
|
||||
|
||||
let result = if let Some(resume) = resume_thread.clone() {
|
||||
cx.update(|_, cx| {
|
||||
|
|
@ -8703,7 +8697,6 @@ pub(crate) mod tests {
|
|||
Some(thread_store),
|
||||
None,
|
||||
history.clone(),
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
|
|
@ -8995,7 +8988,6 @@ pub(crate) mod tests {
|
|||
Some(thread_store),
|
||||
None,
|
||||
history,
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
|
|
@ -9288,7 +9280,6 @@ pub(crate) mod tests {
|
|||
Some(thread_store.clone()),
|
||||
None,
|
||||
history,
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ use project::{
|
|||
agent_server_store::{CLAUDE_CODE_NAME, CODEX_NAME, GEMINI_NAME},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::{
|
||||
DefaultAgentView as DefaultView, LanguageModelProviderSetting, LanguageModelSelection,
|
||||
};
|
||||
use settings::{LanguageModelProviderSetting, LanguageModelSelection};
|
||||
|
||||
use zed_actions::agent::{OpenClaudeCodeOnboardingModal, ReauthenticateAgent};
|
||||
|
||||
|
|
@ -219,6 +217,7 @@ enum HistoryKind {
|
|||
}
|
||||
|
||||
enum ActiveView {
|
||||
Uninitialized,
|
||||
ExternalAgentThread {
|
||||
thread_view: Entity<AcpThreadView>,
|
||||
},
|
||||
|
|
@ -291,43 +290,14 @@ impl From<ExternalAgent> for AgentType {
|
|||
impl ActiveView {
|
||||
pub fn which_font_size_used(&self) -> WhichFontSize {
|
||||
match self {
|
||||
ActiveView::ExternalAgentThread { .. } | ActiveView::History { .. } => {
|
||||
WhichFontSize::AgentFont
|
||||
}
|
||||
ActiveView::Uninitialized
|
||||
| ActiveView::ExternalAgentThread { .. }
|
||||
| ActiveView::History { .. } => WhichFontSize::AgentFont,
|
||||
ActiveView::TextThread { .. } => WhichFontSize::BufferFont,
|
||||
ActiveView::Configuration => WhichFontSize::None,
|
||||
}
|
||||
}
|
||||
|
||||
fn native_agent(
|
||||
fs: Arc<dyn Fs>,
|
||||
prompt_store: Option<Entity<PromptStore>>,
|
||||
thread_store: Entity<ThreadStore>,
|
||||
project: Entity<Project>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
history: Entity<AcpThreadHistory>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
let thread_view = cx.new(|cx| {
|
||||
crate::acp::AcpThreadView::new(
|
||||
ExternalAgent::NativeAgent.server(fs, thread_store.clone()),
|
||||
None,
|
||||
None,
|
||||
workspace,
|
||||
project,
|
||||
Some(thread_store),
|
||||
prompt_store,
|
||||
history,
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
Self::ExternalAgentThread { thread_view }
|
||||
}
|
||||
|
||||
pub fn text_thread(
|
||||
text_thread_editor: Entity<TextThreadEditor>,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
|
|
@ -418,7 +388,6 @@ impl ActiveView {
|
|||
|
||||
pub struct AgentPanel {
|
||||
workspace: WeakEntity<Workspace>,
|
||||
loading: bool,
|
||||
user_store: Entity<UserStore>,
|
||||
project: Entity<Project>,
|
||||
fs: Arc<dyn Fs>,
|
||||
|
|
@ -431,6 +400,7 @@ pub struct AgentPanel {
|
|||
context_server_registry: Entity<ContextServerRegistry>,
|
||||
configuration: Option<Entity<AgentConfiguration>>,
|
||||
configuration_subscription: Option<Subscription>,
|
||||
focus_handle: FocusHandle,
|
||||
active_view: ActiveView,
|
||||
previous_view: Option<ActiveView>,
|
||||
new_thread_menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||
|
|
@ -504,22 +474,15 @@ impl AgentPanel {
|
|||
let panel =
|
||||
cx.new(|cx| Self::new(workspace, text_thread_store, prompt_store, window, cx));
|
||||
|
||||
panel.as_mut(cx).loading = true;
|
||||
if let Some(serialized_panel) = serialized_panel {
|
||||
panel.update(cx, |panel, cx| {
|
||||
panel.width = serialized_panel.width.map(|w| w.round());
|
||||
if let Some(selected_agent) = serialized_panel.selected_agent {
|
||||
panel.selected_agent = selected_agent.clone();
|
||||
panel.new_agent_thread(selected_agent, window, cx);
|
||||
panel.selected_agent = selected_agent;
|
||||
}
|
||||
cx.notify();
|
||||
});
|
||||
} else {
|
||||
panel.update(cx, |panel, cx| {
|
||||
panel.new_agent_thread(AgentType::NativeAgent, window, cx);
|
||||
});
|
||||
}
|
||||
panel.as_mut(cx).loading = false;
|
||||
panel
|
||||
})?;
|
||||
|
||||
|
|
@ -570,37 +533,7 @@ impl AgentPanel {
|
|||
)
|
||||
.detach();
|
||||
|
||||
let panel_type = AgentSettings::get_global(cx).default_view;
|
||||
let active_view = match panel_type {
|
||||
DefaultView::Thread => ActiveView::native_agent(
|
||||
fs.clone(),
|
||||
prompt_store.clone(),
|
||||
thread_store.clone(),
|
||||
project.clone(),
|
||||
workspace.clone(),
|
||||
acp_history.clone(),
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
DefaultView::TextThread => {
|
||||
let context = text_thread_store.update(cx, |store, cx| store.create(cx));
|
||||
let lsp_adapter_delegate = make_lsp_adapter_delegate(&project.clone(), cx).unwrap();
|
||||
let text_thread_editor = cx.new(|cx| {
|
||||
let mut editor = TextThreadEditor::for_text_thread(
|
||||
context,
|
||||
fs.clone(),
|
||||
workspace.clone(),
|
||||
project.clone(),
|
||||
lsp_adapter_delegate,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor.insert_default_prompt(window, cx);
|
||||
editor
|
||||
});
|
||||
ActiveView::text_thread(text_thread_editor, language_registry.clone(), window, cx)
|
||||
}
|
||||
};
|
||||
let active_view = ActiveView::Uninitialized;
|
||||
|
||||
let weak_panel = cx.entity().downgrade();
|
||||
|
||||
|
|
@ -680,6 +613,7 @@ impl AgentPanel {
|
|||
prompt_store,
|
||||
configuration: None,
|
||||
configuration_subscription: None,
|
||||
focus_handle: cx.focus_handle(),
|
||||
context_server_registry,
|
||||
previous_view: None,
|
||||
new_thread_menu_handle: PopoverMenuHandle::default(),
|
||||
|
|
@ -696,7 +630,6 @@ impl AgentPanel {
|
|||
text_thread_history,
|
||||
thread_store,
|
||||
selected_agent: AgentType::default(),
|
||||
loading: false,
|
||||
show_trust_workspace_message: false,
|
||||
};
|
||||
|
||||
|
|
@ -772,7 +705,8 @@ impl AgentPanel {
|
|||
pub(crate) fn active_thread_view(&self) -> Option<&Entity<AcpThreadView>> {
|
||||
match &self.active_view {
|
||||
ActiveView::ExternalAgentThread { thread_view, .. } => Some(thread_view),
|
||||
ActiveView::TextThread { .. }
|
||||
ActiveView::Uninitialized
|
||||
| ActiveView::TextThread { .. }
|
||||
| ActiveView::History { .. }
|
||||
| ActiveView::Configuration => None,
|
||||
}
|
||||
|
|
@ -868,7 +802,6 @@ impl AgentPanel {
|
|||
agent: crate::ExternalAgent,
|
||||
}
|
||||
|
||||
let loading = self.loading;
|
||||
let thread_store = self.thread_store.clone();
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
|
|
@ -918,7 +851,6 @@ impl AgentPanel {
|
|||
summarize_thread,
|
||||
workspace,
|
||||
project,
|
||||
loading,
|
||||
ext_agent,
|
||||
window,
|
||||
cx,
|
||||
|
|
@ -1064,7 +996,9 @@ impl AgentPanel {
|
|||
} => {
|
||||
text_thread_editor.focus_handle(cx).focus(window, cx);
|
||||
}
|
||||
ActiveView::History { .. } | ActiveView::Configuration => {}
|
||||
ActiveView::Uninitialized
|
||||
| ActiveView::History { .. }
|
||||
| ActiveView::Configuration => {}
|
||||
}
|
||||
}
|
||||
cx.notify();
|
||||
|
|
@ -1234,7 +1168,8 @@ impl AgentPanel {
|
|||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
ActiveView::TextThread { .. }
|
||||
ActiveView::Uninitialized
|
||||
| ActiveView::TextThread { .. }
|
||||
| ActiveView::History { .. }
|
||||
| ActiveView::Configuration => {}
|
||||
}
|
||||
|
|
@ -1314,6 +1249,7 @@ impl AgentPanel {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let current_is_uninitialized = matches!(self.active_view, ActiveView::Uninitialized);
|
||||
let current_is_history = matches!(self.active_view, ActiveView::History { .. });
|
||||
let new_is_history = matches!(new_view, ActiveView::History { .. });
|
||||
|
||||
|
|
@ -1323,13 +1259,7 @@ impl AgentPanel {
|
|||
let current_is_special = current_is_history || current_is_config;
|
||||
let new_is_special = new_is_history || new_is_config;
|
||||
|
||||
match &new_view {
|
||||
ActiveView::TextThread { .. } => {}
|
||||
ActiveView::ExternalAgentThread { .. } => {}
|
||||
ActiveView::History { .. } | ActiveView::Configuration => {}
|
||||
}
|
||||
|
||||
if current_is_special && !new_is_special {
|
||||
if current_is_uninitialized || (current_is_special && !new_is_special) {
|
||||
self.active_view = new_view;
|
||||
} else if !current_is_special && new_is_special {
|
||||
self.previous_view = Some(std::mem::replace(&mut self.active_view, new_view));
|
||||
|
|
@ -1539,7 +1469,6 @@ impl AgentPanel {
|
|||
summarize_thread: Option<AgentSessionInfo>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
project: Entity<Project>,
|
||||
loading: bool,
|
||||
ext_agent: ExternalAgent,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
|
|
@ -1565,7 +1494,6 @@ impl AgentPanel {
|
|||
thread_store,
|
||||
self.prompt_store.clone(),
|
||||
self.acp_history.clone(),
|
||||
!loading,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
|
|
@ -1573,7 +1501,7 @@ impl AgentPanel {
|
|||
|
||||
self.set_active_view(
|
||||
ActiveView::ExternalAgentThread { thread_view },
|
||||
!loading,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
|
@ -1583,6 +1511,7 @@ impl AgentPanel {
|
|||
impl Focusable for AgentPanel {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
match &self.active_view {
|
||||
ActiveView::Uninitialized => self.focus_handle.clone(),
|
||||
ActiveView::ExternalAgentThread { thread_view, .. } => thread_view.focus_handle(cx),
|
||||
ActiveView::History { kind } => match kind {
|
||||
HistoryKind::AgentThreads => self.acp_history.focus_handle(cx),
|
||||
|
|
@ -1595,7 +1524,7 @@ impl Focusable for AgentPanel {
|
|||
if let Some(configuration) = self.configuration.as_ref() {
|
||||
configuration.focus_handle(cx)
|
||||
} else {
|
||||
cx.focus_handle()
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1653,7 +1582,12 @@ impl Panel for AgentPanel {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
fn set_active(&mut self, _active: bool, _window: &mut Window, _cx: &mut Context<Self>) {}
|
||||
fn set_active(&mut self, active: bool, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if active && matches!(self.active_view, ActiveView::Uninitialized) {
|
||||
let selected_agent = self.selected_agent.clone();
|
||||
self.new_agent_thread(selected_agent, window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn remote_id() -> Option<proto::PanelId> {
|
||||
Some(proto::PanelId::AssistantPanel)
|
||||
|
|
@ -1806,6 +1740,7 @@ impl AgentPanel {
|
|||
Label::new(title).truncate().into_any_element()
|
||||
}
|
||||
ActiveView::Configuration => Label::new("Settings").truncate().into_any_element(),
|
||||
ActiveView::Uninitialized => Label::new("Agent").truncate().into_any_element(),
|
||||
};
|
||||
|
||||
h_flex()
|
||||
|
|
@ -2043,7 +1978,8 @@ impl AgentPanel {
|
|||
ActiveView::ExternalAgentThread { thread_view } => {
|
||||
thread_view.read(cx).as_native_thread(cx)
|
||||
}
|
||||
ActiveView::TextThread { .. }
|
||||
ActiveView::Uninitialized
|
||||
| ActiveView::TextThread { .. }
|
||||
| ActiveView::History { .. }
|
||||
| ActiveView::Configuration => None,
|
||||
};
|
||||
|
|
@ -2430,7 +2366,8 @@ impl AgentPanel {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
ActiveView::ExternalAgentThread { .. }
|
||||
ActiveView::Uninitialized
|
||||
| ActiveView::ExternalAgentThread { .. }
|
||||
| ActiveView::History { .. }
|
||||
| ActiveView::Configuration => return false,
|
||||
}
|
||||
|
|
@ -2461,7 +2398,9 @@ impl AgentPanel {
|
|||
}
|
||||
|
||||
match &self.active_view {
|
||||
ActiveView::History { .. } | ActiveView::Configuration => false,
|
||||
ActiveView::Uninitialized | ActiveView::History { .. } | ActiveView::Configuration => {
|
||||
false
|
||||
}
|
||||
ActiveView::ExternalAgentThread { thread_view, .. }
|
||||
if thread_view.read(cx).as_native_thread(cx).is_none() =>
|
||||
{
|
||||
|
|
@ -2726,7 +2665,7 @@ impl AgentPanel {
|
|||
);
|
||||
});
|
||||
}
|
||||
ActiveView::History { .. } | ActiveView::Configuration => {}
|
||||
ActiveView::Uninitialized | ActiveView::History { .. } | ActiveView::Configuration => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2768,7 +2707,7 @@ impl AgentPanel {
|
|||
match &self.active_view {
|
||||
ActiveView::ExternalAgentThread { .. } => key_context.add("acp_thread"),
|
||||
ActiveView::TextThread { .. } => key_context.add("text_thread"),
|
||||
ActiveView::History { .. } | ActiveView::Configuration => {}
|
||||
ActiveView::Uninitialized | ActiveView::History { .. } | ActiveView::Configuration => {}
|
||||
}
|
||||
key_context
|
||||
}
|
||||
|
|
@ -2817,6 +2756,7 @@ impl Render for AgentPanel {
|
|||
.children(self.render_workspace_trust_message(cx))
|
||||
.children(self.render_onboarding(window, cx))
|
||||
.map(|parent| match &self.active_view {
|
||||
ActiveView::Uninitialized => parent,
|
||||
ActiveView::ExternalAgentThread { thread_view, .. } => parent
|
||||
.child(thread_view.clone())
|
||||
.child(self.render_drag_target(cx)),
|
||||
|
|
@ -3035,7 +2975,7 @@ impl AgentPanel {
|
|||
};
|
||||
|
||||
self._external_thread(
|
||||
server, None, None, workspace, project, false, ext_agent, window, cx,
|
||||
server, None, None, workspace, project, ext_agent, window, cx,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,6 @@ impl AgentThreadPane {
|
|||
Some(thread_store),
|
||||
prompt_store,
|
||||
history,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue