import re import json from collections import defaultdict from datetime import datetime, timezone def format_created_at(raw: str) -> str: if not raw: return "Unknown time" try: dt = datetime.fromisoformat(raw).astimezone(timezone.utc) return dt.strftime("%B %d, %Y, %H:%M:%S UTC") except (ValueError, TypeError): return raw def extract_metadata_from_messages(messages: list[dict]) -> dict: """ Trích xuất danh sách Link và File từ danh sách tin nhắn. """ links = [] files = [] # Regex đơn giản cho URL url_pattern = r'https?://[^\s]+' for msg in messages: content = msg.get("content", "") # Tìm links found_links = re.findall(url_pattern, content) links.extend(found_links) # Tìm files từ trường attachment attachment_raw = msg.get("attachment") if attachment_raw and attachment_raw != "null": try: # Trường attachment có thể là string JSON hoặc dict tùy vào RedisClient if isinstance(attachment_raw, str): att = json.loads(attachment_raw) else: att = attachment_raw files.append({ "id": att.get("id"), "type": att.get("type"), "name": att.get("name"), "sender": msg.get("senderName") }) except: pass return { "links": list(set(links)), # Loại bỏ trùng "files": files } def group_messages_by_thread(messages: list[dict]) -> dict[str, list[dict]]: # ... (rest of the file) """ Gom nhóm các tin nhắn có cùng roomId lại với nhau. """ threads = defaultdict(list) for msg in messages: # Use roomId as defined in docs/redis-data-structure.md room_id = msg.get("roomId", "unknown") threads[room_id].append(msg) # Sort each thread by timestamp to maintain chronological order for room_id in threads: threads[room_id].sort(key=lambda m: m.get("timestamp", "")) return dict(threads) def format_thread_for_prompt(room_id: str, messages: list[dict]) -> str: """ Chuyển một thread thành đoạn văn bản rõ ràng để đưa vào prompt. """ lines = [] for msg in messages: raw_ts = msg.get("created_at") or msg.get("timestamp", "") timestamp = format_created_at(raw_ts) if raw_ts else "Unknown time" user = msg.get("sender_username") or msg.get("name") or msg.get("senderName") or msg.get("sender_id", "Unknown") content = msg.get("content", "") lines.append(f"[{timestamp}] {user}: {content}") thread_text = "\n".join(lines) return f"=== ROOM/THREAD: {room_id} ===\n{thread_text}\n=== END ===\n" def preprocess_messages(messages: list[dict]) -> str: """ Tiền xử lý toàn bộ: gom nhóm theo room → format thành prompt-ready string. """ threads = group_messages_by_thread(messages) formatted_parts = [] for room_id, thread_msgs in threads.items(): formatted_parts.append(format_thread_for_prompt(room_id, thread_msgs)) return "\n".join(formatted_parts)