You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
EVAL/core/tools/terminal/__init__.py

68 lines
2.0 KiB
Python

import subprocess
from typing import Dict, List
from tempfile import TemporaryFile
from env import settings
from logger import logger
from core.tools.base import tool, BaseToolSet, ToolScope, SessionGetter
from core.tools.terminal.syscall import SyscallTracer
class Terminal(BaseToolSet):
def __init__(self):
self.sessions: Dict[str, List[SyscallTracer]] = {}
@tool(
name="Terminal",
description="Executes commands in a terminal."
"If linux errno occurs, we have to solve the problem with the terminal. "
"It can't execute interactive operations or blocking operations. "
"Input should be valid commands, "
"and the output will be any output from running that command.",
scope=ToolScope.SESSION,
)
def execute(self, commands: str, get_session: SessionGetter) -> str:
session, _ = get_session()
try:
with TemporaryFile() as fp:
process = subprocess.Popen(
commands,
shell=True,
cwd=settings["PLAYGROUND_DIR"],
stdout=fp,
stderr=fp,
)
tracer = SyscallTracer(process.pid)
tracer.attach()
exitcode, reason = tracer.wait_until_stop_or_exit()
logger.debug(f"Stopped terminal execution: {exitcode} {reason}")
fp.seek(0)
output = fp.read().decode()
except Exception as e:
output = str(e)
if len(output) > 1000:
output = output[:1000] + "..."
logger.debug(
f"\nProcessed Terminal, Input Commands: {commands} "
f"Output Answer: {output}"
)
return output
if __name__ == "__main__":
import time
o = Terminal().execute(
"sleep 1; echo 1; sleep 2; echo 2; sleep 3; echo 3; sleep 10;",
lambda: ("", None),
)
print(o)
time.sleep(10) # see if timer has reset