refactor: simplify to see/interact/exec and split server modules
All checks were successful
python-syntax / syntax-check (push) Successful in 6s
All checks were successful
python-syntax / syntax-check (push) Successful in 6s
This commit is contained in:
124
server/models.py
Normal file
124
server/models.py
Normal file
@@ -0,0 +1,124 @@
|
||||
from typing import Literal, Optional
|
||||
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
|
||||
class PixelTarget(BaseModel):
|
||||
mode: Literal["pixel"]
|
||||
x: int
|
||||
y: int
|
||||
dx: int = 0
|
||||
dy: int = 0
|
||||
|
||||
|
||||
class GridTarget(BaseModel):
|
||||
mode: Literal["grid"]
|
||||
region_x: int
|
||||
region_y: int
|
||||
region_width: int = Field(gt=0)
|
||||
region_height: int = Field(gt=0)
|
||||
rows: int = Field(gt=0)
|
||||
cols: int = Field(gt=0)
|
||||
row: int = Field(ge=0)
|
||||
col: int = Field(ge=0)
|
||||
dx: float = 0.0
|
||||
dy: float = 0.0
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _validate_indices(self):
|
||||
if self.row >= self.rows or self.col >= self.cols:
|
||||
raise ValueError("row/col must be inside rows/cols")
|
||||
if not -1.0 <= self.dx <= 1.0:
|
||||
raise ValueError("dx must be in [-1, 1]")
|
||||
if not -1.0 <= self.dy <= 1.0:
|
||||
raise ValueError("dy must be in [-1, 1]")
|
||||
return self
|
||||
|
||||
|
||||
Target = PixelTarget | GridTarget
|
||||
|
||||
|
||||
class ActionRequest(BaseModel):
|
||||
action: Literal[
|
||||
"move",
|
||||
"click",
|
||||
"right_click",
|
||||
"double_click",
|
||||
"middle_click",
|
||||
"scroll",
|
||||
"type",
|
||||
"hotkey",
|
||||
]
|
||||
target: Optional[Target] = None
|
||||
duration_ms: int = Field(default=0, ge=0, le=20000)
|
||||
button: Literal["left", "right", "middle"] = "left"
|
||||
clicks: int = Field(default=1, ge=1, le=10)
|
||||
scroll_amount: int = 0
|
||||
text: str = ""
|
||||
keys: list[str] = Field(default_factory=list)
|
||||
interval_ms: int = Field(default=20, ge=0, le=5000)
|
||||
dry_run: bool = False
|
||||
|
||||
|
||||
class ExecRequest(BaseModel):
|
||||
command: str = Field(min_length=1, max_length=10000)
|
||||
shell: Literal["powershell", "bash", "cmd"] | None = None
|
||||
timeout_s: int | None = Field(default=None, ge=1, le=600)
|
||||
cwd: str | None = None
|
||||
dry_run: bool = False
|
||||
|
||||
|
||||
class WindowQuery(BaseModel):
|
||||
title_contains: str | None = Field(default=None, max_length=512)
|
||||
title_regex: str | None = Field(default=None, max_length=512)
|
||||
process_name: str | None = Field(default=None, max_length=260)
|
||||
hwnd: int | None = Field(default=None, ge=1)
|
||||
visible_only: bool = True
|
||||
|
||||
|
||||
class WindowActionRequest(WindowQuery):
|
||||
action: Literal["focus", "restore", "minimize", "maximize", "close"]
|
||||
timeout_ms: int = Field(default=3000, ge=0, le=60000)
|
||||
|
||||
|
||||
class LaunchRequest(BaseModel):
|
||||
executable: str = Field(min_length=1, max_length=2048)
|
||||
args: list[str] = Field(default_factory=list, max_length=100)
|
||||
cwd: str | None = None
|
||||
wait_for_window: bool = False
|
||||
match: WindowQuery | None = None
|
||||
timeout_ms: int = Field(default=5000, ge=0, le=120000)
|
||||
dry_run: bool = False
|
||||
|
||||
|
||||
class SeeRequest(BaseModel):
|
||||
screen: int = 0
|
||||
region_x: int | None = Field(default=None, ge=0)
|
||||
region_y: int | None = Field(default=None, ge=0)
|
||||
region_width: int | None = Field(default=None, gt=0)
|
||||
region_height: int | None = Field(default=None, gt=0)
|
||||
with_grid: bool = True
|
||||
grid_rows: int = Field(default=12, ge=1, le=300)
|
||||
grid_cols: int = Field(default=12, ge=1, le=300)
|
||||
include_labels: bool = True
|
||||
image_format: Literal["png", "jpeg"] = "png"
|
||||
jpeg_quality: int = Field(default=85, ge=1, le=100)
|
||||
|
||||
|
||||
class SeeZoomRequest(BaseModel):
|
||||
screen: int = 0
|
||||
center_x: int = Field(ge=0)
|
||||
center_y: int = Field(ge=0)
|
||||
width: int = Field(default=500, ge=10)
|
||||
height: int = Field(default=350, ge=10)
|
||||
with_grid: bool = True
|
||||
grid_rows: int = Field(default=20, ge=1, le=300)
|
||||
grid_cols: int = Field(default=20, ge=1, le=300)
|
||||
include_labels: bool = True
|
||||
image_format: Literal["png", "jpeg"] = "png"
|
||||
jpeg_quality: int = Field(default=90, ge=1, le=100)
|
||||
|
||||
|
||||
class InteractRequest(BaseModel):
|
||||
screen: int = 0
|
||||
action: ActionRequest
|
||||
Reference in New Issue
Block a user