1use crate::{AgentServerCommand, AgentServerSettings};
2use acp_thread::AgentConnection;
3use anyhow::Result;
4use gpui::{App, Entity, SharedString, Task};
5use project::Project;
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, settings: &AgentServerSettings) -> Self {
17 Self {
18 name,
19 command: settings.command.clone(),
20 }
21 }
22}
23
24impl crate::AgentServer for CustomAgentServer {
25 fn telemetry_id(&self) -> &'static str {
26 "custom"
27 }
28
29 fn name(&self) -> SharedString {
30 self.name.clone()
31 }
32
33 fn logo(&self) -> IconName {
34 IconName::Terminal
35 }
36
37 fn empty_state_headline(&self) -> SharedString {
38 "No conversations yet".into()
39 }
40
41 fn empty_state_message(&self) -> SharedString {
42 format!("Start a conversation with {}", self.name).into()
43 }
44
45 fn connect(
46 &self,
47 root_dir: &Path,
48 _project: &Entity<Project>,
49 cx: &mut App,
50 ) -> Task<Result<Rc<dyn AgentConnection>>> {
51 let server_name = self.name();
52 let command = self.command.clone();
53 let root_dir = root_dir.to_path_buf();
54
55 cx.spawn(async move |mut cx| {
56 crate::acp::connect(server_name, command, &root_dir, &mut cx).await
57 })
58 }
59
60 fn into_any(self: Rc<Self>) -> Rc<dyn std::any::Any> {
61 self
62 }
63}