chat / app /handlers /message_handler.py
ariansyahdedy's picture
Add memory
7b2511b
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