Spaces:
Sleeping
Sleeping
File size: 2,901 Bytes
71b4454 | 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 | 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
|