@@ -90,6 +90,23 @@ def _is_internal_compiler_error(error_message: str) -> bool:
9090 return bool (_INTERNAL_COMPILER_ERROR_PATTERN .search (error_message ))
9191
9292
93+ def _errors_are_equivalent (err1 : Optional [str ], err2 : Optional [str ]) -> bool :
94+ """Check if two validation errors are essentially identical.
95+
96+ Compares normalized error text to detect when the AI is producing
97+ the same failing code across retry attempts (likely a compiler bug,
98+ not a fixable code issue).
99+ """
100+ if not err1 or not err2 :
101+ return False
102+ # Normalize: strip whitespace, collapse spaces, remove file:line:col refs
103+ def normalize (s : str ) -> str :
104+ s = re .sub (r'-->\s*\S+:\d+:\d+' , '' , s ) # Remove file:line:col
105+ s = re .sub (r'\s+' , ' ' , s ).strip ()
106+ return s
107+ return normalize (err1 ) == normalize (err2 )
108+
109+
93110class IterationStatus (Enum ):
94111 """Status of a dogfooding iteration."""
95112
@@ -1066,6 +1083,7 @@ async def _generate_and_validate_code(
10661083 last_code : Optional [str ] = None
10671084 last_raw_output : Optional [str ] = None
10681085 last_error : Optional [str ] = None
1086+ previous_error : Optional [str ] = None
10691087 total_duration = 0.0
10701088 backend_used : Optional [str ] = None
10711089
@@ -1183,6 +1201,21 @@ async def _generate_and_validate_code(
11831201 f" Pre-validation failed: { prevalidation_error } " , file = sys .stderr
11841202 )
11851203 last_error = f"Pre-validation error: { prevalidation_error } "
1204+ if _errors_are_equivalent (last_error , previous_error ):
1205+ print (
1206+ f" Same error on consecutive attempts — likely a compiler limitation. Stopping retries." ,
1207+ file = sys .stderr ,
1208+ )
1209+ return GenerationResult (
1210+ success = False ,
1211+ code = code ,
1212+ expected_output = extract_expected_output_from_response (gen_result .output ),
1213+ skip_reason = f"Repeated identical error (likely compiler bug): { prevalidation_error } " ,
1214+ backend_used = backend_used ,
1215+ generation_duration = total_duration ,
1216+ attempts = attempt ,
1217+ )
1218+ previous_error = last_error
11861219 if attempt < max_attempts :
11871220 print (
11881221 f" Will retry with feedback ({ attempt } /{ max_attempts } )..." ,
@@ -1225,6 +1258,21 @@ async def _generate_and_validate_code(
12251258 file = sys .stderr ,
12261259 )
12271260 last_error = f"Sharpy compiler error: { semantic_error } "
1261+ if _errors_are_equivalent (last_error , previous_error ):
1262+ print (
1263+ f" Same error on consecutive attempts — likely a compiler limitation. Stopping retries." ,
1264+ file = sys .stderr ,
1265+ )
1266+ return GenerationResult (
1267+ success = False ,
1268+ code = code ,
1269+ expected_output = extract_expected_output_from_response (gen_result .output ),
1270+ skip_reason = f"Repeated identical compiler error (likely compiler bug): { semantic_error } " ,
1271+ backend_used = backend_used ,
1272+ generation_duration = total_duration ,
1273+ attempts = attempt ,
1274+ )
1275+ previous_error = last_error
12281276 if attempt < max_attempts :
12291277 print (
12301278 f" Will retry with feedback ({ attempt } /{ max_attempts } )..." ,
@@ -1355,6 +1403,7 @@ async def _generate_and_validate_multifile_code(
13551403 max_attempts = self .config .max_regeneration_attempts
13561404 last_files : Optional [dict [str , str ]] = None
13571405 last_error : Optional [str ] = None
1406+ previous_error : Optional [str ] = None
13581407 total_duration = 0.0
13591408 backend_used : Optional [str ] = None
13601409
@@ -1486,6 +1535,21 @@ async def _generate_and_validate_multifile_code(
14861535 break
14871536
14881537 if prevalidation_failed :
1538+ if _errors_are_equivalent (last_error , previous_error ):
1539+ print (
1540+ f" Same error on consecutive attempts — likely a compiler limitation. Stopping retries." ,
1541+ file = sys .stderr ,
1542+ )
1543+ return MultifileGenerationResult (
1544+ success = False ,
1545+ files = files ,
1546+ expected_output = extract_expected_output_from_multifile (files ),
1547+ skip_reason = f"Repeated identical error (likely compiler bug): { last_error } " ,
1548+ backend_used = backend_used ,
1549+ generation_duration = total_duration ,
1550+ attempts = attempt ,
1551+ )
1552+ previous_error = last_error
14891553 if attempt < max_attempts :
14901554 print (
14911555 f" Will retry with feedback ({ attempt } /{ max_attempts } )..." ,
@@ -1528,6 +1592,21 @@ async def _generate_and_validate_multifile_code(
15281592 file = sys .stderr ,
15291593 )
15301594 last_error = f"Sharpy compiler error: { semantic_error } "
1595+ if _errors_are_equivalent (last_error , previous_error ):
1596+ print (
1597+ f" Same error on consecutive attempts — likely a compiler limitation. Stopping retries." ,
1598+ file = sys .stderr ,
1599+ )
1600+ return MultifileGenerationResult (
1601+ success = False ,
1602+ files = files ,
1603+ expected_output = extract_expected_output_from_multifile (files ),
1604+ skip_reason = f"Repeated identical compiler error (likely compiler bug): { semantic_error } " ,
1605+ backend_used = backend_used ,
1606+ generation_duration = total_duration ,
1607+ attempts = attempt ,
1608+ )
1609+ previous_error = last_error
15311610 if attempt < max_attempts :
15321611 print (
15331612 f" Will retry with feedback ({ attempt } /{ max_attempts } )..." ,
0 commit comments