codedebugger / orchestrator.py
psdhanushkumar's picture
Upload folder using huggingface_hub
f361447 verified
Raw
History Blame Contribute Delete
5.76 kB
from env.codedebugger_env import CodeDebuggerEnv
from agents.fixer import FixerAgent
class Debugger:
def __init__(self, max_iterations=5):
self.env = CodeDebuggerEnv(max_iterations)
self.fixer = FixerAgent()
def run(self, problem: dict, verbose=True) -> dict:
"""
Full debugging loop for one problem.
"""
obs = self.env.reset(problem)
best_reward = -float('inf')
best_code = None
best_iter = 0
iter_data = []
reward_gain = 0.0
iter1_reward = 0.0
final_reward = 0.0
tests_passed_final = 0
tests_total = len(problem.get("test_cases", []))
solved = False
if verbose:
print(f"\n--- Debugging: {problem['id']} ({problem.get('title', '')}) ---")
for i in range(1, self.env.max_iterations + 1):
# Format history for fixer
prev_explanation = None
test_results = None
if iter_data:
# Use results from the immediate previous iteration
last_env_hist = self.env.history[-1]
test_results = last_env_hist["test_results"]
prev_explanation = iter_data[-1]["fix_result"].get("explanation")
# On first iteration, fix the original buggy code.
# On subsequent iterations, try to fix the previously generated code.
code_to_fix = obs["buggy_code"] if i == 1 else self.env.history[-1]["code"]
# Propose fix
fix_result = self.fixer.fix_code(
buggy_code=code_to_fix,
error_type=problem.get("error_type", ""),
description=problem.get("description", ""),
test_cases=problem.get("test_cases", []),
test_results=test_results,
previous_explanation=prev_explanation,
iteration=i
)
fixed_code = fix_result.get("fixed_code", code_to_fix)
# Step environment
obs, reward_dict, done, info = self.env.step(fixed_code)
current_reward = reward_dict["total"]
if i == 1:
iter1_reward = current_reward
final_reward = current_reward
tests_passed_final = obs["test_results"].get("tests_passed", 0)
# Track best separately
if current_reward > best_reward:
best_reward = current_reward
best_code = fixed_code
best_iter = i
iter_info = {
"iteration": i,
"fix_result": fix_result,
"reward": reward_dict,
"done": done,
"info": info
}
iter_data.append(iter_info)
if verbose:
print(f"Iter {i}: passed {tests_passed_final}/{tests_total} | "
f"reward: {current_reward:.1f} | method: {fix_result.get('method')}")
if done:
if info.get("solved"):
solved = True
if verbose:
print("-> Solved!")
break
# Calculate gain from first iteration
if best_reward != -float('inf'):
reward_gain = best_reward - iter1_reward
else:
best_reward = 0.0
return {
"problem_id": problem["id"],
"difficulty": problem["difficulty"],
"title": problem.get("title", ""),
"n_iterations": len(iter_data),
"final_reward": final_reward,
"best_reward": best_reward,
"iter1_reward": iter1_reward,
"best_iter": best_iter,
"best_code": best_code,
"reward_gain": reward_gain,
"tests_passed_final": tests_passed_final,
"tests_total": tests_total,
"solved": solved,
"iterations": iter_data
}
def run_all(self, problems: list, verbose=True) -> list:
"""Run all problems, return list of results"""
results = []
for prob in problems:
res = self.run(prob, verbose=verbose)
results.append(res)
return results
def print_summary_table(self, results: list):
"""
Print this exact format:
Problem Diff iter1 final best gain solved
----------------------------------------------------------------
...
"""
print(f"\n{'Problem':<20} {'Diff':<7} {'iter1':>6} {'final':>6} {'best':>6} {'gain':>6} {'solved':>6}")
print("-" * 64)
solved_count = 0
total_best_reward = 0.0
for r in results:
pid = str(r["problem_id"])
if len(pid) > 20:
pid = pid[:17] + "..."
diff = str(r["difficulty"])
iter1 = r.get("iter1_reward", 0.0)
final = r["final_reward"]
best = r["best_reward"]
gain = r["reward_gain"]
solved_str = "YES" if r["solved"] else "NO"
print(f"{pid:<20} {diff:<7} {iter1:>6.1f} {final:>6.1f} {best:>6.1f} {gain:>+6.1f} {solved_str:>6}")
if r["solved"]:
solved_count += 1
total_best_reward += best
print("-" * 64)
avg_best = total_best_reward / len(results) if results else 0.0
print(f"TOTAL: {solved_count}/{len(results)} solved | Avg best reward: {avg_best:.1f}")