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>> =
Arc::new(create_system_automation());
let os_specific_instructions = match std::env::consts::OS {
"windows" => indoc! {r#"
let has_display = system_automation.has_display();
let os_specific_instructions = match (std::env::consts::OS, has_display) {
("windows", _) => indoc! {r#"
Here are some extra tools:
automation_script
- Create and run PowerShell or Batch scripts
@@ -363,7 +365,7 @@ impl ComputerControllerServer {
- 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.
"#},
"macos" => indoc! {r#"
("macos", _) => indoc! {r#"
Here are some extra tools:
automation_script
- Create and run Shell, Ruby, or AppleScript scripts
@@ -457,7 +459,7 @@ impl ComputerControllerServer {
- If something fails, check `permissions status` for missing permissions
- Use `capture_screenshot: true` on click/type/press actions to verify the result
"#},
_ => indoc! {r#"
(_, true) => indoc! {r#"
Here are some extra tools:
automation_script
- Create and run Shell scripts
@@ -481,6 +483,19 @@ impl ComputerControllerServer {
- Automating UI interactions
- 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#"
@@ -517,8 +532,13 @@ impl ComputerControllerServer {
cache_dir = cache_dir.display()
};
let mut tool_router = Self::tool_router();
if !has_display {
tool_router.remove_route("computer_control");
}
Self {
tool_router: Self::tool_router(),
tool_router,
cache_dir,
active_resources: Arc::new(Mutex::new(HashMap::new())),
http_client: Client::builder().user_agent("goose/1.0").build().unwrap(),
@@ -31,15 +31,21 @@ impl LinuxAutomation {
display_server: Self::detect_display_server(),
};
INIT.call_once(|| {
automation.initialize().unwrap_or_else(|e| {
eprintln!("Warning: Failed to initialize Linux automation: {}", e);
if automation.has_display() {
INIT.call_once(|| {
automation.initialize().unwrap_or_else(|e| {
eprintln!("Warning: Failed to initialize Linux automation: {}", e);
});
});
});
}
automation
}
pub fn has_display(&self) -> bool {
!matches!(self.display_server, DisplayServer::Unknown)
}
fn detect_display_server() -> DisplayServer {
if let Ok(wayland_display) = std::env::var("WAYLAND_DISPLAY") {
if !wayland_display.is_empty() {
@@ -249,4 +255,8 @@ impl SystemAutomation for LinuxAutomation {
fn get_temp_path(&self) -> PathBuf {
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 get_shell_command(&self) -> (&'static str, &'static str); // (shell, arg)
fn get_temp_path(&self) -> std::path::PathBuf;
fn has_display(&self) -> bool {
true
}
}
pub fn create_system_automation() -> Box<dyn SystemAutomation + Send + Sync> {