File size: 3,394 Bytes
7fee926
 
e00943e
2eba2a0
 
 
5de8b59
 
 
 
 
 
2eba2a0
 
5de8b59
 
7fee926
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7a4edb9
 
 
7fee926
7a4edb9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5de8b59
 
c860ff8
7a4edb9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import re
import json
from collections import defaultdict
from datetime import datetime, timezone, timedelta

_VN_TZ = timezone(timedelta(hours=7))


def format_created_at(raw: str) -> str:
    if not raw:
        return "Unknown time"
    try:
        dt = datetime.fromisoformat(raw).astimezone(_VN_TZ)
        return dt.strftime("%d/%m/%Y %H:%M:%S")
    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)