Files
agentic-mobile-control/tools/find_text.py
T

60 lines
1.5 KiB
Python

from __future__ import annotations
from core.models import Scene, SceneElement
from device.manager import DeviceManager
from tools.describe_screen import describe_screen
def find_text(
scene: Scene,
query: str,
*,
exact: bool = False,
case_sensitive: bool = False,
) -> dict[str, object]:
match = _find_element(scene, query, exact=exact, case_sensitive=case_sensitive)
if not match:
return {"found": False, "query": query, "reason": "not found"}
x, y = match.center
return {
"found": True,
"query": query,
"x": x,
"y": y,
"element": match.to_dict(),
}
def find_text_on_screen(
query: str,
*,
device_id: str | None = None,
manager: DeviceManager | None = None,
exact: bool = False,
case_sensitive: bool = False,
) -> dict[str, object]:
return find_text(
describe_screen(device_id, manager=manager),
query,
exact=exact,
case_sensitive=case_sensitive,
)
def _find_element(
scene: Scene,
query: str,
*,
exact: bool,
case_sensitive: bool,
) -> SceneElement | None:
needle = query if case_sensitive else query.casefold()
for element in scene.elements:
if not element.text:
continue
haystack = element.text if case_sensitive else element.text.casefold()
matched = haystack == needle if exact else needle in haystack
if matched:
return element
return None