Mejoras de sesion: estabilizacion, IA, Nexus Yonke y marketplace B2B
- F0 blindaje: Redis/Celery, pg_hba sin trust LAN, secretos a env 600, backups, webhook auth, jobs muertos - F1 caja: bugs POS, reembolsos al corte, apartados, CFDI, topes de descuento en cotizacion/apartado - F2/F7 IA de catalogo: autocategorizacion, dedup de SKUs con embeddings, OCR de facturas, descripciones, claves SAT, limpieza de fitment - F3 IA en el flujo: vision Yonke, preguntas MeLi, venta cruzada, anomalias, sinonimos, busqueda semantica (rerank/embeddings) - F4/F8 escala y cartera: /metrics+Prometheus+Grafana, pool, score de credito, churn, metricas multi-tenant - Nexus Yonke (M1-M6): modelo de datos 1-de-1, alta por donador, vitrina publica, MeLi usado, consignacion, garantia por dias, reportes, etiquetas - Marketplace B2B entre yonkes (catalogo + pedidos cross-tenant) - Seguridad: auth en /api/admin/* (35 endpoints), alertas por tenant - Migraciones v4.27/v4.28; timers expire-demos y rollup-metrics
This commit is contained in:
@@ -3,8 +3,17 @@
|
||||
|
||||
import requests
|
||||
import json
|
||||
from config import OPENROUTER_API_KEY, HERMES_API_URL, HERMES_API_KEY
|
||||
from config import QWEN_API_URL, QWEN_API_KEY, QWEN_MODEL
|
||||
import os as _os
|
||||
try: # config del POS; con sys.path del dashboard puede resolver el config raíz
|
||||
from config import OPENROUTER_API_KEY, HERMES_API_URL, HERMES_API_KEY
|
||||
from config import QWEN_API_URL, QWEN_API_KEY, QWEN_MODEL
|
||||
except ImportError:
|
||||
OPENROUTER_API_KEY = _os.environ.get('OPENROUTER_API_KEY', '')
|
||||
HERMES_API_URL = _os.environ.get('HERMES_API_URL', '')
|
||||
HERMES_API_KEY = _os.environ.get('HERMES_API_KEY', '')
|
||||
QWEN_API_URL = _os.environ.get('QWEN_API_URL', '')
|
||||
QWEN_API_KEY = _os.environ.get('QWEN_API_KEY', '')
|
||||
QWEN_MODEL = _os.environ.get('QWEN_MODEL', 'qwen3.6')
|
||||
|
||||
OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions"
|
||||
HERMES_ENABLED = bool(HERMES_API_KEY and HERMES_API_URL)
|
||||
@@ -394,7 +403,7 @@ def classify_part(part_number):
|
||||
|
||||
for url, key, model_id in backends:
|
||||
_validate_model(model_id)
|
||||
result = _post_chat_completion(url, key, model_id, messages, max_tokens=300, temperature=0.2, timeout=15)
|
||||
result = _post_chat_completion(url, key, model_id, messages, max_tokens=800, temperature=0.2, timeout=70)
|
||||
if result is None:
|
||||
continue
|
||||
content = result["content"]
|
||||
@@ -543,7 +552,7 @@ def chat_cache_clear():
|
||||
_RESPONSE_CACHE.clear()
|
||||
|
||||
|
||||
def chat(user_message, conversation_history=None, inventory_context=None):
|
||||
def chat(user_message, conversation_history=None, inventory_context=None, persona=None):
|
||||
"""Send a message to the AI and get a response with search suggestions.
|
||||
|
||||
Caches responses for repeated identical questions (subject to bypass
|
||||
@@ -553,6 +562,7 @@ def chat(user_message, conversation_history=None, inventory_context=None):
|
||||
user_message: The user's chat message.
|
||||
conversation_history: Previous messages in the conversation.
|
||||
inventory_context: Optional inventory summary string to inject into the system prompt.
|
||||
persona: Optional persona intro (first line of system prompt) for tenant branding.
|
||||
"""
|
||||
# Cache lookup — only when there's no conversation history (stateless)
|
||||
cache_key = None
|
||||
@@ -564,6 +574,9 @@ def chat(user_message, conversation_history=None, inventory_context=None):
|
||||
return cached
|
||||
|
||||
system_content = SYSTEM_PROMPT
|
||||
if persona:
|
||||
# Replace the hardcoded first line (persona de marca por tenant)
|
||||
system_content = persona + "\n" + system_content.split("\n", 1)[1]
|
||||
if inventory_context:
|
||||
system_content = SYSTEM_PROMPT + "\n\n" + inventory_context
|
||||
|
||||
|
||||
Reference in New Issue
Block a user