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::*;
11pub use gemini::*;
12use project::agent_server_store::AgentServerStore;
13
14use acp_thread::AgentConnection;
15use anyhow::Result;
16use gpui::{App, Entity, SharedString, Task};
17use project::Project;
18use std::{any::Any, path::Path, rc::Rc};
19
20pub use acp::AcpConnection;
21
22pub struct AgentServerDelegate {
23    store: Entity<AgentServerStore>,
24    project: Entity<Project>,
25    status_tx: Option<watch::Sender<SharedString>>,
26    new_version_available: Option<watch::Sender<Option<String>>>,
27}
28
29impl AgentServerDelegate {
30    pub fn new(
31        store: Entity<AgentServerStore>,
32        project: Entity<Project>,
33        status_tx: Option<watch::Sender<SharedString>>,
34        new_version_tx: Option<watch::Sender<Option<String>>>,
35    ) -> Self {
36        Self {
37            store,
38            project,
39            status_tx,
40            new_version_available: new_version_tx,
41        }
42    }
43
44    pub fn project(&self) -> &Entity<Project> {
45        &self.project
46    }
47}
48
49pub trait AgentServer: Send {
50    fn logo(&self) -> ui::IconName;
51    fn name(&self) -> SharedString;
52    fn telemetry_id(&self) -> &'static str;
53
54    fn connect(
55        &self,
56        root_dir: Option<&Path>,
57        delegate: AgentServerDelegate,
58        cx: &mut App,
59    ) -> Task<Result<(Rc<dyn AgentConnection>, Option<task::SpawnInTerminal>)>>;
60
61    fn into_any(self: Rc<Self>) -> Rc<dyn Any>;
62}
63
64impl dyn AgentServer {
65    pub fn downcast<T: 'static + AgentServer + Sized>(self: Rc<Self>) -> Option<Rc<T>> {
66        self.into_any().downcast().ok()
67    }
68}