Spaces:
Sleeping
Sleeping
File size: 7,771 Bytes
5b33b3c 2898fad 5b33b3c 2898fad 5b33b3c 2898fad 5b33b3c 2898fad 5b33b3c 2898fad 5b33b3c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | import re
import json
from typing import Optional, List, Dict, Any
from .llm import LLMClient
from .compiler import CppCompiler
class BaseAgent:
def __init__(self, llm: LLMClient, compiler: CppCompiler):
self.llm = llm
self.compiler = compiler
def extract_code_blocks(self, text: str, expected_count: int = None) -> List[str]:
pattern = re.compile(r"```(?:cpp|c\+\+)?\s*\n(.*?)```", re.DOTALL | re.IGNORECASE)
matches = pattern.findall(text)
blocks = [m.strip() for m in matches if m.strip()]
if expected_count is not None and len(blocks) != expected_count:
pass
return blocks
def extract_json(self, text: str) -> Optional[Dict[str, Any]]:
text = text.strip()
if text.startswith("```"):
text = re.sub(r"^```(?:json)?\s*\n", "", text, flags=re.IGNORECASE)
text = re.sub(r"\n```$", "", text, flags=re.IGNORECASE)
try:
return json.loads(text)
except json.JSONDecodeError:
match = re.search(r"\{.*\}", text, re.DOTALL)
if match:
try:
return json.loads(match.group(0))
except json.JSONDecodeError:
return None
return None
class CoderAgent(BaseAgent):
def run(self, problem: str, objective: str, max_retries: int = 3) -> Dict[str, Any]:
prompt = self.llm.get_coder_prompt(problem, objective)
code = ""
response = ""
compile_result = {"compiled": False, "compile_error": "No attempts made", "compile_stderr": ""}
for attempt in range(1, max_retries + 1):
response = self.llm.generate(prompt, max_tokens=4096, temperature=0.1)
code_blocks = self.extract_code_blocks(response)
if not code_blocks:
code_blocks = [response]
code = code_blocks[0]
compile_result = self.compiler.compile("solution", code)
if compile_result["compiled"]:
run_result = self.compiler.run(compile_result["binary_path"])
return {
"code": code,
"compile_result": compile_result,
"run_result": run_result,
"attempts": attempt,
"agent": "coder",
}
prompt = f"{prompt}\n\nPREVIOUS ATTEMPT FAILED WITH COMPILATION ERROR:\n{compile_result['compile_error']}\n\nFix the error and output ONLY valid C++ code."
return {
"code": code if code else response,
"compile_result": compile_result,
"run_result": None,
"attempts": max_retries,
"agent": "coder",
"failed": True,
}
class ResearcherAgent(BaseAgent):
def run(self, problem: str, baseline_code: str, objective: str, n: int = 3) -> List[Dict[str, Any]]:
prompt = self.llm.get_researcher_prompt(problem, baseline_code, objective, n)
response = self.llm.generate(prompt, max_tokens=8192, temperature=0.4)
code_blocks = self.extract_code_blocks(response, expected_count=n)
if not code_blocks:
code_blocks = [response]
algorithms = []
for i, code in enumerate(code_blocks[:n]):
label = f"algo_{i+1}"
compile_result = self.compiler.compile(label, code)
run_result = None
if compile_result["compiled"]:
run_result = self.compiler.run(compile_result["binary_path"])
algorithms.append({
"index": i + 1,
"label": label,
"code": code,
"compile_result": compile_result,
"run_result": run_result,
"agent": "researcher",
})
while len(algorithms) < n:
algorithms.append({
"index": len(algorithms) + 1,
"label": f"algo_{len(algorithms)+1}",
"code": "",
"compile_result": {"compiled": False, "compile_error": "No code generated"},
"run_result": None,
"agent": "researcher",
"failed": True,
})
return algorithms
class ValidatorAgent(BaseAgent):
def _build_metrics_table(self, algorithms: List[Dict[str, Any]], baseline: Dict[str, Any]) -> str:
lines = ["| Algorithm | Compiled | Return Code | Exec Time (s) | Memory (KB) | Stdout |"]
lines.append("|-----------|----------|-------------|---------------|-------------|--------|")
b_run = baseline.get("run_result") or {}
lines.append(f"| Baseline | {'Yes' if baseline.get('compile_result', {}).get('compiled') else 'No'} | {'0' if b_run.get('ran') else 'N/A'} | {b_run.get('execution_time_s', 'N/A')} | {b_run.get('memory_kb', 'N/A')} | (baseline) |")
for algo in algorithms:
compiled = "Yes" if (algo.get("compile_result") or {}).get("compiled") else "No"
a_run = algo.get("run_result") or {}
if a_run.get("ran"):
rc = str(a_run.get("returncode"))
et = str(a_run.get("execution_time_s"))
mem = str(a_run.get("memory_kb"))
else:
rc = "N/A"
et = "N/A"
mem = "N/A"
stdout_preview = (a_run.get("stdout", "") or "")[:30].replace("\n", " ")
lines.append(f"| Algo {algo['index']} | {compiled} | {rc} | {et} | {mem} | {stdout_preview} |")
return "\n".join(lines)
def run(self, problem: str, objective: str, user_metric: str, algorithms: List[Dict[str, Any]], baseline: Dict[str, Any]) -> Dict[str, Any]:
metrics_table = self._build_metrics_table(algorithms, baseline)
prompt = self.llm.get_validator_prompt(problem, objective, user_metric, metrics_table, len(algorithms))
response = self.llm.generate(prompt, max_tokens=1024, temperature=0.0)
result = self.extract_json(response)
if result is None:
result = {"winner": 1, "failed": False, "reason": "Default fallback selection"}
return {
"validation": result,
"metrics_table": metrics_table,
"agent": "validator",
}
class RealWorldAgent(BaseAgent):
def run(self, problem: str, winner_code: str, baseline_code: str, objective: str, n: int = 3) -> Dict[str, Any]:
prompt = self.llm.get_realworld_prompt(problem, winner_code, baseline_code, objective, n)
response = self.llm.generate(prompt, max_tokens=8192, temperature=0.3)
code_blocks = self.extract_code_blocks(response, expected_count=n)
if not code_blocks:
code_blocks = [response]
scenarios = []
for i, code in enumerate(code_blocks[:n]):
label = f"scenario_{i+1}"
compile_result = self.compiler.compile(label, code)
run_result = None
if compile_result["compiled"]:
run_result = self.compiler.run(compile_result["binary_path"], timeout=60)
scenarios.append({
"index": i + 1,
"label": label,
"code": code,
"compile_result": compile_result,
"run_result": run_result,
})
while len(scenarios) < n:
scenarios.append({
"index": len(scenarios) + 1,
"label": f"scenario_{len(scenarios)+1}",
"code": "",
"compile_result": {"compiled": False, "compile_error": "No code generated"},
"run_result": None,
"failed": True,
})
return {
"scenarios": scenarios,
"agent": "realworld",
}
|