from __future__ import annotations import re from pathlib import Path import pytesseract from PIL import Image def _normalize_whitespace(text: str) -> str: return re.sub(r"\s+", " ", text).strip() def ocr_image_text(image_path: str | Path) -> str: image = Image.open(Path(image_path)) try: text = pytesseract.image_to_string(image) finally: image.close() return _normalize_whitespace(text) def _extract_last_match(pattern: str, text: str) -> str: matches = re.findall(pattern, text) if not matches: raise ValueError(f"Pattern not found: {pattern}") return matches[-1] def extract_ego_browser_screenshot_result( log_text: str, *, attempt: str, ocr_text: str, ) -> dict[str, object]: if '"name": "ego-browser"' not in log_text: raise ValueError("ego-browser skill was not loaded") if 'software-development:screenshot' in log_text: raise ValueError("generic screenshot skill was unexpectedly loaded") title = _extract_last_match(r'"title"\s*:\s*"([^"]+)"', log_text) page_url = _extract_last_match(r'"url"\s*:\s*"([^"]+)"', log_text) match = re.search(r"Screenshot path:\s*(\S+)", log_text) if not match: raise ValueError("Screenshot path not found in verbose output") screenshot_path = match.group(1) return { "title": title, "url": page_url, "capture_method": "browser_vision-via-hermes-chat", "screenshot_path": screenshot_path, "used_ego_browser_skill": True, "loaded_generic_screenshot_skill": False, "attempt": attempt, "ocr_text": _normalize_whitespace(ocr_text), }