from chatbot.agents.states.state import SwapState from chatbot.agents.tools.food_retriever import food_retriever from chatbot.agents.nodes.app_functions.generate_candidates import generate_numerical_constraints import logging # --- Cấu hình logging --- logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def find_replacement_candidates(state: SwapState): logger.info("---NODE: FIND REPLACEMENTS (SELF QUERY)---") food_old = state.get("food_old") profile = state.get("user_profile", {}) if not food_old: logger.warning("⚠️ Không tìm thấy thông tin món cũ (food_old).") return {"candidates": []} diet_mode = profile.get('diet', '') # VD: Chế độ HighProtein restrictions = profile.get('limitFood', '') # VD: Dị ứng sữa, Thuần chay health_status = profile.get('healthStatus', '') # VD: Suy thận constraint_prompt = "" if restrictions not in ["Không có"]: constraint_prompt += f"Yêu cầu bắt buộc: {restrictions}. " if health_status not in ["Khỏe mạnh", "Không có", "Bình thường", None]: constraint_prompt += f"Phù hợp người bệnh: {health_status}. " if diet_mode not in ["Bình thường"]: constraint_prompt += f"Chế độ: {diet_mode}." # 1. Trích xuất ngữ cảnh từ món cũ role = food_old.get("role", "main") # VD: main, side, carb vibe = food_old.get("retrieval_vibe", "Món ăn kèm cơ bản") # VD: món nhẹ nhàng, món giàu đạm meal_type = food_old.get("assigned_meal", "trưa") # VD: trưa old_name = food_old.get("name", "") numerical_query = generate_numerical_constraints(profile, meal_type) # 2. Xây dựng Query tự nhiên để SelfQueryRetriever hiểu query = ( f"Tìm các món ăn đóng vai trò '{role}' phù hợp cho bữa '{meal_type}'. Phong cách: '{vibe}'. " f"Khác với món '{old_name}'. " f"{constraint_prompt}" ) if numerical_query: query += f"Yêu cầu: {numerical_query}" logger.info(f"🔎 Query: {query}") # 3. Gọi Retriever try: docs = food_retriever.invoke(query) except Exception as e: logger.info(f"⚠️ Lỗi Retriever: {e}") return {"candidates": []} # 4. Lọc sơ bộ (Python Filter) candidates = [] for doc in docs: item = doc.metadata.copy() if item.get("name") == old_name: continue item["target_role"] = role item["target_meal"] = meal_type candidates.append(item) logger.info(f"📚 Tìm thấy {len(candidates)} ứng viên tiềm năng.") return {"candidates": candidates}