import os import re import sys import httpx import asyncio import subprocess from github import Github from src.config import GH_TOKEN, TARGET_REPO from src.gemini_utils import call_gemini_with_retry async def analyze_pr_diff(diff_text: str) -> str: prompt = f""" You are the Nubenetes PR Guardian. Analyze this PR diff against the Nubenetes GEMINI.md mandates. Check for: 1. Are new links added using the high-density description standard? (No generic clickbait) 2. Are URLs normalized? (No tracking params) 3. Are there emojis in H2/H3 titles? (Should be rejected) If the PR looks good, say 'โ PR Meets Nubenetes Standards.' If it violates mandates, list the violations clearly so the contributor can fix them. PR Diff: {diff_text} """ try: # Mandate 50: Use Flash/Lite for rapid auditing and specify text format to avoid JSON parsing loops response = await call_gemini_with_retry(prompt, prefer_flash=True, response_format="text", role="PR-Guardian") await asyncio.sleep(1.0) # Safety delay to respect global RPM quota return str(response) except Exception as e: return f"โ ๏ธ Guardian AI temporarily unavailable: {e}" def auto_format_file(filepath: str): if not os.path.exists(filepath): return with open(filepath, "r", encoding="utf-8") as f: content = f.read() original_content = content # 1. Clean URLs from src.gemini_utils import normalize_url def repl_link(match): text = match.group(1) url = match.group(2) if url.startswith(("http://", "https://")): try: cleaned = normalize_url(url) return f"[{text}]({cleaned})" except: return match.group(0) return match.group(0) content = re.sub(r'\[([^\]]+)\]\((https?://[^\)]+)\)', repl_link, content) # 2. Clean headers (e.g., ampersands to "and", strip emojis) lines = content.splitlines() new_lines = [] for line in lines: if line.strip().startswith("#"): line = line.replace("&", "and") line = re.sub(r'[\U00010000-\U0010ffff]', '', line) for char in "๐ง โ๏ธ๐๐ก๏ธ๐งช๐๐ต๏ธโจโ ๏ธ๐ด๐กโ ๐๐ฅ": line = line.replace(char, "") line = re.sub(r'\s+', ' ', line).strip() match = re.match(r'^(#+)\s*(.*)', line) if match: level, title = match.groups() line = f"{level} {title.strip()}" new_lines.append(line) content = "\n".join(new_lines) + ("\n" if original_content.endswith("\n") else "") # 3. Clean