from __future__ import annotations from dataclasses import dataclass from typing import Any from cockpit_agent.common.enums import ActionStatus, Interaction from cockpit_agent.common.schema import SchemaValidationError @dataclass(frozen=True) class MockAction: interaction: Interaction status: ActionStatus = ActionStatus.PROPOSED pixel: tuple[int, int] | None = None repeat: int | None = None start_pixel: tuple[int, int] | None = None end_pixel: tuple[int, int] | None = None reason: str | None = None def __post_init__(self) -> None: if self.interaction is Interaction.TAP: if self.pixel is None or self.repeat is None or self.repeat < 1: raise SchemaValidationError("tap action requires pixel and repeat") elif self.interaction is Interaction.DRAG: if self.start_pixel is None or self.end_pixel is None: raise SchemaValidationError( "drag action requires start_pixel and end_pixel" ) elif self.interaction is Interaction.NOOP and not self.reason: raise SchemaValidationError("noop action requires a reason") def to_dict(self) -> dict[str, Any]: value: dict[str, Any] = { "interaction": self.interaction.value, "status": self.status.value, } if self.pixel is not None: value["pixel"] = list(self.pixel) if self.repeat is not None: value["repeat"] = self.repeat if self.start_pixel is not None: value["start_pixel"] = list(self.start_pixel) if self.end_pixel is not None: value["end_pixel"] = list(self.end_pixel) if self.reason is not None: value["reason"] = self.reason return value