diffusiongemma-agent-iq3-cuda13 / payload /app /scripts /dg_agent_capabilities.py
aogavrilov's picture
Add files using upload-large-folder tool
dc7b96e verified
Raw
History Blame Contribute Delete
23.9 kB
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import os
import re
import subprocess
import sys
import tempfile
import time
import urllib.request
from pathlib import Path
from typing import Any
DG_ROOT = Path(__file__).resolve().parents[1]
DG_AGENT = DG_ROOT / "scripts" / "dg_agent.sh"
TRACE_PATH = DG_ROOT / "runlogs" / "aider_proxy.trace.jsonl"
DEFAULT_REPORT_ROOT = DG_ROOT / "runlogs" / "dg-agent-capabilities"
CORE_WORKSPACE_LAUNCHER_HELP_CHECKS = {
"run": ["--help"],
"agent": ["--help"],
"context": ["--help"],
"rag": ["--help"],
"repo-pack": ["--help"],
"repo-map": ["--help"],
"ast-grep": ["--help"],
"code-outline": ["--help"],
"client-init": ["--help"],
"client-smoke": ["--help"],
"client-report": ["--help"],
"agent-commands": ["--help"],
"codex-profile": ["--help"],
"agent-bridge": ["--help"],
"hub": ["--json"],
"plan": ["--help"],
"edit": ["--help"],
"task": ["--help"],
"verify": ["--help"],
"status": ["--help"],
"doctor": ["--help"],
"preflight": ["--help"],
"capabilities": ["--help"],
"sessions": ["--help"],
"supervisor": ["--help"],
"aider": ["--help"],
"opencode": ["--help"],
"opencode-mcp": ["--help"],
"opencode-acp": ["--help"],
"mini-swe-run": ["--help"],
"mini-swe-runs": ["--help"],
"mcp": ["--list-tools"],
"mcp-http": ["--help-local"],
"mcp-client-config": ["--help"],
"agent-rules": ["--help"],
}
def run_cmd(args: list[str], cwd: Path | None = None, timeout: int = 120) -> subprocess.CompletedProcess[str]:
return subprocess.run(
args,
cwd=str(cwd or DG_ROOT),
text=True,
errors="replace",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=timeout,
check=False,
)
def shell_cmd(command: str, cwd: Path, timeout: int = 120) -> subprocess.CompletedProcess[str]:
return subprocess.run(
command,
cwd=str(cwd),
shell=True,
executable="/bin/bash",
text=True,
errors="replace",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=timeout,
check=False,
)
def tail(text: str, limit: int = 3000) -> str:
return text[-limit:] if len(text) > limit else text
def http_ok(url: str, timeout: int = 5) -> bool:
try:
with urllib.request.urlopen(url, timeout=timeout) as response:
data = json.loads(response.read().decode("utf-8", errors="replace"))
return bool(data.get("ok")) if isinstance(data, dict) else True
except Exception:
return False
def init_repo(prefix: str, files: dict[str, str]) -> Path:
repo = Path(tempfile.mkdtemp(prefix=prefix))
run_cmd(["git", "init", "-q"], cwd=repo, timeout=20)
run_cmd(["git", "config", "user.email", "local-capabilities@example.invalid"], cwd=repo, timeout=20)
run_cmd(["git", "config", "user.name", "Local Capabilities"], cwd=repo, timeout=20)
for rel, content in files.items():
path = repo / rel
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(content, encoding="utf-8")
run_cmd(["git", "add", "."], cwd=repo, timeout=20)
run_cmd(["git", "commit", "-qm", "initial"], cwd=repo, timeout=20)
return repo
def scenario_result(name: str, started: float, status: str, **extra: Any) -> dict[str, Any]:
return {
"name": name,
"status": status,
"elapsed_sec": round(time.time() - started, 3),
**extra,
}
def report_timestamp(ts: float) -> str:
return time.strftime("%Y%m%d-%H%M%S", time.localtime(ts))
def write_json(path: Path, data: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
def save_report(report: dict[str, Any], out: str, save_default: bool) -> dict[str, str]:
saved: dict[str, str] = {}
if save_default:
root = DEFAULT_REPORT_ROOT
started = float(report.get("started_at") or time.time())
suffix = "live" if report.get("live") else "static"
timestamped = root / f"{report_timestamp(started)}-{suffix}.json"
latest = root / "latest.json"
saved["timestamped"] = str(timestamped)
saved["latest"] = str(latest)
if out:
saved["out"] = str(Path(out).resolve())
if saved:
report["report_paths"] = saved
if "timestamped" in saved:
write_json(Path(saved["timestamped"]), report)
if "latest" in saved:
write_json(Path(saved["latest"]), report)
if "out" in saved:
write_json(Path(saved["out"]), report)
return saved
def load_latest_report() -> tuple[Path | None, dict[str, Any] | None]:
latest = DEFAULT_REPORT_ROOT / "latest.json"
if not latest.exists():
reports = sorted(DEFAULT_REPORT_ROOT.glob("*.json")) if DEFAULT_REPORT_ROOT.exists() else []
reports = [path for path in reports if path.name != "latest.json"]
if not reports:
return None, None
latest = reports[-1]
try:
return latest, json.loads(latest.read_text(encoding="utf-8"))
except Exception:
return latest, None
def scenario_workspace_run_dry(timeout: int) -> dict[str, Any]:
started = time.time()
repo = init_repo(
"/tmp/dg-cap-workspace.",
{"hello.py": 'def greet(name):\n return f"hello {name}"\n'},
)
proc = run_cmd(
[
str(DG_AGENT),
"run",
"--repo",
str(repo),
"--task",
"Fix hello.py so greet('Ada') returns exactly hello, Ada!",
"--file",
"hello.py",
"--dry-run",
"--json",
],
timeout=timeout,
)
data: dict[str, Any]
try:
data = json.loads(proc.stdout)
except Exception:
data = {"parse_error": True}
status_proc = run_cmd(["git", "status", "--short", "--untracked-files=all"], cwd=repo, timeout=20)
status_text = status_proc.stdout.strip()
launchers_ok = os.access(repo / ".dg-agent" / "bin" / "run", os.X_OK)
ok = (
proc.returncode == 0
and data.get("status") == "dry-run"
and launchers_ok
and ".dg-agent" not in status_text
)
return scenario_result(
"workspace-run-dry",
started,
"passed" if ok else "failed",
repo=str(repo),
returncode=proc.returncode,
dry_status=data.get("status"),
launchers_ok=launchers_ok,
git_status=status_text,
stdout_tail="" if ok else tail(proc.stdout),
stderr_tail="" if ok else tail(proc.stderr),
)
def scenario_workspace_launchers_static(timeout: int) -> dict[str, Any]:
started = time.time()
repo = init_repo(
"/tmp/dg-cap-launchers.",
{"hello.py": 'def greet(name):\n return f"hello {name}"\n'},
)
init_proc = run_cmd(
[str(DG_AGENT), "workspace-init", "--repo", str(repo), "--json"],
timeout=min(timeout, 60),
)
init_report: dict[str, Any]
try:
init_report = json.loads(init_proc.stdout)
except Exception:
init_report = {"parse_error": True}
per_launcher_timeout = max(10, min(timeout, 45))
launcher_results: list[dict[str, Any]] = []
for name, argv in CORE_WORKSPACE_LAUNCHER_HELP_CHECKS.items():
path = repo / ".dg-agent" / "bin" / name
exists = path.exists()
executable = os.access(path, os.X_OK)
if not exists or not executable:
launcher_results.append(
{
"name": name,
"exists": exists,
"executable": executable,
"status": "failed",
"reason": "missing or not executable",
}
)
continue
try:
proc = run_cmd([str(path), *argv], cwd=repo, timeout=per_launcher_timeout)
combined = proc.stdout + proc.stderr
launcher_results.append(
{
"name": name,
"exists": exists,
"executable": executable,
"status": "passed" if proc.returncode == 0 and bool(combined.strip()) else "failed",
"returncode": proc.returncode,
"stdout_bytes": len(proc.stdout),
"stderr_bytes": len(proc.stderr),
"output_tail": "" if proc.returncode == 0 and combined.strip() else tail(combined),
}
)
except subprocess.TimeoutExpired as exc:
launcher_results.append(
{
"name": name,
"exists": exists,
"executable": executable,
"status": "failed",
"reason": f"timeout after {exc.timeout}s",
}
)
status_proc = run_cmd(["git", "status", "--short", "--untracked-files=all"], cwd=repo, timeout=20)
status_text = status_proc.stdout.strip()
failed_launchers = [item["name"] for item in launcher_results if item["status"] != "passed"]
ok = (
init_proc.returncode == 0
and init_report.get("status") == "success"
and not failed_launchers
and ".dg-agent" not in status_text
)
return scenario_result(
"workspace-launchers-static",
started,
"passed" if ok else "failed",
repo=str(repo),
returncode=init_proc.returncode,
workspace_init_status=init_report.get("status"),
launchers_checked=len(launcher_results),
failed_launchers=failed_launchers,
git_status=status_text,
launcher_results=launcher_results if not ok else [],
stdout_tail="" if ok else tail(init_proc.stdout),
stderr_tail="" if ok else tail(init_proc.stderr),
)
def scenario_oss_wrapper_audit_static(timeout: int) -> dict[str, Any]:
started = time.time()
proc = run_cmd(
[
str(DG_AGENT),
"bootstrap",
"--json",
"--smoke-static",
"--smoke-timeout",
str(min(timeout, 120)),
],
timeout=min(timeout, 120) + 30,
)
data: dict[str, Any]
try:
data = json.loads(proc.stdout)
except Exception:
data = {"parse_error": True}
after = data.get("after") if isinstance(data.get("after"), list) else []
smoke_results = data.get("smoke_results") if isinstance(data.get("smoke_results"), list) else []
required = {"aider", "opencode", "mcp"}
missing = [str(item.get("id")) for item in after if item.get("id") in required and not item.get("installed")]
optional_missing = [str(item.get("id")) for item in after if item.get("id") not in required and not item.get("installed")]
failed_smokes = [str(item.get("suite")) for item in smoke_results if item.get("status") != "success"]
ok = proc.returncode == 0 and not missing and not failed_smokes and bool(smoke_results)
return scenario_result(
"oss-wrapper-audit-static",
started,
"passed" if ok else "failed",
returncode=proc.returncode,
installed=[str(item.get("id")) for item in after if item.get("installed")],
missing=missing,
optional_missing=optional_missing,
smoke_results=[{"suite": item.get("suite"), "status": item.get("status")} for item in smoke_results],
failed_smokes=failed_smokes,
stdout_tail="" if ok else tail(proc.stdout),
stderr_tail="" if ok else tail(proc.stderr),
)
def scenario_external_agent_profiles_static(timeout: int) -> dict[str, Any]:
started = time.time()
smoke = run_cmd(
[str(DG_AGENT), "smoke", "--suite", "qwen-code", "--timeout", str(min(timeout, 120))],
timeout=min(timeout, 120) + 30,
)
audit = run_cmd([str(DG_AGENT), "bootstrap", "--only", "qwen-code", "--json"], timeout=60)
qwen_installed = False
qwen_binary = ""
try:
data = json.loads(audit.stdout)
rows = data.get("after") if isinstance(data.get("after"), list) else []
for row in rows:
if row.get("id") == "qwen-code":
qwen_installed = bool(row.get("installed"))
checks = row.get("checks") if isinstance(row.get("checks"), list) else []
for check in checks:
if check.get("exists") and "qwen" in str(check.get("path") or "").lower():
qwen_binary = str(check.get("path") or "")
break
except Exception:
pass
ok = smoke.returncode == 0 and audit.returncode == 0 and qwen_installed
return scenario_result(
"external-agent-profiles-static",
started,
"passed" if ok else "failed",
returncode=smoke.returncode,
audit_returncode=audit.returncode,
qwen_code_installed=qwen_installed,
qwen_code_binary=qwen_binary,
stdout_tail="" if ok else tail(smoke.stdout),
stderr_tail="" if ok else tail(smoke.stderr),
audit_tail="" if ok else tail(audit.stdout + audit.stderr),
)
def scenario_proxy_adapter_static(timeout: int) -> dict[str, Any]:
started = time.time()
proc = run_cmd([str(DG_AGENT), "smoke", "--suite", "proxy-adapter", "--timeout", str(timeout)], timeout=timeout + 15)
return scenario_result(
"proxy-adapter-static",
started,
"passed" if proc.returncode == 0 else "failed",
returncode=proc.returncode,
stdout_tail="" if proc.returncode == 0 else tail(proc.stdout),
stderr_tail="" if proc.returncode == 0 else tail(proc.stderr),
)
def scenario_supervisor_exact_replace(timeout: int) -> dict[str, Any]:
started = time.time()
repo = init_repo(
"/tmp/dg-cap-replace.",
{"message.py": 'WELCOME = "hello beta"\n\ndef welcome():\n return WELCOME\n'},
)
test_cmd = "python3 -c 'from message import welcome; assert welcome() == \"hello stable\"'"
report_path = repo / "replace-report.json"
proc = run_cmd(
[
str(DG_AGENT),
"supervisor",
"--",
"--repo",
str(repo),
"--task",
"In message.py, replace 'hello beta' with 'hello stable'. Keep everything else unchanged.",
"--file",
"message.py",
"--test-cmd",
test_cmd,
"--aider-timeout",
str(timeout),
"--repair-attempts",
"0",
"--report",
str(report_path),
],
timeout=timeout + 30,
)
verify = shell_cmd(test_cmd, repo, timeout=30)
strategy = ""
status = ""
if report_path.exists():
try:
report = json.loads(report_path.read_text(encoding="utf-8"))
strategy = str(report.get("strategy") or "")
status = str(report.get("status") or "")
except Exception as exc:
status = f"report-error: {exc}"
text = (repo / "message.py").read_text(encoding="utf-8", errors="replace")
ok = (
proc.returncode == 0
and verify.returncode == 0
and status == "success"
and strategy == "deterministic-first"
and 'WELCOME = "hello stable"' in text
)
return scenario_result(
"supervisor-exact-replace",
started,
"passed" if ok else "failed",
repo=str(repo),
returncode=proc.returncode,
verify_returncode=verify.returncode,
report_status=status,
strategy=strategy,
stdout_tail="" if ok else tail(proc.stdout),
stderr_tail="" if ok else tail(proc.stderr),
verify_output_tail="" if ok else tail(verify.stdout + verify.stderr),
)
def read_trace_since(started_at: float, kinds: set[str]) -> list[dict[str, Any]]:
if not TRACE_PATH.exists():
return []
events: list[dict[str, Any]] = []
for line in TRACE_PATH.read_text(encoding="utf-8", errors="replace").splitlines():
try:
event = json.loads(line)
except Exception:
continue
if float(event.get("ts") or 0.0) < started_at:
continue
if str(event.get("kind")) in kinds:
events.append(event)
return events
def session_from_stdout(stdout: str) -> Path | None:
match = re.search(r"(?m)^Session dir:\s*(.+)$", stdout)
if not match:
return None
path = Path(match.group(1).strip())
return path if path.exists() else None
def step_strategy(session_dir: Path) -> tuple[str, str]:
task_report = json.loads((session_dir / "task-report.json").read_text(encoding="utf-8"))
step_path = Path(task_report["steps"][0]["step_report"])
step_report = json.loads(step_path.read_text(encoding="utf-8"))
return str(step_report.get("status") or ""), str(step_report.get("strategy") or "")
def scenario_live_proxy_repair(timeout: int) -> dict[str, Any]:
started = time.time()
services_ok = {
"backend": http_ok("http://127.0.0.1:4100/healthz"),
"proxy": http_ok("http://127.0.0.1:8090/healthz"),
}
if not all(services_ok.values()):
return scenario_result("live-proxy-repair", started, "skipped", reason="backend/proxy not live", services=services_ok)
repo = init_repo(
"/tmp/dg-cap-live.",
{"score.py": 'def label_score(score):\n return "TODO"\n'},
)
test_cmd = "python3 -c 'from score import label_score; assert label_score(90) == \"high\"; assert label_score(89) == \"normal\"'"
proc = run_cmd(
[
str(DG_AGENT),
"run",
"--repo",
str(repo),
"--task",
"Edit score.py. Implement label_score(score): return 'high' when score is greater than or equal to 90, otherwise return 'normal'. Keep the same function name.",
"--file",
"score.py",
"--test-cmd",
test_cmd,
"--repair-attempts",
"0",
"--aider-timeout",
str(timeout),
"--wall-timeout",
str(timeout + 60),
"--max-files",
"1",
],
timeout=timeout + 90,
)
verify = shell_cmd(test_cmd, repo, timeout=30)
session_dir = session_from_stdout(proc.stdout)
step_status = ""
strategy = ""
if session_dir:
try:
step_status, strategy = step_strategy(session_dir)
except Exception as exc:
step_status = f"report-error: {exc}"
repair_events = read_trace_since(started, {"proxy_exact_repair"})
score_text = (repo / "score.py").read_text(encoding="utf-8", errors="replace")
strategy_ok = strategy == "deterministic-first" or (
strategy in {"aider", "aider-with-deterministic-repair"} and bool(repair_events)
)
ok = (
proc.returncode == 0
and verify.returncode == 0
and strategy_ok
and "return 'high' if score >= 90 else 'normal'" in score_text
)
return scenario_result(
"live-proxy-repair",
started,
"passed" if ok else "failed",
repo=str(repo),
services=services_ok,
returncode=proc.returncode,
verify_returncode=verify.returncode,
session_dir=str(session_dir) if session_dir else "",
step_status=step_status,
strategy=strategy,
proxy_exact_repair_events=len(repair_events),
score_py=score_text,
stdout_tail="" if ok else tail(proc.stdout),
stderr_tail="" if ok else tail(proc.stderr),
verify_output_tail="" if ok else tail(verify.stdout + verify.stderr),
)
def run_capabilities(args: argparse.Namespace) -> dict[str, Any]:
started = time.time()
scenarios = [
scenario_workspace_run_dry(args.timeout),
scenario_workspace_launchers_static(args.timeout),
scenario_oss_wrapper_audit_static(args.timeout),
scenario_external_agent_profiles_static(args.timeout),
scenario_proxy_adapter_static(min(args.timeout, 120)),
scenario_supervisor_exact_replace(min(args.timeout, 120)),
]
if args.live:
scenarios.append(scenario_live_proxy_repair(args.timeout))
passed = sum(1 for item in scenarios if item["status"] == "passed")
failed = [item["name"] for item in scenarios if item["status"] == "failed"]
skipped = [item["name"] for item in scenarios if item["status"] == "skipped"]
return {
"status": "success" if not failed else "failed",
"live": args.live,
"started_at": started,
"elapsed_sec": round(time.time() - started, 3),
"summary": {"passed": passed, "failed": failed, "skipped": skipped},
"scenarios": scenarios,
}
def print_report(report: dict[str, Any]) -> None:
print(f"DG agent capabilities: {report['status']}")
print(f"live: {report['live']} elapsed={report['elapsed_sec']}s")
paths = report.get("report_paths")
if isinstance(paths, dict) and paths.get("latest"):
print(f"latest: {paths['latest']}")
for item in report["scenarios"]:
print(f"- {item['name']}: {item['status']} ({item['elapsed_sec']}s)")
if item.get("strategy"):
print(f" strategy: {item['strategy']}")
if item.get("proxy_exact_repair_events") is not None:
print(f" proxy_exact_repair_events: {item['proxy_exact_repair_events']}")
if item.get("launchers_checked") is not None:
print(f" launchers_checked: {item['launchers_checked']}")
if item.get("installed") is not None:
print(f" installed: {', '.join(item['installed'])}")
if item.get("mini_swe_agent_installed") is not None:
print(f" mini_swe_agent_installed: {item['mini_swe_agent_installed']}")
if item.get("session_dir"):
print(f" session: {item['session_dir']}")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Run capability probes for the local DG agent wrapper stack.")
parser.add_argument("--live", action="store_true", help="Include live model/proxy/Aider capability probes")
parser.add_argument("--timeout", type=int, default=180)
parser.add_argument("--json", action="store_true")
parser.add_argument("--out", default="", help="Optional JSON report path")
parser.add_argument("--no-save", action="store_true", help="Do not write runlogs/dg-agent-capabilities/latest.json")
parser.add_argument("--latest", action="store_true", help="Show the last saved capability report instead of running probes")
parser.add_argument("--path-only", action="store_true", help="With --latest, print only the report path")
return parser.parse_args()
def main() -> int:
args = parse_args()
if args.latest:
path, report = load_latest_report()
if path is None:
print("No saved capability report found.", file=sys.stderr)
return 2
if args.path_only:
print(path)
return 0 if report is not None else 1
if report is None:
print(f"Saved capability report is not valid JSON: {path}", file=sys.stderr)
return 1
if args.json:
print(json.dumps(report, ensure_ascii=False, indent=2))
else:
print_report(report)
return 0 if report.get("status") == "success" else 1
report = run_capabilities(args)
save_report(report, args.out, not args.no_save)
if args.json:
print(json.dumps(report, ensure_ascii=False, indent=2))
else:
print_report(report)
return 0 if report["status"] == "success" else 1
if __name__ == "__main__":
raise SystemExit(main())