Files
skill-template/tools/ui_inspector/skip_policy.py
chendelian 633ecff4e2 chore: archive tools/ui_inspector snapshot before migration removal.
Keep the last in-template copy on main so history can restore it; product continues in jiangchang-ui-recorder.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 11:19:14 +08:00

90 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Decide whether a dump is blank/empty-shell and should not become a flow step.
Only applied to browser surface. Does NOT skip same-URL scrolls
(content may change without URL change).
"""
from __future__ import annotations
from typing import Any, Optional
import target
# Locatable below this counts as "no useful candidates"
_MIN_LOCATABLE = 3
# Tree/index tiny enough to treat as empty shell
_MAX_EMPTY_NODES = 2
def _norm_url(url: str) -> str:
return (url or "").strip()
def is_blankish_url(url: str) -> bool:
u = _norm_url(url).lower()
if not u:
return True
if u == "about:blank" or u.startswith("about:blank?"):
return True
if u in {"about:srcdoc", "about:newtab"}:
return True
if u.startswith("chrome://newtab") or u.startswith("chrome://new-tab-page"):
return True
if u.startswith("edge://newtab") or u.startswith("edge://new-tab-page"):
return True
return False
def should_skip_empty_dump(
*,
surface: str,
url: str = "",
locatable_count: Optional[int] = None,
nodes_kept: Optional[int] = None,
sparse: bool = False,
locatable: Optional[list[dict[str, Any]]] = None,
stats: Optional[dict[str, Any]] = None,
) -> Optional[str]:
"""Return skip reason code, or None if the dump should be kept.
Safe rules (browser only):
- blank/newtab URL **and** almost no locatable → skip
- tiny tree + sparse/blankish + almost no locatable → skip
A page with about:blank URL but rich locatable (nav race) is **kept**.
"""
if surface != target.SURFACE_BROWSER:
return None
st = stats or {}
if locatable_count is None:
if locatable is not None:
locatable_count = len(locatable)
else:
locatable_count = int(st.get("locatable_count") or 0)
if nodes_kept is None:
nodes_kept = int(st.get("nodes_kept") or st.get("findall_count") or 0)
if not sparse:
sparse = bool(st.get("uia_sparse"))
loc_n = int(locatable_count or 0)
kept = int(nodes_kept or 0)
blankish = is_blankish_url(url)
if blankish and loc_n < _MIN_LOCATABLE:
return "blank_or_newtab_empty"
if loc_n < _MIN_LOCATABLE and kept <= _MAX_EMPTY_NODES and (sparse or blankish):
return "empty_shell"
return None
def skip_reason_text(reason: str, *, url: str = "") -> str:
u = _norm_url(url) or "(empty)"
if reason == "blank_or_newtab_empty":
return f"跳过空页:url={u!r} 且可定位候选过少(blank/新标签页)。"
if reason == "empty_shell":
return f"跳过空壳页:url={u!r} 节点过少且 sparse。"
return f"跳过本拍:{reason} url={u!r}"