Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/agents/sandbox/apply_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async def apply_operation(
moved_destination = self._session.normalize_path(moved_relative_path)
await self._write_text(moved_destination, updated_text)
if moved_destination != destination:
await self._session.rm(destination)
await self._session.rm(destination, user=self._user)
moved_display_path = moved_relative_path.as_posix()
return ApplyPatchResult(
output=f"Updated {display_path}\nMoved {display_path} to {moved_display_path}"
Expand Down
25 changes: 25 additions & 0 deletions tests/sandbox/capabilities/test_apply_patch_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,31 @@ async def test_editor_runs_file_operations_as_bound_user(self) -> None:
assert session.write_users == ["sandbox-user", "sandbox-user"]
assert session.rm_users == ["sandbox-user"]

@pytest.mark.asyncio
async def test_editor_runs_move_cleanup_as_bound_user(self) -> None:
session = UserRecordingApplyPatchSession()
session.files[Path("/workspace/existing.txt")] = b"old\n"
tool = SandboxApplyPatchTool(session=session, user=User(name="sandbox-user"))

await cast(
Awaitable[ApplyPatchResult],
tool.editor.update_file(
ApplyPatchOperation(
type="update_file",
path="existing.txt",
diff="@@\n-old\n+new\n",
move_to="renamed.txt",
)
),
)

# Renaming writes the new file and removes the original; both must run
# as the editor's bound user, not the default sandbox user.
assert session.write_users == ["sandbox-user"]
assert session.rm_users == ["sandbox-user"]
assert Path("/workspace/existing.txt") not in session.files
assert Path("/workspace/renamed.txt") in session.files

@pytest.mark.asyncio
async def test_custom_tool_input_create_update_move_delete(self) -> None:
session = ApplyPatchSession()
Expand Down
Loading