# pylint: disable=missing-docstring from unittest.mock import MagicMock, patch from sentinel.conversation import ConversationManager from sentinel.models import ( ConversationResponse, InitialAssessment, ) from sentinel.user_input import ( Anthropometrics, Demographics, Lifestyle, PersonalMedicalHistory, SmokingHistory, UserInput, ) def sample_user() -> UserInput: return UserInput( demographics=Demographics( age_years=30, sex="male", anthropometrics=Anthropometrics(height_cm=175, weight_kg=70), ), lifestyle=Lifestyle( smoking=SmokingHistory( status="never", cigarettes_per_day=0, years_smoked=0, ), ), personal_medical_history=PersonalMedicalHistory( chronic_conditions=[], previous_cancers=[], ), family_history=[], ) @patch("sentinel.llm_service.create_initial_assessment_chain") @patch("sentinel.llm_service.create_conversational_chain") def test_conversation_flow(mock_create_conversational_chain, mock_create_initial_chain): structured = MagicMock() freeform = MagicMock() structured.invoke.return_value = { "overall_summary": "ok", "llm_risk_interpretations": [], "dx_recommendations": [], } freeform.invoke.return_value = "hi" mock_create_initial_chain.return_value = structured mock_create_conversational_chain.return_value = freeform conv = ConversationManager(structured, freeform) user = sample_user() result = conv.initial_assessment(user) assert isinstance(result, InitialAssessment) assert result.overall_summary == "ok" assert result.calculated_risk_scores == {} # Verify history contains initial assessment message assert len(conv.history) == 1 assert conv.history[0][0].startswith("Initial assessment for user profile:") assert conv.history[0][1] == result.model_dump_json() answer = conv.follow_up("question") assert isinstance(answer, ConversationResponse) assert answer.response == "hi" # Verify follow-up added to history assert len(conv.history) == 2 assert conv.history[1] == ("question", "hi")