Spaces:
Sleeping
Sleeping
| """Phase 6: agentic generate -> execute -> repair loop. | |
| Model-agnostic: takes a `generate_fn(intent, feedback) -> code` callable, so it | |
| works with CodeAssistant or any other generator (and is unit-testable with a mock). | |
| """ | |
| from __future__ import annotations | |
| import sys | |
| from dataclasses import dataclass, field | |
| from pathlib import Path | |
| from typing import Callable | |
| sys.path.append(str(Path(__file__).resolve().parents[2])) | |
| from src.eval.sandbox import run_code # noqa: E402 | |
| class RepairTrace: | |
| final_code: str | |
| success: bool | |
| iterations: int | |
| history: list = field(default_factory=list) # list of (code, error) | |
| def repair_loop( | |
| intent: str, | |
| generate_fn: Callable[[str, str | None], str], | |
| check_program_fn: Callable[[str], str], | |
| max_iters: int = 3, | |
| timeout: float = 8.0, | |
| ) -> RepairTrace: | |
| """Iteratively generate and self-correct. | |
| generate_fn(intent, feedback) -> candidate code | |
| feedback is None on the first call, else the previous error string. | |
| check_program_fn(code) -> a runnable program string (code + a smoke | |
| test or the harness test) used to decide pass/fail. | |
| """ | |
| feedback = None | |
| history = [] | |
| for i in range(1, max_iters + 1): | |
| code = generate_fn(intent, feedback) | |
| result = run_code(check_program_fn(code), timeout=timeout) | |
| history.append((code, result.error)) | |
| if result.ok: | |
| return RepairTrace(code, True, i, history) | |
| feedback = result.error # feed the traceback back in | |
| return RepairTrace(history[-1][0], False, max_iters, history) | |
| def make_repair_generator(assistant): | |
| """Adapt a CodeAssistant into a generate_fn for the repair loop.""" | |
| def generate_fn(intent: str, feedback: str | None) -> str: | |
| if feedback: | |
| intent = (f"{intent}\n\n# Your previous attempt failed with this error:\n" | |
| f"# {feedback}\n# Fix it and return the corrected function.") | |
| return assistant.generate(intent, mode="rag") | |
| return generate_fn | |