gemini.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 Gemini;
15
16impl AgentServer for Gemini {
17    fn name(&self) -> &'static str {
18        "Gemini"
19    }
20
21    fn empty_state_headline(&self) -> &'static str {
22        "Welcome to Gemini"
23    }
24
25    fn empty_state_message(&self) -> &'static str {
26        "Ask questions, edit files, run commands.\nBe specific for the best results."
27    }
28
29    fn logo(&self) -> ui::IconName {
30        ui::IconName::AiGemini
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).gemini.clone()
44            })?;
45
46            let Some(command) = AgentServerCommand::resolve(
47                "gemini",
48                &["--experimental-mcp"],
49                settings,
50                &project,
51                cx,
52            )
53            .await
54            else {
55                anyhow::bail!("Failed to find gemini binary");
56            };
57
58            let conn = AcpConnection::stdio(server_name, command, cx).await?;
59            Ok(Rc::new(conn) as _)
60        })
61    }
62}
63
64#[cfg(test)]
65pub(crate) mod tests {
66    use super::*;
67    use crate::AgentServerCommand;
68    use std::path::Path;
69
70    crate::common_e2e_tests!(Gemini, allow_option_id = "allow");
71
72    pub fn local_command() -> AgentServerCommand {
73        let cli_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../../gemini/packages/cli");
74
75        AgentServerCommand {
76            path: "node".into(),
77            args: vec![cli_path.to_string_lossy().to_string()],
78            env: None,
79        }
80    }
81}