
    i                        d Z ddlZddlZddlmZmZm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZmZmZmZ ddlmZ d	d
lmZ ddlmZ ddlmZ  ej:                  e      ZdZ dZ!dZ" eejF                  d      Z$ G d d      Z%y)zY
Servicio de flujos multi-paso: redirect a agente, consulta de saldo y opciones de pago.
    N)HumanMessage	AIMessageSystemMessage)
ChatOpenAI)	get_tools)_extract_mcp_result)BALANCE_PROMPTPAYMENT_PROMPT
FAQ_PROMPTFAQ_MARCIMEX)settings   )SearchChatResponse)session_manager   )IdentityServiceiX     )modeltemperaturec                   z   e Zd ZdZdefdZdededededz  fd	Z	d
e
defdZ	 	 ddededededz  ded
e
dedz  dedz  defdZ	 	 ddeded
e
dededz  dedz  defdZ	 	 ddeded
e
dedz  dedz  defdZdeded
e
defdZdededededz  fdZ	 	 ddeded
e
dededz  dedz  defdZdeded
e
defdZy)FlowServiceuF   Máquinas de estado multi-paso para redirect a agente, balance y pago.identity_servicec                     || _         y )N)identity)selfr   s     9/opt/lhia/marcimex/agent/app/api/services/flow_service.py__init__zFlowService.__init__!   s	    (    uuidredirect_ctxqueryreturnNc                 0  K   d| }|j                  d      }|j                  d      }|j                  d      }t        j                  |       d{   }|j                  j                  dg       }	|dk(  r[|j	                         }
| j
                  j                  |
      sT|j                  dd	      d
z   }t        j                  d| d|
 d| d       |dk\  rat        j                  j                  |       d{    t        j                  d| d| d       | j                  |||	|||       d{   S ||d<   t        j                  j                  |t        t        j                   |             d{    d}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S |
|d<   d|d<   t        j                  j                  |t        t        j                   |             d{    t        j                  d| d|
 d       d}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S |dk(  rV|j	                         j-                         }|dv rd}nj|dv rd }nb|j                  d!d	      d
z   }t        j                  d| d"|j	                          d| d       |dk\  rat        j                  j                  |       d{    t        j                  d| d#| d       | j                  |||	|||       d{   S ||d!<   t        j                  j                  |t        t        j                   |             d{    d$}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S |j                  dd%      }
|dk(  rf|j                  d&      }|rxt        j                  d'| d(| d)|        |j/                  d*d+      }t        j                  j                  |       d{    | j1                  ||
||||	|||	       d{   S ||d,<   d-|d<   t        j                  j                  |t        t        j                   |             d{    t        j                  d| d(| d.       d/}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S t        j                  j                  |       d{    | j1                  ||
|d||	|||	       d{   S |d-k(  r|j	                         }|j                  dd%      }
|j                  d,d      }| j
                  j3                  |      }|sT|j                  d0d	      d
z   }t        j                  d| d1| d| d       |dk\  rat        j                  j                  |       d{    t        j                  d| d2| d       | j                  |||	|||       d{   S ||d0<   t        j                  j                  |t        t        j                   |             d{    d3}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S |j/                  d*d+      }t        j                  j                  |       d{    t        j                  d| d4| d5       | j1                  ||
||||	|||	       d{   S y7 7 V7 7 7 {7 $7 7 7 7 ~7 7 7 o7 (7 7 v7 X7 7 l7 *7 7 7 Ew)6u  
        Maneja el flujo multi-paso de redirección a agente humano.
        Pasos: awaiting_cedula → awaiting_tipo_pago → (si Crédito) awaiting_fecha_nacimiento → MCP
        Tras 2 intentos fallidos en cualquier paso se llama redirect_to_agent_direct.
        search_redirect_ctx:stepplatform_idusuarioNmessagesawaiting_cedulacedula_attemptsr   r      ⚠️ [u"   ] Cédula inválida en redirect: '' (intento )r      🚨 [   ] Cédula inválida (    veces — redirigiendo a asesor directof   La cédula ingresada no es válida. Por favor, verifica e ingresa tu número de cédula correctamente:contentAGENTuuid_conversationanswerintenttotalproductscedulaawaiting_tipo_pagou   📋 [   ] Cédula recibida: z. Pidiendo tipo de pago.u   ¡Gracias! 😊

Ahora, por favor selecciona el tipo de pago:

1️⃣ Crédito Directo
2️⃣ Efectivo / Tarjetas

Escribe el número o el nombre de la opción para continuar:)1zcredito directou   crédito directocreditou   créditozCredito Directo)2zefectivo/tarjetasefectivotarjetastarjetazefectivo tarjetaszEfectivo/Tarjetastipo_pago_attemptsz] Tipo de pago no reconocido: 'z] Tipo de pago no reconocido u   No reconocí esa opción. Por favor selecciona el tipo de pago:

1. Crédito Directo
2. Efectivo/Tarjetas

Escribe el número o el nombre de la opción: fecha_nacimiento_saved   🔑 [z] Tipo de pago: z. Reutilizando fecha guardada: -/	tipo_pagoawaiting_fecha_nacimiento. Pidiendo fecha de nacimiento.uT   Para Crédito Directo 💳 necesito tu fecha de nacimiento 📅

Ejemplo: 25/07/1997fecha_attemptsu   ] Fecha no válida: '] Fecha invalida us   No pude reconocer la fecha ingresada. Por favor, ingrésala nuevamente (ejemplo: 25 de julio de 1997 o 25-07-1997):z] Fecha de nacimiento: z. Invocando redirect_to_agent.)getr   get_sessionstatestripr   validate_cedulaloggerwarningclientdeleteinfoinvoke_redirect_to_agent_directsetexREDIRECT_CTX_TTLjson_moddumpsappendLCHumanMessageLCAIMessagesave_sessionr   lowerreplace_invoke_redirect_to_agent
parse_date)r   r   r    r!   REDIRECT_CTX_KEYr%   r&   r'   sessionhistory_messagesr;   attemptsr7   rawrJ   saved_fecha	fecha_api	raw_fechafecha_normalizadas                      r   handle_redirect_flowz FlowService.handle_redirect_flow(   s     2$8'"&&}5""9-'33D99"==,,Z<$$[[]F==008'++,=qAAE$/QRXQYYdemdnnopqq=)00778HIIIKK&.B8*Lt uv!%!E!Ee%5wW"   3;./%,,223CEUW_WeWefrWsttt B ''u(EF ''F(CD,<j)%224AAA)&*6'QR]_  &,L"#7L !((.. "2HNN<4P   KK&&:6(BZ[\ PF##N5$AB##K$?@(8GMM*%!..tW===%"&vgQY[  ))++-%%'CYY-	jj/	'++,@!DqH$/Nu{{}o]hiqhrrstuq=)00778HIIIKK&.KH:U} ~!%!E!Ee%5wW"   6>12%,,223CEUW_WeWefrWsttt y ''u(EF ''F(CD,<j)%224AAA)&*6'QR]_  "%%h3F--*../GHKK&.>ykIhithu vw + 3 3C =I)00778HIII!%!?!?fiECSU\#W"  
 -6[)'BV$%,,22$&6|8T   fTF*:9+Edefq ''u(EF ''F(CD,<j)%224AAA)&*6'QR]_  &,,334DEEE!;;&)T5:JG  
 00I!%%h3F$((6GHI $ 8 8 C$'++,<a@1D$/DYK{[cZddefgq=)00778HIIIKK&.?zIq rs!%!E!Ee%5wW"   2:-.%,,223CEUW_WeWefrWsttt O ''u(EF ''F(CD,<j)%224AAA)&*6'QR]_  *11#s;I!((//0@AAAKK&&=i[Hfgh77fiE;KWW  
 W : J u
 B >" J u
 B J B F J u
 B Bs  AbaB-ba9b;a<Ab aA$b%a &Ab?a# B b a&B1b2a)39b,a,-Ab1a/2A$ba2Bb(a5) b	a8
A	ba;B ba>6bb b,b-B7b$b%9bb
Ab#b$A$bb	Abb<bbbbbb b#b&b)b,b/b2b5b8b;b>bbbb
bbbbbrh   c                    d}|s|S 	 g }|D ]c  }t        |t              r|j                  d|j                          2t        |t              sC|j                  d|j                  dd         e dj                  |      j                         }|s|S t        j                  t        d| d	      g      }|j                  j                         }|r|S |S # t        $ r |cY S w xY w)
u\   Genera un resumen completo de la conversación con emojis y análisis emocional del usuario.z+Usuario solicito que se le asigne un asesorz	Usuario: zAsistente: N,  
u  Eres un analista experto en experiencia de cliente. Analiza la conversación entre un usuario y un asistente de ventas.

Genera un resumen BREVE que incluya:
1. 🛒 Productos e intereses: productos, categorías, marcas, precios o características mencionadas.
2. 📋 Resumen de la conversación: breve y claro, máximo 3-4 líneas.
3. 😊 Análisis emocional: emociones detectadas con porcentajes y emojis.
4. 💡 Necesidad principal: en una sola oración.

Usa emojis de forma natural y responde en español.

CONVERSACIÓN COMPLETA:
z


RESUMEN:r2   )
isinstancer_   r^   r3   r`   joinrR   _llminvoker   	Exception)r   rh   defaultlinesmsgconversation_textresponsesummarys           r   _build_resumenzFlowService._build_resumen   s    ?N	E' Dc>2LL9S[[M!:;[1LL;s{{4C/@.A!BC	D
 !%		% 0 6 6 8${{, ->+>lL	$ H &&,,.G%7272 	N	s&   AC AC AC C C'&C'r;   rJ   fecha_nacimientor&   r'   c
           	      :  K   | j                   j                  t        j                  |||       d{    d}
| j	                  |      }	 t               }t        d |D        d      }|rmt        j                  d| d       |||d}|r||d<   |	r|	|d<   |r||d	<   |j                  |      }t        j                  d
| dt        |      dd         nt        j                  d| d       |j                  t        |             |j                  t!        |
             ||j"                  d<   t        j$                  ||       d{    t'        ||
ddd|g       S 7 3# t        $ r%}t        j                  d| d|        Y d}~d}~ww xY w7 Jw)zOInvoca el tool redirect_to_agent via MCP, guarda identidad y retorna respuesta.NREDIRECTION_ASESOR_BOTc              3   @   K   | ]  }|j                   d k(  s|  yw)redirect_to_agentNname.0ts     r   	<genexpr>z8FlowService._invoke_redirect_to_agent.<locals>.<genexpr>   s     !Taff@S6S!!T      📡 [z(] Invocando redirect_to_agent via MCP...)r;   rJ   resumen_conversacion
platformIdr'   r      📥 [z] Resultado MCP redirect: rq   r+   z&] Tool redirect_to_agent no encontrado   ❌ [z] Error en redirect_to_agent: r2   r(   r4   r   Tr6   r7   r8   r9   redirect_asesorsummary_agentr:   )r   save_identityr   rV   r~   r   nextrT   rX   rv   strrU   rw   errorr^   r_   r`   rQ   ra   r   )r   r   r;   rJ   r   r!   rh   rg   r&   r'   r7   resumentoolsredirect_toolparamsresultes                    r   rd   z%FlowService._invoke_redirect_to_agent   s     mm))/*@*@$P`aaa)%%&67	JKE !TU!TVZ[MfTF*RST$*\cd+6F<((/F9%#1AF-.&--f5fTF*DS[QURUEVDWXY$/UVW
 	u =>F ;<$4j!**4999!" !
 	
; 	b*  	JLL5&DQCHII	J 	:sG   0FE%FB%E( 0AFFF(	F1FFFFquestionexisting_identityc                   K   d| }|j                  d      }	|j                  d      }
|	rt        j                  d| d|	        d}d|	d}|
r|
|d	<   |r||d
<   |r||d<   t        j                  j                  |t        t        j                  |             d{    |j                  t        |             |j                  t        |             ||j                  d<   t        j                  ||       d{    t        ||ddg       S d}ddi}|r||d
<   |r||d<   t        j                  j                  |t        t        j                  |             d{    |j                  t        |             |j                  t        |             ||j                  d<   t        j                  ||       d{    t        ||ddg       S 7 ?7 7 |7 w)uM   Inicializa el flujo AGENT, reutilizando cédula guardada si está disponible.r$   r;   r   rG   "   ] Reutilizando cédula existente: uh   Ahora, ¿cómo te gustaría realizar el pago? 💳

1️⃣ Crédito Directo
2️⃣ Efectivo / Tarjetasr<   )r%   r;   rF   r&   r'   Nr2   r(   r4   r   r5   u   Para asignarte un asesor lo más pronto posible, necesito validar un dato 😊
¿Me compartes tu número de cédula, por favor?r%   r)   )rO   rT   rX   r   rV   rZ   r[   r\   r]   r^   r_   r`   rQ   ra   r   )r   r   r   rh   rg   r   r&   r'   rf   saved_cedulark   r7   r    s                r   init_redirect_flowzFlowService.init_redirect_flow  s     2$8(,,X6'++,>?KK&&HWX CF*>,!WL9D56.9]+*1Y'!((.. "2HNN<4P   ##N8$DE##K$?@(8GMM*%!..tW===%"&vgQY[  T 12*5L'&-L#$$**.|0L
 	
 	
 	x @AF ;<$4j!**4999!"6'UW
 	
5 >	
 	:sK   BG&GA"G&G A#G&%G"&A"G&G$	G& G&"G&$G&c           	        K   d}| j                  |      }	 t               }	t        d |	D        d      }
|
rt        j	                  d| d       t        j	                  d| d| d| d	       d
|i}|r||d<   |r||d<   |
j                  |      }t        j	                  d| dt        |      dd         nt        j                  d| d       |j                  t        |             |j                  t        |             ||j                  d<   t        j                  ||       d{    t!        ||ddd|g       S # t        $ r%}t        j                  d| d|        Y d}~d}~ww xY w7 Gw)z
        Invoca redirect_to_agent_direct via MCP para usuarios frustrados o atascados.
        No requiere flujo multi-paso: solo necesita platformId y usuario.
        r   c              3   @   K   | ]  }|j                   d k(  s|  yw)redirect_to_agent_directNr   r   s     r   r   z>FlowService.invoke_redirect_to_agent_direct.<locals>.<genexpr>a  s     ![aff@Z6Z!![r   Nr   z/] Invocando redirect_to_agent_direct via MCP...u   🔎 [u#   ] Datos recibidos → platform_id='z' | usuario=''r   r   r'   r   z!] Resultado MCP redirect_direct: rq   r+   z-] Tool redirect_to_agent_direct no encontrador   z%] Error en redirect_to_agent_direct: r2   r(   AGENT_DIRECTr   Tr   )r~   r   r   rT   rX   rv   r   rU   rw   r   r^   r_   r`   rQ   r   ra   r   )r   r   r!   rh   rg   r&   r'   r7   r   r   r   r   r   r   s                 r   rY   z+FlowService.invoke_redirect_to_agent_directP  s     *%%&67	QKE ![U![]abMfTF*YZ[fTF*Mk]Zghogppqrs0':+6F<((/F9%&--f5fTF*KCPVKX\Y\L]K^_`$/\]^
 	u =>F ;<$4j!**4999!"! !
 	
  	QLL5&KA3OPP	Q 	:s<   E:B;E AE:0E81E:	E5E0+E:0E55E:c                 V  K   t         j                  d| d|dd  d       t        |      dkD  }|rdnd}t        j                  |t
        	      }t        |      d
kD  r|dd n|}g }	|D ]r  }
t        |
t              r|	j                  |
       %t        |
dd      }d|v r"|j                  d      d   j                         }|	j                  t        |             t t        |      g}|j                  |	       |j                  t        |             d}	 t        j!                  |      }|j"                  j                         xs |}t         j                  d| d       |j                  t        |             |j                  t        |             t        |      t(        kD  r
|t(         d }||j*                  d<   t-        j.                  ||       d{    t1        ||ddg       S # t$        $ r%}t         j'                  d| d|        Y d}~d}~ww xY w7 Ew)zNResponde preguntas generales usando el FAQ embebido directamente en el prompt.u   ❓ [z] Manejando pregunta FAQ: 'NP   r   r   u`   
IMPORTANTE: Ya hay conversación previa. NO saludes ni digas 'Hola'. Ve directo a la respuesta.rE   )no_greeting_rulefaq_content
   r3   z[CONTEXTO DEL SISTEMAr2   un   En este momento no tengo esa información disponible. Te recomiendo contactar a uno de nuestros asesores. 😊   ✅ [z] Respuesta FAQ generadar   z] Error en handle_faq: r(   OTHERr5   )rT   rX   lenr   formatr   rs   r_   r^   getattrsplitrR   r`   r   extendru   rv   r3   rw   r   MAX_TOTAL_HISTORYrQ   r   ra   r   )r   r   r!   rh   rg   has_historyr   system_promptrecent_historycleaned_historymr3   llm_messagesr7   r|   r   s                   r   
handle_faqzFlowService.handle_faq  s4     	eD6!<U3BZLJK*+a/  p " 	
 #))-$

 477G3H23M)#$/Sc  	EA!^,&&q)!!Y3*g5%mm,CDQGMMOG&&{7'CD	E &m<=O,N59: B	C{{<0H%%++-7FKK%v%=>? 	u =>F ;< #44/1B0B0CD$4j!**4999!"
 	
  	CLL5&=aSABB	C 	:s>   DH)AG6 'A:H)!H'"H)6	H$?HH)H$$H)balance_ctxc                   K   d| }|j                  d      }|j                  d      }|j                  d      }t        j                  |       d{   }|j                  j                  dg       }	|dk(  r\|j	                         }
| j
                  j                  |
      sT|j                  dd	      d
z   }t        j                  d| d|
 d| d       |dk\  rat        j                  j                  |       d{    t        j                  d| d| d       | j                  |||	|||       d{   S ||d<   t        j                  j                  |t        t        j                   |             d{    d}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S 	 t-               }t/        d |D        d      }|r|j1                  d|
i      }t3        |      }t5        |t6              r||j                  dd      si|j                  dd	      d
z   }|j                  dd      }t        j                  d| d|
 d| d| d	       |dk\  rat        j                  j                  |       d{    t        j                  d| d | d       | j                  |||	|||       d{   S ||d<   t        j                  j                  |t        t        j                   |             d{    d}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S t        j                  d!| d"|
        nt        j                  d| d#       |
|d<   d'|d<   t        j                  j                  |t        t        j                   |             d{    t        j                  d(| d)|
 d*       d+}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S |d'k(  r|j	                         }|j                  dd      }| j
                  j=                  |      }|sT|j                  d,d	      d
z   }t        j                  d| d-| d| d       |dk\  rat        j                  j                  |       d{    t        j                  d| d.| d       | j                  |||	|||       d{   S ||d,<   t        j                  j                  |t        t        j                   |             d{    d/}|	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S t        j                  j                  |       d{    | j
                  j?                  t        j                  |||       d{    t        j                  d(| d0| d1| d2       d3}	 t-               }t/        d4 |D        d      }|rIt        j                  d5| d6       |j1                  ||d7      }t        j                  d8| d9tA        |      dd:         t3        |      }t5        |t6              rt        j                   |dd;      n
tA        |      }tC        |	      d	kD  }|rd<nd}tE        jF                  ||=      }tC        |	      d>kD  r|	d?d n|	}tI        |      g}|jK                  |       |j#                  t%        d@|              tL        j1                  |      }|jN                  }t        j                  d!| dA       nt        j                  d| dB       |	j#                  t%        |             |	j#                  t'        |             |	|j                  d<   t        j(                  ||       d{    t+        ||dd	g       S y7 7 7 7 l7 
7 %7 7 7 J# t8        $ r'}t        j;                  d$| d%| d&       Y d}~.d}~ww xY w7 7 s7 7 7 G7 7 7 # t8        $ r&}t        j;                  d$| dC|        Y d}~d}~ww xY w7 w)Du   
        Maneja el flujo multi-paso de consulta de saldo.
        Pasos: awaiting_cedula → awaiting_fecha → invoca consultar_deuda_actual via MCP.
        Tras 2 intentos fallidos en cualquier paso se llama redirect_to_agent_direct.
        search_balance_ctx:r%   r&   r'   Nr(   r)   r*   r   r   r+   u   ] Cédula inválida: 'r,   r-   r   r.   r/   r0   r1   r2   BALANCEr5   c              3   @   K   | ]  }|j                   d k(  s|  yw)validar_cedulaNr   r   s     r   r   z2FlowService.handle_balance_flow.<locals>.<genexpr>  s     $T1CS9SQ$Tr   nro_idevalidaFmensajerE   u   ] Cédula inválida por MCP: z - z
 (intento u   ] Cédula inválida por MCP r   u   ] Cédula válida: uI   ] Tool validar_cedula no encontrado, continuando con validación básica.r   u#   ] Error validando cédula via MCP: u&   . Continuando con validación básica.awaiting_fechau   💰 [r=   rL   uO   ¡Gracias! 😊
Solo me falta tu fecha de nacimiento para poder para continuar.rM   z] No se pudo parsear fecha: 'rN   zvNo pude interpretar la fecha. Por favor ingresa tu fecha de nacimiento, por ejemplo: 25 de julio de 1997 o 25-07-1997.z] Fecha recibida: 'u   ' → parseada: z#. Invocando consultar_deuda_actual.uI   No pude consultar tu saldo en este momento. Por favor intenta más tarde.c              3   @   K   | ]  }|j                   d k(  s|  yw)consultar_deuda_actualNr   r   s     r   r   z2FlowService.handle_balance_flow.<locals>.<genexpr>D  s     "ZqvvAY7Y1"Zr   r   z-] Invocando consultar_deuda_actual via MCP...)r   r   r   z] Resultado MCP saldo:   ensure_asciiindentuc   IMPORTANTE: Ya hay conversación previa. NO saludes ni digas 'Hola'. Ve directo a la información.
)history_hintbalance_datar   r   u   Consulta de saldo para cédula z%] Respuesta de saldo generada con LLMz2] Tool consultar_deuda_actual no encontrado en MCPz#] Error en consultar_deuda_actual: )(rO   r   rP   rQ   rR   r   rS   rT   rU   rV   rW   rX   rY   rZ   BALANCE_CTX_TTLr\   r]   r^   r_   r`   ra   r   r   r   rv   r   rs   dictrw   r   re   r   r   r   r	   r   r   r   ru   r3   ) r   r   r   r!   BALANCE_CTX_KEYr%   r&   r'   rg   rh   r;   ri   r7   r   validar_tool
val_resultval_datamensaje_tecnicor   rm   r   r   
saldo_toolr   r   balance_textr   r   r   r   r   r|   s                                    r   handle_balance_flowzFlowService.handle_balance_flow  sj	     0v6v&!oom4//),'33D99"==,,Z<$$[[]F==008&??+<a@1D$/EfX[YaXbbcdeq=)0077HHHKK&.B8*Lt uv!%!E!Ee%5wW"   2:-.%,,22?OU]UcUcdoUpqqq B ''u(EF ''F(CD,<j)%224AAA)&*6)ST_a 
 y!#$T$TVZ[!-!4!4i5H!IJ2:>H!(D1(,,xQV:W#.??3Da#H1#L*2,,y"*E$7TU[T\\_`o_ppz  |D  {E  EF  (G  H#q="1"8"8"?"?"PPP"KK&6RS[R\  ]E  )F  G)-)M)M $e-=wU\* $  :B$56-44::?O]e]k]klw]xyyy "J(//u0MN(//F0KL4Dj1-::4III1.26)[\gi   KK%v-@ IJNNXdV3|#}~ &,K	""2K!((..(..2M   KK&&:6(BabcgF##N5$AB##K$?@(8GMM*%!..tW===%"&viq[]  %%I!ooi4G#}}77	B#&??+;Q?!C$/LYKWbckbllmnoq=)0077HHHKK&.?zIq rs!%!E!Ee%5wW"   19,-%,,22?OU]UcUcdoUpqqq R ''u(EF ''F(CD,<j)%224AAA)&*6)ST_a  "((//@@@----o.D.DdGUefffKK&&9)DTUeTf  gJ  K  L`F&S!!"Ze"Z\`a
KK&.[ \]'..7Xh/ijFKK&.Ec&kRVSVFWEX YZ#6v#>L &lD9 !|%PQR . ! #&&6"7!";K ' ,. ! %3$9$9%1%1%M
 @CCS?TWY?Y%5cd%;_oN$1-$H#IL ''7 ''A`ah`i?j(kl#{{<8H%--FKK%v-R STNNXdV3e#fg
 ##N5$AB##K$?@(8GMM*%!..tW===%"&viq[]  { : I r
 B& Q$ z
 J  yuTF*MaSPvwxxy
 > I r
 B
 AfR  SuTF*MaSQRRS >s  Ae=c#B-e=c&9e=;c)<Ae= c,A$e=%c/&e=;Cc> c29c> c5c> e=A c> c8A$c> 1c;2c> e=5c> ;Ae= d1B e=d4B5e=7d789e=1d:2Ae=6d=7A$e=e 6e=e3e=e%e=-Fe	 /Ae=e;e=&e=)e=,e=/e=2c> 5c> 8c> ;c> >	d.d)#e=)d..e=4e=7e=:e==e= e=e=e=		e8e3-e=3e88e=c                 <  K   d| }|j                  d      }	|j                  d      }
|	r|
rt        j                  d| d|	        d}|j                  t	        |             |j                  t        |             ||j                  d<   t        j                  ||       d	{    |	d
d}|r||d<   |r||d<   | j                  |||
       d	{   }|r|S |	rt        j                  d| d|	 d       d}d
|	d}|r||d<   |r||d<   t        j                  j                  |t        t        j                  |             d	{    |j                  t	        |             |j                  t        |             ||j                  d<   t        j                  ||       d	{    t        ||ddg       S d}ddi}|r||d<   |r||d<   t        j                  j                  |t        t        j                  |             d	{    |j                  t	        |             |j                  t        |             ||j                  d<   t        j                  ||       d	{    t        ||ddg       S 7 7 7 E7 7 7 !w)uS   Inicializa el flujo BALANCE, reutilizando datos de identidad si están disponibles.r   r;   r   rG   u,   ] Reutilizando identidad existente: cédula=z5Ya tengo tus datos registrados. Consultando tu saldo.r2   r(   Nr   )r   r%   r&   r'   r   z. Pidiendo fecha.uT   ✅ Ya tengo tu cédula registrada.

Ahora solo necesito tu fecha de nacimiento 📅)r%   r   r   r   r5   ur   Con gusto te ayudo a consultar tu saldo 😊
Para poder verificar tu información, necesito tu número de cédula.r%   r)   )rO   rT   rX   r^   r_   r`   rQ   r   ra   r   rV   rZ   r   r\   r]   r   )r   r   r   rh   rg   r   r&   r'   r   r   rk   r7   r   balance_responses                 r   init_balance_flowzFlowService.init_balance_flowu  s     0v6(,,X6'++,>?KKK&&RS_R`abLF##N8$DE##K$?@(8GMM*%!..tW===,8BR SK-8M*)0I&%)%=%=dKQ\%]]''KK&&HVghimF#3MK-8M*)0I&!((..(..2M   ##N8$DE##K$?@(8GMM*%!..tW===%"&viq[]  G01)4K&%,K	"$$**_hnn[.I
 	
 	
 	x @AF ;<$4j!**4999!"6)1WY
 	
[ >  ^ >	
 	:sp   B'J)J*-JJA6JJA"J1J2A#JJA"J8J9JJJJJJc                 
  K   t         j                  d| d       d}	 t               }t        d |D        d      }|rt         j                  d| d       |j	                  i       }t         j                  d| d	t        |      dd
         t        |      }t        |t        t        f      rt        j                  |dd      }n%t        |      }nt         j                  d| d       t        |      dkD  }
|
rdnd}t!        j"                  ||      }t%        |      g}t        |      dkD  r|dd n|}|j'                  |       |j)                  t+        |             t,        j	                  |      }|j.                  }t         j                  d| d       t1        j2                  |       d{   }|j)                  t+        |             |j)                  t5        |             t        |      t6        kD  r
|t6         d }||j8                  d<   t1        j:                  ||       d{    t=        ||ddg       S # t        $ r&}	t         j                  d| d|	        Y d}	~	d}	~	ww xY w7 7 Hw)zUConsulta las opciones de pago via MCP get_payment_options y genera respuesta con LLM.u   💳 [z&] Consultando opciones de pago via MCPz<No se pudieron obtener las opciones de pago en este momento.c              3   @   K   | ]  }|j                   d k(  s|  yw)get_payment_optionsNr   r   s     r   r   z-FlowService.handle_payment.<locals>.<genexpr>  s      UqQVV?T5T Ur   Nr   z*] Invocando get_payment_options via MCP...r   z] Resultado MCP payment: r   Fr   r   r+   z/] Tool get_payment_options no encontrado en MCPr   z ] Error en get_payment_options: r   uk   IMPORTANTE: Ya hay conversación previa. NO saludes ni digas 'Hola'. Ve directo a la información de pago.
rE   )r   tool_resultr2   r   r   r   z] Respuesta de pago generadar(   PAYMENTr5   )rT   rX   r   r   rv   r   r   rs   r   listr\   r]   rU   rw   r   r   r
   r   r   r   r^   r_   ru   r3   r   rP   r`   r   rQ   ra   r   )r   r   r!   rh   r   r   payment_tool
raw_resultpayment_datar   r   r   r   r   r   r|   r7   rg   s                     r   handle_paymentzFlowService.handle_payment  sf     	fTF"HIJT	LKE UE UW[\LfTF*TUV)004
fTF*CC
OTXUXDYCZ[\2:>lT4L9"*..EZ["\K"%l"3K$/^_`
 *+a/  { " 	 '--<U`a%m<=367G3H23M)#$/ScN+N59:;;|,!!eD6!=>?'33D99u =>F ;< #44/1B0B0CD$4j!**4999!"6)1WY
 	
7  	LLL5&FqcJKK	L& : 	:sO   JCI .CJ9I?:A>J8J9J	I<I71J7I<<JJ)NN)__name__
__module____qualname____doc__r   r   r   r   r   ro   r   r~   rd   r   rY   r   r   r   r    r   r   r   r      sf   P) )[[ [ 	[
 
d	"[zt  R #'"2
2
 2
 	2

 *2
 2
 2
 4Z2
 t2
 
2
v #'"5
5
 5
 	5
  5
 4Z5
 t5
 
5
z #'"0
0
 0
 	0
 4Z0
 t0
 
0
l:
:
 :
 	:
 
:
@mm m 	m
 
d	"ml #'"D
D
 D
 	D
  D
 4ZD
 tD
 
D
T8
8
 8
 	8

 
8
r   r   )&r   jsonr\   logginglangchain_core.messagesr   r_   r   r`   r   langchain_openair   mcp_integration.toolsr   agent.chat_products_nodesr   agent.promptsr	   r
   r   r   config.settingsr   modelsr   core.session_managerr   r   r   	getLoggerr   rT   r[   r   r   
MODEL_NAMEru   r   r   r   r   <module>r      sz      
 ( + 9 R R $ ' 0 -			8	$  ++;Y
 Y
r   