import os
import subprocess
import json
from typing import Any
from sandbox import safe_path
_agent_cfg_path = os.path.join(os.path.dirname(__file__), "agent", "config.json")
WORKSPACE = None
if os.path.exists(_agent_cfg_path):
try:
with open(_agent_cfg_path, "r", encoding="utf-8") as _f:
_agent_cfg = json.load(_f)
WORKSPACE = _agent_cfg.get("WORKSPACE")
except Exception:
WORKSPACE = None
_agent_tools_path = os.path.join(os.path.dirname(__file__), "agent", "tools.json")
TOOLS_META = None
if os.path.exists(_agent_tools_path):
try:
with open(_agent_tools_path, "r", encoding="utf-8") as _f:
TOOLS_META = json.load(_f)
except Exception:
TOOLS_META = None
def get_tools_meta():
return TOOLS_META
def list_files(path: str = "", **kwargs) -> str:
"""List files under `path` inside the workspace. If `path` is empty, list whole workspace."""
try:
if path:
base = safe_path(path)
else:
base = os.path.abspath(WORKSPACE)
files = []
for root, _, filenames in os.walk(base):
for f in filenames:
rel = os.path.relpath(os.path.join(root, f), os.path.abspath(WORKSPACE))
files.append(rel)
return "\n".join(files) or "(empty)"
except Exception as e:
return f"[error listing files] {e}"
def read_file(path: str, **kwargs) -> str:
try:
p = safe_path(path)
with open(p, "r", encoding="utf-8") as f:
data = f.read()
if not data:
return "file is empty"
return data
except Exception as e:
return f"[error reading file] {e}"
def write_file(path: str, content: str, **kwargs) -> str:
try:
p = safe_path(path)
os.makedirs(os.path.dirname(p), exist_ok=True)
with open(p, "w", encoding="utf-8") as f:
f.write(content)
return f"Wrote {p}"
except Exception as e:
return f"[error writing file] {e}"
def run_command(command: str, timeout: int = 30, **kwargs) -> str:
try:
completed = subprocess.run(
command,
shell=True,
cwd=os.path.abspath(WORKSPACE),
capture_output=True,
text=True,
timeout=int(timeout),
stdin=subprocess.DEVNULL,
)
out = completed.stdout or ""
err = completed.stderr or ""
if completed.returncode != 0:
return f"[exit {completed.returncode}]\n{out}{err}"
return out + err
except Exception as e:
return f"[error running command] {e}"
def research(query: str, **kwargs) -> str:
return f"research not implemented: {query}"
TOOLS = {
"list_files": list_files,
"read_file": read_file,
"write_file": write_file,
"run_command": run_command,
"research": research,
}