
    Yi^/                        d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
mZ d dlmZmZ ddlmZ ddlmZmZ dd	l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 d dl m!Z!  ee!j"        d e!j#                  Z$d Z%defdZ&deded         fdZ'defdZ(defdZ)defdZ*defdZ+deded         fdZ, ee          Z-e-.                    de&           e-.                    de(           e-.                    de)           e-.                    de           e-.                    d e           e-.                    d!e           e-.                    d"e           e-.                    d#e*           e-.                    d$e+           e-/                    d           e-0                    de'ded           e-1                    dd           dd d!d"d$dZ2e-0                    de,e2           e-0                    de,e2           e-0                    d e,e2           e-0                    d!e,e2           e-0                    d"e,e2           e-1                    d$e           e-3                                Z4dS )%    N)Literal)
ChatOpenAI)SystemMessage	AIMessage)
StateGraphEND   )
AgentState)SYSTEM_PROMPTget_classification_prompt)ub_presupuesto_skill_node)cartera_skill_node)talento_humano_skill_node)resumen_pdf_skill_node)get_active_archetypesget_cached_resultsave_archetype_to_backend)settings)modeltemperatureapi_keyc                     | j                             di           }|                    dd          |                    dd          |                    dd          dS )zExtrae el consumo de tokens.token_usageprompt_tokensr   completion_tokenstotal_tokens)prompt
completiontotal)response_metadataget)messageusages     hc:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\agent\graph.pyextract_usager%      s]    %))-<<E))OQ//ii 3Q77>1--      statec                 (  K   |                      dg           }|sddiS |d         j        }t          j                    }|                      d          }|                      dd          }|r||z
  dk     rddiS |rvt          j        d|                                          }|r9t          d           |dd	|                    d
          t          d          gdS dt          d          gdS t          d           dt          d          gdS )uU   Verifica si la sesión de 12 horas ha caducado y solicita la cédula si es necesario.messagesis_authenticatingFauth_validated_ati  z^\d{10}$u;   🔒 [SECURITY] Cédula validada. Sesión iniciada por 12h.securityr   u@   ✅ Acceso validado correctamente. ¿En qué puedo ayudarte hoy?content)r,   r*   	intencionuser_cedular)   Tuk   ⚠️ El número de cédula ingresado no es válido (debe tener 10 dígitos). Por favor, intenta de nuevo.)r*   r)   uD   🔒 [SECURITY] Sesión expirada o inexistente. Solicitando cédula.uu   Hola, por motivos de seguridad tu sesión ha expirado (12h). Por favor, ingresa tu número de cédula para continuar.)	r!   r/   timerematchstripprintgroupr   )r'   r)   last_msgnowlast_valis_authcedula_matchs          r$   security_check_noder=   &   s|     yyR((H ,#U++|#H
)++Cyy,--Hii+U33G  ,S8^e++#U++  xX^^-=-=>> 	OPPP%(%*'+11!44&/qrrrs   &*&  0]  ^  ^  ^  _   

PQQQ!  (_  `  `  `  a  r&   return)classifyr   c                 ^    |                      d          s|                      d          sdS dS )uB   Decide si continuar con el flujo o detenerse a esperar la cédula.r*   r,   r   r?   )r!   )r'   s    r$   security_routerrA   O   s5    yy$%% UYY7J-K-K u:r&   c                   K   | d         }|sdddS t                       d{V }|rd                    d |D                       nd}|dd         }t                              t	          t          |          	          g|           d{V }	 |j                                        }t          j	        d
|t          j
                  }|r't          j        |                    d                    ni }t          t          |                    dg                               }	|	s+|                    d          r|                    d          g}	|                    di           }
|	|	                                |	r|	d         nd|                    d          |
|
                    d          p|                     d          |
                    d          p|                     d          t%          |          dg ddddS # t&          $ r/}t)          d|            ddt%          |          dcY d}~S d}~ww xY w)uH   Nodo para clasificar la intención y detectar arquetipos pre-calculados.r)   GENERAL_CHATN)r0   archetype_key
c                 6    g | ]}d |d          d|d          S )z- archetypeKeyz: sampleQuestion ).0as     r$   
<listcomp>z(classify_intent_node.<locals>.<listcomp>]   s5    dddTU OQ~%6 O O!<L:M O Odddr&   zNinguno disponibler.   z\{.*\}r   intencionesr0   entitiesUNKNOWNrD   	user_nameuser_positionF )rN   intenciones_pendientesr0   rD   last_entitiesrQ   rR   r#   is_precalculatedresultados_tecnicosmensaje_skill	dashboard	dax_queryu   ⚠️ Error clasificación: )r0   rD   r#   )r   joinllmainvoker   r   r/   r5   r3   searchDOTALLjsonloadsr7   listsetr!   copyr%   	Exceptionr6   )r'   r)   
archetypesarchetypes_txtrecent_messagesresponser/   
json_matchdatarN   rO   es               r$   classify_intent_noderm   U   s     Z H D+dCCC -........Jis  NTYYddYcdddeee  zNNrssmO[[7GGHHH"	"        H
a"((**Yy'29==
2<Dtz***1--..."3txxr::;;<< 	2txx44 	288K001K88J++ '&1&6&6&8&8+6EQI!XXo66%!k22Leii6L6L%\\/::Xeii>X>X"8,, %#%
 
 	
  a a a1a11222&V^H_H_````````as   E2H 
H>$H93H>9H>c                 ,  K   |                      d          }|sddiS t          d|            t          |           d{V }|r<t          d           t          j        |d          d|                      d	          d
S t          d           ddiS )zRVerifica si existe un resultado pre-calculado en Java para el arquetipo detectado.rD   rV   Fu0   🔍 [CACHE] Buscando resultado para arquetipo: Nu8   ✅ [CACHE] Hit! Usando resultado pre-calculado de Java.)ensure_asciiTr0   )ultimo_resultadorV   r0   u1   ❌ [CACHE] Miss. Procediendo a consulta en vivo.)r!   r6   r   r`   dumps)r'   rD   cache_results      r$   check_cache_noders      s      IIo..M +"E**	
L]
L
LMMM*=99999999L 
HIII !%
<e L L L $;//
 
 	
 

=>>>&&r&   c                   K   |                      d          s|                      d          r|                      d          rg d}|                      d          |vri S d|                      dd                                          v ri S | d         d	         j        }|                      d          }|                      d          }t          d
|dd          d           t	          |||           d{V  i S )u[   Nodo que registra automáticamente consultas exitosas como nuevos arquetipos en el backend.rV   rp   rZ   )UB_PRESUPUESTOCARTERATALENTO_HUMANOr0   u   ¡HOLArS   r)   r+   u@   🧠 [LEARNING] Auto-registrando nueva consulta como arquetipo: N2   z...)r!   upperr/   r6   r   )r'   allowed_intentsquestiondaxcategorys        r$   register_archetype_noder~      s"      99'(( AUYY7I-J-J AuyyYdOeOe A JII99[!!88I uyyb11779999I$R(0ii$$99[))cQYZ][]Z]Q^cccddd'#x@@@@@@@@@Ir&   c                   K   | d         }t          j        d          }t          j                            |                              d          }t          j        |          }d|                     d           d}|                     d          r|d	|                     d           dz  }|                     d
          r|d|                     d
           dz  }|                     dg           }|r*|dz  }t          |          D ]\  }}|d|dz    d| dz  }n0|                     d          r|d|                     d           z  }t          
                    t          |          g|dd         t          d|                      d{V }	t          |	j                  gt          |	          dS )z@Genera la respuesta final persuasiva y ejecutiva usando Felizia.r)   zAmerica/Guayaquilz%Y-%m-%d)current_dateu   Intención Detectada: r0   rE   rQ   z	Usuario: rR   zCargo: rW   u$   Datos Técnicos Consolidados (MCP):
z--- Resultado r	   z ---
rp   u   Dato Técnico (MCP): r.   iNu   Contexto técnico actual:
)r)   r#   )pytztimezonedatetimer9   strftimer   formatr!   	enumerater\   r]   r   r   r/   r%   )
r'   r)   tzr   
sys_promptcontext
resultadosiresresponse_objs
             r$   response_noder      s%     Z H	*	+	+B$((,,55jAAL%<@@@JAuyy'='=AAAGyy :9uyy559999yy!! <;UYY77;;;; 0"55J K::
++ 	; 	;FAs:!::3::::GG	;	%	&	& KJ5995G+H+HJJJj)))&
344.& 	EGEEFFF&        L |';<<<=|,,  r&   )ub_presupuesto_skillcartera_skilltalento_humano_skillresumen_pdf_skillr   c                     |                      d          rdS |                      dg           }|st          d           dS |d         }t          d| d|            |dk    rd	S |d
k    rdS |dk    rdS |dk    rdS dS )zARouter secuencial que maneja la cola de intenciones (Dashboards).rV   r   rT   uE   🏁 [ROUTER] No hay más tareas pendientes. Yendo a respuesta final.r   u!   🔄 [ROUTER] Tareas pendientes: z. Ejecutando: ru   r   rv   r   rw   r   RESUMEN_EJECUTIVO_PDFr   )r!   r6   )r'   
pendientesproximas      r$   unified_routerr      s     yy#$$  3R88J UVVV mG	
Qj
Q
Q
Q
QRRR"""%%	I			$	$	$%%	+	+	+""?r&   security_checkr?   check_cacher   r   r   r   register_archetyper   )5r`   r   r   r3   r2   typingr   langchain_openair   langchain_core.messagesr   r   langgraph.graphr   r   r'   r
   promptsr   r   skills.ub_presupuesto_skillr   skills.cartera_skillr   skills.talento_humano_skillr   skills.resumen_pdf_skillr   utils.precalc_helperr   r   r   config.settingsr   
MODEL_NAMEOPENAI_API_KEYr\   r%   r=   rA   rm   rs   r~   r   r   workflow_builderadd_nodeset_entry_pointadd_conditional_edgesadd_edgedestinos_routercompileworkflow_compiledrI   r&   r$   <module>r      sN      				        ' ' ' ' ' ' < < < < < < < < + + + + + + + +       = = = = = = = = B B B B B B 4 4 4 4 4 4 B B B B B B < < < < < < e e e e e e e e e e $ $ $ $ $ $ j

#    'Z ' ' ' 'R: '2C*D    -aj -a -a -a -a^'* ' ' ' ',    .z    D*   2W  *X    < :j))    *,? @ @ @   *&: ; ; ;   -)9 : : :   02K L L L   /+= > > >   02K L L L   -/E F F F   .0G H H H   /= 9 9 9     !1 2 2 2  & &'7K K      *m 4 4 4 3$2,$   & &}no V V V  & &'=~ _ _ _  & & X X X  & &'=~ _ _ _  & &':NO \ \ \   /3 / / /$,,..   r&   