Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/agents/sandbox/snapshot_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@
import sys
import time
from collections.abc import Mapping
from pathlib import Path
from pathlib import Path, PureWindowsPath

from .snapshot import LocalSnapshotSpec

_DEFAULT_LOCAL_SNAPSHOT_TTL_SECONDS = 60 * 60 * 24 * 30
_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,
Expand All @@ -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"
Expand Down
44 changes: 43 additions & 1 deletion tests/sandbox/test_snapshot_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)},
Expand All @@ -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()
Expand Down