63 lines
1.9 KiB
Python
63 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import pwd
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
from .config import Settings
|
|
|
|
|
|
class AiderAgent:
|
|
def __init__(self, settings: Settings) -> None:
|
|
self.settings = settings
|
|
|
|
def run(self, workspace: Path, task: str) -> str:
|
|
task_file = workspace / ".git" / "failure-task.txt"
|
|
task_file.write_text(task)
|
|
task_file.chmod(0o600)
|
|
command = [
|
|
self.settings.agent_command,
|
|
"--model",
|
|
self.settings.agent_model,
|
|
"--message-file",
|
|
str(task_file),
|
|
"--yes",
|
|
"--no-auto-commits",
|
|
"--no-dirty-commits",
|
|
"--no-stream",
|
|
]
|
|
coder = pwd.getpwnam("coder")
|
|
os.chown(task_file, coder.pw_uid, coder.pw_gid)
|
|
for path in workspace.rglob("*"):
|
|
if ".git" not in path.parts:
|
|
os.chown(path, coder.pw_uid, coder.pw_gid, follow_symlinks=False)
|
|
os.chown(workspace, coder.pw_uid, coder.pw_gid, follow_symlinks=False)
|
|
|
|
environment = {
|
|
"HOME": coder.pw_dir,
|
|
"PATH": os.environ.get("PATH", "/usr/local/bin:/usr/bin:/bin"),
|
|
}
|
|
for name in ("MISTRAL_API_KEY", "OPENAI_API_KEY", "ANTHROPIC_API_KEY"):
|
|
if os.getenv(name):
|
|
environment[name] = os.environ[name]
|
|
|
|
def drop_privileges() -> None:
|
|
os.setgroups([])
|
|
os.setgid(coder.pw_gid)
|
|
os.setuid(coder.pw_uid)
|
|
|
|
result = subprocess.run(
|
|
command,
|
|
cwd=workspace,
|
|
env=environment,
|
|
text=True,
|
|
capture_output=True,
|
|
check=False,
|
|
preexec_fn=drop_privileges,
|
|
timeout=3600,
|
|
)
|
|
if result.returncode != 0:
|
|
raise RuntimeError(f"Aider failed ({result.returncode}): {result.stderr[-4000:]}")
|
|
return result.stdout[-12_000:]
|