From f41a5579cbc69feec8791acbdbdc17695fee7eac Mon Sep 17 00:00:00 2001 From: Vic <125237471+vicsanity623@users.noreply.github.com> Date: Sat, 21 Mar 2026 12:30:19 -0700 Subject: [PATCH 1/2] Update reviewer_mixins.py --- src/pyob/reviewer_mixins.py | 44 ++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/pyob/reviewer_mixins.py b/src/pyob/reviewer_mixins.py index 3475f24..db72483 100644 --- a/src/pyob/reviewer_mixins.py +++ b/src/pyob/reviewer_mixins.py @@ -244,6 +244,14 @@ def _fix_runtime_errors( self, logs: str, entry_file: str, context_of_change: str = "" ): """Detects crashes. Handles missing packages automatically, otherwise asks AI.""" + + # --- 0. SANITIZE TARGET --- + # Prevent the bot from hallucinating log headers as filenames + if entry_file == "Validation Suite" or "Validation Suite" in entry_file: + # Fallback to searching for a real file in the logs or use the project main + found_file = getattr(self, "_find_entry_file")() + entry_file = found_file if found_file else "main.js" + package_match = re.search(r"ModuleNotFoundError: No module named '(.*?)'", logs) if not package_match: package_match = re.search(r"ImportError: No module named '(.*?)'", logs) @@ -312,20 +320,40 @@ def _fix_runtime_errors( except subprocess.CalledProcessError as e: logger.error(f"Failed to install {pkg} automatically: {e}") + # --- 1. SMART FILE IDENTIFICATION --- + # Look for Python tracebacks first tb_files = re.findall(r'File "([^"]+)"', logs) + + # NEW: Look for JavaScript/HTML filenames if Python search fails + if not tb_files: + tb_files = re.findall(r"([\w\-/]+\.(?:js|html|css))", logs) + target_file = entry_file for f in reversed(tb_files): - abs_f = os.path.abspath(f) + # Block the "Validation Suite" hallucination here too + if "Validation Suite" in f: + continue + + abs_f = os.path.abspath(f) if os.path.isabs(f) else os.path.join(self.target_dir, f) + if ( abs_f.startswith(self.target_dir) - and not any(ign in abs_f for ign in IGNORE_DIRS) + and not any(ign in abs_f for ign in getattr(self, "IGNORE_DIRS", [])) and os.path.exists(abs_f) ): target_file = abs_f break + + # Ensure we have a valid path before proceeding + if not os.path.exists(target_file): + target_file = entry_file + rel_path = os.path.relpath(target_file, self.target_dir) - with open(target_file, "r", encoding="utf-8") as f_obj: + + # --- 2. LOAD CODE AND PROMPT --- + with open(target_file, "r", encoding="utf-8", errors="ignore") as f_obj: code = f_obj.read() + if context_of_change: logger.info( f"Applying CONTEXT-AWARE fix for runtime crash in `{rel_path}`..." @@ -340,8 +368,8 @@ def _fix_runtime_errors( else: logger.info(f"Applying standard fix for runtime crash in `{rel_path}`...") memory_section = ( - f"### Project Memory / Context:\n{self.memory}\n\n" - if self.memory + f"### Project Memory / Context:\n{getattr(self, 'memory', '')}\n\n" + if getattr(self, "memory", None) else "" ) prompt = getattr(self, "load_prompt")( @@ -351,9 +379,12 @@ def _fix_runtime_errors( rel_path=rel_path, code=code, ) + + # --- 3. EXECUTE REPAIR --- new_code, explanation, _ = getattr(self, "get_valid_edit")( prompt, code, require_edit=True, target_filepath=target_file ) + if new_code != code: with open(target_file, "w", encoding="utf-8") as f_out: f_out.write(new_code) @@ -361,7 +392,8 @@ def _fix_runtime_errors( self.session_context.append( f"Auto-fixed runtime crash in `{rel_path}`: {explanation}" ) - self.run_linter_fix_loop() + if hasattr(self, "run_linter_fix_loop"): + self.run_linter_fix_loop() def check_downstream_breakages(self, target_path: str, rel_path: str) -> bool: logger.info( From e5743eac83cbe5871186d39fd5317c2329d4de2c Mon Sep 17 00:00:00 2001 From: vicsanity623 <125237471+vicsanity623@users.noreply.github.com> Date: Sat, 21 Mar 2026 19:30:50 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=AA=84=20PyOB:=20Automated=20Lint=20&?= =?UTF-8?q?=20Format=20Fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pyob/reviewer_mixins.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/pyob/reviewer_mixins.py b/src/pyob/reviewer_mixins.py index db72483..bc8a7f2 100644 --- a/src/pyob/reviewer_mixins.py +++ b/src/pyob/reviewer_mixins.py @@ -244,7 +244,7 @@ def _fix_runtime_errors( self, logs: str, entry_file: str, context_of_change: str = "" ): """Detects crashes. Handles missing packages automatically, otherwise asks AI.""" - + # --- 0. SANITIZE TARGET --- # Prevent the bot from hallucinating log headers as filenames if entry_file == "Validation Suite" or "Validation Suite" in entry_file: @@ -323,7 +323,7 @@ def _fix_runtime_errors( # --- 1. SMART FILE IDENTIFICATION --- # Look for Python tracebacks first tb_files = re.findall(r'File "([^"]+)"', logs) - + # NEW: Look for JavaScript/HTML filenames if Python search fails if not tb_files: tb_files = re.findall(r"([\w\-/]+\.(?:js|html|css))", logs) @@ -333,9 +333,13 @@ def _fix_runtime_errors( # Block the "Validation Suite" hallucination here too if "Validation Suite" in f: continue - - abs_f = os.path.abspath(f) if os.path.isabs(f) else os.path.join(self.target_dir, f) - + + abs_f = ( + os.path.abspath(f) + if os.path.isabs(f) + else os.path.join(self.target_dir, f) + ) + if ( abs_f.startswith(self.target_dir) and not any(ign in abs_f for ign in getattr(self, "IGNORE_DIRS", [])) @@ -343,17 +347,17 @@ def _fix_runtime_errors( ): target_file = abs_f break - + # Ensure we have a valid path before proceeding if not os.path.exists(target_file): target_file = entry_file rel_path = os.path.relpath(target_file, self.target_dir) - + # --- 2. LOAD CODE AND PROMPT --- with open(target_file, "r", encoding="utf-8", errors="ignore") as f_obj: code = f_obj.read() - + if context_of_change: logger.info( f"Applying CONTEXT-AWARE fix for runtime crash in `{rel_path}`..." @@ -384,7 +388,7 @@ def _fix_runtime_errors( new_code, explanation, _ = getattr(self, "get_valid_edit")( prompt, code, require_edit=True, target_filepath=target_file ) - + if new_code != code: with open(target_file, "w", encoding="utf-8") as f_out: f_out.write(new_code)