Files
screen-leads-app/agent/scroller.py
T
bhushanct 511e36b660 Add auto-advance: click Next, scroll to top, capture next page
After each capture the controller asks the vision model to locate a 'Next'
control (returned as normalized screen coordinates), clicks it via OS input,
scrolls to top, and continues the loop. Configurable via SCREEN_LEADS_AUTO_NEXT
/ _NEXT_LOAD_PAUSE / _MAX_AUTO_NEXT, with a per-run safety cap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 07:56:13 +05:30

58 lines
1.5 KiB
Python

"""OS-level scrolling of the focused window via pyautogui.
We drive real scroll input rather than the DOM, so it works over a plain
screenshot pipeline on any OS. Needs Accessibility permission on macOS and an
X11 session on Linux.
"""
from __future__ import annotations
import time
from config import SCROLL_AMOUNT, SCROLL_PAUSE
class ScrollError(RuntimeError):
pass
def _pyautogui():
try:
import pyautogui
pyautogui.FAILSAFE = False
return pyautogui
except Exception as e: # pragma: no cover
raise ScrollError(
f"pyautogui not available ({e}). On macOS grant Accessibility; "
f"on Linux use X11."
)
def scroll_to_top() -> None:
pg = _pyautogui()
# A large upward scroll reliably returns most pages to the top.
for _ in range(10):
pg.scroll(SCROLL_AMOUNT)
time.sleep(SCROLL_PAUSE)
def scroll_down(amount: int = SCROLL_AMOUNT) -> None:
pg = _pyautogui()
pg.scroll(-abs(amount))
time.sleep(SCROLL_PAUSE)
def click_at_fraction(x_frac: float, y_frac: float) -> None:
"""Click at a position given as fractions (0..1) of the logical screen.
Fractions are resolution- and Retina-independent: pyautogui reports the
logical screen size, and the capture covers the same primary display, so a
fraction of the screenshot maps directly to a fraction of the screen.
"""
pg = _pyautogui()
w, h = pg.size()
x = int(max(0.0, min(1.0, x_frac)) * w)
y = int(max(0.0, min(1.0, y_frac)) * h)
pg.moveTo(x, y, duration=0.2)
pg.click()