"""Prompt contract tests for load-bearing navigator model calls.""" from __future__ import annotations import json from typing import Any from figment.prompt_builder import build_prompt REQUIRED_TOP_LEVEL_KEYS = { "protocol_urgency", "red_flags", "intake_facts", "candidate_protocol_pathways", "missing_info_to_collect", "next_observations_to_collect", "conflicts_or_uncertainties", "responder_checklist", "do_not_do", "source_cards", "handoff_note_sbar", "responder_plain_language_script", "safety_boundary", } def _context_from_prompt(prompt: str) -> dict[str, Any]: return json.loads(prompt.split("\n\nCONTEXT:\n", maxsplit=1)[1]) def _confirmed_chest_pain_intake() -> dict[str, Any]: return { "setting": "mobile clinic", "patient_age": "52", "pregnancy_status": "not_applicable", "chief_concern": "Chest pain", "symptoms": "Crushing chest pain and shortness of breath", "vitals": "HR 118; blood pressure pending", "allergies": "unknown", "medications": "unknown", "available_supplies": "AED, radio", "responder_note": "Adult reports chest pain after cleanup work.", "confirmed": True, } def _emergency_chest_pain_rules() -> list[dict[str, Any]]: return [ { "rule_id": "red_flag_chest_pain", "label": "Chest pain escalation cue", "urgency": "emergency", "evidence": "chest pain", "card_id": "CHEST-PAIN-ESCALATION-v1", } ] def _retrieved_cards() -> list[dict[str, Any]]: return [ { "card_id": "CHEST-PAIN-ESCALATION-v1", "score": 1.0, "source": "test", "card": { "card_id": "CHEST-PAIN-ESCALATION-v1", "title": "Chest pain escalation", "required_observations": [ "chest pain description", "onset and duration", "available vital signs", ], "red_flags": ["chest pain or pressure"], "escalation_criteria": [ "Chest pain with shortness of breath requires emergency escalation.", ], "local_actions": ["Document onset, duration, and vital signs."], "forbidden_actions": ["Do not diagnose the cause of chest pain."], }, }, { "card_id": "REFERRAL-SBAR-v1", "score": 0.5, "source": "test", "card": { "card_id": "REFERRAL-SBAR-v1", "title": "Referral and SBAR format", "required_observations": [ "situation or reason for handoff", "objective observations only", "source protocol card IDs", ], "local_actions": ["Use Situation, Background, Assessment, and Request."], "forbidden_actions": ["Do not add a diagnosis as the assessment."], }, }, ] def test_prompt_includes_literal_required_json_skeleton_with_all_schema_keys() -> None: prompt, _ = build_prompt( _confirmed_chest_pain_intake(), _retrieved_cards(), _emergency_chest_pain_rules(), "emergency", ) assert "REQUIRED_JSON_SKELETON:" in prompt assert "Do not discharge" in prompt assert "autonomous routing" in prompt context = _context_from_prompt(prompt) skeleton = context["required_json_skeleton"] assert set(skeleton) == REQUIRED_TOP_LEVEL_KEYS assert set(skeleton["handoff_note_sbar"]) == { "situation", "background", "assessment_observations_only", "handoff_request", } assert isinstance(skeleton["source_cards"], list) assert isinstance(skeleton["missing_info_to_collect"], list) def test_prompt_context_lists_allowed_facts_and_required_observations() -> None: prompt, _ = build_prompt( _confirmed_chest_pain_intake(), _retrieved_cards(), _emergency_chest_pain_rules(), "emergency", audio_draft={ "confirmation_status": "unconfirmed", "transcript": "Audio-only chest pain phrase must not become an allowed fact.", }, ) context = _context_from_prompt(prompt) allowed_facts_text = json.dumps(context["allowed_facts_inventory"], sort_keys=True) assert "confirmed_intake" in allowed_facts_text assert "Crushing chest pain and shortness of breath" in allowed_facts_text assert "deterministic_rule" in allowed_facts_text assert "red_flag_chest_pain" in allowed_facts_text assert "retrieved_protocol_card" in allowed_facts_text assert "Chest pain escalation" in allowed_facts_text assert "Audio-only chest pain phrase" not in allowed_facts_text assert "Audio-only chest pain phrase" not in prompt observations = context["required_observations_inventory"] chest = next(item for item in observations if item["card_id"] == "CHEST-PAIN-ESCALATION-v1") assert chest["required_observations"] == [ "chest pain description", "onset and duration", "available vital signs", ] def test_prompt_context_guides_routine_and_negated_cases() -> None: prompt, _ = build_prompt( { **_confirmed_chest_pain_intake(), "chief_concern": "routine cough check", "symptoms": "mild cough, no chest pain, no shortness of breath, speaking normally", }, _retrieved_cards(), [], "routine", ) context = _context_from_prompt(prompt) guidance_text = " ".join(context["routine_or_negated_case_guidance"]) assert "Do not convert denied or absent symptoms into red_flags" in guidance_text assert "keep protocol_urgency routine" in guidance_text assert "nearby emergency card language" in guidance_text