davidtran999 commited on
Commit
e721a27
·
verified ·
1 Parent(s): d18a456

Upload backend/hue_portal/chatbot/chatbot.py with huggingface_hub

Browse files
backend/hue_portal/chatbot/chatbot.py CHANGED
@@ -6,9 +6,11 @@ import copy
6
  import logging
7
  import json
8
  import time
 
 
9
  from typing import Dict, Any, Optional
10
  from hue_portal.core.chatbot import Chatbot as CoreChatbot, get_chatbot as get_core_chatbot
11
- from hue_portal.chatbot.router import decide_route, IntentRoute, RouteDecision
12
  from hue_portal.chatbot.context_manager import ConversationContext
13
  from hue_portal.chatbot.llm_integration import LLMGenerator
14
  from hue_portal.core.models import LegalSection
@@ -158,6 +160,68 @@ class Chatbot(CoreChatbot):
158
  except Exception as e:
159
  print(f"⚠️ Failed to save cached bot message: {e}")
160
  return cached_response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
  # Always send legal intent through Slow Path RAG
163
  if intent == "search_legal":
@@ -501,6 +565,25 @@ class Chatbot(CoreChatbot):
501
  if not response.get("results"):
502
  return False
503
  return True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
 
505
  def _handle_legal_query(self, query: str, session_id: Optional[str] = None) -> Dict[str, Any]:
506
  """
 
6
  import logging
7
  import json
8
  import time
9
+ import unicodedata
10
+ import re
11
  from typing import Dict, Any, Optional
12
  from hue_portal.core.chatbot import Chatbot as CoreChatbot, get_chatbot as get_core_chatbot
13
+ from hue_portal.chatbot.router import decide_route, IntentRoute, RouteDecision, DOCUMENT_CODE_PATTERNS
14
  from hue_portal.chatbot.context_manager import ConversationContext
15
  from hue_portal.chatbot.llm_integration import LLMGenerator
16
  from hue_portal.core.models import LegalSection
 
160
  except Exception as e:
161
  print(f"⚠️ Failed to save cached bot message: {e}")
162
  return cached_response
163
+
164
+ # Wizard / option-first ngay tại chatbot layer:
165
+ # Nếu là câu hỏi search_legal chung, chưa chọn văn bản, không có mã văn bản trong câu hỏi
166
+ # => trả về danh sách văn bản để người dùng chọn, không sinh câu trả lời chi tiết.
167
+ if (
168
+ intent == "search_legal"
169
+ and not selected_doc_code
170
+ and not self._query_has_document_code(query)
171
+ ):
172
+ intro_message = (
173
+ "Tôi tìm thấy một số nhóm văn bản có thể liên quan đến câu hỏi của bạn.\n\n"
174
+ "Bạn hãy chọn văn bản muốn tra cứu trước, sau đó tôi sẽ trả lời chi tiết hơn:"
175
+ )
176
+ clarification_options = [
177
+ {
178
+ "code": "264-QD-TW",
179
+ "title": "Quyết định 264-QĐ/TW về kỷ luật đảng viên",
180
+ "reason": "Quy định chung về xử lý kỷ luật đối với đảng viên vi phạm.",
181
+ },
182
+ {
183
+ "code": "QD-69-TW",
184
+ "title": "Quy định 69-QĐ/TW về kỷ luật tổ chức đảng, đảng viên",
185
+ "reason": "Quy định chi tiết về các hành vi vi phạm và hình thức kỷ luật.",
186
+ },
187
+ {
188
+ "code": "TT-02-CAND",
189
+ "title": "Thông tư 02/2021/TT-BCA về điều lệnh CAND",
190
+ "reason": "Quy định về điều lệnh, lễ tiết, tác phong trong CAND.",
191
+ },
192
+ {
193
+ "code": "__other__",
194
+ "title": "Khác",
195
+ "reason": "Tôi muốn hỏi văn bản hoặc chủ đề pháp luật khác.",
196
+ },
197
+ ]
198
+ response = {
199
+ "message": intro_message,
200
+ "intent": intent,
201
+ "confidence": confidence,
202
+ "results": [],
203
+ "count": 0,
204
+ "routing": "legal_wizard",
205
+ "type": "options",
206
+ "wizard_stage": "choose_document",
207
+ "clarification": {
208
+ "message": intro_message,
209
+ "options": clarification_options,
210
+ },
211
+ "options": clarification_options,
212
+ }
213
+ if session_id:
214
+ response["session_id"] = session_id
215
+ try:
216
+ ConversationContext.add_message(
217
+ session_id=session_id,
218
+ role="bot",
219
+ content=intro_message,
220
+ intent=intent,
221
+ )
222
+ except Exception as e:
223
+ print(f"⚠️ Failed to save wizard bot message: {e}")
224
+ return response
225
 
226
  # Always send legal intent through Slow Path RAG
227
  if intent == "search_legal":
 
565
  if not response.get("results"):
566
  return False
567
  return True
568
+
569
+ def _query_has_document_code(self, query: str) -> bool:
570
+ """
571
+ Check if the raw query string explicitly contains a known document code pattern
572
+ (ví dụ: '264/QĐ-TW', 'QD-69-TW', 'TT-02-CAND').
573
+ """
574
+ if not query:
575
+ return False
576
+ # Remove accents để regex đơn giản hơn
577
+ normalized = unicodedata.normalize("NFD", query)
578
+ normalized = "".join(ch for ch in normalized if unicodedata.category(ch) != "Mn")
579
+ normalized = normalized.upper()
580
+ for pattern in DOCUMENT_CODE_PATTERNS:
581
+ try:
582
+ if re.search(pattern, normalized):
583
+ return True
584
+ except re.error:
585
+ continue
586
+ return False
587
 
588
  def _handle_legal_query(self, query: str, session_id: Optional[str] = None) -> Dict[str, Any]:
589
  """