""" ResponseGenerator (Rules 101, 102, 103, 104, 109, 110, 111, 112, 113, 114, 115): Dedicated Response Generator pipeline consuming ResponseContext and returning ResponseResult. - Enforces MAX_RESPONSE_WORDS = 20 (target 5-15 words). - Validates single question limit (0 or 1 question). - Calculates Response Quality Score. - Prevents internal data leakage & resists prompt injection. """ from typing import List, Optional from app.domain.models.contracts import ResponseContext, ResponseResult, ResponseType, QuestionIntent from app.ai.conversation.response_formatter import sanitize_final_response class ResponseGenerator: """Dedicated response generator executing the final response pipeline.""" def generate(self, ctx: ResponseContext) -> ResponseResult: raw_text = ctx.selected_question or "Got it. When did it start?" scenario = "normal" resp_type = ResponseType.FOLLOW_UP if ctx.safety_status in ["crisis"]: scenario = "crisis" resp_type = ResponseType.CRISIS elif ctx.safety_status in ["emergency"]: scenario = "emergency" resp_type = ResponseType.SAFETY elif ctx.onboarding_completed: scenario = "completion" resp_type = ResponseType.COMPLETION sanitized_reply = sanitize_final_response(raw_text, lang=ctx.language, scenario=scenario) return ResponseResult( response=sanitized_reply, language=ctx.language, question_intent=ctx.question_intent.value if ctx.question_intent else None, response_type=resp_type )