Spaces:
Sleeping
Sleeping
| from chatbot.llm import gemini_llm # Import Gemini LLM | |
| from chatbot.memory import memory | |
| from chatbot.prompts import chat_prompt | |
| from langchain.retrievers import WikipediaRetriever | |
| from langchain.chains import ConversationalRetrievalChain | |
| from pydantic import Field | |
| from typing import List, Callable | |
| from langchain.schema import BaseRetriever, Document | |
| from langchain.schema import HumanMessage, AIMessage | |
| from datetime import datetime | |
| import pytz | |
| def get_current_time(): | |
| utc_plus_7 = pytz.timezone("Asia/Ho_Chi_Minh") # UTC+7 | |
| now = datetime.now(utc_plus_7) | |
| return now.strftime("%A, %Y-%m-%d %H:%M:%S") # Example: "Saturday, 2025-03-29 14:30:00" | |
| def translate_to_english(text: str) -> str: | |
| """Use Gemini LLM to translate text to English with recent chat context.""" | |
| recent_messages = memory.chat_memory.messages[-3:] # Lấy 3 tin nhắn gần nhất | |
| recent_context = "\n".join([msg.content for msg in recent_messages]) | |
| prompt = f""" | |
| You are an assistant for Wikipedia searches. The query may be in any language. | |
| There are two types of query: general informational queries and queries asking about you. Determine the type and respond as follows: | |
| **If the query asks for general information**: | |
| Extract and return only the most relevant keyword (e.g. a person's name, city, or key term) in English/international form. | |
| If the query includes a specific time reference (date, month, or year), ensure that the translated keyword includes this time reference. | |
| Current time: {get_current_time()}. | |
| Identify the referenced time point (day, month, year, decade or century) mentioned in the query, calculate its exact value, and include it in the keyword if necessary. | |
| If the query refers to time but does not require absolute precision (e.g., using words like "around" or "approximately"), return a broader time range and include it in the keyword if necessary. | |
| For example: | |
| If the current year is 2025, then: "around 30 years ago" is 1990s, "about 200 years ago" is 19th century. | |
| **If query asks about what happened to you**: | |
| Interpret 'you' as Kumiko, based on your knowledge of the Hibike! Euphonium plot, return one of the following keywords: | |
| - Liz and the Blue Bird (Regarding information about Nozomi and Mizore) | |
| - Sound! Euphonium: The Movie – Welcome to the Kitauji High School Concert Band (Information about Kumiko and Reina) | |
| - Sound! Euphonium: The Movie – May the Melody Reach You! (Information about Asuka and Mamiko) | |
| - Sound! Euphonium: The Movie – Our Promise: A Brand New Day (Information about Kumiko's second year) | |
| - Sound! Euphonium (Information about Kumiko's other acquaintances) | |
| - List of Sound! Euphonium episodes (other information) | |
| Consider the recent conversation context to disambiguate references. | |
| Recent Context: | |
| {recent_context} | |
| Query: | |
| {text} | |
| Return only the keyword — no explanations. | |
| """ | |
| response = gemini_llm.invoke(prompt) # Invoke Gemini for translation | |
| return response | |
| class WikipediaTranslationRetriever(BaseRetriever): | |
| retriever: WikipediaRetriever = Field(..., description="The underlying Wikipedia retriever") | |
| translator: Callable[[str], str] = Field(..., description="Function to translate queries to English") | |
| def get_relevant_documents(self, query: str) -> List[Document]: | |
| translated_query = self.translator(query) | |
| print(f"🔄 Translated Query: {translated_query}") | |
| return self.retriever.get_relevant_documents(translated_query) | |
| async def aget_relevant_documents(self, query: str) -> List[Document]: | |
| # For simplicity, we are not implementing the async version. | |
| raise NotImplementedError("Async retrieval is not implemented.") | |
| def custom_get_chat_history(chat_history): | |
| # Nếu chat_history là chuỗi (summary) thì trả về chuỗi đó | |
| if isinstance(chat_history, str): | |
| return chat_history | |
| # Nếu là danh sách các message, chuyển thành chuỗi | |
| elif isinstance(chat_history, list): | |
| return "\n".join([msg.content for msg in chat_history]) | |
| else: | |
| raise ValueError("Unsupported chat history format.") | |
| # Create the retriever instance to be used in your qa_chain: | |
| retriever = WikipediaTranslationRetriever( | |
| retriever=WikipediaRetriever(), | |
| translator=translate_to_english | |
| ) | |
| # ✅ Use ConversationalRetrievalChain | |
| qa_chain = ConversationalRetrievalChain.from_llm( | |
| llm=gemini_llm, | |
| retriever=retriever, | |
| memory=memory, | |
| return_source_documents=False, | |
| combine_docs_chain_kwargs={"prompt": chat_prompt}, | |
| output_key="result" | |
| ) | |
| qa_chain.get_chat_history = custom_get_chat_history | |
| def get_chat_response(user_input: str) -> str: | |
| """Process user input and return chat response using Wikipedia retrieval.""" | |
| response = qa_chain({ | |
| "question": user_input, | |
| "current_time": get_current_time() # Pass the current time | |
| }) | |
| return response["result"] | |