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:
119
tools/ui_inspector/models/action.py
Normal file
119
tools/ui_inspector/models/action.py
Normal file
@@ -0,0 +1,119 @@
|
||||
"""ActionRecord + ActionFlow models."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Any, Optional
|
||||
|
||||
SCHEMA_ACTION = "openclaw.ui_inspector.action.v1"
|
||||
SCHEMA_ACTION_FLOW = "openclaw.ui_inspector.action_flow.v1"
|
||||
|
||||
# Full vocabulary — capability flags live elsewhere for unimplemented types.
|
||||
ACTION_TYPES: tuple[str, ...] = (
|
||||
"click",
|
||||
"double_click",
|
||||
"right_click",
|
||||
"fill",
|
||||
"type",
|
||||
"clear",
|
||||
"press_key",
|
||||
"hotkey",
|
||||
"select",
|
||||
"toggle",
|
||||
"hover",
|
||||
"scroll",
|
||||
"drag_drop",
|
||||
"focus",
|
||||
"window_switch",
|
||||
"navigation",
|
||||
"checkpoint",
|
||||
"wait",
|
||||
"verify",
|
||||
"unknown",
|
||||
)
|
||||
|
||||
# Capability status for this Inspector release.
|
||||
ACTION_CAPABILITY: dict[str, str] = {
|
||||
"click": "implemented",
|
||||
"double_click": "schema_only",
|
||||
"right_click": "schema_only",
|
||||
"fill": "implemented",
|
||||
"type": "implemented", # aggregated into fill/type
|
||||
"clear": "schema_only",
|
||||
"press_key": "implemented",
|
||||
"hotkey": "schema_only",
|
||||
"select": "schema_only",
|
||||
"toggle": "schema_only",
|
||||
"hover": "schema_only",
|
||||
"scroll": "schema_only",
|
||||
"drag_drop": "schema_only",
|
||||
"focus": "schema_only",
|
||||
"window_switch": "schema_only",
|
||||
"navigation": "partial",
|
||||
"checkpoint": "implemented",
|
||||
"wait": "schema_only",
|
||||
"verify": "schema_only",
|
||||
"unknown": "fallback",
|
||||
}
|
||||
|
||||
|
||||
def _now_iso() -> str:
|
||||
return datetime.now().astimezone().isoformat()
|
||||
|
||||
|
||||
def _new_id(prefix: str = "act") -> str:
|
||||
return f"{prefix}_{uuid.uuid4().hex[:12]}"
|
||||
|
||||
|
||||
@dataclass
|
||||
class ActionRecord:
|
||||
schema: str = SCHEMA_ACTION
|
||||
id: str = field(default_factory=lambda: _new_id("act"))
|
||||
sequence: int = 0
|
||||
action_type: str = "unknown"
|
||||
started_at: str = field(default_factory=_now_iso)
|
||||
ended_at: Optional[str] = None
|
||||
surface: str = "windows"
|
||||
target_element_id: Optional[str] = None
|
||||
target_snapshot: dict[str, Any] = field(default_factory=dict)
|
||||
input: dict[str, Any] = field(default_factory=dict)
|
||||
sensitive: bool = False
|
||||
before_state_id: Optional[str] = None
|
||||
after_state_id: Optional[str] = None
|
||||
before_observation_id: Optional[str] = None
|
||||
after_observation_id: Optional[str] = None
|
||||
observed_changes: list[dict[str, Any]] = field(default_factory=list)
|
||||
proposed_postconditions: list[dict[str, Any]] = field(default_factory=list)
|
||||
status: str = "ok" # ok | partial | failed | skipped
|
||||
confidence: float = 0.0
|
||||
evidence: dict[str, Any] = field(default_factory=dict)
|
||||
raw_event: dict[str, Any] = field(default_factory=dict)
|
||||
raw_event_ids: list[str] = field(default_factory=list)
|
||||
capability: str = ""
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if self.action_type not in ACTION_TYPES:
|
||||
self.action_type = "unknown"
|
||||
if not self.capability:
|
||||
self.capability = ACTION_CAPABILITY.get(self.action_type, "schema_only")
|
||||
|
||||
|
||||
@dataclass
|
||||
class ActionFlow:
|
||||
schema: str = SCHEMA_ACTION_FLOW
|
||||
flow_id: str = ""
|
||||
flow_name: str = ""
|
||||
created_at: str = field(default_factory=_now_iso)
|
||||
ended_at: Optional[str] = None
|
||||
states: list[str] = field(default_factory=list) # state ids in order seen
|
||||
observations: list[str] = field(default_factory=list) # every concrete capture
|
||||
actions: list[str] = field(default_factory=list) # action ids in sequence
|
||||
elements: list[str] = field(default_factory=list) # element ids
|
||||
entry_state_id: Optional[str] = None
|
||||
final_state_id: Optional[str] = None
|
||||
metadata: dict[str, Any] = field(default_factory=dict)
|
||||
recording_mode: str = "auto" # auto | guided | checkpoint | legacy_interval
|
||||
surface: str = ""
|
||||
status: str = "open"
|
||||
Reference in New Issue
Block a user