"""Expose the gesture model and safety configuration bundled with this project.""" from __future__ import annotations from pathlib import Path from typing import Any import yaml DEFAULT_ACTION_COPY = { "POINT_UP": {"action": "SEAT_UP", "utterance": "副驾驶座椅坐垫前端升高一点"}, "POINT_DOWN": {"action": "SEAT_DOWN", "utterance": "副驾驶座椅坐垫前端降低一点"}, "POINT_RIGHT": {"action": "SEAT_FORWARD", "utterance": "副驾驶座椅向前移动一点"}, "POINT_LEFT": {"action": "SEAT_BACKWARD", "utterance": "副驾驶座椅向后移动一点"}, "THUMB_UP": {"action": "BACKREST_FORWARD", "utterance": "副驾驶靠背向前调一点"}, "THUMB_DOWN": {"action": "BACKREST_BACKWARD", "utterance": "副驾驶靠背向后调一点"}, "GUN_UP": {"action": "LEGREST_EXTEND", "utterance": "副驾驶腿托伸出一点"}, "GUN_DOWN": {"action": "LEGREST_RETRACT", "utterance": "副驾驶腿托收回一点"}, "VICTORY_RIGHT": {"action": "LEGREST_EXTEND", "utterance": "副驾驶腿托伸出一点"}, "VICTORY_LEFT": {"action": "LEGREST_RETRACT", "utterance": "副驾驶腿托收回一点"}, } class GestureCapabilityBridge: """Expose the repository-owned gesture assets to the browser runtime.""" def __init__(self, repository_root: Path, asset_root: Path | None = None) -> None: self.repository_root = repository_root.resolve() self.asset_root = ( asset_root or self.repository_root / "apps" / "web-console" / "assets" / "gesture" ).resolve() self.config_path = self.repository_root / "config" / "gesture" / "default.yaml" self.model_path = self.asset_root / "gesture_recognizer.task" @property def available(self) -> bool: return self.config_path.is_file() and self.model_path.is_file() def runtime_info(self) -> dict[str, Any]: recognition: dict[str, Any] = {} if self.config_path.is_file(): try: payload = yaml.safe_load(self.config_path.read_text(encoding="utf-8")) or {} recognition = dict(payload.get("recognition", {})) except (OSError, TypeError, ValueError, yaml.YAMLError): recognition = {} defaults = { "action_hold_ms": 600, "min_action_frames": 8, "arm_hold_ms": 1000, "armed_idle_timeout_ms": 3000, "max_continuous_motion_ms": 1500, "neutral_release_ms": 350, } safety = {name: int(recognition.get(name, value)) for name, value in defaults.items()} return { "available": self.available, "model_available": self.model_path.is_file(), "source": "cognitive-agent-bundled-assets", "asset_strategy": "bundled", "safety": safety, "actions": DEFAULT_ACTION_COPY, }