Spaces:
Running
Running
| 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) | |