agent_servers.rs

 1mod acp;
 2mod claude;
 3mod custom;
 4mod gemini;
 5
 6#[cfg(any(test, feature = "test-support"))]
 7pub mod e2e_tests;
 8
 9pub use claude::*;
10pub use custom::*;
11use fs::Fs;
12pub use gemini::*;
13use project::agent_server_store::AgentServerStore;
14
15use acp_thread::AgentConnection;
16use anyhow::Result;
17use gpui::{App, Entity, SharedString, Task};
18use project::Project;
19use std::{any::Any, path::Path, rc::Rc, sync::Arc};
20
21pub use acp::AcpConnection;
22
23pub struct AgentServerDelegate {
24    store: Entity<AgentServerStore>,
25    project: Entity<Project>,
26    status_tx: Option<watch::Sender<SharedString>>,
27    new_version_available: Option<watch::Sender<Option<String>>>,
28}
29
30impl AgentServerDelegate {
31    pub fn new(
32        store: Entity<AgentServerStore>,
33        project: Entity<Project>,
34        status_tx: Option<watch::Sender<SharedString>>,
35        new_version_tx: Option<watch::Sender<Option<String>>>,
36    ) -> Self {
37        Self {
38            store,
39            project,
40            status_tx,
41            new_version_available: new_version_tx,
42        }
43    }
44
45    pub fn project(&self) -> &Entity<Project> {
46        &self.project
47    }
48}
49
50pub trait AgentServer: Send {
51    fn logo(&self) -> ui::IconName;
52    fn name(&self) -> SharedString;
53    fn telemetry_id(&self) -> &'static str;
54    fn default_mode(&self, _cx: &mut App) -> Option<agent_client_protocol::SessionModeId> {
55        None
56    }
57    fn set_default_mode(
58        &self,
59        _mode_id: Option<agent_client_protocol::SessionModeId>,
60        _fs: Arc<dyn Fs>,
61        _cx: &mut App,
62    ) {
63    }
64
65    fn connect(
66        &self,
67        root_dir: Option<&Path>,
68        delegate: AgentServerDelegate,
69        cx: &mut App,
70    ) -> Task<Result<(Rc<dyn AgentConnection>, Option<task::SpawnInTerminal>)>>;
71
72    fn into_any(self: Rc<Self>) -> Rc<dyn Any>;
73}
74
75impl dyn AgentServer {
76    pub fn downcast<T: 'static + AgentServer + Sized>(self: Rc<Self>) -> Option<Rc<T>> {
77        self.into_any().downcast().ok()
78    }
79}