codex.rs

 1use project::Project;
 2use settings::SettingsStore;
 3use std::path::Path;
 4use std::rc::Rc;
 5
 6use anyhow::Result;
 7use gpui::{App, Entity, Task};
 8
 9use crate::acp_connection::AcpConnection;
10use crate::{AgentServer, AgentServerCommand, AllAgentServersSettings};
11use acp_thread::AgentConnection;
12
13#[derive(Clone)]
14pub struct Codex;
15
16impl AgentServer for Codex {
17    fn name(&self) -> &'static str {
18        "Codex"
19    }
20
21    fn empty_state_headline(&self) -> &'static str {
22        "Welcome to Codex"
23    }
24
25    fn empty_state_message(&self) -> &'static str {
26        "What can I help with?"
27    }
28
29    fn logo(&self) -> ui::IconName {
30        ui::IconName::AiOpenAi
31    }
32
33    fn connect(
34        &self,
35        _root_dir: &Path,
36        project: &Entity<Project>,
37        cx: &mut App,
38    ) -> Task<Result<Rc<dyn AgentConnection>>> {
39        let project = project.clone();
40        let server_name = self.name();
41        cx.spawn(async move |cx| {
42            let settings = cx.read_global(|settings: &SettingsStore, _| {
43                settings.get::<AllAgentServersSettings>(None).codex.clone()
44            })?;
45
46            let Some(command) =
47                AgentServerCommand::resolve("codex", &["mcp"], settings, &project, cx).await
48            else {
49                anyhow::bail!("Failed to find codex binary");
50            };
51
52            let conn = AcpConnection::stdio(server_name, command, cx).await?;
53            Ok(Rc::new(conn) as _)
54        })
55    }
56}
57
58#[cfg(test)]
59pub(crate) mod tests {
60    use super::*;
61    use crate::AgentServerCommand;
62    use std::path::Path;
63
64    crate::common_e2e_tests!(Codex, allow_option_id = "approve");
65
66    pub fn local_command() -> AgentServerCommand {
67        let cli_path = Path::new(env!("CARGO_MANIFEST_DIR"))
68            .join("../../../codex/codex-rs/target/debug/codex");
69
70        AgentServerCommand {
71            path: cli_path,
72            args: vec!["mcp".into()],
73            env: None,
74        }
75    }
76}