""" UI application state models. Source of truth for all frontend store state shapes. Generates TypeScript types via modelgen. The store implementation (Pinia, etc.) is just the reactive container. """ from dataclasses import dataclass, field from typing import List, Optional # --------------------------------------------------------------------------- # Pipeline store # --------------------------------------------------------------------------- @dataclass class NodeState: """A pipeline node's current status.""" id: str status: str = "pending" # pending | running | done | error has_checkpoint: bool = False has_region_editor: bool = False # stage works with visual regions has_config_editor: bool = True # all stages have config @dataclass class PipelineState: """Full pipeline run state.""" job_id: str = "" status: str = "idle" # idle | running | paused | completed | error layout_mode: str = "normal" # normal | bbox_editor | stage_editor editor_stage: Optional[str] = None # which stage's editor is open nodes: List[NodeState] = field(default_factory=list) current_stage: Optional[str] = None run_id: Optional[str] = None parent_job_id: Optional[str] = None run_type: str = "initial" # initial | replay | retry error: Optional[str] = None # --------------------------------------------------------------------------- # Config store # --------------------------------------------------------------------------- @dataclass class DetectionConfigOverrides: """Tunable detection stage config.""" model_name: Optional[str] = None confidence_threshold: Optional[float] = None target_classes: Optional[List[str]] = None @dataclass class OCRConfigOverrides: """Tunable OCR stage config.""" languages: Optional[List[str]] = None min_confidence: Optional[float] = None @dataclass class ResolverConfigOverrides: """Tunable brand resolver config.""" fuzzy_threshold: Optional[int] = None @dataclass class EscalationConfigOverrides: """Tunable escalation config.""" vlm_min_confidence: Optional[float] = None cloud_min_confidence: Optional[float] = None cloud_provider: Optional[str] = None @dataclass class PreprocessingConfigOverrides: """Tunable preprocessing config.""" binarize: Optional[bool] = None deskew: Optional[bool] = None contrast: Optional[bool] = None @dataclass class ConfigOverrides: """Aggregated config overrides from all panels.""" detection: Optional[DetectionConfigOverrides] = None ocr: Optional[OCRConfigOverrides] = None resolver: Optional[ResolverConfigOverrides] = None escalation: Optional[EscalationConfigOverrides] = None preprocessing: Optional[PreprocessingConfigOverrides] = None @dataclass class ConfigState: """Config store state.""" current: ConfigOverrides = field(default_factory=ConfigOverrides) pending: ConfigOverrides = field(default_factory=ConfigOverrides) dirty: bool = False # --------------------------------------------------------------------------- # Selection store # --------------------------------------------------------------------------- @dataclass class BboxRegion: """A user-drawn bounding box region.""" x: int y: int w: int h: int @dataclass class SelectionState: """Cross-panel selection state.""" selected_frame: Optional[int] = None selected_brand: Optional[str] = None hovered_timestamp: Optional[float] = None bbox_region: Optional[BboxRegion] = None # --------------------------------------------------------------------------- # Export for modelgen # --------------------------------------------------------------------------- UI_STATE_VIEWS = [ NodeState, PipelineState, DetectionConfigOverrides, OCRConfigOverrides, ResolverConfigOverrides, EscalationConfigOverrides, PreprocessingConfigOverrides, ConfigOverrides, ConfigState, BboxRegion, SelectionState, ]