fix duplicate message
Browse files- app/main.py +12 -6
- app/sheets.py +12 -12
app/main.py
CHANGED
|
@@ -185,17 +185,18 @@ async def process_message(message_data: Dict[str, Any]):
|
|
| 185 |
'vehicle': '',
|
| 186 |
'action': '',
|
| 187 |
'purpose': '',
|
| 188 |
-
'timestamp': timestamp,
|
| 189 |
'is_done': False
|
| 190 |
}
|
| 191 |
|
|
|
|
| 192 |
conv = None
|
| 193 |
|
| 194 |
if history:
|
| 195 |
# 1. Chặn duplicate message (trùng sender_id, page_id, timestamp)
|
| 196 |
for row in history:
|
| 197 |
if (
|
| 198 |
-
str(row.get('timestamp'
|
| 199 |
and str(row.get('recipient_id')) == str(sender_id)
|
| 200 |
and str(row.get('page_id')) == str(page_id)
|
| 201 |
):
|
|
@@ -223,9 +224,14 @@ async def process_message(message_data: Dict[str, Any]):
|
|
| 223 |
logger.error("Không thể tạo conversation mới!")
|
| 224 |
return
|
| 225 |
else:
|
|
|
|
| 226 |
for key, value in log_kwargs.items():
|
| 227 |
if value not in (None, "", []) and conv.get(key) in (None, "", []):
|
| 228 |
conv[key] = value
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
|
| 230 |
# Get page access token (sync)
|
| 231 |
page_token = supabase_client.get_page_token(page_id)
|
|
@@ -275,14 +281,14 @@ async def process_message(message_data: Dict[str, Any]):
|
|
| 275 |
'vehicle': ','.join(keywords),
|
| 276 |
'action': hanh_vi_vi_pham,
|
| 277 |
'purpose': muc_dich,
|
| 278 |
-
'timestamp': timestamp,
|
| 279 |
'is_done': False
|
| 280 |
}
|
| 281 |
|
| 282 |
for key, value in update_kwargs.items():
|
| 283 |
if value not in (None, "", []) and conv.get(key) in (None, "", []):
|
| 284 |
conv[key] = value
|
| 285 |
-
|
| 286 |
# 5. Xử lý logic nghiệp vụ
|
| 287 |
response = await process_business_logic(conv, page_token)
|
| 288 |
|
|
@@ -354,7 +360,7 @@ async def format_search_results(question: str, matches: List[Dict[str, Any]]) ->
|
|
| 354 |
top = match
|
| 355 |
|
| 356 |
# Chuẩn bị context cho LLM: liệt kê tất cả các item với chú thích rõ ràng
|
| 357 |
-
full_result_text += f"
|
| 358 |
# Thực hiện hành vi
|
| 359 |
tieude = (top.get('tieude') or '').strip()
|
| 360 |
noidung = (top.get('noidung') or '').strip()
|
|
@@ -400,7 +406,7 @@ async def format_search_results(question: str, matches: List[Dict[str, Any]]) ->
|
|
| 400 |
"Chỉ sử dụng thông tin có trong các đoạn, không tự đoán.\n"
|
| 401 |
f"Các đoạn luật liên quan:\n{full_result_text}"
|
| 402 |
"\nHãy trả lời ngắn gọn, dễ hiểu, trích dẫn rõ ràng thông tin từ các đoạn luật nếu cần."
|
| 403 |
-
f"
|
| 404 |
)
|
| 405 |
|
| 406 |
logger.info(f"[DEBUG] prompt:\n {prompt}")
|
|
|
|
| 185 |
'vehicle': '',
|
| 186 |
'action': '',
|
| 187 |
'purpose': '',
|
| 188 |
+
'timestamp': [timestamp],
|
| 189 |
'is_done': False
|
| 190 |
}
|
| 191 |
|
| 192 |
+
logger.info(f"[DEBUG] Message cơ bản: {log_kwargs}")
|
| 193 |
conv = None
|
| 194 |
|
| 195 |
if history:
|
| 196 |
# 1. Chặn duplicate message (trùng sender_id, page_id, timestamp)
|
| 197 |
for row in history:
|
| 198 |
if (
|
| 199 |
+
str(timestamp) in row.get('timestamp', [])
|
| 200 |
and str(row.get('recipient_id')) == str(sender_id)
|
| 201 |
and str(row.get('page_id')) == str(page_id)
|
| 202 |
):
|
|
|
|
| 224 |
logger.error("Không thể tạo conversation mới!")
|
| 225 |
return
|
| 226 |
else:
|
| 227 |
+
logger.info(f"[DEBUG] Message history: {conv}")
|
| 228 |
for key, value in log_kwargs.items():
|
| 229 |
if value not in (None, "", []) and conv.get(key) in (None, "", []):
|
| 230 |
conv[key] = value
|
| 231 |
+
logger.info(f"[DEBUG] Message history sau update: {conv}")
|
| 232 |
+
# Thêm timestamp mới nếu chưa có
|
| 233 |
+
if timestamp not in conv['timestamp']:
|
| 234 |
+
conv['timestamp'].append(timestamp)
|
| 235 |
|
| 236 |
# Get page access token (sync)
|
| 237 |
page_token = supabase_client.get_page_token(page_id)
|
|
|
|
| 281 |
'vehicle': ','.join(keywords),
|
| 282 |
'action': hanh_vi_vi_pham,
|
| 283 |
'purpose': muc_dich,
|
| 284 |
+
'timestamp': conv['timestamp'],
|
| 285 |
'is_done': False
|
| 286 |
}
|
| 287 |
|
| 288 |
for key, value in update_kwargs.items():
|
| 289 |
if value not in (None, "", []) and conv.get(key) in (None, "", []):
|
| 290 |
conv[key] = value
|
| 291 |
+
logger.info(f"[DEBUG] Message history update cuối cùng: {conv}")
|
| 292 |
# 5. Xử lý logic nghiệp vụ
|
| 293 |
response = await process_business_logic(conv, page_token)
|
| 294 |
|
|
|
|
| 360 |
top = match
|
| 361 |
|
| 362 |
# Chuẩn bị context cho LLM: liệt kê tất cả các item với chú thích rõ ràng
|
| 363 |
+
full_result_text += f"\nĐoạn {i}:\n"
|
| 364 |
# Thực hiện hành vi
|
| 365 |
tieude = (top.get('tieude') or '').strip()
|
| 366 |
noidung = (top.get('noidung') or '').strip()
|
|
|
|
| 406 |
"Chỉ sử dụng thông tin có trong các đoạn, không tự đoán.\n"
|
| 407 |
f"Các đoạn luật liên quan:\n{full_result_text}"
|
| 408 |
"\nHãy trả lời ngắn gọn, dễ hiểu, trích dẫn rõ ràng thông tin từ các đoạn luật nếu cần."
|
| 409 |
+
f"\nCâu hỏi của người dùng: {question}\n"
|
| 410 |
)
|
| 411 |
|
| 412 |
logger.info(f"[DEBUG] prompt:\n {prompt}")
|
app/sheets.py
CHANGED
|
@@ -90,8 +90,8 @@ class SheetsClient:
|
|
| 90 |
history = []
|
| 91 |
|
| 92 |
for row in values:
|
| 93 |
-
# Bổ sung cột rỗng cho đủ 12 cột
|
| 94 |
row = row + [""] * (12 - len(row))
|
|
|
|
| 95 |
if row[4] == user_id and row[5] == page_id and row[11].lower() == 'false':
|
| 96 |
history.append({
|
| 97 |
'conversation_id': row[0],
|
|
@@ -104,7 +104,7 @@ class SheetsClient:
|
|
| 104 |
'originalvehicle': row[7],
|
| 105 |
'originalaction': row[8],
|
| 106 |
'originalpurpose': row[9],
|
| 107 |
-
'timestamp':
|
| 108 |
'isdone': row[11].lower() == 'true'
|
| 109 |
})
|
| 110 |
|
|
@@ -152,14 +152,11 @@ class SheetsClient:
|
|
| 152 |
if not conversation_id:
|
| 153 |
# Check for duplicates before creating new conversation
|
| 154 |
for row in values:
|
| 155 |
-
# Ensure row has enough columns
|
| 156 |
if len(row) >= 11:
|
| 157 |
-
|
| 158 |
row_user_id = row[4]
|
| 159 |
row_page_id = row[5]
|
| 160 |
-
if (str(
|
| 161 |
-
str(row_user_id) == str(user_id) and
|
| 162 |
-
str(row_page_id) == str(page_id)):
|
| 163 |
# Found duplicate, return existing conversation
|
| 164 |
logger.info(f"Found duplicate conversation for user {user_id}, page {page_id}, timestamp {timestamp}")
|
| 165 |
return {
|
|
@@ -173,7 +170,7 @@ class SheetsClient:
|
|
| 173 |
'originalvehicle': row[7],
|
| 174 |
'originalaction': row[8],
|
| 175 |
'originalpurpose': row[9],
|
| 176 |
-
'timestamp':
|
| 177 |
'isdone': row[11].lower() == 'true' if len(row) > 11 else False
|
| 178 |
}
|
| 179 |
|
|
@@ -190,7 +187,7 @@ class SheetsClient:
|
|
| 190 |
vehicle,
|
| 191 |
action,
|
| 192 |
purpose,
|
| 193 |
-
timestamp,
|
| 194 |
str(is_done).lower()
|
| 195 |
]
|
| 196 |
|
|
@@ -220,7 +217,7 @@ class SheetsClient:
|
|
| 220 |
'originalvehicle': vehicle,
|
| 221 |
'originalaction': action,
|
| 222 |
'originalpurpose': purpose,
|
| 223 |
-
'timestamp': timestamp,
|
| 224 |
'isdone': is_done
|
| 225 |
}
|
| 226 |
else:
|
|
@@ -241,6 +238,9 @@ class SheetsClient:
|
|
| 241 |
while len(current_row) < 13:
|
| 242 |
current_row.append("")
|
| 243 |
# Tạo dòng mới với giá trị mới nếu có, giữ nguyên nếu không
|
|
|
|
|
|
|
|
|
|
| 244 |
new_row = [
|
| 245 |
conversation_id,
|
| 246 |
command if command else current_row[1],
|
|
@@ -252,7 +252,7 @@ class SheetsClient:
|
|
| 252 |
vehicle if vehicle else current_row[7],
|
| 253 |
action if action else current_row[8],
|
| 254 |
purpose if purpose else current_row[9],
|
| 255 |
-
|
| 256 |
str(is_done).lower() if is_done is not None else current_row[11]
|
| 257 |
]
|
| 258 |
update_range = f"{SHEET_RANGE.split('!')[0]}!A{sheet_row_number}"
|
|
@@ -285,7 +285,7 @@ class SheetsClient:
|
|
| 285 |
'originalvehicle': new_row[7],
|
| 286 |
'originalaction': new_row[8],
|
| 287 |
'originalpurpose': new_row[9],
|
| 288 |
-
'timestamp': new_row[10],
|
| 289 |
'isdone': new_row[11].lower() == 'true'
|
| 290 |
}
|
| 291 |
|
|
|
|
| 90 |
history = []
|
| 91 |
|
| 92 |
for row in values:
|
|
|
|
| 93 |
row = row + [""] * (12 - len(row))
|
| 94 |
+
timestamps = json.loads(row[10]) if row[10] else []
|
| 95 |
if row[4] == user_id and row[5] == page_id and row[11].lower() == 'false':
|
| 96 |
history.append({
|
| 97 |
'conversation_id': row[0],
|
|
|
|
| 104 |
'originalvehicle': row[7],
|
| 105 |
'originalaction': row[8],
|
| 106 |
'originalpurpose': row[9],
|
| 107 |
+
'timestamp': timestamps,
|
| 108 |
'isdone': row[11].lower() == 'true'
|
| 109 |
})
|
| 110 |
|
|
|
|
| 152 |
if not conversation_id:
|
| 153 |
# Check for duplicates before creating new conversation
|
| 154 |
for row in values:
|
|
|
|
| 155 |
if len(row) >= 11:
|
| 156 |
+
row_timestamps = json.loads(row[10]) if row[10] else []
|
| 157 |
row_user_id = row[4]
|
| 158 |
row_page_id = row[5]
|
| 159 |
+
if (str(timestamp) in row_timestamps and str(row_user_id) == str(user_id) and str(row_page_id) == str(page_id)):
|
|
|
|
|
|
|
| 160 |
# Found duplicate, return existing conversation
|
| 161 |
logger.info(f"Found duplicate conversation for user {user_id}, page {page_id}, timestamp {timestamp}")
|
| 162 |
return {
|
|
|
|
| 170 |
'originalvehicle': row[7],
|
| 171 |
'originalaction': row[8],
|
| 172 |
'originalpurpose': row[9],
|
| 173 |
+
'timestamp': row_timestamps,
|
| 174 |
'isdone': row[11].lower() == 'true' if len(row) > 11 else False
|
| 175 |
}
|
| 176 |
|
|
|
|
| 187 |
vehicle,
|
| 188 |
action,
|
| 189 |
purpose,
|
| 190 |
+
json.dumps([timestamp]),
|
| 191 |
str(is_done).lower()
|
| 192 |
]
|
| 193 |
|
|
|
|
| 217 |
'originalvehicle': vehicle,
|
| 218 |
'originalaction': action,
|
| 219 |
'originalpurpose': purpose,
|
| 220 |
+
'timestamp': [timestamp],
|
| 221 |
'isdone': is_done
|
| 222 |
}
|
| 223 |
else:
|
|
|
|
| 238 |
while len(current_row) < 13:
|
| 239 |
current_row.append("")
|
| 240 |
# Tạo dòng mới với giá trị mới nếu có, giữ nguyên nếu không
|
| 241 |
+
current_timestamps = json.loads(current_row[10]) if current_row[10] else []
|
| 242 |
+
if timestamp not in current_timestamps:
|
| 243 |
+
current_timestamps.append(timestamp)
|
| 244 |
new_row = [
|
| 245 |
conversation_id,
|
| 246 |
command if command else current_row[1],
|
|
|
|
| 252 |
vehicle if vehicle else current_row[7],
|
| 253 |
action if action else current_row[8],
|
| 254 |
purpose if purpose else current_row[9],
|
| 255 |
+
json.dumps(current_timestamps),
|
| 256 |
str(is_done).lower() if is_done is not None else current_row[11]
|
| 257 |
]
|
| 258 |
update_range = f"{SHEET_RANGE.split('!')[0]}!A{sheet_row_number}"
|
|
|
|
| 285 |
'originalvehicle': new_row[7],
|
| 286 |
'originalaction': new_row[8],
|
| 287 |
'originalpurpose': new_row[9],
|
| 288 |
+
'timestamp': json.loads(new_row[10]),
|
| 289 |
'isdone': new_row[11].lower() == 'true'
|
| 290 |
}
|
| 291 |
|