fix: disable some computercontroller functionality when no $DISPLAY detected (#7824)

This commit is contained in:
Jack Amadeo
2026-03-11 23:28:28 -04:00
committed by GitHub
parent c00371b126
commit 9adff9b177
3 changed files with 42 additions and 9 deletions
+25 -5
View File
@@ -346,8 +346,10 @@ impl ComputerControllerServer {
let system_automation: Arc<Box<dyn SystemAutomation + Send + Sync>> = let system_automation: Arc<Box<dyn SystemAutomation + Send + Sync>> =
Arc::new(create_system_automation()); Arc::new(create_system_automation());
let os_specific_instructions = match std::env::consts::OS { let has_display = system_automation.has_display();
"windows" => indoc! {r#"
let os_specific_instructions = match (std::env::consts::OS, has_display) {
("windows", _) => indoc! {r#"
Here are some extra tools: Here are some extra tools:
automation_script automation_script
- Create and run PowerShell or Batch scripts - Create and run PowerShell or Batch scripts
@@ -363,7 +365,7 @@ impl ComputerControllerServer {
- System automation using PowerShell - System automation using PowerShell
- Consider the screenshot tool to work out what is on screen and what to do to help with the control task. - Consider the screenshot tool to work out what is on screen and what to do to help with the control task.
"#}, "#},
"macos" => indoc! {r#" ("macos", _) => indoc! {r#"
Here are some extra tools: Here are some extra tools:
automation_script automation_script
- Create and run Shell, Ruby, or AppleScript scripts - Create and run Shell, Ruby, or AppleScript scripts
@@ -457,7 +459,7 @@ impl ComputerControllerServer {
- If something fails, check `permissions status` for missing permissions - If something fails, check `permissions status` for missing permissions
- Use `capture_screenshot: true` on click/type/press actions to verify the result - Use `capture_screenshot: true` on click/type/press actions to verify the result
"#}, "#},
_ => indoc! {r#" (_, true) => indoc! {r#"
Here are some extra tools: Here are some extra tools:
automation_script automation_script
- Create and run Shell scripts - Create and run Shell scripts
@@ -481,6 +483,19 @@ impl ComputerControllerServer {
- Automating UI interactions - Automating UI interactions
- Desktop environment control - Desktop environment control
"#}, "#},
(_, false) => indoc! {r#"
Here are some extra tools:
automation_script
- Create and run Shell scripts
- Shell (bash) is recommended for most tasks
- Scripts can save their output to files
- Linux-specific features:
- System automation through shell scripting
- D-Bus system services integration
Note: No display server detected (headless mode). The computer_control tool
is not available in this environment. Use automation_script for shell-based tasks.
"#},
}; };
let instructions = formatdoc! {r#" let instructions = formatdoc! {r#"
@@ -517,8 +532,13 @@ impl ComputerControllerServer {
cache_dir = cache_dir.display() cache_dir = cache_dir.display()
}; };
let mut tool_router = Self::tool_router();
if !has_display {
tool_router.remove_route("computer_control");
}
Self { Self {
tool_router: Self::tool_router(), tool_router,
cache_dir, cache_dir,
active_resources: Arc::new(Mutex::new(HashMap::new())), active_resources: Arc::new(Mutex::new(HashMap::new())),
http_client: Client::builder().user_agent("goose/1.0").build().unwrap(), http_client: Client::builder().user_agent("goose/1.0").build().unwrap(),
@@ -31,15 +31,21 @@ impl LinuxAutomation {
display_server: Self::detect_display_server(), display_server: Self::detect_display_server(),
}; };
INIT.call_once(|| { if automation.has_display() {
automation.initialize().unwrap_or_else(|e| { INIT.call_once(|| {
eprintln!("Warning: Failed to initialize Linux automation: {}", e); automation.initialize().unwrap_or_else(|e| {
eprintln!("Warning: Failed to initialize Linux automation: {}", e);
});
}); });
}); }
automation automation
} }
pub fn has_display(&self) -> bool {
!matches!(self.display_server, DisplayServer::Unknown)
}
fn detect_display_server() -> DisplayServer { fn detect_display_server() -> DisplayServer {
if let Ok(wayland_display) = std::env::var("WAYLAND_DISPLAY") { if let Ok(wayland_display) = std::env::var("WAYLAND_DISPLAY") {
if !wayland_display.is_empty() { if !wayland_display.is_empty() {
@@ -249,4 +255,8 @@ impl SystemAutomation for LinuxAutomation {
fn get_temp_path(&self) -> PathBuf { fn get_temp_path(&self) -> PathBuf {
std::env::temp_dir() std::env::temp_dir()
} }
fn has_display(&self) -> bool {
self.has_display()
}
} }
@@ -19,6 +19,9 @@ pub trait SystemAutomation: Send + Sync {
fn execute_system_script(&self, script: &str) -> std::io::Result<String>; fn execute_system_script(&self, script: &str) -> std::io::Result<String>;
fn get_shell_command(&self) -> (&'static str, &'static str); // (shell, arg) fn get_shell_command(&self) -> (&'static str, &'static str); // (shell, arg)
fn get_temp_path(&self) -> std::path::PathBuf; fn get_temp_path(&self) -> std::path::PathBuf;
fn has_display(&self) -> bool {
true
}
} }
pub fn create_system_automation() -> Box<dyn SystemAutomation + Send + Sync> { pub fn create_system_automation() -> Box<dyn SystemAutomation + Send + Sync> {