Files
Autoparts-DB/scripts/suggest_meli_answer.py
consultoria-as a386ca5b4a
Some checks failed
CI / lint-and-test (3.11) (push) Has been cancelled
CI / lint-and-test (3.13) (push) Has been cancelled
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
2026-10-12 00:57:31 +00:00

83 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""A7 CLI — intent + suggested answer for MercadoLibre buyer questions.
Uses ``services.question_ai``. Never sends anything unless ``--auto-answer`` is
given AND the tenant has ``meli_auto_answer_questions = true``.
Usage (from /home/Autopartes):
python3 scripts/suggest_meli_answer.py --tenant 28 --question 123
python3 scripts/suggest_meli_answer.py --tenant 28 --pending --no-llm
python3 scripts/suggest_meli_answer.py --tenant 28 --auto-answer
"""
import argparse
import json
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'pos'))
def _load_env():
env_file = '/etc/nexus/pos.env'
if os.environ.get('MASTER_DB_URL') or not os.path.exists(env_file):
return
for line in open(env_file):
line = line.strip()
if not line or line.startswith('#') or '=' not in line:
continue
k, v = line.split('=', 1)
os.environ.setdefault(k.strip(), v.strip().strip('"').strip("'"))
def main():
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument('--tenant', type=int, required=True)
ap.add_argument('--question', type=int, help='local marketplace_questions.id')
ap.add_argument('--pending', action='store_true',
help='suggest for every unanswered question (limit --limit)')
ap.add_argument('--limit', type=int, default=20)
ap.add_argument('--no-llm', action='store_true', help='templates only, no LLM fallback')
ap.add_argument('--auto-answer', action='store_true',
help='send high-confidence template answers (requires tenant flag)')
args = ap.parse_args()
_load_env()
from tenant_db import get_tenant_conn
from services import question_ai, marketplace_external_service as meli
conn = get_tenant_conn(args.tenant)
try:
if args.auto_answer:
print(json.dumps(meli.auto_answer_questions(conn), ensure_ascii=False, indent=2))
return 0
use_llm = not args.no_llm
if args.question:
result = question_ai.get_question_suggestion(conn, args.question, use_llm=use_llm)
print(json.dumps(result, ensure_ascii=False, indent=2))
return 0
if args.pending:
cur = conn.cursor()
cur.execute("""
SELECT id FROM marketplace_questions
WHERE (status IS NULL OR status = 'unanswered')
ORDER BY question_date ASC NULLS LAST LIMIT %s
""", (args.limit,))
ids = [r[0] for r in cur.fetchall()]
cur.close()
for qid in ids:
result = question_ai.get_question_suggestion(conn, qid, use_llm=use_llm)
print(json.dumps({'question_id': qid, **result}, ensure_ascii=False, indent=2))
return 0
ap.error('use --question, --pending or --auto-answer')
finally:
conn.close()
if __name__ == '__main__':
sys.exit(main())