""" Dialogue management for multi-turn conversations. """ from typing import Dict, Any, Optional, List, Tuple from enum import Enum class DialogueState(Enum): """Dialogue states.""" INITIAL = "initial" COLLECTING_INFO = "collecting_info" CLARIFYING = "clarifying" PROVIDING_ANSWER = "providing_answer" FOLLOW_UP = "follow_up" COMPLETED = "completed" class DialogueManager: """Manages dialogue state and multi-turn conversations.""" def __init__(self): self.state = DialogueState.INITIAL self.slots = {} # Slot filling for missing information self.context_switch_detected = False def update_state( self, query: str, intent: str, results_count: int, confidence: float, recent_messages: Optional[List[Dict[str, Any]]] = None ) -> DialogueState: """ Update dialogue state based on current query and context. Args: query: Current user query. intent: Detected intent. results_count: Number of results found. confidence: Confidence score. recent_messages: Recent conversation messages. Returns: Updated dialogue state. """ # Detect context switching if recent_messages and len(recent_messages) > 0: last_intent = recent_messages[-1].get("intent") if last_intent and last_intent != intent and intent != "greeting": self.context_switch_detected = True self.state = DialogueState.INITIAL self.slots = {} return self.state # State transitions if results_count == 0 and confidence < 0.5: # No results and low confidence - need clarification self.state = DialogueState.CLARIFYING elif results_count > 0 and confidence >= 0.7: # Good results - providing answer self.state = DialogueState.PROVIDING_ANSWER elif results_count > 0 and confidence < 0.7: # Some results but uncertain - might need follow-up self.state = DialogueState.FOLLOW_UP else: self.state = DialogueState.PROVIDING_ANSWER return self.state def needs_clarification( self, query: str, intent: str, results_count: int ) -> Tuple[bool, Optional[str]]: """ Check if clarification is needed. Args: query: User query. intent: Detected intent. results_count: Number of results. Returns: Tuple of (needs_clarification, clarification_message). """ if results_count == 0: # No results - ask for clarification clarification_messages = { "search_fine": "Bạn có thể cho biết cụ thể hơn về loại vi phạm không? Ví dụ: vượt đèn đỏ, không đội mũ bảo hiểm...", "search_procedure": "Bạn muốn tìm thủ tục nào? Ví dụ: đăng ký cư trú, thủ tục ANTT...", "search_office": "Bạn muốn tìm đơn vị nào? Ví dụ: công an phường, điểm tiếp dân...", "search_advisory": "Bạn muốn tìm cảnh báo về chủ đề gì?", } message = clarification_messages.get(intent, "Bạn có thể cung cấp thêm thông tin không?") return (True, message) return (False, None) def detect_missing_slots( self, intent: str, query: str, results_count: int ) -> Dict[str, Any]: """ Detect missing information slots. Args: intent: Detected intent. query: User query. results_count: Number of results. Returns: Dictionary of missing slots. """ missing_slots = {} if intent == "search_fine": # Check for fine code or fine name if "v001" not in query.lower() and "v002" not in query.lower(): if not any(kw in query.lower() for kw in ["vượt đèn đỏ", "mũ bảo hiểm", "nồng độ cồn"]): missing_slots["fine_specification"] = True elif intent == "search_procedure": # Check for procedure name or domain if not any(kw in query.lower() for kw in ["cư trú", "antt", "pccc", "đăng ký"]): missing_slots["procedure_specification"] = True elif intent == "search_office": # Check for office name or location if not any(kw in query.lower() for kw in ["phường", "huyện", "tỉnh", "điểm tiếp dân"]): missing_slots["office_specification"] = True return missing_slots def handle_follow_up( self, query: str, recent_messages: List[Dict[str, Any]] ) -> Optional[str]: """ Generate follow-up question if needed. Args: query: Current query. recent_messages: Recent conversation messages. Returns: Follow-up question or None. """ if not recent_messages: return None # Check if query is very short (likely a follow-up) if len(query.split()) <= 3: last_message = recent_messages[-1] last_intent = last_message.get("intent") if last_intent == "search_fine": return "Bạn muốn biết thêm thông tin gì về mức phạt này? (ví dụ: điều luật, biện pháp khắc phục)" elif last_intent == "search_procedure": return "Bạn muốn biết thêm thông tin gì về thủ tục này? (ví dụ: hồ sơ, lệ phí, thời hạn)" return None def reset(self): """Reset dialogue manager state.""" self.state = DialogueState.INITIAL self.slots = {} self.context_switch_detected = False