Spaces:
Sleeping
Sleeping
| import ast | |
| import os | |
| from typing import Dict, List, Any, Optional, Callable | |
| class AutonomousCodeBuilder: | |
| """Manages file generation, incremental patching, syntax validation, and self-healing repair loops.""" | |
| def __init__(self, workspace_root: str = "."): | |
| self.workspace_root = workspace_root | |
| def generate_project(self, files: Dict[str, str]) -> List[str]: | |
| """Scaffolds directory structures and writes initial project file assets.""" | |
| created_files = [] | |
| for relative_path, content in files.items(): | |
| full_path = os.path.join(self.workspace_root, relative_path) | |
| os.makedirs(os.path.dirname(full_path), exist_ok=True) | |
| with open(full_path, "w", encoding="utf-8") as f: | |
| f.write(content) | |
| created_files.append(relative_path) | |
| return created_files | |
| def apply_patch(self, relative_path: str, search_text: str, replace_text: str) -> bool: | |
| """Applies targeted incremental search-and-replace patches to workspace files.""" | |
| full_path = os.path.join(self.workspace_root, relative_path) | |
| if not os.path.exists(full_path): | |
| return False | |
| with open(full_path, "r", encoding="utf-8") as f: | |
| content = f.read() | |
| if search_text not in content: | |
| return False | |
| new_content = content.replace(search_text, replace_text, 1) | |
| with open(full_path, "w", encoding="utf-8") as f: | |
| f.write(new_content) | |
| return True | |
| def validate_syntax(self, relative_path: str) -> Optional[str]: | |
| """Validates Python AST structure and returns syntax error message if invalid.""" | |
| full_path = os.path.join(self.workspace_root, relative_path) | |
| if not os.path.exists(full_path): | |
| return f"File not found: {relative_path}" | |
| with open(full_path, "r", encoding="utf-8") as f: | |
| content = f.read() | |
| try: | |
| ast.parse(content) | |
| return None | |
| except SyntaxError as e: | |
| return f"SyntaxError on line {e.lineno}: {e.msg}" | |
| def auto_repair( | |
| self, | |
| relative_path: str, | |
| repair_fn: Callable[[str, str], Optional[str]], | |
| max_attempts: int = 3 | |
| ) -> bool: | |
| """Executes automated repair loop until syntax validation passes or max_attempts is reached.""" | |
| error_msg = self.validate_syntax(relative_path) | |
| attempts = 0 | |
| while error_msg and attempts < max_attempts: | |
| attempts += 1 | |
| repaired_code = repair_fn(relative_path, error_msg) | |
| if repaired_code is not None: | |
| full_path = os.path.join(self.workspace_root, relative_path) | |
| with open(full_path, "w", encoding="utf-8") as f: | |
| f.write(repaired_code) | |
| error_msg = self.validate_syntax(relative_path) | |
| return error_msg is None | |