openenv-testing/echo_env
0
1# Copyright (c) Meta Platforms, Inc. and affiliates.2# All rights reserved.3#4# This source code is licensed under the BSD-style license found in the5# LICENSE file in the root directory of this source tree.6 7"""8Local Python Executor.9 10This module provides functionality for executing Python code locally by wrapping11the smolagents LocalPythonExecutor.12"""13 14from smolagents import LocalPythonExecutor15 16from core.env_server.types import CodeExecResult17 18 19class PyExecutor:20 """21 Wrapper around smolagents LocalPythonExecutor for executing Python code.22 23 This class provides a simple interface to execute Python code in a subprocess24 and capture the results including stdout, stderr, and exit code.25 26 Args:27 additional_imports: List of additional module imports to authorize.28 For example: ["numpy", "pandas", "matplotlib"]29 These will be added to the base authorized imports.30 31 Example:32 >>> # Basic usage with default imports33 >>> executor = PyExecutor()34 >>> result = executor.run("print('Hello, World!')")35 >>> print(result.stdout) # "Hello, World!\n"36 >>> print(result.exit_code) # 037 >>>38 >>> # Usage with additional imports39 >>> executor = PyExecutor(additional_imports=["numpy", "pandas"])40 >>> result = executor.run("import numpy as np\\nprint(np.array([1, 2, 3]))")41 >>> print(result.stdout) # "[1 2 3]\n"42 """43 44 def __init__(self, additional_imports: list[str] | None = None):45 """46 Initialize the PyExecutor with a LocalPythonExecutor instance.47 48 Args:49 additional_imports: List of additional module names to authorize for import.50 Defaults to an empty list if not provided.51 """52 if additional_imports is None:53 additional_imports = []54 self._executor = LocalPythonExecutor(55 additional_authorized_imports=additional_imports56 )57 # Initialize tools to make BASE_PYTHON_TOOLS available (including print)58 self._executor.send_tools({})59 60 def run(self, code: str) -> CodeExecResult:61 """62 Execute Python code and return the result.63 64 Args:65 code: Python code string to execute66 67 Returns:68 CodeExecResult containing stdout, stderr, and exit_code69 70 Example:71 >>> executor = PyExecutor()72 >>> result = executor.run("x = 5 + 3\\nprint(x)")73 >>> print(result.stdout) # "8\n"74 >>> print(result.exit_code) # 075 >>>76 >>> # Error handling77 >>> result = executor.run("1 / 0")78 >>> print(result.exit_code) # 179 >>> print(result.stderr) # Contains error message80 """81 try:82 # Execute the code using LocalPythonExecutor83 # LocalPythonExecutor returns a CodeOutput object with output, logs, is_final_answer84 exec_result = self._executor(code)85 86 # Extract the logs (which contain print outputs) as stdout87 # The output field contains the return value of the code88 stdout = exec_result.logs89 stderr = ""90 exit_code = 0 # Success91 92 return CodeExecResult(93 stdout=stdout,94 stderr=stderr,95 exit_code=exit_code,96 )97 98 except Exception as e:99 # LocalPythonExecutor raises InterpreterError for various issues100 # (syntax errors, forbidden operations, runtime errors, etc.)101 return CodeExecResult(102 stdout="",103 stderr=str(e),104 exit_code=1, # Non-zero indicates error105 )106 