"""WeCom (企业微信) adapter — profile / window / postcondition helpers.""" from __future__ import annotations from typing import Any, Optional from .registry import register_adapter PROFILE_WECOM = "wecom" PROFILE_WECOM_SEARCH = "wecom_search" _THRESHOLDS = { PROFILE_WECOM: 80, PROFILE_WECOM_SEARCH: 20, } class WeComAdapter: name = "wecom" def matches( self, *, class_name: str = "", title: str = "", process_name: str = "" ) -> bool: return self.wake_profile(class_name=class_name, title=title) is not None or ( "WXWork" in (process_name or "") ) def wake_profile(self, *, class_name: str = "", title: str = "") -> Optional[str]: cls = (class_name or "").strip() title = title or "" if cls == "SearchResultWindow2": return PROFILE_WECOM_SEARCH if cls == "WeWorkWindow": return PROFILE_WECOM if "WeWork" in cls and ( "企业微信" in title or "WeCom" in title or "wecom" in title.lower() ): return PROFILE_WECOM return None def cache_key(self, *, profile: str, hwnd: int = 0) -> str: """Separate main window vs SearchResultWindow2 warm caches.""" return f"{profile}:hwnd:{int(hwnd or 0)}" def warm_threshold(self, profile: str) -> int: return int(_THRESHOLDS.get(profile, 80)) def is_search_popup(self, *, class_name: str = "") -> bool: return (class_name or "") == "SearchResultWindow2" def is_main_window(self, *, class_name: str = "") -> bool: return (class_name or "") == "WeWorkWindow" def known_ids(self) -> dict[str, str]: return { "searchedit": "search_box", "groupbuddyname": "contact_row_name", "search_name": "search_result_name", "send_rich_edit": "compose_box", "panel_title_label": "panel_title", } def propose_postconditions(self, changes: list[dict[str, Any]]) -> list[dict[str, Any]]: props: list[dict[str, Any]] = [] for ch in changes or []: kind = ch.get("kind") detail = ch.get("detail") or {} if kind == "popup_disappeared" and "SearchResult" in str( detail.get("class_name") or "" ): props.append( { "description": "SearchResultWindow2 disappeared", "kind": "window_absent", "status": "proposed", "detail": detail, } ) if kind == "element_appeared": name = str(detail.get("name") or detail.get("automation_id") or "") if name in {"send_rich_edit", "main_chattext", "panel_title_label"}: props.append( { "description": f"WeCom element {name} appeared", "kind": "element_present", "status": "proposed", "detail": detail, } ) if kind == "title_changed": props.append( { "description": f"Chat title became {detail.get('to')!r}", "kind": "title_equals", "status": "proposed", "detail": detail, } ) return props wecom_adapter = WeComAdapter() register_adapter(wecom_adapter)