feat(shell): enhance exec method to support timeout parameter and improve background command handling

This commit is contained in:
Soulter
2026-04-28 23:55:24 +08:00
parent 66d620dab5
commit 962c299c2d
2 changed files with 22 additions and 9 deletions

View File

@@ -105,8 +105,11 @@ class ExecuteShellTool(FunctionTool):
current_workspace_root.mkdir(parents=True, exist_ok=True)
cwd = str(current_workspace_root)
env = dict(env or {})
effective_background = background and not _is_self_detached_command(command)
stdout_file: str | None = None
if background:
if effective_background:
local_runtime = is_local_runtime(context)
stdout_file = _build_background_output_path(
local_runtime=local_runtime,
@@ -117,8 +120,6 @@ class ExecuteShellTool(FunctionTool):
local_runtime=local_runtime,
)
env = dict(env or {})
effective_background = background and not _is_self_detached_command(command)
result = await sb.shell.exec(
command,
cwd=cwd,

View File

@@ -56,7 +56,9 @@ async def test_execute_shell_defaults_to_foreground(monkeypatch):
calls = []
class FakeShell:
async def exec(self, command, cwd=None, background=False, env=None):
async def exec(
self, command, cwd=None, background=False, env=None, timeout=None
):
calls.append({"command": command, "background": background})
return {"success": True, "stdout": "", "stderr": "", "exit_code": 0}
@@ -98,7 +100,9 @@ async def test_execute_shell_uses_fresh_default_env_per_call(monkeypatch):
calls = []
class FakeShell:
async def exec(self, command, cwd=None, background=False, env=None):
async def exec(
self, command, cwd=None, background=False, env=None, timeout=None
):
env["MUTATED_BY_FAKE_SHELL"] = command
calls.append(env)
return {"success": True, "stdout": "", "stderr": "", "exit_code": 0}
@@ -142,7 +146,9 @@ async def test_execute_shell_copies_user_env_before_execution(monkeypatch):
calls = []
class FakeShell:
async def exec(self, command, cwd=None, background=False, env=None):
async def exec(
self, command, cwd=None, background=False, env=None, timeout=None
):
env["MUTATED_BY_FAKE_SHELL"] = command
calls.append(env)
return {"success": True, "stdout": "", "stderr": "", "exit_code": 0}
@@ -186,7 +192,9 @@ async def test_execute_shell_avoids_double_background_for_detached_commands(
calls = []
class FakeShell:
async def exec(self, command, cwd=None, background=False, env=None):
async def exec(
self, command, cwd=None, background=False, env=None, timeout=None
):
calls.append({"command": command, "background": background})
return {"success": True, "stdout": "", "stderr": "", "exit_code": 0}
@@ -229,7 +237,9 @@ async def test_execute_shell_recognizes_commented_background_command(monkeypatch
calls = []
class FakeShell:
async def exec(self, command, cwd=None, background=False, env=None):
async def exec(
self, command, cwd=None, background=False, env=None, timeout=None
):
calls.append({"command": command, "background": background})
return {"success": True, "stdout": "", "stderr": "", "exit_code": 0}
@@ -292,7 +302,9 @@ async def test_execute_shell_reports_blank_exception_type(monkeypatch):
return ""
class FakeShell:
async def exec(self, command, cwd=None, background=False, env=None):
async def exec(
self, command, cwd=None, background=False, env=None, timeout=None
):
raise BlankError()
class FakeBooter: