| import subprocess |
| import sys |
| from typing import Optional |
|
|
| from langchain.tools import tool |
| from langchain_experimental.tools import PythonREPLTool |
|
|
|
|
| @tool |
| def execute_python_code(intent: str, code: Optional[str] = None, file_reference: Optional[str] = None) -> str: |
| """ |
| Executes the provided python code snippet or python file identified by its reference and returns the outcome of |
| the execution |
| :param intent: this parameter should be set to either code_snippet or file_execution depending on |
| the intent of the user |
| :param code: if the intent is code_snippet, this parameter should be populated with the |
| python code snippet to be executed |
| :param file_reference: if the intent is file_execution, this parameter should |
| be populated with the reference of the file to be executed |
| :return: the outcome of the python code execution |
| """ |
| if intent == "code_snippet": |
| python_tool = PythonREPLTool() |
| if not code: |
| raise Exception("Invalid arguments. Tool intent is code_snippet but no value provided for code argument") |
| return python_tool.run(code, verbose=True) |
|
|
| if intent == "file_execution": |
| return subprocess_python_exec(file_reference) |
| raise Exception("Invalid arguments. Invalid value for intent parameter") |
|
|
|
|
| def subprocess_python_exec(file_reference: str) -> str: |
| """Execute Python code in a subprocess for better isolation""" |
| try: |
|
|
| |
| result = subprocess.run( |
| [sys.executable, file_reference], |
| capture_output=True, |
| text=True, |
| timeout=90 |
| ) |
|
|
| if result.returncode == 0: |
| return result.stdout if result.stdout else "Code executed successfully" |
| else: |
| return f"Error: {result.stderr}" |
| except subprocess.TimeoutExpired: |
| return "Error: Code execution timed out" |
| except Exception as e: |
| return f"Error: {str(e)}" |
|
|