57 lines
1.6 KiB
Python
57 lines
1.6 KiB
Python
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),
|
|
}
|