GUI-Swift-Mobile-2B / runtime /trace2task /mobile133_protocol.py
dongjintao's picture
Release GUI-Swift-Mobile-2B: Mobile105 SFT step4658
b7fc81a verified
Raw History Blame Contribute Delete
2.98 kB
"""Versioned mobile semantics; no model, device or frozen codec changes on import."""
import math
from dataclasses import asdict, dataclass
LEGACY_PROTOCOL = "gui-owl-unified133-desktop-android-historybins-v1"
PROTOCOL = "gui-owl-unified133-mobile-semantics-v2"
SCHEMA = "unified133-mobile-subgoal-sft-v2"
DIRECTIONS = ("up", "down", "left", "right")
ANDROID_WORLD_REVISION = "55ddaf5edc6f6c25673aed343907d5b9dca66f84"
@dataclass(frozen=True)
class MobileExecutionConfig:
"""Runtime policy, never a claim about missing demonstration durations.
AndroidWorld uses 1 second for wait and long press. Its directional scroll
leaves duration to Android's input command. Coordinate swipe stays on the
frozen executor's explicit 800 ms path.
"""
protocol: str = PROTOCOL
wait_seconds: float = 1.0
long_press_seconds: float = 1.0
scroll_duration_ms: int | None = None
scroll_geometry: str = "androidworld-screen-center-to-edge"
reference_revision: str = ANDROID_WORLD_REVISION
def __post_init__(self):
if self.protocol != PROTOCOL:
raise ValueError("execution_protocol_mismatch")
for value in (self.wait_seconds, self.long_press_seconds):
if (
type(value) not in (int, float)
or not math.isfinite(value)
or not 0 < value <= 999.99
):
raise ValueError("invalid_execution_default_duration")
if self.scroll_duration_ms is not None and (
type(self.scroll_duration_ms) is not int or not 1 <= self.scroll_duration_ms <= 999990
):
raise ValueError("invalid_scroll_duration")
if self.scroll_geometry != "androidworld-screen-center-to-edge":
raise ValueError("unknown_scroll_geometry")
if self.reference_revision != ANDROID_WORLD_REVISION:
raise ValueError("execution_reference_mismatch")
def as_dict(self):
return asdict(self)
def direction_scroll_argv(direction, size, config):
"""Small argv-only adapter for pinned AndroidWorld execute_adb_action(scroll).
Apache-2.0 reference: third_party/android_world_mobile_reference. The full
executor imports AndroidEnv/ADB services and also changes text-entry semantics;
only this GUI primitive is adapted. Endpoints are runtime geometry, not labels.
"""
if direction not in DIRECTIONS:
raise ValueError("invalid_scroll_direction")
if len(size) != 2 or any(type(v) is not int or v <= 0 for v in size):
raise ValueError("invalid_screen_size")
width, height = size
start = [width // 2, height // 2]
ends = {
"down": [width // 2, 0],
"up": [width // 2, height],
"right": [0, height // 2],
"left": [width, height // 2],
}
argv = ["input", "swipe", *map(str, start + ends[direction])]
if config.scroll_duration_ms is not None:
argv.append(str(config.scroll_duration_ms))
return argv