from typing import List, Tuple, Optional from groq import Groq from config.settings import settings from core.rag_system import EnhancedRAGSystem from core.tts_service import EnhancedTTSService from models.schemas import ChatMessage class ChatService: def __init__(self, groq_client: Groq, rag_system: EnhancedRAGSystem, tts_service: EnhancedTTSService): self.groq_client = groq_client self.rag_system = rag_system self.tts_service = tts_service self.multilingual_manager = rag_system.multilingual_manager def respond(self, message: str, chat_history: List) -> tuple: """Tạo phản hồi cho tin nhắn đầu vào dựa trên lịch sử trò chuyện và ngôn ngữ.""" if chat_history is None: chat_history = [] # Kiểm tra message hợp lệ if not message or message.strip() == "": return "", chat_history, chat_history, None, "unknown" try: language = self.multilingual_manager.detect_language(message) llm_model = self.multilingual_manager.get_llm_model(language) # Xây dựng messages từ chat history (CHUYỂN SANG FORMAT MESSAGES) messages = [] for msg in chat_history: if isinstance(msg, dict) and 'role' in msg and 'content' in msg: messages.append(msg) elif isinstance(msg, (list, tuple)) and len(msg) == 2: # Convert từ format tuple cũ sang format messages mới user_msg, assistant_msg = msg messages.append({"role": "user", "content": user_msg}) messages.append({"role": "assistant", "content": assistant_msg}) # Thêm tin nhắn hiện tại messages.append({"role": "user", "content": message}) # Tìm kiếm RAG rag_results = self.rag_system.semantic_search(message, top_k=3) context_text = "" if rag_results: context_text = "\n".join([f"- {result.text}" for result in rag_results]) # Tạo system message if language == 'vi': system_content = f"""Bạn là trợ lý AI hữu ích chuyên về tiếng Việt. Hãy trả lời một cách tự nhiên và thân thiện. Thông tin tham khảo: {context_text if context_text else "Không có thông tin tham khảo cụ thể."} Nếu thông tin tham khảo có liên quan, hãy sử dụng nó. Nếu không, dựa vào kiến thức chung của bạn. Luôn trả lời bằng tiếng Việt.""" else: system_content = f"""You are a helpful AI assistant. Please respond naturally and friendly. Reference information: {context_text if context_text else "No specific reference information available."} If reference information is relevant, use it. Otherwise, rely on your general knowledge. Always respond in the same language as the user.""" system_message = {"role": "system", "content": system_content} # Tạo messages với context messages_with_context = [system_message] + messages # Gọi Groq API completion = self.groq_client.chat.completions.create( model=llm_model, messages=messages_with_context, max_tokens=512, temperature=0.7, ) assistant_message = completion.choices[0].message.content.strip() # Cập nhật chat history với FORMAT MESSAGES MỚI # Thêm cả user message và assistant message vào history new_history = chat_history.copy() new_history.append({"role": "user", "content": message}) new_history.append({"role": "assistant", "content": assistant_message}) # Tạo TTS tts_audio_path = None if assistant_message and not assistant_message.startswith("Error"): try: tts_bytes = self.tts_service.text_to_speech(assistant_message, language) if tts_bytes: tts_audio_path = self.tts_service.save_tts_audio(tts_bytes) except Exception as tts_error: print(f"⚠️ Lỗi TTS: {tts_error}") # Vẫn tiếp tục nếu TTS fail return "", new_history, new_history, tts_audio_path, language except Exception as e: error_msg = f"❌ Lỗi trong quá trình tạo phản hồi: {str(e)}" new_history = chat_history.copy() new_history.append({"role": "user", "content": message}) new_history.append({"role": "assistant", "content": error_msg}) return "", new_history, new_history, None, "unknown" def clear_chat_history(self, chat_history: List) -> tuple: """Xóa lịch sử trò chuyện.""" return [], []