diff --git a/app/agent/base.py b/app/agent/base.py index 9ece688..65f6600 100644 --- a/app/agent/base.py +++ b/app/agent/base.py @@ -6,6 +6,7 @@ from pydantic import BaseModel, Field, model_validator from app.llm import LLM from app.logger import logger +from app.sandbox.client import SANDBOX_CLIENT from app.schema import ROLE_TYPE, AgentState, Memory, Message @@ -149,7 +150,7 @@ class BaseAgent(BaseModel, ABC): self.current_step = 0 self.state = AgentState.IDLE results.append(f"Terminated: Reached max steps ({self.max_steps})") - + await SANDBOX_CLIENT.cleanup() return "\n".join(results) if results else "No steps executed" @abstractmethod diff --git a/app/config.py b/app/config.py index f62354a..3c0ebc3 100644 --- a/app/config.py +++ b/app/config.py @@ -210,18 +210,17 @@ class Config: def llm(self) -> Dict[str, LLMSettings]: return self._config.llm + @property + def sandbox(self) -> SandboxSettings: + return self._config.sandbox -def sandbox(self) -> SandboxSettings: - return self._config.sandbox + @property + def browser_config(self) -> Optional[BrowserSettings]: + return self._config.browser_config - -def browser_config(self) -> Optional[BrowserSettings]: - return self._config.browser_config - - -@property -def search_config(self) -> Optional[SearchSettings]: - return self._config.search_config + @property + def search_config(self) -> Optional[SearchSettings]: + return self._config.search_config config = Config() diff --git a/app/sandbox/client.py b/app/sandbox/client.py index 06a534e..09a8f2e 100644 --- a/app/sandbox/client.py +++ b/app/sandbox/client.py @@ -189,7 +189,7 @@ class LocalSandboxClient(BaseSandboxClient): self.sandbox = None -async def create_sandbox_client() -> LocalSandboxClient: +def create_sandbox_client() -> LocalSandboxClient: """Creates a sandbox client. Returns: diff --git a/app/tool/str_replace_editor.py b/app/tool/str_replace_editor.py index 84580de..a907f41 100644 --- a/app/tool/str_replace_editor.py +++ b/app/tool/str_replace_editor.py @@ -100,7 +100,6 @@ class StrReplaceEditor(BaseTool): } _file_history: DefaultDict[PathLike, List[str]] = defaultdict(list) _local_operator: LocalFileOperator = LocalFileOperator() - # todo: Sandbox resources need to be destroyed at the appropriate time. _sandbox_operator: SandboxFileOperator = SandboxFileOperator() # def _get_operator(self, use_sandbox: bool) -> FileOperator: @@ -129,7 +128,7 @@ class StrReplaceEditor(BaseTool): operator = self._get_operator() # Validate path and command combination - await self.validate_path(command, path, operator) + await self.validate_path(command, Path(path), operator) # Execute the appropriate command if command == "view": @@ -164,14 +163,12 @@ class StrReplaceEditor(BaseTool): return str(result) - # <<<<<<< HEAD async def validate_path( self, command: str, path: Path, operator: FileOperator ) -> None: """Validate path and command combination based on execution environment.""" # Check if path is absolute if not path.is_absolute(): - # suggested_path = f"/{path}" raise ToolError(f"The path {path} is not an absolute path") # Only check if path exists for non-create commands @@ -184,27 +181,6 @@ class StrReplaceEditor(BaseTool): # Check if path is a directory is_dir = await operator.is_directory(path) if is_dir and command != "view": - # ======= - # def validate_path(self, command: str, path: Path): - # """ - # Check that the path/command combination is valid. - # """ - # # Check if its an absolute path - # if not path.is_absolute(): - # raise ToolError(f"The path {path} is not an absolute path") - # # Check if path exists - # if not path.exists() and command != "create": - # raise ToolError( - # f"The path {path} does not exist. Please provide a valid path." - # ) - # if path.exists() and command == "create": - # raise ToolError( - # f"File already exists at: {path}. Cannot overwrite files using command `create`." - # ) - # # Check if the path points to a directory - # if path.is_dir(): - # if command != "view": - # >>>>>>> upstream/main raise ToolError( f"The path {path} is a directory and only the `view` command can be used on directories" ) diff --git a/config/config.example.toml b/config/config.example.toml index dcddeb8..d5750a2 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -69,7 +69,7 @@ temperature = 0.0 # Controls randomness for vision mod ## Sandbox configuration #[sandbox] #use_sandbox = false -#image = "python:3.10-slim" +#image = "python:3.12-slim" #work_dir = "/workspace" #memory_limit = "1g" # 512m #cpu_limit = 2.0 diff --git a/tests/sandbox/test_client.py b/tests/sandbox/test_client.py index 1e4557d..a69b894 100644 --- a/tests/sandbox/test_client.py +++ b/tests/sandbox/test_client.py @@ -12,7 +12,7 @@ from app.sandbox.client import LocalSandboxClient, create_sandbox_client @pytest_asyncio.fixture(scope="function") async def local_client() -> AsyncGenerator[LocalSandboxClient, None]: """Creates a local sandbox client for testing.""" - client = await create_sandbox_client() + client = create_sandbox_client() try: yield client finally: