feat(pos): chatbot IA con OpenRouter — busqueda de partes por lenguaje natural
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
83
pos/services/ai_chat.py
Normal file
83
pos/services/ai_chat.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# /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.
|
||||
|
||||
Cuando el usuario describe lo que necesita, extrae:
|
||||
1. Marca del vehiculo (si la menciona)
|
||||
2. Modelo del vehiculo (si lo menciona)
|
||||
3. Ano del vehiculo (si lo menciona)
|
||||
4. Tipo de parte que busca
|
||||
|
||||
Responde en espanol, de forma breve y directa. Si puedes identificar el numero de parte OEM, incluyelo.
|
||||
Si no tienes suficiente informacion, pregunta lo que falte.
|
||||
|
||||
IMPORTANTE: Responde SIEMPRE en formato JSON con esta estructura:
|
||||
{
|
||||
"message": "Tu respuesta al usuario",
|
||||
"search_query": "texto para buscar en el catalogo" | null,
|
||||
"vehicle": {"brand": "TOYOTA", "model": "Corolla", "year": 2020} | null
|
||||
}
|
||||
|
||||
Reglas:
|
||||
- "message" es tu respuesta conversacional al usuario.
|
||||
- "search_query" es el texto clave para buscar partes en la base de datos (nombre de parte en ingles, numero OEM, etc). Usa null si no hay busqueda.
|
||||
- "vehicle" extrae marca, modelo y ano si los menciona. Usa null si no hay vehiculo.
|
||||
- La marca debe ir en MAYUSCULAS (NISSAN, TOYOTA, CHEVROLET, etc).
|
||||
- Nombres comunes mexicanos: Tsuru = Sentra/Tsuru, Aveo, Jetta, Pointer, Chevy = Corsa, Vocho = Beetle.
|
||||
"""
|
||||
|
||||
|
||||
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,
|
||||
}
|
||||
Reference in New Issue
Block a user