from __future__ import annotations from types import SimpleNamespace from svrnty_vision.visual_evidence import visual_evidence_from_vlm_response def test_vlm_raw_mode_response_becomes_visual_evidence() -> None: response = SimpleNamespace( rubric_mode="raw", justification="", model_id="qwen-test", raw_scores_json='{"description":"solid red square","objects":["red square"],"detected_text":[]}', ) evidence = visual_evidence_from_vlm_response( response, source_reference="fixture://red-square.png", provider_mode="sovereign", retention_disclosure="synchronous_no_async_persistence", timestamp="2026-06-06T00:00:00Z", ) assert evidence.producing_package_id == "visual-perception-package-candidate" assert evidence.producing_tool_id == "vision.image_analyze" assert evidence.capability_surface == "vision.image_analyze" assert evidence.source_reference == "fixture://red-square.png" assert evidence.provider_mode == "sovereign" assert evidence.retention_disclosure == "synchronous_no_async_persistence" assert evidence.observed_content_summary == "solid red square" assert "description: solid red square" in evidence.extracted_claims assert "objects: red square" in evidence.extracted_claims assert "detected_text: []" in evidence.extracted_claims assert evidence.validation_status == "candidate_validated" assert "research_synthesis" not in evidence.model_dump() def test_non_json_vlm_response_gets_safe_raw_fallback() -> None: response = SimpleNamespace( rubric_mode="raw", justification="", model_id="qwen-test", raw_scores_json="a screenshot of a pricing page with two columns", ) evidence = visual_evidence_from_vlm_response( response, source_reference="fixture://pricing.png", provider_mode="sovereign", retention_disclosure="synchronous_no_async_persistence", timestamp="2026-06-06T00:00:00Z", ) assert evidence.observed_content_summary == "a screenshot of a pricing page with two columns" assert evidence.extracted_claims == [ "raw: a screenshot of a pricing page with two columns" ]