1use std::{any::Any, path::Path, rc::Rc, sync::Arc};
2
3use agent_servers::AgentServer;
4use anyhow::Result;
5use fs::Fs;
6use gpui::{App, Entity, Task};
7use project::Project;
8use prompt_store::PromptStore;
9
10use crate::{HistoryStore, NativeAgent, NativeAgentConnection, templates::Templates};
11
12#[derive(Clone)]
13pub struct NativeAgentServer {
14 fs: Arc<dyn Fs>,
15 history: Entity<HistoryStore>,
16}
17
18impl NativeAgentServer {
19 pub fn new(fs: Arc<dyn Fs>, history: Entity<HistoryStore>) -> Self {
20 Self { fs, history }
21 }
22}
23
24impl AgentServer for NativeAgentServer {
25 fn name(&self) -> &'static str {
26 "Native Agent"
27 }
28
29 fn empty_state_headline(&self) -> &'static str {
30 "Native Agent"
31 }
32
33 fn empty_state_message(&self) -> &'static str {
34 "How can I help you today?"
35 }
36
37 fn logo(&self) -> ui::IconName {
38 // Using the ZedAssistant icon as it's the native built-in agent
39 ui::IconName::ZedAssistant
40 }
41
42 fn connect(
43 &self,
44 _root_dir: &Path,
45 project: &Entity<Project>,
46 cx: &mut App,
47 ) -> Task<Result<Rc<dyn acp_thread::AgentConnection>>> {
48 log::info!(
49 "NativeAgentServer::connect called for path: {:?}",
50 _root_dir
51 );
52 let project = project.clone();
53 let fs = self.fs.clone();
54 let history = self.history.clone();
55 let prompt_store = PromptStore::global(cx);
56 cx.spawn(async move |cx| {
57 log::debug!("Creating templates for native agent");
58 let templates = Templates::new();
59 let prompt_store = prompt_store.await?;
60
61 log::debug!("Creating native agent entity");
62 let agent =
63 NativeAgent::new(project, history, templates, Some(prompt_store), fs, cx).await?;
64
65 // Create the connection wrapper
66 let connection = NativeAgentConnection(agent);
67 log::info!("NativeAgentServer connection established successfully");
68
69 Ok(Rc::new(connection) as Rc<dyn acp_thread::AgentConnection>)
70 })
71 }
72
73 fn into_any(self: Rc<Self>) -> Rc<dyn Any> {
74 self
75 }
76}