Informe: cómo funcionaba el bot original MoneyPro
Investigación del 2026-07-02 sobre los proyectos
C:/Users/pined/Escritorio/Agente moneypro(original, agent.py de 8.204 líneas) yC:/Users/pined/Escritorio/Agente moneypro headless(refactor con Lambda AWS). Objetivo: identificar las virtudes que explican que “corriera bastante bien” para portarlas al bot nuevo de finanzas-app.
1. Arquitectura (flujo de punta a punta)
Meta Webhook (WhatsApp)
↓
API Gateway AWS (https://8u8c5ws3xb.execute-api...)
↓
Lambda NLP (nlp_extracted/handler.py:2050-2092)
├─ Interpreta el mensaje con Claude Haiku (Bedrock)
├─ Construye contexto con categorías/payees/historial (context_builder.py:292-328)
└─ Empuja el resultado a SQS FIFO
↓
SQS: moneypro-commands.fifo (agent.py:55)
↓
Agente local (headless_engine.py + agent.py)
├─ Consume con long-polling (agent.py:8027-8041)
├─ Ejecuta la transacción en la UI de MoneyPro vía RPA (pywinauto)
├─ Persiste en el SQLite local de MoneyPro
└─ Notifica el resultado vía Lambda Notifier (agent.py:77-81)
↓
Lambda Notifier (lambda_extracted/handler.py:66-118) → respuesta a WhatsApp
- Fuente de verdad: SQLite local de MoneyPro (
%LOCALAPPDATA%\Packages\iBearLLC...). - Backup remoto: Appwrite Storage (ZIP tras cada transacción exitosa, appwrite_sync.py:115-179).
- Contexto conversacional: DynamoDB (
USER#{sender}#PROFILE#{profile_id}) con categorías, payees, historial (10 intercambios) y estado de confirmación.
2. Cerebro NLP/LLM
- Modelo: Claude Haiku 4.5 vía Bedrock,
temperature=0.0,max_tokens=500, respuesta solo-JSON. - Prompt multiestrato (context_builder.py): estructura de MoneyPro (activo/pasivo/gasto/ingreso), categorías y payees reales sincronizados desde DynamoDB, reglas de conversación (“Reglas de Oro”), y 20+ ejemplos incluidos casos edge.
- Confirmación en dos fases: extrae borrador → si falta algo pregunta (
status: incomplete+partial_dataguardado en DynamoDB) → usuario responde → combina y re-invoca → “¿Procedo?” → solo ejecuta con confirmación explícita. El estado vive en BD, NO en la sesión del LLM: nunca “olvida” datos parciales entre turnos. - 13 rutas heurísticas PRE-LLM (regex) interceptan ~80% de los mensajes (saludo, saldo, deudas, gastos por período, informes, presupuesto, gestión, soporte, etc.) → solo lo ambiguo sube a Bedrock. Menos latencia y costo.
- Enriquecimiento POST-LLM agresivo (handler.py:1697-1891): corrige tipos confundidos (compra de activo vs gasto), rechaza payees genéricos inventados (lista
_GENERIC_PAYEES), extrae nombres de activos/pasivos por regex, normaliza fechas/horas, exige subcategoría cuando el tronco las tiene.
3. Funcionalidades que tenía
- 8 tipos de transacción: gasto, ingreso, transferencia, compra/venta de activo, adquisición/descarga/pago de pasivo — con campos payee, nota, clase (Negocios/Personal), estado de pago (pagada/sin pagar/planificada) y repetición (diaria→anual con fecha fin).
- Multi-transacción: “compré X por 35.300 y Y por 35.000” → 2 registros, cada uno con SU nota.
- Consultas: saldo, patrimonio neto, gastos del mes por categoría, deudas, pendientes, historial, categorías, payees.
- CRUD conversacional: editar/borrar transacciones (“me equivoqué”), crear/editar/borrar categorías, payees y cuentas.
- Informes y gráficos (analytics_engine.py): pie de gastos, barras últimos 30 días, ingreso vs gasto, y predicción de gasto del próximo mes por regresión OLS; PNGs subidos a Appwrite.
- Notificador diario (daily_notifier.py): pendientes vencidos vs programados de hoy, con botón “✅ Marcar Pagados”.
- Resiliencia: dedupe con ring-buffer de 1000 message_ids, descarte de mensajes SQS >5 min, reintento si la UI falla (el mensaje queda en la cola), backoff exponencial 5→60s.
4. Las 7 virtudes a portar al bot nuevo
- Prompt restrictivo y específico — 11 reglas imperativas numeradas (“NUNCA inventes categorías”, “SIEMPRE extrae payee y note”), no instrucciones genéricas.
- Confirmación en dos fases con estado persistente en BD — el borrador incompleto sobrevive entre turnos; la pregunta clarificadora pide SOLO el campo faltante.
- Heurísticas pre-LLM — regex primero, LLM solo para lo ambiguo.
- Enriquecimiento/validación post-LLM — nunca confiar ciegamente en el JSON del modelo.
- Subcategorización obligatoria — datos con 2 niveles de profundidad para reportes.
- Historial conversacional inyectado solo cuando hay flujo activo — evita contaminación.
- Formato WhatsApp-first — emojis, líneas cortas, botones; nada de paredes de texto.
5. Relación entre los dos proyectos
headless es un refactor del original: el NLP completo se extrajo de agent.py (8.204 líneas) a la Lambda (nlp_extracted/handler.py, 2.877 líneas) y el RPA se redujo a lo mínimo (730 líneas). Comparten query_handler.py, report_capabilities.py, text_utils.py y appwrite_sync.py.
6. Archivos clave como referencia para portar
| Archivo (en headless) | Propósito | Prioridad |
|---|---|---|
nlp_extracted/context_builder.py | Construcción del prompt (reglas + ejemplos) | Máxima |
nlp_extracted/handler.py | Flujo NLP, heurísticas, enriquecimiento | Máxima |
nlp_extracted/concept_glossary.py | Glosario de tipos de transacción | Alta |
query_handler.py | Consultas SQL | Alta |
analytics_engine.py | Dashboard + predicción OLS | Media |
daily_notifier.py | Notificaciones de pendientes | Media |
7. Estado actual (post-migración 2026-07-02)
El webhook de Meta ya NO apunta a este pipeline (ver fixes-2026-07-02.md §3): ahora va a api.finanzasai.me. El pipeline viejo (API Gateway 8u8c5ws3xb + Lambda + SQS moneypro-commands.fifo) sigue desplegado en AWS pero sin tráfico — apagarlo cuando el bot nuevo esté confirmado, y considerar portar las virtudes de arriba antes de desmantelarlo.