clean and shell

This commit is contained in:
Adam Cohen Hillel 2025-04-09 13:46:13 +01:00
parent 87129a1e61
commit 01c1501198
3 changed files with 39 additions and 26 deletions

View File

@ -4,10 +4,12 @@ from agentpress.tool import ToolResult, openapi_schema, xml_schema
from agent.tools.utils.daytona_sandbox import SandboxToolsBase
import os
WORKSPACE_PATH = "/workspace"
def clean_path(path: str) -> str:
return path.replace(WORKSPACE_PATH, "").lstrip("/")
# TODO: might want to be more granular with the tool names:
# file_read - Read file content. Use for checking file contents, analyzing logs, or reading configuration files.
# file_write - Overwrite or append content to a file. Use for creating new files, appending content, or modifying existing files.
# file_str_replace - Replace specified string in a file. Use for updating specific content in files or fixing errors in code.
# file_find_in_content - Search for matching text within file content. Use for finding specific content or patterns in files.
# file_find_by_name - Find files by name pattern in specified directory. Use for locating files with specific naming patterns.
class SandboxFilesTool(SandboxToolsBase):
@ -83,7 +85,7 @@ class SandboxFilesTool(SandboxToolsBase):
"""Get the current workspace state by reading all files"""
files_state = {}
try:
files = self.sandbox.fs.list_files(WORKSPACE_PATH)
files = self.sandbox.fs.list_files(self.workspace_path)
for file_info in files:
rel_path = file_info.name
@ -92,7 +94,7 @@ class SandboxFilesTool(SandboxToolsBase):
continue
try:
full_path = f"{WORKSPACE_PATH}/{rel_path}"
full_path = f"{self.workspace_path}/{rel_path}"
content = self.sandbox.fs.download_file(full_path).decode()
files_state[rel_path] = {
"content": content,
@ -149,9 +151,9 @@ class SandboxFilesTool(SandboxToolsBase):
'''
)
async def create_file(self, file_path: str, file_contents: str, permissions: str = "644") -> ToolResult:
file_path = clean_path(file_path)
file_path = self.clean_path(file_path)
try:
full_path = f"{WORKSPACE_PATH}/{file_path}"
full_path = f"{self.workspace_path}/{file_path}"
if self._file_exists(full_path):
return self.fail_response(f"File '{file_path}' already exists. Use update_file to modify existing files.")
@ -209,8 +211,8 @@ class SandboxFilesTool(SandboxToolsBase):
)
async def str_replace(self, file_path: str, old_str: str, new_str: str) -> ToolResult:
try:
file_path = clean_path(file_path)
full_path = f"{WORKSPACE_PATH}/{file_path}"
file_path = self.clean_path(file_path)
full_path = f"{self.workspace_path}/{file_path}"
if not self._file_exists(full_path):
return self.fail_response(f"File '{file_path}' does not exist")
@ -281,8 +283,8 @@ class SandboxFilesTool(SandboxToolsBase):
)
async def full_file_rewrite(self, file_path: str, file_contents: str, permissions: str = "644") -> ToolResult:
try:
file_path = clean_path(file_path)
full_path = f"{WORKSPACE_PATH}/{file_path}"
file_path = self.clean_path(file_path)
full_path = f"{self.workspace_path}/{file_path}"
if not self._file_exists(full_path):
return self.fail_response(f"File '{file_path}' does not exist. Use create_file to create a new file.")
@ -322,8 +324,8 @@ class SandboxFilesTool(SandboxToolsBase):
)
async def delete_file(self, file_path: str) -> ToolResult:
try:
file_path = clean_path(file_path)
full_path = f"{WORKSPACE_PATH}/{file_path}"
file_path = self.clean_path(file_path)
full_path = f"{self.workspace_path}/{file_path}"
if not self._file_exists(full_path):
return self.fail_response(f"File '{file_path}' does not exist")
@ -366,8 +368,8 @@ class SandboxFilesTool(SandboxToolsBase):
)
async def search_files(self, path: str, pattern: str) -> ToolResult:
try:
path = clean_path(path)
full_path = f"{WORKSPACE_PATH}/{path}" if not path.startswith(WORKSPACE_PATH) else path
path = self.clean_path(path)
full_path = f"{self.workspace_path}/{path}" if not path.startswith(self.workspace_path) else path
results = self.sandbox.fs.find_files(
path=full_path,
pattern=pattern
@ -436,8 +438,8 @@ class SandboxFilesTool(SandboxToolsBase):
)
async def replace_in_files(self, files: list[str], pattern: str, new_value: str) -> ToolResult:
try:
files = [clean_path(f) for f in files]
full_paths = [f"{WORKSPACE_PATH}/{f}" if not f.startswith(WORKSPACE_PATH) else f for f in files]
files = [self.clean_path(f) for f in files]
full_paths = [f"{self.workspace_path}/{f}" if not f.startswith(self.workspace_path) else f for f in files]
self.sandbox.fs.replace_in_files(
files=full_paths,
pattern=pattern,

View File

@ -2,11 +2,6 @@ from agentpress.tool import ToolResult, openapi_schema, xml_schema
from agent.tools.utils.daytona_sandbox import SandboxToolsBase
# TODO: might want to be more granular with the tool names:
# file_read - Read file content. Use for checking file contents, analyzing logs, or reading configuration files.
# file_write - Overwrite or append content to a file. Use for creating new files, appending content, or modifying existing files.
# file_str_replace - Replace specified string in a file. Use for updating specific content in files or fixing errors in code.
# file_find_in_content - Search for matching text within file content. Use for finding specific content or patterns in files.
# file_find_by_name - Find files by name pattern in specified directory. Use for locating files with specific naming patterns.
# shell_exec - Execute commands in a specified shell session. Use for running code, installing packages, or managing files.
# shell_view - View the content of a specified shell session. Use for checking command execution results or monitoring output.
# shell_wait - Wait for the running process in a specified shell session to return. Use after running commands that require longer runtime.
@ -14,6 +9,7 @@ from agent.tools.utils.daytona_sandbox import SandboxToolsBase
# shell_kill_process - Terminate a running process in a specified shell session. Use for stopping long-running processes or handling frozen commands.
class SandboxShellTool(SandboxToolsBase):
"""Tool for executing tasks in a Daytona sandbox with browser-use capabilities."""
@ -25,7 +21,7 @@ class SandboxShellTool(SandboxToolsBase):
"type": "function",
"function": {
"name": "execute_command",
"description": "Execute a shell command in the workspace directory",
"description": "Execute a shell command in the workspace directory. Working directory is the workspace directory.",
"parameters": {
"type": "object",
"properties": {
@ -51,7 +47,7 @@ class SandboxShellTool(SandboxToolsBase):
)
async def execute_command(self, command: str, folder: str = None) -> ToolResult:
try:
folder = folder or self.sandbox.get_user_root_dir()
folder = folder or self.workspace_path
response = self.sandbox.process.exec(command, cwd=folder, timeout=60)
if response.exit_code == 0:
@ -66,3 +62,14 @@ class SandboxShellTool(SandboxToolsBase):
except Exception as e:
return self.fail_response(f"Error executing command: {str(e)}")
async def test_shell_tool():
shell_tool = SandboxShellTool(
sandbox_id="sandbox-15a2c059",
password="vvv"
)
print("1)", "*"*10)
res = await shell_tool.execute_command("ls -l")
print(res)

View File

@ -279,6 +279,7 @@ class SandboxToolsBase(Tool):
super().__init__()
self.sandbox = None
self.daytona = daytona
self.workspace_path = "/workspace"
self.sandbox_id = sandbox_id
try:
@ -292,4 +293,7 @@ class SandboxToolsBase(Tool):
print("\033[95m***")
print(self.sandbox.get_preview_link(6080))
print(self.sandbox.get_preview_link(8080))
print("***\033[0m")
print("***\033[0m")
def clean_path(self, path: str) -> str:
return path.replace(self.workspace_path, "").lstrip("/")