diff --git a/tests/tools/test_terminal_task_cwd.py b/tests/tools/test_terminal_task_cwd.py new file mode 100644 index 00000000000..8c8ff867c36 --- /dev/null +++ b/tests/tools/test_terminal_task_cwd.py @@ -0,0 +1,74 @@ +"""Regression tests for task/session cwd propagation in terminal_tool.""" + +import json + +import tools.terminal_tool as terminal_tool + + +def _minimal_terminal_config(cwd="/default"): + return { + "env_type": "local", + "cwd": cwd, + "timeout": 60, + } + + +def test_foreground_command_uses_registered_task_cwd_for_existing_environment(monkeypatch): + """ACP can update task cwd after the local env exists; foreground must honor it.""" + calls = [] + + class FakeEnv: + env = {} + + def execute(self, command, **kwargs): + calls.append((command, kwargs)) + return {"output": "ok", "returncode": 0} + + task_id = "acp-session-1" + monkeypatch.setattr(terminal_tool, "_active_environments", {task_id: FakeEnv()}) + monkeypatch.setattr(terminal_tool, "_last_activity", {}) + monkeypatch.setattr(terminal_tool, "_task_env_overrides", {task_id: {"cwd": "/workspace/acp"}}) + monkeypatch.setattr(terminal_tool, "_get_env_config", lambda: _minimal_terminal_config()) + monkeypatch.setattr( + terminal_tool, + "_check_all_guards", + lambda command, env_type: {"approved": True}, + ) + + result = json.loads(terminal_tool.terminal_tool(command="pwd", task_id=task_id)) + + assert result["exit_code"] == 0 + assert calls == [("pwd", {"timeout": 60, "cwd": "/workspace/acp"})] + + +def test_explicit_workdir_still_wins_over_registered_task_cwd(monkeypatch): + calls = [] + + class FakeEnv: + env = {} + + def execute(self, command, **kwargs): + calls.append(kwargs) + return {"output": "ok", "returncode": 0} + + task_id = "acp-session-1" + monkeypatch.setattr(terminal_tool, "_active_environments", {task_id: FakeEnv()}) + monkeypatch.setattr(terminal_tool, "_last_activity", {}) + monkeypatch.setattr(terminal_tool, "_task_env_overrides", {task_id: {"cwd": "/workspace/acp"}}) + monkeypatch.setattr(terminal_tool, "_get_env_config", lambda: _minimal_terminal_config()) + monkeypatch.setattr( + terminal_tool, + "_check_all_guards", + lambda command, env_type: {"approved": True}, + ) + + result = json.loads( + terminal_tool.terminal_tool( + command="pwd", + task_id=task_id, + workdir="/explicit/workdir", + ) + ) + + assert result["exit_code"] == 0 + assert calls == [{"timeout": 60, "cwd": "/explicit/workdir"}] diff --git a/tools/terminal_tool.py b/tools/terminal_tool.py index b65af93fa3b..52de7873e5f 100644 --- a/tools/terminal_tool.py +++ b/tools/terminal_tool.py @@ -2001,9 +2001,10 @@ def terminal_tool( while retry_count <= max_retries: try: - execute_kwargs = {"timeout": effective_timeout} - if workdir: - execute_kwargs["cwd"] = workdir + execute_kwargs = { + "timeout": effective_timeout, + "cwd": workdir or cwd, + } result = env.execute(command, **execute_kwargs) except Exception as e: error_str = str(e).lower()