File size: 4,267 Bytes
be9a762
f169c98
 
 
 
 
 
 
 
 
7b2511b
 
f169c98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b2511b
f169c98
 
 
e0c1af0
f169c98
 
 
 
 
8d2f9d4
f169c98
7b2511b
 
 
 
f169c98
7b2511b
e0c1af0
7b2511b
 
f169c98
 
 
 
7b2511b
 
e0c1af0
7b2511b
 
8d2f9d4
 
7b2511b
f169c98
 
e0c1af0
f169c98
7b2511b
 
f169c98
7b2511b
f169c98
 
 
 
 
e0c1af0
f169c98
 
8d2f9d4
f169c98
 
 
 
 
 
 
 
 
 
 
 
 
8d2f9d4
f169c98
 
 
 
 
 
 
 
 
 
 
 
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
105
106
107
from typing import Dict, List, Optional, Any

from app.services.cache import MessageCache
from app.services.chat_manager import ChatManager
from app.handlers.media_handler import MediaHandler
from app.services.message_parser import MessageParser
from app.services.download_media import download_whatsapp_media
from app.services.message import process_message_with_llm
from app.models.message_types import Message, MediaType, MediaContent

from app.memory import AgentMemory

import logging

logger = logging.getLogger(__name__)


class MessageHandler:
    def __init__(
        self,
        message_cache: MessageCache,
        chat_manager: ChatManager,
        media_handler: MediaHandler,
        logger: logging.Logger
    ):
        self.message_cache = message_cache
        self.chat_manager = chat_manager
        self.media_handler = media_handler
        self.logger = logger

    async def handle(self, raw_message: dict, whatsapp_token: str, whatsapp_url:str,gemini_api:str, rag_system:Any = None, agentMemory:Any=None, memory:Any=None) -> dict:
        try:
            # Parse message
            message = MessageParser.parse(raw_message)
            self.logger.info(f"Parsed Message: {message}")
            if self.message_cache.exists(message.id):
                self.logger.info(f"Duplicate message detected and skipped: {message.id}")
                return {"status": "duplicate", "message_id": message.id}

            # Download media
            media_paths = await self._process_media(message, whatsapp_token)
            
            # Simple class to store chat temporarily
            # self.chat_manager.initialize_chat(message.sender_id)

            user = await agentMemory.add_user(message.sender_id, message.sender_id)

            await memory.add_message(message.sender_id, "user", message.content)
            
            history =  await memory.get_history(message.sender_id, last_n = 2)
            print(f"chat_history: {history }")
            # Process message with LLM
            result = await process_message_with_llm(
                message.sender_id,
                message.content,
                # self.chat_manager.get_chat_history(message.sender_id), 
                history,
                rag_system = rag_system,
                agentMemory=agentMemory,
                memory = memory,
                whatsapp_token=whatsapp_token, 
                whatsapp_url=whatsapp_url,

                **media_paths
            )
            self.logger.info(f"Result: {result}")
            # Append message to chat to keep track of conversation
            # self.chat_manager.append_message(message.sender_id, "user", message.content)
            # self.chat_manager.append_message(message.sender_id, "model", result)
            
            await memory.add_message(message.sender_id, "model", result)
            self.message_cache.add(message.id)
            
            return {"status": "success", "message_id": message.id, "result": result}
            
        except Exception as e:
            self.logger.error(f"Error processing message: {str(e)}")
            return {"status": "error", "message_id": raw_message.get("id"), "error": str(e)}

    async def _process_media(self, message: Message, whatsapp_token: str) -> Dict[str, Optional[str]]:
        media_paths = {
            "image_file_path": None,
            "doc_path": None,
            "video_file_path": None
        }
        
        if not message.media:
            return media_paths

        for media_type, content in message.media.items():
            self.logger.info(f"Processing {media_type.value}: {content.file_path}")
            file_path = await self.media_handler.download(
                content.id,
                whatsapp_token,
                content.file_path
            )
            self.logger.info(f"{media_type.value} file_path: {file_path}")
            
            if media_type == MediaType.IMAGE:
                media_paths["image_file_path"] = file_path
            elif media_type == MediaType.DOCUMENT:
                media_paths["doc_path"] = file_path
            elif media_type == MediaType.VIDEO:
                media_paths["video_file_path"] = file_path

        return media_paths