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
10 changes: 2 additions & 8 deletions src/agents/extensions/sandbox/blaxel/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
)
from ....sandbox.session.runtime_helpers import RESOLVE_WORKSPACE_PATH_HELPER, RuntimeHelperScript
from ....sandbox.session.sandbox_client import BaseSandboxClient
from ....sandbox.session.tar_workspace import shell_tar_exclude_args
from ....sandbox.snapshot import SnapshotBase, SnapshotSpec, resolve_snapshot
from ....sandbox.types import ExecResult, ExposedPortEndpoint, User
from ....sandbox.util.retry import (
Expand Down Expand Up @@ -510,14 +511,7 @@ async def running(self) -> bool:
# -- workspace persistence -----------------------------------------------

def _tar_exclude_args(self) -> list[str]:
excludes: list[str] = []
for rel in sorted(self._persist_workspace_skip_relpaths(), key=lambda p: p.as_posix()):
rel_posix = rel.as_posix().lstrip("/")
if not rel_posix or rel_posix in {".", "/"}:
continue
excludes.append(f"--exclude={shlex.quote(rel_posix)}")
excludes.append(f"--exclude={shlex.quote(f'./{rel_posix}')}")
return excludes
return shell_tar_exclude_args(self._persist_workspace_skip_relpaths())

@retry_async(
retry_if=lambda exc, self: (
Expand Down
10 changes: 2 additions & 8 deletions src/agents/extensions/sandbox/daytona/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
)
from ....sandbox.session.runtime_helpers import RESOLVE_WORKSPACE_PATH_HELPER, RuntimeHelperScript
from ....sandbox.session.sandbox_client import BaseSandboxClient, BaseSandboxClientOptions
from ....sandbox.session.tar_workspace import shell_tar_exclude_args
from ....sandbox.snapshot import SnapshotBase, SnapshotSpec, resolve_snapshot
from ....sandbox.types import ExecResult, ExposedPortEndpoint, User
from ....sandbox.util.retry import (
Expand Down Expand Up @@ -878,14 +879,7 @@ async def running(self) -> bool:
return False

def _tar_exclude_args(self) -> list[str]:
excludes: list[str] = []
for rel in sorted(self._persist_workspace_skip_relpaths(), key=lambda p: p.as_posix()):
rel_posix = rel.as_posix().lstrip("/")
if not rel_posix or rel_posix in {".", "/"}:
continue
excludes.append(f"--exclude={shlex.quote(rel_posix)}")
excludes.append(f"--exclude={shlex.quote(f'./{rel_posix}')}")
return excludes
return shell_tar_exclude_args(self._persist_workspace_skip_relpaths())

@retry_async(
retry_if=lambda exc, self, tar_cmd, tar_path: (
Expand Down
10 changes: 2 additions & 8 deletions src/agents/extensions/sandbox/e2b/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
)
from ....sandbox.session.runtime_helpers import RESOLVE_WORKSPACE_PATH_HELPER, RuntimeHelperScript
from ....sandbox.session.sandbox_client import BaseSandboxClient, BaseSandboxClientOptions
from ....sandbox.session.tar_workspace import shell_tar_exclude_args
from ....sandbox.snapshot import SnapshotBase, SnapshotSpec, resolve_snapshot
from ....sandbox.types import ExecResult, ExposedPortEndpoint, User
from ....sandbox.util.retry import (
Expand Down Expand Up @@ -1226,14 +1227,7 @@ async def _terminate_pty_entry(self, entry: _E2BPtyProcessEntry) -> None:
pass

def _tar_exclude_args(self) -> list[str]:
excludes: list[str] = []
for rel in sorted(self._persist_workspace_skip_relpaths(), key=lambda p: p.as_posix()):
rel_posix = rel.as_posix().lstrip("/")
if not rel_posix or rel_posix in {".", "/"}:
continue
excludes.append(f"--exclude={shlex.quote(rel_posix)}")
excludes.append(f"--exclude={shlex.quote(f'./{rel_posix}')}")
return excludes
return shell_tar_exclude_args(self._persist_workspace_skip_relpaths())

@retry_async(
retry_if=lambda exc, self, tar_cmd: (
Expand Down
18 changes: 18 additions & 0 deletions src/agents/sandbox/session/tar_workspace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from __future__ import annotations
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we prob should have a utils lib to keep these


import shlex
from collections.abc import Iterable
from pathlib import Path

__all__ = ["shell_tar_exclude_args"]


def shell_tar_exclude_args(skip_relpaths: Iterable[Path]) -> list[str]:
excludes: list[str] = []
for rel in sorted(skip_relpaths, key=lambda p: p.as_posix()):
rel_posix = rel.as_posix().lstrip("/")
if not rel_posix or rel_posix in {".", "/"}:
continue
excludes.append(f"--exclude={shlex.quote(rel_posix)}")
excludes.append(f"--exclude={shlex.quote(f'./{rel_posix}')}")
return excludes
28 changes: 28 additions & 0 deletions tests/sandbox/test_tar_workspace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from pathlib import Path

from agents.sandbox.session.tar_workspace import shell_tar_exclude_args


def test_shell_tar_exclude_args_skips_empty_and_dot_paths() -> None:
assert shell_tar_exclude_args([Path(""), Path("."), Path("/")]) == []


def test_shell_tar_exclude_args_sorts_and_adds_plain_and_dot_prefixed_patterns() -> None:
assert shell_tar_exclude_args(
[
Path("logs/events.jsonl"),
Path("cache dir/file.txt"),
]
) == [
"--exclude='cache dir/file.txt'",
"--exclude='./cache dir/file.txt'",
"--exclude=logs/events.jsonl",
"--exclude=./logs/events.jsonl",
]


def test_shell_tar_exclude_args_normalizes_absolute_paths() -> None:
assert shell_tar_exclude_args([Path("/tmp/workspace/cache")]) == [
"--exclude=tmp/workspace/cache",
"--exclude=./tmp/workspace/cache",
]
Loading