from __future__ import annotations from agents.models import ( Observation, ReflectionAction, ReflectionOutcome, VerificationVerdict, ) def test_observation_round_trip() -> None: obs = Observation( scene_summary="Screen 1080x1920\n [button] Send", semantic_page="chat", semantic_intents=["send_message"], world_app="com.example.messenger", world_page="conversation", world_variables={"draft": "hello"}, raw_scene={"screen": {"width": 1080, "height": 1920}, "elements": []}, ) data = obs.to_dict() restored = Observation.from_dict(data) assert restored == obs def test_observation_minimal_round_trip() -> None: obs = Observation(scene_summary="empty") data = obs.to_dict() restored = Observation.from_dict(data) assert restored.scene_summary == "empty" assert restored.semantic_page is None assert restored.semantic_intents == [] assert restored.world_app is None assert restored.world_page is None assert restored.world_variables == {} assert restored.raw_scene is None def test_verification_verdict_achieved_round_trip() -> None: verdict = VerificationVerdict(result="achieved", reasoning="Effect observed.") data = verdict.to_dict() restored = VerificationVerdict.from_dict(data) assert restored == verdict def test_verification_verdict_not_achieved_round_trip() -> None: verdict = VerificationVerdict(result="not_achieved", reasoning="Scene unchanged.") data = verdict.to_dict() restored = VerificationVerdict.from_dict(data) assert restored == verdict def test_reflection_action_round_trip() -> None: action = ReflectionAction( action="tap", description="Tap the send button", args={"element_id": "btn_send"}, ) data = action.to_dict() restored = ReflectionAction.from_dict(data) assert restored == action def test_reflection_outcome_with_action_round_trip() -> None: action = ReflectionAction(action="tap", description="Retry tap", args={}) outcome = ReflectionOutcome(replan=False, action=action, reasoning="Try again.") data = outcome.to_dict() restored = ReflectionOutcome.from_dict(data) assert restored == outcome def test_reflection_outcome_replan_round_trip() -> None: outcome = ReflectionOutcome(replan=True, reasoning="No recovery possible.") data = outcome.to_dict() restored = ReflectionOutcome.from_dict(data) assert restored == outcome assert restored.action is None