fix(win): use PowerShell instead of cmd.exe for bash tool on Windows

This commit is contained in:
zhayujie
2026-04-08 16:18:56 +08:00
parent a653ed07eb
commit 89251e603f

View File

@@ -18,9 +18,13 @@ from common.utils import expand_path
class Bash(BaseTool): class Bash(BaseTool):
"""Tool for executing bash commands""" """Tool for executing bash commands"""
_IS_WIN = sys.platform == "win32"
name: str = "bash" name: str = "bash"
description: str = f"""Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last {DEFAULT_MAX_LINES} lines or {DEFAULT_MAX_BYTES // 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. description: str = f"""Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last {DEFAULT_MAX_LINES} lines or {DEFAULT_MAX_BYTES // 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file.
{'''
PLATFORM: Windows (PowerShell).
''' if _IS_WIN else ''}
ENVIRONMENT: All API keys from env_config are auto-injected. Use $VAR_NAME directly. ENVIRONMENT: All API keys from env_config are auto-injected. Use $VAR_NAME directly.
SAFETY: SAFETY:
@@ -102,14 +106,24 @@ SAFETY:
else: else:
logger.debug(f"[Bash] Process User: {os.environ.get('USERNAME', os.environ.get('USER', 'unknown'))}") logger.debug(f"[Bash] Process User: {os.environ.get('USERNAME', os.environ.get('USER', 'unknown'))}")
# On Windows, convert $VAR references to %VAR% for cmd.exe if self._IS_WIN:
if sys.platform == "win32":
env["PYTHONIOENCODING"] = "utf-8" env["PYTHONIOENCODING"] = "utf-8"
command = self._convert_env_vars_for_windows(command, dotenv_vars) # Use PowerShell so that LLM-generated commands can use
if command and not command.strip().lower().startswith("chcp"): # Select-String, Select-Object, curl (Invoke-WebRequest alias),
command = f"chcp 65001 >nul 2>&1 && {command}" # etc. instead of Unix-only head/grep/tail.
result = subprocess.run(
# Execute command with inherited environment variables ["powershell.exe", "-NoProfile", "-NonInteractive",
"-ExecutionPolicy", "Bypass", "-Command", command],
cwd=self.cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
encoding="utf-8",
errors="replace",
timeout=timeout,
env=env,
)
else:
result = subprocess.run( result = subprocess.run(
command, command,
shell=True, shell=True,
@@ -120,7 +134,7 @@ SAFETY:
encoding="utf-8", encoding="utf-8",
errors="replace", errors="replace",
timeout=timeout, timeout=timeout,
env=env env=env,
) )
logger.debug(f"[Bash] Exit code: {result.returncode}") logger.debug(f"[Bash] Exit code: {result.returncode}")