from __future__ import annotations from typing import TYPE_CHECKING, Any from agents.models import Observation from core.models import Scene, Step from runtime.executor import StepResult from runtime.planner import PlannedStep if TYPE_CHECKING: from semantic.models import SemanticScene from world.models import WorldState class Observer: def observe( self, *, scene: Scene, step: PlannedStep | None = None, result: StepResult | None = None, semantic_scene: SemanticScene | None = None, world: WorldState | None = None, ) -> Observation: scene_summary = self._build_scene_summary(scene) semantic_page = None semantic_intents: list[str] = [] if semantic_scene is not None: semantic_page = semantic_scene.page semantic_intents = list(semantic_scene.intents) world_app = None world_page = None world_variables: dict[str, Any] = {} if world is not None: world_app = world.current_app world_page = world.current_page world_variables = dict(world.variables) return Observation( scene_summary=scene_summary, semantic_page=semantic_page, semantic_intents=semantic_intents, world_app=world_app, world_page=world_page, world_variables=world_variables, raw_scene=scene.to_dict(), ) def _build_scene_summary(self, scene: Scene) -> str: parts = [f"Screen {scene.width}x{scene.height}"] for element in scene.elements[:10]: text = element.text or element.type parts.append(f" [{element.type}] {text}") return "\n".join(parts)