feat: orchestrator MVP — webhooks, agent launcher, QG checks

This commit is contained in:
Dev Agent
2026-05-19 15:57:00 +03:00
commit daf8cdad9e
19 changed files with 515 additions and 0 deletions

0
src/agents/__init__.py Normal file
View File

105
src/agents/launcher.py Normal file
View File

@@ -0,0 +1,105 @@
import subprocess
import os
from ..config import settings
from ..db import get_db
class AgentLauncher:
"""Launch Claude CLI agents for specific tasks."""
AGENT_CONFIGS = {
"analyst": {
"system_prompt": ".openclaw/agents/analyst.md",
"task_file": ".task.md",
"allowed_tools": "Read,Write,Edit,Bash",
},
"architect": {
"system_prompt": ".openclaw/agents/architect.md",
"task_file": ".task-arch.md",
"allowed_tools": "Read,Write,Edit,Bash",
},
"developer": {
"system_prompt": ".openclaw/agents/developer.md",
"task_file": ".task-dev.md",
"allowed_tools": "Read,Write,Edit,Bash",
},
"reviewer": {
"system_prompt": ".openclaw/agents/reviewer.md",
"task_file": ".task-review.md",
"allowed_tools": "Read,Write,Edit,Bash",
},
"tester": {
"system_prompt": ".openclaw/agents/tester.md",
"task_file": ".task-test.md",
"allowed_tools": "Read,Write,Edit,Bash",
},
}
def launch(self, agent: str, repo: str, task_content: str = None) -> int:
"""
Launch a Claude CLI agent.
Args:
agent: Agent role (analyst, architect, developer, reviewer, tester)
repo: Repository name
task_content: Optional task content to write to task file
Returns:
agent_run_id from DB
"""
config = self.AGENT_CONFIGS.get(agent)
if not config:
raise ValueError(f"Unknown agent: {agent}")
repo_path = os.path.join(settings.repos_dir, repo)
if not os.path.isdir(repo_path):
raise FileNotFoundError(f"Repo not found: {repo_path}")
# Write task file if content provided
if task_content:
task_path = os.path.join(repo_path, config["task_file"])
with open(task_path, "w") as f:
f.write(task_content)
# Record run in DB
conn = get_db()
cursor = conn.execute(
"INSERT INTO agent_runs (task_id, agent) VALUES (NULL, ?)",
(agent,),
)
run_id = cursor.lastrowid
conn.commit()
# Prepare output log
output_path = f"/app/data/runs/{run_id}.log"
os.makedirs(os.path.dirname(output_path), exist_ok=True)
# Build shell command
cmd = (
f'cd {repo_path} && {settings.claude_bin} --print '
f'"$(cat {config["task_file"]})" '
f'--system-prompt "$(cat {config["system_prompt"]})" '
f'--allowedTools {config["allowed_tools"]}'
)
# Launch as background process
with open(output_path, "w") as log_file:
subprocess.Popen(
["bash", "-c", cmd],
stdout=log_file,
stderr=subprocess.STDOUT,
cwd=repo_path,
)
# Update DB with output path
conn.execute(
"UPDATE agent_runs SET output_path = ? WHERE id = ?",
(output_path, run_id),
)
conn.commit()
conn.close()
return run_id
launcher = AgentLauncher()