1010from parser import extract_function_source , replace_function_source
1111from google .antigravity import Agent , LocalAgentConfig
1212
13- # Load environment variables from .env
1413load_dotenv ()
1514
1615def clean_agent_code (response_text : str , function_name : str ) -> str :
1716 """Cleans up markdown code blocks, conversational prefixes, and whitespaces from agent response."""
1817 code = response_text .strip ()
19- # Remove markdown code blocks if the agent wrapped its response in it
2018 if code .startswith ("```python" ):
2119 code = code [len ("```python" ):].strip ()
2220 elif code .startswith ("```" ):
2321 code = code [3 :].strip ()
2422 if code .endswith ("```" ):
2523 code = code [:- 3 ].strip ()
2624
27- # Isolate code starting with 'def <function_name>' if prefixed by conversation
2825 def_prefix = f"def { function_name } "
2926 if def_prefix in code :
3027 idx = code .find (def_prefix )
3128 code = code [idx :]
3229
33- # Final cleanup of any trailing backticks
3430 if code .endswith ("```" ):
3531 code = code [:- 3 ].strip ()
3632
@@ -48,7 +44,6 @@ async def run_pytest_suite(test_file: str) -> tuple[int, str]:
4844
4945 cmd = [python_exe , "-m" , "pytest" , test_file ]
5046
51- # Propagate environment variables and set PYTHONPATH to allow relative package imports
5247 env = os .environ .copy ()
5348 env ["PYTHONPATH" ] = os .getcwd ()
5449
@@ -75,7 +70,6 @@ async def run_script_file(script_file: str) -> tuple[int, str]:
7570
7671 cmd = [python_exe , script_file ]
7772
78- # Propagate environment variables and set PYTHONPATH to allow relative package imports
7973 env = os .environ .copy ()
8074 env ["PYTHONPATH" ] = os .getcwd ()
8175
@@ -103,15 +97,12 @@ def parse_python_traceback(traceback_text: str) -> tuple[str, str, str]:
10397 file_path = None
10498 function_name = None
10599
106- # Matches: File "tests/mock_code.py", line 4, in divide_numbers
107100 traceback_re = re .compile (r'^\s*File\s+"([^"]+)",\s+line\s+(\d+),\s+in\s+(\w+)' )
108101
109- # Iterate backwards to find the innermost frame causing the error
110102 for i in range (len (lines ) - 2 , - 1 , - 1 ):
111103 match = traceback_re .match (lines [i ])
112104 if match :
113105 func = match .group (3 )
114- # Skip top-level module execution frame as it does not define a function
115106 if func == "<module>" :
116107 continue
117108 file_path = match .group (1 ).replace ("\\ " , "/" )
@@ -136,7 +127,6 @@ def parse_pytest_failure(pytest_output: str) -> tuple[str, str, str]:
136127 function_name = None
137128 error_log = []
138129
139- # Matches: tests/mock_code.py:4: ZeroDivisionError
140130 file_line_err_re = re .compile (r"^([a-zA-Z0-9_\-\/\\\. ]+\.py):(\d+): (\w+)" )
141131
142132 for i in range (len (lines ) - 1 , - 1 , - 1 ):
@@ -149,15 +139,13 @@ def parse_pytest_failure(pytest_output: str) -> tuple[str, str, str]:
149139
150140 file_path = possible_file
151141
152- # Find the error details (lines starting with 'E ')
153142 for j in range (i , - 1 , - 1 ):
154143 if lines [j ].strip ().startswith ("E " ):
155144 error_log .append (lines [j ].strip ()[4 :])
156145 break
157146 if not error_log :
158147 error_log .append (line )
159148
160- # Find the function definition in the traceback
161149 func_def_re = re .compile (r"^\s*def\s+(\w+)\s*\(" )
162150 for j in range (i , - 1 , - 1 ):
163151 m = func_def_re .match (lines [j ])
@@ -280,17 +268,14 @@ async def auto_heal_code(run_target: str, mode: str = "script", max_attempts: in
280268 print (f" File Path: { file_path } " )
281269 print (f" Function Name: { function_name } " )
282270 print (f" Error Message: { error_msg } " )
283-
284271 payload = IssuePayload (
285272 file_path = file_path ,
286273 function_name = function_name ,
287274 error_log = error_msg
288275 )
289-
290276 print (f"Triggering repair for function '{ function_name } '..." )
291277 await heal_once (payload )
292278
293- # Respect Gemini Free Tier rate limits (RPM) by pausing between calls
294279 print ("Pausing for 8 seconds to stay under the API rate limit..." )
295280 await asyncio .sleep (8 )
296281
0 commit comments