mod acp; mod custom; #[cfg(any(test, feature = "test-support"))] pub mod e2e_tests; use client::ProxySettings; use collections::{HashMap, HashSet}; pub use custom::*; use fs::Fs; use http_client::read_no_proxy_from_env; use project::{AgentId, Project, agent_server_store::AgentServerStore}; use acp_thread::AgentConnection; use agent_client_protocol::schema as acp_schema; use anyhow::Result; use gpui::{App, AppContext, Entity, Task}; use settings::SettingsStore; use std::{any::Any, rc::Rc, sync::Arc}; #[cfg(any(test, feature = "test-support"))] pub use acp::test_support::{ FakeAcpAgentServer, FakeAcpConnectionHarness, connect_fake_acp_connection, }; pub use acp::{ AcpConnection, AcpDebugMessage, AcpDebugMessageContent, AcpDebugMessageDirection, GEMINI_TERMINAL_AUTH_METHOD_ID, }; pub struct AgentServerDelegate { store: Entity, new_version_available: Option>>, } impl AgentServerDelegate { pub fn new( store: Entity, new_version_tx: Option>>, ) -> Self { Self { store, new_version_available: new_version_tx, } } } pub trait AgentServer: Send { fn logo(&self) -> ui::IconName; fn agent_id(&self) -> AgentId; fn connect( &self, delegate: AgentServerDelegate, project: Entity, cx: &mut App, ) -> Task>>; fn into_any(self: Rc) -> Rc; fn default_mode(&self, _cx: &App) -> Option { None } fn set_default_mode( &self, _mode_id: Option, _fs: Arc, _cx: &mut App, ) { } fn default_model(&self, _cx: &App) -> Option { None } fn set_default_model( &self, _model_id: Option, _fs: Arc, _cx: &mut App, ) { } fn favorite_model_ids(&self, _cx: &mut App) -> HashSet { HashSet::default() } fn default_config_option(&self, _config_id: &str, _cx: &App) -> Option { None } fn set_default_config_option( &self, _config_id: &str, _value_id: Option<&str>, _fs: Arc, _cx: &mut App, ) { } fn favorite_config_option_value_ids( &self, _config_id: &acp_schema::SessionConfigId, _cx: &mut App, ) -> HashSet { HashSet::default() } fn toggle_favorite_config_option_value( &self, _config_id: acp_schema::SessionConfigId, _value_id: acp_schema::SessionConfigValueId, _should_be_favorite: bool, _fs: Arc, _cx: &App, ) { } fn toggle_favorite_model( &self, _model_id: acp_schema::ModelId, _should_be_favorite: bool, _fs: Arc, _cx: &App, ) { } } impl dyn AgentServer { pub fn downcast(self: Rc) -> Option> { self.into_any().downcast().ok() } } /// Load the default proxy environment variables to pass through to the agent pub fn load_proxy_env(cx: &mut App) -> HashMap { let proxy_url = cx .read_global(|settings: &SettingsStore, _| settings.get::(None).proxy_url()); let mut env = HashMap::default(); if let Some(proxy_url) = &proxy_url { let env_var = if proxy_url.scheme() == "https" { "HTTPS_PROXY" } else { "HTTP_PROXY" }; env.insert(env_var.to_owned(), proxy_url.to_string()); } if let Some(no_proxy) = read_no_proxy_from_env() { env.insert("NO_PROXY".to_owned(), no_proxy); } else if proxy_url.is_some() { // We sometimes need local MCP servers that we don't want to proxy env.insert("NO_PROXY".to_owned(), "localhost,127.0.0.1".to_owned()); } env }