|
|
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 = [] |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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: |
|
|
|
|
|
user_msg, assistant_msg = msg |
|
|
messages.append({"role": "user", "content": user_msg}) |
|
|
messages.append({"role": "assistant", "content": assistant_msg}) |
|
|
|
|
|
|
|
|
messages.append({"role": "user", "content": message}) |
|
|
|
|
|
|
|
|
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]) |
|
|
|
|
|
|
|
|
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} |
|
|
|
|
|
|
|
|
messages_with_context = [system_message] + messages |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
|
|
|
new_history = chat_history.copy() |
|
|
new_history.append({"role": "user", "content": message}) |
|
|
new_history.append({"role": "assistant", "content": assistant_message}) |
|
|
|
|
|
|
|
|
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}") |
|
|
|
|
|
|
|
|
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 [], [] |