| |
| |
| |
| |
| |
|
|
| """ |
| Local Python Executor. |
| |
| This module provides functionality for executing Python code locally by wrapping |
| the smolagents LocalPythonExecutor. |
| """ |
|
|
| from smolagents import LocalPythonExecutor |
|
|
| from core.env_server.types import CodeExecResult |
|
|
|
|
| class PyExecutor: |
| """ |
| Wrapper around smolagents LocalPythonExecutor for executing Python code. |
| |
| This class provides a simple interface to execute Python code in a subprocess |
| and capture the results including stdout, stderr, and exit code. |
| |
| Args: |
| additional_imports: List of additional module imports to authorize. |
| For example: ["numpy", "pandas", "matplotlib"] |
| These will be added to the base authorized imports. |
| |
| Example: |
| >>> # Basic usage with default imports |
| >>> executor = PyExecutor() |
| >>> result = executor.run("print('Hello, World!')") |
| >>> print(result.stdout) # "Hello, World!\n" |
| >>> print(result.exit_code) # 0 |
| >>> |
| >>> # Usage with additional imports |
| >>> executor = PyExecutor(additional_imports=["numpy", "pandas"]) |
| >>> result = executor.run("import numpy as np\\nprint(np.array([1, 2, 3]))") |
| >>> print(result.stdout) # "[1 2 3]\n" |
| """ |
|
|
| def __init__(self, additional_imports: list[str] | None = None): |
| """ |
| Initialize the PyExecutor with a LocalPythonExecutor instance. |
| |
| Args: |
| additional_imports: List of additional module names to authorize for import. |
| Defaults to an empty list if not provided. |
| """ |
| if additional_imports is None: |
| additional_imports = [] |
| self._executor = LocalPythonExecutor( |
| additional_authorized_imports=additional_imports |
| ) |
| |
| self._executor.send_tools({}) |
|
|
| def run(self, code: str) -> CodeExecResult: |
| """ |
| Execute Python code and return the result. |
| |
| Args: |
| code: Python code string to execute |
| |
| Returns: |
| CodeExecResult containing stdout, stderr, and exit_code |
| |
| Example: |
| >>> executor = PyExecutor() |
| >>> result = executor.run("x = 5 + 3\\nprint(x)") |
| >>> print(result.stdout) # "8\n" |
| >>> print(result.exit_code) # 0 |
| >>> |
| >>> # Error handling |
| >>> result = executor.run("1 / 0") |
| >>> print(result.exit_code) # 1 |
| >>> print(result.stderr) # Contains error message |
| """ |
| try: |
| |
| |
| exec_result = self._executor(code) |
|
|
| |
| |
| stdout = exec_result.logs |
| stderr = "" |
| exit_code = 0 |
|
|
| return CodeExecResult( |
| stdout=stdout, |
| stderr=stderr, |
| exit_code=exit_code, |
| ) |
|
|
| except Exception as e: |
| |
| |
| return CodeExecResult( |
| stdout="", |
| stderr=str(e), |
| exit_code=1, |
| ) |
|
|