codex.rs

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