From 5591fc810e8c5cf31463bac2127cc89008c0599b Mon Sep 17 00:00:00 2001 From: Bennet Bo Fenner Date: Mon, 18 Aug 2025 12:22:00 +0200 Subject: [PATCH] agent: Restore last used agent session on startup (#36401) Release Notes: - N/A --- crates/agent2/src/agent.rs | 17 ++++--- crates/agent2/src/thread.rs | 5 ++- crates/agent_ui/src/agent_panel.rs | 71 ++++++++++++++++++------------ crates/agent_ui/src/agent_ui.rs | 2 +- 4 files changed, 60 insertions(+), 35 deletions(-) diff --git a/crates/agent2/src/agent.rs b/crates/agent2/src/agent.rs index 0ad90753e1..af740d9901 100644 --- a/crates/agent2/src/agent.rs +++ b/crates/agent2/src/agent.rs @@ -425,13 +425,18 @@ impl NativeAgent { cx: &mut Context, ) { self.models.refresh_list(cx); + + let default_model = LanguageModelRegistry::read_global(cx) + .default_model() + .map(|m| m.model.clone()); + for session in self.sessions.values_mut() { - session.thread.update(cx, |thread, _| { - if let Some(model) = thread.model() { - let model_id = LanguageModels::model_id(model); - if let Some(model) = self.models.model_from_id(&model_id) { - thread.set_model(model.clone()); - } + session.thread.update(cx, |thread, cx| { + if thread.model().is_none() + && let Some(model) = default_model.clone() + { + thread.set_model(model); + cx.notify(); } }); } diff --git a/crates/agent2/src/thread.rs b/crates/agent2/src/thread.rs index c4181a1f42..429832010b 100644 --- a/crates/agent2/src/thread.rs +++ b/crates/agent2/src/thread.rs @@ -622,7 +622,10 @@ impl Thread { ) -> Result>> { self.cancel(); - let model = self.model.clone().context("No language model configured")?; + let model = self + .model() + .cloned() + .context("No language model configured")?; let (events_tx, events_rx) = mpsc::unbounded::>(); let event_stream = AgentResponseEventStream(events_tx); let message_ix = self.messages.len().saturating_sub(1); diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index b01bf39728..391d6aa6e9 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -573,6 +573,7 @@ impl AgentPanel { panel.width = serialized_panel.width.map(|w| w.round()); if let Some(selected_agent) = serialized_panel.selected_agent { panel.selected_agent = selected_agent; + panel.new_agent_thread(selected_agent, window, cx); } cx.notify(); }); @@ -1631,16 +1632,53 @@ impl AgentPanel { menu } - pub fn set_selected_agent(&mut self, agent: AgentType, cx: &mut Context) { + pub fn set_selected_agent( + &mut self, + agent: AgentType, + window: &mut Window, + cx: &mut Context, + ) { if self.selected_agent != agent { self.selected_agent = agent; self.serialize(cx); + self.new_agent_thread(agent, window, cx); } } pub fn selected_agent(&self) -> AgentType { self.selected_agent } + + pub fn new_agent_thread( + &mut self, + agent: AgentType, + window: &mut Window, + cx: &mut Context, + ) { + match agent { + AgentType::Zed => { + window.dispatch_action( + NewThread { + from_thread_id: None, + } + .boxed_clone(), + cx, + ); + } + AgentType::TextThread => { + window.dispatch_action(NewTextThread.boxed_clone(), cx); + } + AgentType::NativeAgent => { + self.new_external_thread(Some(crate::ExternalAgent::NativeAgent), window, cx) + } + AgentType::Gemini => { + self.new_external_thread(Some(crate::ExternalAgent::Gemini), window, cx) + } + AgentType::ClaudeCode => { + self.new_external_thread(Some(crate::ExternalAgent::ClaudeCode), window, cx) + } + } + } } impl Focusable for AgentPanel { @@ -2221,16 +2259,13 @@ impl AgentPanel { panel.update(cx, |panel, cx| { panel.set_selected_agent( AgentType::Zed, + window, cx, ); }); } }); } - window.dispatch_action( - NewThread::default().boxed_clone(), - cx, - ); } }), ) @@ -2250,13 +2285,13 @@ impl AgentPanel { panel.update(cx, |panel, cx| { panel.set_selected_agent( AgentType::TextThread, + window, cx, ); }); } }); } - window.dispatch_action(NewTextThread.boxed_clone(), cx); } }), ) @@ -2275,19 +2310,13 @@ impl AgentPanel { panel.update(cx, |panel, cx| { panel.set_selected_agent( AgentType::NativeAgent, + window, cx, ); }); } }); } - window.dispatch_action( - NewExternalAgentThread { - agent: Some(crate::ExternalAgent::NativeAgent), - } - .boxed_clone(), - cx, - ); } }), ) @@ -2308,19 +2337,13 @@ impl AgentPanel { panel.update(cx, |panel, cx| { panel.set_selected_agent( AgentType::Gemini, + window, cx, ); }); } }); } - window.dispatch_action( - NewExternalAgentThread { - agent: Some(crate::ExternalAgent::Gemini), - } - .boxed_clone(), - cx, - ); } }), ) @@ -2339,19 +2362,13 @@ impl AgentPanel { panel.update(cx, |panel, cx| { panel.set_selected_agent( AgentType::ClaudeCode, + window, cx, ); }); } }); } - window.dispatch_action( - NewExternalAgentThread { - agent: Some(crate::ExternalAgent::ClaudeCode), - } - .boxed_clone(), - cx, - ); } }), ); diff --git a/crates/agent_ui/src/agent_ui.rs b/crates/agent_ui/src/agent_ui.rs index f25b576886..ce1c2203bf 100644 --- a/crates/agent_ui/src/agent_ui.rs +++ b/crates/agent_ui/src/agent_ui.rs @@ -146,7 +146,7 @@ pub struct NewExternalAgentThread { agent: Option, } -#[derive(Default, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] enum ExternalAgent { #[default]