diff --git a/crates/acp_thread/src/connection.rs b/crates/acp_thread/src/connection.rs index aaf170928cf82719990e9b46a1e182b919db0102..372f0614afa299fe4afdfd40983fcdd63c7be20b 100644 --- a/crates/acp_thread/src/connection.rs +++ b/crates/acp_thread/src/connection.rs @@ -37,6 +37,22 @@ pub trait AgentConnection { cx: &mut App, ) -> Task>>; + /// Whether this agent supports loading existing sessions. + fn supports_load_session(&self) -> bool { + false + } + + /// Load an existing session by ID. + fn load_session( + self: Rc, + _session: AgentSessionInfo, + _project: Entity, + _cwd: &Path, + _cx: &mut App, + ) -> Task>> { + Task::ready(Err(anyhow::Error::msg("Loading sessions is not supported"))) + } + fn auth_methods(&self) -> &[acp::AuthMethod]; fn authenticate(&self, method: acp::AuthMethodId, cx: &mut App) -> Task>; diff --git a/crates/agent/src/agent.rs b/crates/agent/src/agent.rs index c2927a9a4c6469dced798e3a7a2b17acf0efc7d2..88921596291d9789b2a9f53f85a57c0e65d7ab67 100644 --- a/crates/agent/src/agent.rs +++ b/crates/agent/src/agent.rs @@ -1220,6 +1220,21 @@ impl acp_thread::AgentConnection for NativeAgentConnection { }) } + fn supports_load_session(&self) -> bool { + true + } + + fn load_session( + self: Rc, + session: AgentSessionInfo, + _project: Entity, + _cwd: &Path, + cx: &mut App, + ) -> Task>> { + self.0 + .update(cx, |agent, cx| agent.open_thread(session.session_id, cx)) + } + fn auth_methods(&self) -> &[acp::AuthMethod] { &[] // No auth for in-process } diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index ea6b08c6d0c17cb4e0784adaad62c50be746e1c9..3c5fcd3722742ba11d6c64fc91e4a393293b7c2c 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -613,6 +613,9 @@ impl AcpThreadView { } }) .next(); + let fallback_cwd = root_dir + .clone() + .unwrap_or_else(|| paths::home_dir().as_path().into()); let (status_tx, mut status_rx) = watch::channel("Loading…".into()); let (new_version_available_tx, mut new_version_available_rx) = watch::channel(None); let delegate = AgentServerDelegate::new( @@ -647,23 +650,34 @@ impl AcpThreadView { telemetry::event!("Agent Thread Started", agent = connection.telemetry_id()); } - let result = if let Some(native_agent) = connection - .clone() - .downcast::() - && let Some(resume) = resume_thread.clone() - { - cx.update(|_, cx| { - native_agent - .0 - .update(cx, |agent, cx| agent.open_thread(resume.session_id, cx)) - }) - .log_err() + let result = if let Some(resume) = resume_thread.clone() { + if connection.supports_load_session() { + let session_cwd = resume + .cwd + .clone() + .unwrap_or_else(|| fallback_cwd.as_ref().to_path_buf()); + cx.update(|_, cx| { + connection.clone().load_session( + resume, + project.clone(), + session_cwd.as_path(), + cx, + ) + }) + .log_err() + } else { + cx.update(|_, _| { + Task::ready(Err(anyhow!(LoadError::Other( + "Loading sessions is not supported by this agent.".into() + )))) + }) + .log_err() + } } else { - let root_dir = root_dir.unwrap_or(paths::home_dir().as_path().into()); cx.update(|_, cx| { connection .clone() - .new_thread(project.clone(), &root_dir, cx) + .new_thread(project.clone(), fallback_cwd.as_ref(), cx) }) .log_err() }; @@ -709,7 +723,11 @@ impl AcpThreadView { let connection = thread.read(cx).connection().clone(); let session_id = thread.read(cx).session_id().clone(); - let session_list = connection.session_list(cx); + let session_list = if connection.supports_load_session() { + connection.session_list(cx) + } else { + None + }; this.history.update(cx, |history, cx| { history.set_session_list(session_list, cx); }); diff --git a/crates/agent_ui_v2/src/agents_panel.rs b/crates/agent_ui_v2/src/agents_panel.rs index a9c65dd5abe70f75bf8e4f648287f9a823f31ea3..51329176210287da5b7c27c89a25caa44a6cd7e5 100644 --- a/crates/agent_ui_v2/src/agents_panel.rs +++ b/crates/agent_ui_v2/src/agents_panel.rs @@ -151,7 +151,9 @@ impl AgentsPanel { }; cx.update(|cx| { - if let Some(session_list) = connection.session_list(cx) { + if connection.supports_load_session() + && let Some(session_list) = connection.session_list(cx) + { history_handle.update(cx, |history, cx| { history.set_session_list(Some(session_list), cx); });