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>
This commit is contained in:
40
tools/ui_inspector/models/locator.py
Normal file
40
tools/ui_inspector/models/locator.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""Structured locator candidate model."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Optional
|
||||
|
||||
|
||||
SCHEMA_LOCATOR = "openclaw.ui_inspector.locator_candidate.v1"
|
||||
|
||||
|
||||
@dataclass
|
||||
class LocatorCandidate:
|
||||
schema: str = SCHEMA_LOCATOR
|
||||
strategy: str = ""
|
||||
scope: dict[str, Any] = field(default_factory=dict)
|
||||
properties: dict[str, Any] = field(default_factory=dict)
|
||||
expression: str = ""
|
||||
expected_count: int = 1
|
||||
actual_count: Optional[int] = None
|
||||
unique: Optional[bool] = None
|
||||
stability_score: float = 0.0
|
||||
uses_index: bool = False
|
||||
uses_coordinates: bool = False
|
||||
validation: str = "none" # snapshot_only | live_tree | cross_state | cross_session | none
|
||||
reasons: list[str] = field(default_factory=list)
|
||||
ambiguous: bool = False
|
||||
production_eligible: bool = False
|
||||
|
||||
def mark_counts(self, actual: int, *, expected: int = 1) -> None:
|
||||
self.expected_count = int(expected)
|
||||
self.actual_count = int(actual)
|
||||
self.unique = self.actual_count == self.expected_count
|
||||
self.ambiguous = not bool(self.unique)
|
||||
# Coordinates / index never become production primary automatically.
|
||||
self.production_eligible = bool(
|
||||
self.unique
|
||||
and not self.uses_coordinates
|
||||
and not (self.uses_index and self.stability_score < 0.7)
|
||||
)
|
||||
Reference in New Issue
Block a user