from __future__ import annotations from collections import deque from agents.observer import Observer from core.models import Bounds, Scene, SceneElement from semantic.models import SemanticScene, SemanticWidget from world.models import WorldState def _make_scene() -> Scene: return Scene( width=1080, height=1920, elements=[ SceneElement(id="btn1", type="button", bounds=Bounds(10, 20, 100, 50), text="Send"), SceneElement(id="txt1", type="text", bounds=Bounds(0, 0, 500, 30), text="Hello"), ], ) def _make_semantic_scene() -> SemanticScene: return SemanticScene( page="chat", intents=["send_message"], widgets=[SemanticWidget(element_id="btn1", purpose="send button")], ) def _make_world() -> WorldState: state = WorldState( current_app="com.example.messenger", current_page="conversation", variables={"draft": "hello"}, ) return state def test_observe_with_semantic_and_world() -> None: obs = Observer().observe( scene=_make_scene(), semantic_scene=_make_semantic_scene(), world=_make_world(), ) assert obs.semantic_page == "chat" assert obs.semantic_intents == ["send_message"] assert obs.world_app == "com.example.messenger" assert obs.world_page == "conversation" assert obs.world_variables == {"draft": "hello"} assert obs.raw_scene is not None def test_observe_without_semantic_or_world() -> None: obs = Observer().observe(scene=_make_scene()) assert obs.semantic_page is None assert obs.semantic_intents == [] assert obs.world_app is None assert obs.world_page is None assert obs.world_variables == {} assert obs.scene_summary is not None assert obs.raw_scene is not None def test_observe_with_semantic_only() -> None: obs = Observer().observe( scene=_make_scene(), semantic_scene=_make_semantic_scene(), ) assert obs.semantic_page == "chat" assert obs.world_app is None def test_observe_with_world_only() -> None: obs = Observer().observe( scene=_make_scene(), world=_make_world(), ) assert obs.semantic_page is None assert obs.world_app == "com.example.messenger" def test_observe_scene_summary_includes_elements() -> None: obs = Observer().observe(scene=_make_scene()) assert "1080x1920" in obs.scene_summary assert "Send" in obs.scene_summary