File size: 2,042 Bytes
7d5aa59 9bf7dd5 7d5aa59 bf60e31 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | from langchain.tools import BaseTool
import subprocess
import sys
import tempfile
import os
import requests
class PythonExecTool(BaseTool):
"""
Инструмент для выполнения прикрепленного Python-кода и возврата его вывода.
Формат команды: URL или локальный путь к .py файлу.
"""
name: str = "exec_python"
description: str = (
"Run Python scripts/files and return their output. Use for any question that provides a .py file and asks ‘what does this code print?’, ‘what is the return value?’, etc."
)
def _run(self, source: str) -> str:
# определяем локальный путь к файлу
if source.startswith("http://") or source.startswith("https://"):
# скачиваем файл
resp = requests.get(source)
resp.raise_for_status()
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".py")
tmp.write(resp.content)
tmp.flush()
file_path = tmp.name
else:
file_path = source
# выполняем файл и захватываем вывод
try:
result = subprocess.run(
[sys.executable, file_path],
capture_output=True,
text=True,
check=False
)
# stdout содержит финальный вывод
output = result.stdout.strip()
if not output:
# если stdout пуст, возвращаем stderr
output = result.stderr.strip()
return output
finally:
# удаляем временный файл, если он был скачан
if source.startswith("http://") or source.startswith("https://"):
os.remove(file_path)
async def _arun(self, source: str) -> str:
raise NotImplementedError("Async not supported.") |