codex.rs

 1use agent_client_protocol as acp;
 2use std::rc::Rc;
 3use std::{any::Any, path::Path};
 4
 5use crate::{AgentServer, AgentServerDelegate, load_proxy_env};
 6use acp_thread::AgentConnection;
 7use anyhow::{Context as _, Result};
 8use gpui::{App, SharedString, Task};
 9
10#[derive(Clone)]
11pub struct Codex;
12
13impl AgentServer for Codex {
14    fn telemetry_id(&self) -> &'static str {
15        "codex"
16    }
17
18    fn name(&self) -> SharedString {
19        "Codex".into()
20    }
21
22    fn logo(&self) -> ui::IconName {
23        // No dedicated Codex icon yet; use the generic AI icon.
24        ui::IconName::AiOpenAi
25    }
26
27    fn connect(
28        &self,
29        root_dir: Option<&Path>,
30        delegate: AgentServerDelegate,
31        cx: &mut App,
32    ) -> Task<Result<(Rc<dyn AgentConnection>, Option<task::SpawnInTerminal>)>> {
33        let name = self.name();
34        let root_dir = root_dir.map(|root_dir| root_dir.to_string_lossy().into_owned());
35        let is_remote = delegate.project.read(cx).is_via_remote_server();
36        let store = delegate.store.downgrade();
37        let extra_env = load_proxy_env(cx);
38        // No modes for Codex (yet).
39        let default_mode = self.default_mode(cx);
40
41        cx.spawn(async move |cx| {
42            // Look up the external agent registered under the "codex" name.
43            // The AgentServerStore is responsible for:
44            // - Downloading the correct GitHub release tar.gz for the OS/arch
45            // - Extracting the binary
46            // - Returning an AgentServerCommand to launch the binary
47            // - Always reporting "no updates" for now
48            let (command, root_dir, login) = store
49                .update(cx, |store, cx| {
50                    let agent = store
51                        .get_external_agent(&"codex".into())
52                        .context("Codex is not registered")?;
53                    anyhow::Ok(agent.get_command(
54                        root_dir.as_deref(),
55                        extra_env,
56                        delegate.status_tx,
57                        // For now, Codex should report that there are no updates.
58                        // The LocalCodex implementation in AgentServerStore should not send any updates.
59                        delegate.new_version_available,
60                        &mut cx.to_async(),
61                    ))
62                })??
63                .await?;
64
65            let connection = crate::acp::connect(
66                name,
67                command,
68                root_dir.as_ref(),
69                default_mode,
70                is_remote,
71                cx,
72            )
73            .await?;
74            Ok((connection, login))
75        })
76    }
77
78    fn into_any(self: Rc<Self>) -> Rc<dyn Any> {
79        self
80    }
81}