""" Error classifier - identifies error categories from tracebacks/output. Used by repair engine to produce targeted repair plans. """ from __future__ import annotations import re from dataclasses import dataclass from typing import Optional @dataclass class ErrorClass: category: str detail: str suggested_fix: str RULES = [ # python module / pip (r"ModuleNotFoundError: No module named ['\"]([\w\.\-]+)['\"]", "missing_python_module"), (r"ImportError: No module named ([\w\.\-]+)", "missing_python_module"), (r"pip(?:3)?: command not found", "missing_pip"), # node / npm (r"command not found: (npm|node|npx)", "missing_node"), (r"npm ERR! code E?ENOENT", "npm_failure"), (r"npm ERR! code (E\w+)", "npm_failure"), # playwright (r"playwright[^\s]*: command not found", "missing_playwright"), (r"Executable doesn't exist at .+(chrom|firefox|webkit)", "playwright_browsers_missing"), (r"BrowserType\.launch:.*Host system is missing dependencies", "playwright_missing_deps"), # git (r"fatal: unable to auto-detect email address", "git_identity_missing"), (r"Please tell me who you are\.", "git_identity_missing"), (r"fatal: not a git repository", "not_a_git_repo"), (r"Authentication failed", "git_auth_failed"), # python version / build (r"greenlet[^\n]*failed to build", "greenlet_build_failure"), (r"Could not build wheels for ([\w\-]+)", "python_build_failure"), (r"requires Python ['\"][^'\"]+['\"]", "python_version_mismatch"), # network (r"Could not resolve host", "network_failure"), (r"Connection refused", "network_failure"), (r"Read timed out", "network_failure"), # http (r"\b429\b", "rate_limited"), (r"\b401\b|\b403\b", "auth_failure"), ] def classify(output: str) -> Optional[ErrorClass]: if not output: return None for pattern, category in RULES: m = re.search(pattern, output) if m: detail = m.group(0) return ErrorClass(category=category, detail=detail, suggested_fix=_fix_for(category, m)) # Generic exception detection if "Traceback (most recent call last):" in output: return ErrorClass(category="python_exception", detail="Unclassified Python exception", suggested_fix="inspect traceback and retry") return None def _fix_for(category: str, m: re.Match) -> str: if category == "missing_python_module": return f"pip install {m.group(1)}" if category == "missing_pip": return "ensure python3-pip is installed" if category == "missing_node": return "install node + npm" if category == "npm_failure": return "delete node_modules and reinstall" if category == "missing_playwright": return "pip install playwright && python -m playwright install" if category == "playwright_browsers_missing": return "python -m playwright install chromium" if category == "playwright_missing_deps": return "python -m playwright install-deps chromium" if category == "git_identity_missing": return "git config user.email and user.name" if category == "not_a_git_repo": return "git init or cd into repo" if category == "git_auth_failed": return "verify GITHUB_TOKEN and remote URL" if category == "greenlet_build_failure": return "pin Python 3.11 and install build essentials" if category == "python_build_failure": return "install build-essential and retry" if category == "python_version_mismatch": return "use Python 3.11" if category == "network_failure": return "retry after backoff" if category == "rate_limited": return "rotate provider key or wait" if category == "auth_failure": return "rotate API key" return "retry"