# /home/Autopartes/pos/services/ai_chat.py """AI Chat service using OpenRouter for parts lookup assistance.""" import requests import json from config import OPENROUTER_API_KEY OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions" MODEL = "anthropic/claude-haiku-4.5" # Fast + cheap for chat SYSTEM_PROMPT = """Eres un asistente de refaccionaria automotriz mexicana. Tu trabajo es ayudar a encontrar autopartes. IMPORTANTE: Responde SIEMPRE en formato JSON valido con esta estructura: { "message": "Tu respuesta al usuario en espaƱol", "search_query": "termino de busqueda EN INGLES para el catalogo", "vehicle": {"brand": "TOYOTA", "model": "Corolla", "year": 2020} } Reglas OBLIGATORIAS: 1. "search_query" SIEMPRE debe tener un valor cuando el usuario menciona una parte. NUNCA dejes null si el usuario pide algo. 2. "search_query" debe estar EN INGLES porque el catalogo TecDoc tiene nombres en ingles. Traducciones comunes: - Balatas/Pastillas de freno = "Brake Pad" - Discos de freno = "Brake Disc" - Amortiguador = "Shock Absorber" - Filtro de aceite = "Oil Filter" - Filtro de aire = "Air Filter" - Bujias = "Spark Plug" - Banda serpentina = "V-Belt" o "Serpentine Belt" - Bomba de agua = "Water Pump" - Alternador = "Alternator" - Radiador = "Radiator" - Sensor de oxigeno = "Oxygen Sensor" - Terminal de direccion = "Tie Rod End" - Bomba de gasolina = "Fuel Pump" - Clutch/Embrague = "Clutch Kit" - Mofle/Escape = "Exhaust" - Inyector = "Injector" 3. "vehicle" extrae marca, modelo y ano. La marca en MAYUSCULAS. 4. Nombres mexicanos: Tsuru = TSURU, Aveo = AVEO, Jetta = JETTA, Pointer = POINTER, Chevy = CORSA, Vocho = BEETLE. 5. No preguntes mas info si ya puedes buscar. Si el usuario dice "balatas para Tsuru 2015", busca directo. 6. "message" es breve y directo: "Buscando balatas para Nissan Tsuru 2015..." """ def chat(user_message, conversation_history=None): """Send a message to the AI and get a response with search suggestions.""" messages = [{"role": "system", "content": SYSTEM_PROMPT}] if conversation_history: messages.extend(conversation_history) messages.append({"role": "user", "content": user_message}) try: resp = requests.post( OPENROUTER_URL, headers={ "Authorization": f"Bearer {OPENROUTER_API_KEY}", "Content-Type": "application/json", }, json={ "model": MODEL, "messages": messages, "max_tokens": 500, "temperature": 0.3, }, timeout=15, ) resp.raise_for_status() data = resp.json() content = data["choices"][0]["message"]["content"] # Try to parse JSON response try: # Handle markdown-wrapped JSON (```json ... ```) stripped = content.strip() if stripped.startswith("```"): lines = stripped.split("\n") # Remove first and last lines (``` markers) json_str = "\n".join(lines[1:-1]) parsed = json.loads(json_str) else: parsed = json.loads(stripped) return parsed except (json.JSONDecodeError, IndexError): return {"message": content, "search_query": None, "vehicle": None} except Exception as e: return { "message": f"Error de conexion: {str(e)}", "search_query": None, "vehicle": None, }