diff --git a/src/agents/sandbox/snapshot_defaults.py b/src/agents/sandbox/snapshot_defaults.py index afe7b9c8a8..1a54a14f72 100644 --- a/src/agents/sandbox/snapshot_defaults.py +++ b/src/agents/sandbox/snapshot_defaults.py @@ -4,7 +4,7 @@ import sys import time from collections.abc import Mapping -from pathlib import Path +from pathlib import Path, PureWindowsPath from .snapshot import LocalSnapshotSpec @@ -12,6 +12,16 @@ _DEFAULT_LOCAL_SNAPSHOT_SUBDIR = Path("openai-agents-python") / "sandbox" / "snapshots" +def _first_absolute_windows_env_path(env: Mapping[str, str], *names: str) -> Path | None: + for name in names: + value = env.get(name) + if not value: + continue + if PureWindowsPath(value).is_absolute(): + return Path(value) + return None + + def default_local_snapshot_base_dir( *, home: Path | None = None, @@ -27,8 +37,12 @@ def default_local_snapshot_base_dir( if resolved_platform == "darwin": base = resolved_home / "Library" / "Application Support" elif resolved_os_name == "nt": - local_app_data = resolved_env.get("LOCALAPPDATA") or resolved_env.get("APPDATA") - base = Path(local_app_data) if local_app_data else resolved_home / "AppData" / "Local" + env_base = _first_absolute_windows_env_path( + resolved_env, + "LOCALAPPDATA", + "APPDATA", + ) + base = env_base if env_base is not None else resolved_home / "AppData" / "Local" else: xdg_state_home = resolved_env.get("XDG_STATE_HOME") base = Path(xdg_state_home) if xdg_state_home else resolved_home / ".local" / "state" diff --git a/tests/sandbox/test_snapshot_defaults.py b/tests/sandbox/test_snapshot_defaults.py index f752b4f859..2c34be69a7 100644 --- a/tests/sandbox/test_snapshot_defaults.py +++ b/tests/sandbox/test_snapshot_defaults.py @@ -45,7 +45,7 @@ def test_default_local_snapshot_base_dir_uses_macos_application_support(tmp_path def test_default_local_snapshot_base_dir_uses_localappdata_on_windows(tmp_path: Path) -> None: - local_app_data = tmp_path / "LocalAppData" + local_app_data = Path(r"C:\Users\me\AppData\Local") result = default_local_snapshot_base_dir( home=tmp_path / "home", env={"LOCALAPPDATA": str(local_app_data)}, @@ -56,6 +56,48 @@ def test_default_local_snapshot_base_dir_uses_localappdata_on_windows(tmp_path: assert result == local_app_data / "openai-agents-python" / "sandbox" / "snapshots" +def test_default_local_snapshot_base_dir_uses_absolute_appdata_when_localappdata_is_relative( + tmp_path: Path, +) -> None: + app_data = Path(r"C:\Users\me\AppData\Roaming") + result = default_local_snapshot_base_dir( + home=tmp_path / "home", + env={"LOCALAPPDATA": "relative-local", "APPDATA": str(app_data)}, + platform="win32", + os_name="nt", + ) + + assert result == app_data / "openai-agents-python" / "sandbox" / "snapshots" + + +def test_default_local_snapshot_base_dir_ignores_relative_windows_env_paths( + tmp_path: Path, +) -> None: + home = tmp_path / "home" + result = default_local_snapshot_base_dir( + home=home, + env={"LOCALAPPDATA": "relative-local", "APPDATA": "relative-roaming"}, + platform="win32", + os_name="nt", + ) + + assert result == home / "AppData" / "Local" / "openai-agents-python" / "sandbox" / "snapshots" + + +def test_default_local_snapshot_base_dir_ignores_posix_absolute_localappdata_on_windows( + tmp_path: Path, +) -> None: + home = tmp_path / "home" + result = default_local_snapshot_base_dir( + home=home, + env={"LOCALAPPDATA": "/tmp/localappdata"}, + platform="win32", + os_name="nt", + ) + + assert result == home / "AppData" / "Local" / "openai-agents-python" / "sandbox" / "snapshots" + + def test_cleanup_stale_default_local_snapshots_removes_only_old_tar_files(tmp_path: Path) -> None: managed_dir = tmp_path / "snapshots" managed_dir.mkdir()