# File: src/response_generator.py # Purpose: Generate patient-facing voice responses using ONLY verified backend data from pathlib import Path import sys sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from src.verification_engine import VerificationResult def generate_success_response(result: VerificationResult) -> str: """ Generate a confirmation response using only verified API data. No LLM generation here — template-based to prevent hallucination. Args: result: Verified VerificationResult with verified=True Returns: Patient-facing spoken response string. """ assert result.verified, "generate_success_response called with unverified result" assert result.appointment_id, "Appointment ID missing from verified result" response = ( f"Your appointment has been confirmed. " f"Your reference number is {result.appointment_id}. " ) if result.doctor: response += f"You will be seen by {result.doctor} " if result.department: response += f"in the {result.department} department " if result.date and result.slot: response += f"on {result.date} at {result.slot}. " response += "Please arrive 15 minutes early. Is there anything else I can help you with?" return response.strip() def generate_failure_response(result: VerificationResult, alternative_slots: list[str]) -> str: """ Generate a failure response using only verified failure reason from the API. Offers alternatives if available. Args: result: VerificationResult with verified=False alternative_slots: List of other available slots (from API, not LLM) Returns: Patient-facing spoken response string. """ assert not result.verified, "generate_failure_response called with verified=True result" reason = result.failure_reason or "The slot is no longer available" response = f"I'm sorry, I was unable to book your appointment. {reason}. " if alternative_slots: options = ", ".join(alternative_slots[:3]) response += f"However, the following slots are available for {result.department}: {options}. " response += "Would you like me to book one of these instead?" else: response += "Unfortunately, there are no other slots available at this time. " response += "I'll transfer you to our scheduling team who can assist you further." return response.strip() def generate_escalation_response() -> str: """ Response when agent confidence is below threshold. Used to prevent low-confidence actions from proceeding. """ return ( "I want to make sure I understood your request correctly. " "Let me connect you with one of our scheduling specialists " "who can assist you directly." ) def generate_response( result: VerificationResult, alternative_slots: list[str] | None = None, ) -> str: """ Top-level response dispatcher. Routes to the correct template based on verification outcome. Args: result: VerificationResult from the verification engine. alternative_slots: Fallback slots to offer on failure (from API). Returns: Final patient-facing response string. """ if result.verified: return generate_success_response(result) else: return generate_failure_response(result, alternative_slots or []) if __name__ == "__main__": from src.verification_engine import VerificationResult # Test success path mock_success = VerificationResult( verified=True, appointment_id="APT-AB1234", patient_name="Ranjith Kumar", department="Cardiology", date="2025-06-01", slot="2:00 PM", doctor="Dr. Sample_3", failure_reason=None, attempts=1, ) print("[Success]:", generate_response(mock_success)) # Test failure path mock_failure = VerificationResult( verified=False, appointment_id=None, patient_name="Ranjith Kumar", department="Cardiology", date="2025-06-01", slot="2:00 PM", doctor=None, failure_reason="Slot unavailable. Please choose another time.", attempts=2, ) alt_slots = ["10:00 AM", "11:00 AM", "3:00 PM"] print("[Failure]:", generate_response(mock_failure, alt_slots))