agent: Restore last used agent session on startup (#36401)

Release Notes:

- N/A
This commit is contained in:
Bennet Bo Fenner 2025-08-18 12:22:00 +02:00 committed by GitHub
parent 2eadd5a396
commit 5591fc810e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 35 deletions

View file

@ -425,13 +425,18 @@ impl NativeAgent {
cx: &mut Context<Self>,
) {
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();
}
});
}

View file

@ -622,7 +622,10 @@ impl Thread {
) -> Result<mpsc::UnboundedReceiver<Result<AgentResponseEvent>>> {
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::<Result<AgentResponseEvent>>();
let event_stream = AgentResponseEventStream(events_tx);
let message_ix = self.messages.len().saturating_sub(1);

View file

@ -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<Self>) {
pub fn set_selected_agent(
&mut self,
agent: AgentType,
window: &mut Window,
cx: &mut Context<Self>,
) {
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<Self>,
) {
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,
);
}
}),
);

View file

@ -146,7 +146,7 @@ pub struct NewExternalAgentThread {
agent: Option<ExternalAgent>,
}
#[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]