Dave-13/DevSecOps
0
1from agents.classifier import classify2from agents.debugger import debug3from agents.patcher import generate_patches4from agents.decision import decide5from env.openenv_env import OpenEnvDevSecOps6from core.patch_applier import apply_patch7from utils.logger import log, trim_logs8 9 10MAX_REGEN = 2 # max patch regeneration rounds11 12 13def run(code: str, raw_logs: str, test_code: str) -> dict:14 logs = trim_logs(raw_logs)15 env = OpenEnvDevSecOps(code, logs, test_code)16 17 # ── 1. Classify ────────────────────────────────────────────────────────18 classification = classify(code, logs)19 log("classifier", classification)20 21 # ── 2. Debug ───────────────────────────────────────────────────────────22 debug_info = debug(code, logs, classification)23 log("debugger", debug_info)24 25 root_cause = debug_info.get("root_cause", "unknown")26 fix_strategy = debug_info.get("fix_strategy", "apply defensive fix")27 28 retries = 029 failure_context = ""30 final_patch = None31 final_test = {}32 final_security = {}33 34 for regen in range(MAX_REGEN):35 # ── 3. Generate patches ────────────────────────────────────────────36 patch_result = generate_patches(code, root_cause, fix_strategy, failure_context)37 log("patcher", {"regen": regen, "patches_count": len(patch_result.get("patches", []))})38 39 patches = patch_result.get("patches", [])40 if not patches:41 break42 43 for patch in patches:44 patched_code = apply_patch(code, patch.get("code", ""))45 log("applying_patch", {"id": patch.get("id"), "desc": patch.get("description", "")})46 47 # ── 4. Env step: apply → test → security → reward ──────────────48 step = env.step(patched_code)49 retries += 150 51 test_result = step["test_result"]52 security_result = step["security_result"]53 reward = step["reward"]54 log("env_step", {"reward": reward, "tests_passed": test_result.get("passed"), "secure": security_result.get("secure")})55 56 # ── 5. Decision ────────────────────────────────────────────────57 decision = decide(test_result, security_result, retries)58 log("decision", decision)59 60 if decision["action"] == "finalize":61 final_patch = patched_code62 final_test = test_result63 final_security = security_result64 break65 66 if not test_result.get("passed"):67 failure_context += f"Patch {patch.get('id')} failed tests: {test_result.get('stderr', '')[:200]}. "68 elif not security_result.get("secure"):69 failure_context += f"Patch {patch.get('id')} failed security: {security_result.get('issues')}. "70 71 if decision["action"] == "abort":72 break73 74 if final_patch or decision["action"] == "abort":75 break76 77 # ── 6. Final report ────────────────────────────────────────────────────78 success = final_patch is not None79 total_reward = env.compute_reward() if success else -1.080 81 report = {82 "status": "success" if success else "failure",83 "patch": final_patch or "",84 "tests_passed": final_test.get("passed", False),85 "secure": final_security.get("secure", False),86 "retries": retries,87 "reward": total_reward,88 "classification": classification,89 "root_cause": root_cause,90 "security_issues": final_security.get("issues", []),91 "summary": (92 f"Fixed: {fix_strategy}. Patch passed tests and security audit."93 if success94 else f"Failed after {retries} retries. Last issue: {failure_context[:200]}"95 ),96 }97 log("final_report", {k: v for k, v in report.items() if k != "patch"})98 return report99 