voicebot / services /chat_service.py
datbkpro's picture
Update services/chat_service.py
fa3d989 verified
raw
history blame
5 kB
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 [], []