davidtran999 commited on
Commit
ddcc450
·
verified ·
1 Parent(s): 2f1e37b

Upload backend/chatbot/dialogue_manager.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. backend/chatbot/dialogue_manager.py +173 -0
backend/chatbot/dialogue_manager.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Dialogue management for multi-turn conversations.
3
+ """
4
+ from typing import Dict, Any, Optional, List, Tuple
5
+ from enum import Enum
6
+
7
+
8
+ class DialogueState(Enum):
9
+ """Dialogue states."""
10
+ INITIAL = "initial"
11
+ COLLECTING_INFO = "collecting_info"
12
+ CLARIFYING = "clarifying"
13
+ PROVIDING_ANSWER = "providing_answer"
14
+ FOLLOW_UP = "follow_up"
15
+ COMPLETED = "completed"
16
+
17
+
18
+ class DialogueManager:
19
+ """Manages dialogue state and multi-turn conversations."""
20
+
21
+ def __init__(self):
22
+ self.state = DialogueState.INITIAL
23
+ self.slots = {} # Slot filling for missing information
24
+ self.context_switch_detected = False
25
+
26
+ def update_state(
27
+ self,
28
+ query: str,
29
+ intent: str,
30
+ results_count: int,
31
+ confidence: float,
32
+ recent_messages: Optional[List[Dict[str, Any]]] = None
33
+ ) -> DialogueState:
34
+ """
35
+ Update dialogue state based on current query and context.
36
+
37
+ Args:
38
+ query: Current user query.
39
+ intent: Detected intent.
40
+ results_count: Number of results found.
41
+ confidence: Confidence score.
42
+ recent_messages: Recent conversation messages.
43
+
44
+ Returns:
45
+ Updated dialogue state.
46
+ """
47
+ # Detect context switching
48
+ if recent_messages and len(recent_messages) > 0:
49
+ last_intent = recent_messages[-1].get("intent")
50
+ if last_intent and last_intent != intent and intent != "greeting":
51
+ self.context_switch_detected = True
52
+ self.state = DialogueState.INITIAL
53
+ self.slots = {}
54
+ return self.state
55
+
56
+ # State transitions
57
+ if results_count == 0 and confidence < 0.5:
58
+ # No results and low confidence - need clarification
59
+ self.state = DialogueState.CLARIFYING
60
+ elif results_count > 0 and confidence >= 0.7:
61
+ # Good results - providing answer
62
+ self.state = DialogueState.PROVIDING_ANSWER
63
+ elif results_count > 0 and confidence < 0.7:
64
+ # Some results but uncertain - might need follow-up
65
+ self.state = DialogueState.FOLLOW_UP
66
+ else:
67
+ self.state = DialogueState.PROVIDING_ANSWER
68
+
69
+ return self.state
70
+
71
+ def needs_clarification(
72
+ self,
73
+ query: str,
74
+ intent: str,
75
+ results_count: int
76
+ ) -> Tuple[bool, Optional[str]]:
77
+ """
78
+ Check if clarification is needed.
79
+
80
+ Args:
81
+ query: User query.
82
+ intent: Detected intent.
83
+ results_count: Number of results.
84
+
85
+ Returns:
86
+ Tuple of (needs_clarification, clarification_message).
87
+ """
88
+ if results_count == 0:
89
+ # No results - ask for clarification
90
+ clarification_messages = {
91
+ "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...",
92
+ "search_procedure": "Bạn muốn tìm thủ tục nào? Ví dụ: đăng ký cư trú, thủ tục ANTT...",
93
+ "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...",
94
+ "search_advisory": "Bạn muốn tìm cảnh báo về chủ đề gì?",
95
+ }
96
+ message = clarification_messages.get(intent, "Bạn có thể cung cấp thêm thông tin không?")
97
+ return (True, message)
98
+
99
+ return (False, None)
100
+
101
+ def detect_missing_slots(
102
+ self,
103
+ intent: str,
104
+ query: str,
105
+ results_count: int
106
+ ) -> Dict[str, Any]:
107
+ """
108
+ Detect missing information slots.
109
+
110
+ Args:
111
+ intent: Detected intent.
112
+ query: User query.
113
+ results_count: Number of results.
114
+
115
+ Returns:
116
+ Dictionary of missing slots.
117
+ """
118
+ missing_slots = {}
119
+
120
+ if intent == "search_fine":
121
+ # Check for fine code or fine name
122
+ if "v001" not in query.lower() and "v002" not in query.lower():
123
+ if not any(kw in query.lower() for kw in ["vượt đèn đỏ", "mũ bảo hiểm", "nồng độ cồn"]):
124
+ missing_slots["fine_specification"] = True
125
+
126
+ elif intent == "search_procedure":
127
+ # Check for procedure name or domain
128
+ if not any(kw in query.lower() for kw in ["cư trú", "antt", "pccc", "đăng ký"]):
129
+ missing_slots["procedure_specification"] = True
130
+
131
+ elif intent == "search_office":
132
+ # Check for office name or location
133
+ if not any(kw in query.lower() for kw in ["phường", "huyện", "tỉnh", "điểm tiếp dân"]):
134
+ missing_slots["office_specification"] = True
135
+
136
+ return missing_slots
137
+
138
+ def handle_follow_up(
139
+ self,
140
+ query: str,
141
+ recent_messages: List[Dict[str, Any]]
142
+ ) -> Optional[str]:
143
+ """
144
+ Generate follow-up question if needed.
145
+
146
+ Args:
147
+ query: Current query.
148
+ recent_messages: Recent conversation messages.
149
+
150
+ Returns:
151
+ Follow-up question or None.
152
+ """
153
+ if not recent_messages:
154
+ return None
155
+
156
+ # Check if query is very short (likely a follow-up)
157
+ if len(query.split()) <= 3:
158
+ last_message = recent_messages[-1]
159
+ last_intent = last_message.get("intent")
160
+
161
+ if last_intent == "search_fine":
162
+ 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)"
163
+ elif last_intent == "search_procedure":
164
+ 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)"
165
+
166
+ return None
167
+
168
+ def reset(self):
169
+ """Reset dialogue manager state."""
170
+ self.state = DialogueState.INITIAL
171
+ self.slots = {}
172
+ self.context_switch_detected = False
173
+