custom.rs

 1use crate::{AgentServerCommand, AgentServerDelegate};
 2use acp_thread::AgentConnection;
 3use anyhow::Result;
 4use gpui::{App, SharedString, Task};
 5use language_models::provider::anthropic::AnthropicLanguageModelProvider;
 6use std::{path::Path, rc::Rc};
 7use ui::IconName;
 8
 9/// A generic agent server implementation for custom user-defined agents
10pub struct CustomAgentServer {
11    name: SharedString,
12    command: AgentServerCommand,
13}
14
15impl CustomAgentServer {
16    pub fn new(name: SharedString, command: AgentServerCommand) -> Self {
17        Self { name, command }
18    }
19}
20
21impl crate::AgentServer for CustomAgentServer {
22    fn telemetry_id(&self) -> &'static str {
23        "custom"
24    }
25
26    fn name(&self) -> SharedString {
27        self.name.clone()
28    }
29
30    fn logo(&self) -> IconName {
31        IconName::Terminal
32    }
33
34    fn connect(
35        &self,
36        root_dir: &Path,
37        _delegate: AgentServerDelegate,
38        cx: &mut App,
39    ) -> Task<Result<Rc<dyn AgentConnection>>> {
40        let server_name = self.name();
41        let mut command = self.command.clone();
42        let root_dir = root_dir.to_path_buf();
43
44        // TODO: Remove this once we have Claude properly
45        cx.spawn(async move |mut cx| {
46            if let Some(api_key) = cx
47                .update(AnthropicLanguageModelProvider::api_key)?
48                .await
49                .ok()
50            {
51                command
52                    .env
53                    .get_or_insert_default()
54                    .insert("ANTHROPIC_API_KEY".to_owned(), api_key.key);
55            }
56
57            crate::acp::connect(server_name, command, &root_dir, &mut cx).await
58        })
59    }
60
61    fn into_any(self: Rc<Self>) -> Rc<dyn std::any::Any> {
62        self
63    }
64}