
    i<c                        d Z ddl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mZmZmZmZmZmZmZ ddlmZ d	d
lmZ  ej>                  e       Z!dZ" e
ejF                  d      Z$dZ%de&de'fdZ( G d d      Z)y)ue   
Servicio de productos: búsqueda MCP, clasificación de intención y generación de respuestas LLM.
    N)SystemMessageHumanMessage	AIMessage)
ChatOpenAI)	get_tools)_extract_mcp_result)MARCI_BASE_IDENTITYSEARCH_EXTRACT_QUERY_PROMPTSEARCH_NO_RESULTS_PROMPT SEARCH_NO_PROMO_AVAILABLE_PROMPTSEARCH_NO_PRODUCT_PROMPTCHAT_CLASSIFICATION_PROMPT"SEARCH_EXTRACT_PRODUCT_NAME_PROMPTSEARCH_PRODUCT_DETAIL_PROMPTSEARCH_PRODUCT_COMPARE_PROMPTRESUME_PURCHASE_GREETING_PROMPTGREETING_FOLLOWUP_PROMPT)settings   )SearchProductItemuu  {marci_identity}
{greeting_hint}
{history_hint}

El usuario buscó: "{query}"
Se encontraron {total} productos.

PRODUCTOS ENCONTRADOS (solo para tu contexto interno, NO los menciones en texto):
{products_context}

REGLA FUNDAMENTAL: Los productos de la lista arriba están en el catálogo de Marcimex. Preséntales con confianza SOLO si son genuinamente relevantes para lo que el usuario pidió. Si el usuario pidió algo que claramente NO existe en el catálogo (ej: terrenos, casas, carros, ropa) y los productos mostrados son completamente distintos a eso, sé honesto e indica que ese tipo de producto no está disponible en nuestra tienda y ofrece alternativas de nuestras categorías (electrodomésticos, tecnología, muebles, movilidad). NUNCA presentes productos irrelevantes como si fueran lo que el usuario buscó.

INSTRUCCIONES:
1. Escribe UNA respuesta breve y amigable presentando los productos encontrados (1-2 frases máximo).
2. USA EMOJIS RELEVANTES en tu respuesta para hacerla más visual y amigable (ej: 📺 para TV, 📱 para celular, ✨ para destacar).
3. CRÍTICO: NUNCA menciones el nombre específico de ningún producto, marca ni modelo en tu texto (ej: NO digas "Whirlpool X", "Samsung Y", ni ningún nombre). Los productos se muestran como tarjetas visuales — usa referencias genéricas como "estas lavadoras", "estas opciones", "encontramos X opciones".
4. NUNCA incluyas listas de productos, precios, IDs ni especificaciones en tu respuesta de texto.
5. Si hay varias opciones, menciona que hay variedad para elegir (sin nombrar ninguna).
6. CRÍTICO: NUNCA hagas preguntas adicionales ni pidas más información. HAY PRODUCTOS DISPONIBLES — preséntelos directamente.
7. CRÍTICO: NUNCA incluyas texto con formato "[CONTEXTO DEL SISTEMA...]" en tu respuesta.
8. Si la pregunta del usuario es sobre REGALOS (qué regalar a alguien, Día de la Madre, cumpleaños, aniversario, graduación, etc.), presenta los productos con tono festivo y emotivo usando emojis de celebración (🎁 🎉 ✨ 🎊). Ej: "¡Aquí tienes unas opciones perfectas para regalar! 🎁✨" o "¡Estas opciones son ideales como detalle especial! 🎉".
)modeltemperature   labelmessagesc                    d}t         j                  d|        t         j                  d|         t         j                  |       t        |      D ]w  \  }}|j                  j                  j                  dd      j                         }t        |dd      }t         j                  d| d| d	       t         j                  |       y t         j                  d| d       y
)u<   Imprime en consola el payload completo que se envía al LLM.zF======================================================================
u   🔷 LLM PAYLOAD — Message contentz
--- [] z ---N)loggerdebug	enumerate	__class____name__replaceuppergetattr)r   r   sepimsgroler    s          </opt/lhia/marcimex/agent/app/api/services/product_service.py_print_llm_payloadr/   :   s    
C
LL2cU
LL(01
LLH% 3}}%%--i<BBD#y"-wqcD6./W	
 LL2cU"    c                   |   e Zd ZdZdededefdZdededefdZ	d$d	ed
edz  defdZ
dededeedz  edz  f   fdZdedee   fdZdededededededefdZdedededededefdZdededz  dedefdZ	 d%dedee   dedefdZdededefdZdededefdZdededefdZdeded edefd!Zd"edefd#Zy)&ProductServiceuU   Búsqueda de productos, clasificación de intención y generación de respuestas LLM.queryhistory_messagesreturnc                 8   t        t              g}|r
|t         d ng }|rg }|D ]r  }t        |t              r|j                  |       %t        |dd      }d|v r"|j                  d      d   j                         }|j                  t        |             t |j                  |       |j                  t	        | d             t        t              }t        d |D              }	t        |      }
||	z   |
z   }t        j                  d	| d
|dz   dt        |       d|	 d|
 d|dz   d       t        j                  d| d       |rgt        d |D              }t        j                  dt        |       d| ddj!                  d |D              z          |st        j#                  d       t%        d|       t'        j&                         }t(        j+                  |      }t'        j&                         |z
  }|j,                  j                         j/                         }t        |j,                        }t        j                  d|dd| d|j,                  j                          d       d|v ryd |v ry d!|v ry!d"|v ry"d#|v ry#d$|v ry$d%|v ry%y&)'u   
        Clasifica la intención del usuario usando el prompt de clasificación.
        Retorna: AGENT, AGENT_DIRECT, BALANCE, PAYMENT, GREETING, PRODUCT_DETAIL, PRODUCT u OTHER.
        r    Nr    r   [CONTEXTO DEL SISTEMAr   u   

[TAREA: clasifica el mensaje anterior. Responde SOLO con una palabra — AGENT / AGENT_DIRECT / PRODUCT_DETAIL / PRODUCT / PAYMENT / BALANCE / GREETING / OTHER]c              3   H   K   | ]  }t        t        |d d              ywr    r   Nlenr)   .0ms     r.   	<genexpr>z1ProductService.classify_intent.<locals>.<genexpr>g        OAWQ	267O    "u4   📤 [classify_intent] Enviando al LLM | sys_prompt=c (~   tok) | historial= msgs/z
c | query=c | TOTAL ~ tokens estimadosu.   📝 [classify_intent] Pregunta del usuario: ''c              3   :   K   | ]  }d t        |dd      v   yw)r8   r    r   N)r)   r=   s     r.   r@   z1ProductService.classify_intent.<locals>.<genexpr>s   s&      " (71i+DD"s   u+   📜 [classify_intent] Historial (últimos z msgs, tiene_productos_en_ctx=z):  | c           	   3   v   K   | ]1  }d |j                   j                  dd  dt        |dd      dd  3 yw)[Nr   r!   r    r   x   r%   r&   r)   r=   s     r.   r@   z1ProductService.classify_intent.<locals>.<genexpr>z   sH       ,,Ra01GAy"4Mds4S3VW   79u   ⚠️ [classify_intent] Historial SIN [CONTEXTO DEL SISTEMA] — PRODUCT_DETAIL no podrá detectarse aunque el usuario pida detalleszclassify_intent (PASO 3)u+   ⏱️ [classify_intent] LLM respondió en .2fs | respuesta=c: 'AGENT_DIRECTAGENTBALANCEPAYMENTGREETINGPRODUCT_DETAILPRODUCTOTHER)r   r   CLASSIFY_HISTORY_SLICE
isinstancer   appendr)   splitstripr   extendr<   sumr"   infoanyjoinwarningr/   time_llminvoker    r(   )selfr3   r4   classify_messageshistory_slicecleanedr?   r    	sys_chars
hist_charsquery_charstotal_charshas_product_ctxt0classificationelapsed
intent_raw
resp_charss                     r.   classify_intentzProductService.classify_intentK   s   
 +3MNOFV(*@)@)AB\^ G" ?a.NN1%%aB7G.'9")--0G"H"K"Q"Q"SNN9W#=>? $$W-  g H H" 	 23	OOO
%j*,{:#DA 7]+,F:, ? M "!1n%%6	8	
 	DUG1MN! "&" O KK=c->P=Q R**9):#?** *  #Z
 	57HIYY[%67))+"#++11399;
//0
9'# G#D)?)?)E)E)G(HK	

 Z'!
"*$*$:%+#*$r0   countc                   K   	 t               }t        d |D        d      }|st        j                  d       g ddS |j	                  ||d      }t        |      }g }t        |t              r|}n"t        |t              r|j                  dg       }t        |      }t        |t              r|j                  dt        |            }|||d	S # t        $ r'}	t        j                  d
|	        g ddcY d}	~	S d}	~	ww xY ww)z|
        Llama al tool search_products via MCP.
        Retorna dict con {products: [], totalFound: N, query: str}.
        c              3   @   K   | ]  }|j                   d k(  s|  yw)search_productsNnamer>   ts     r.   r@   z5ProductService.search_products_mcp.<locals>.<genexpr>   s     PaAFF>O4OP   Nu-   ❌ Tool search_products no encontrado en MCPr   )products
totalFound)r3   ry   r   r   )r   r   r3   u)   ❌ Error invocando search_products MCP: )r   nextr"   errorri   r   r]   listdictgetr<   	Exception)
rj   r3   ry   toolssearch_tool
result_rawresult_datar   total_foundes
             r.   search_products_mcpz"ProductService.search_products_mcp   s     
	5KEP5PRVWKLM$&a88$++ee,LMJ-j9KH+t,&K.&??:r:h-K+t,)oolCMJ (eTT 	5LLDQCHI "!44	5s?   D8C DBC D	C?C:4C?5D:C??DNproduct_name
product_idc                   K   	 t               }t        d |D        d      }|st        j                  d       i S |j	                  d|i      }t        |      }t        |t              r|r|S |rJt        j                  d|        |j	                  d|i      }t        |      }t        |t              r|r|S i S # t        $ r$}t        j                  d|        i cY d}~S d}~ww xY ww)z
        Llama al tool search_product_detail via MCP.
        Intenta primero por nombre y luego por ID como fallback.
        c              3   @   K   | ]  }|j                   d k(  s|  yw)search_product_detailNr}   r   s     r.   r@   z8ProductService.get_product_detail_mcp.<locals>.<genexpr>   s     VaAFF>U4UVr   Nu3   ❌ Tool search_product_detail no encontrado en MCPproductNameu6   🔄 Reintentando búsqueda de detalle con productId: u/   ❌ Error invocando search_product_detail MCP: )
r   r   r"   r   ri   r   r]   r   rc   r   )rj   r   r   r   detail_toolr   r   r   s           r.   get_product_detail_mcpz%ProductService.get_product_detail_mcp   s     
	KEV5VX\]KRS	$++]L,IJJ-j9K+t,""TU_T`ab(//
0KL
1*=k40[&&I 	LLJ1#NOI	sW   C*5B: C*1B: +C*,AB: 7C*8B: 9C*:	C'C"C'C*"C''C*questionc                 @   	 t        t              g}|r|j                  |dd        |j                  t	        |             t
        j                  |      }|j                  j                         }|j                         j                  d      r|dfS |dk(  s|syd|v rL|j                  dd      }|d	   j                         }t        |      dkD  r|d   j                         nd}||fS |dfS # t        $ r"}	t        j                  d
|	        Y d}	~	yd}	~	ww xY w)u   
        Usa el LLM para identificar a qué producto del historial se refiere el usuario.
        Retorna (nombre_producto, product_id) o (None, None).
        r7   Nz	COMPARAR:NO_MATCH)NN|   r   u7   ❌ Error extrayendo nombre de producto del historial: )r   r   ra   r^   r   rh   ri   r    r`   r(   
startswithr_   r<   r   r"   r   )
rj   r   r4   extract_messagesresponseresultpartsr   r   r   s
             r.   !extract_product_name_from_historyz0ProductService.extract_product_name_from_history   s   	 -6X YZ ''(8(>?##L$BC{{#34H%%++-F ||~((5t|##6!f}S!,$Qx~~/14UaU1X^^-T
#Z//4< 	LLRSTRUVW	s+   BC2 C2 AC2 .C2 2	D;DDraw_productsc                    g }|D ]  }|j                  t        |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      xs |j                  d      -t        |j                  d      xs |j                  d            nd	|j                  d
      |j                  d      	              |S )zJConvierte la lista de productos de la API/MCP a modelos SearchProductItem.	productIdskuIdr~   brandcategorylink	spotPricepriceNimagespecs)	r   r   r~   r   r   r   r   r   r   )r^   r   r   str)rj   r   itemsps       r.   parse_productszProductService.parse_products  s     	ALL*%%,eeGnUU6]eeGnz*UU6]DEEE+DVDhZ[Z_Z_`gZhCuc!%%,>g?{eeGneeGn
 
	 r0   extracted_queryr   is_first_interactionc                    |rd}d}nd}d}|rdj                  |D 	cg c]P  }	d|	j                  dd       d|	j                  d	      xs |	j                  d
d       d|	j                  dd       R c}	      }
t        j                  t        |||||
      }nt        j                  t        |||      }t        |      g}t        |      dkD  r|dd n|}|j                  |       |j                  t        |             t        |      }t        d |D              }t        |      }||z   |z   }t        j                  d| d|dz   dt        |       d| d| d| d|dz   d       t        j                  d| d| d        t        j                  d!|dd"  t        |      d"kD  rd#nd        t        d$|       t        j                         }t         j#                  |      }t        j                         |z
  }|j$                  }t        j                  d%|d&d't        |       d(|dd)  d*       d+|v r7|j'                  d+      d,   j)                         }t        j+                  d-       |S c c}	w ).u   
        Genera la respuesta conversacional para una búsqueda de productos usando LLM.
        Incluye emojis y adapta el tono según si es primera interacción o no.
        u   Es la PRIMERA interacción. Saluda brevemente (ej: '¡Hola!') y luego presenta los productos. No hagas una presentación larga.r   u`   IMPORTANTE: Ya hay conversación previa. NO saludes ni digas 'Hola'. Ve directo a los productos.r   - r~   
Sin nombre | Precio: $r   r   N/A
 | Marca: r   )marci_identitygreeting_hinthistory_hintr3   totalproducts_context)r   r   r   r3   r7   
   r   Nc              3   H   K   | ]  }t        t        |d d              ywr:   r;   r=   s     r.   r@   z:ProductService.generate_search_response.<locals>.<genexpr>F  s     PAWQ	267PrB   u=   📤 [generate_search_response] Enviando al LLM | sys_prompt=rC   rD   rE   rF   c | question=zc | productos_en_prompt=z
 | TOTAL ~rH   u+   📝 [generate_search_response] Pregunta: 'u   ' | Query extraído: 'rI   u?   📋 [generate_search_response] System prompt (primeros 400c):
i  z...z!generate_search_response (PASO 8)u4   ⏱️ [generate_search_response] LLM respondió en rQ   rR   rS   rN   ...'r8   r   u@   Se eliminó texto '[CONTEXTO DEL SISTEMA...]' copiado por el LLM)re   r   #_SEARCH_RESPONSE_PROMPT_WITH_EMOJISformatr	   r   r   r<   ra   r^   r   rb   r"   rc   r/   rg   rh   ri   r    r_   r`   rf   )rj   r   r   r   r   r4   r   r   r   r   r   system_promptllm_messagesrecent_historyrn   ro   rp   rq   rs   r   ru   answers                         r.   generate_search_responsez'ProductService.generate_search_response  s      ^MLM}L#yy%* QUU6<01aeeK>P>iTUTYTYZachTi=jjtuvuzuz  |C  EJ  vK  uL  M*   @FF2+)%!!1 G M 5;;2+)%	M &m<=367G3H23M)#$/ScN+L:;&	PPP
(m*,{:#DA 7^,-VJ< @#} %##.- 0!1n%%68	
 	A(KabqarrstuNTc"#S-?#-EE2#NP	

 	>MYY[;;|,))+"!!B73- PVT&#,t=	

 #f,\\"9:1=CCEFNN]^s*s   AI8c                    |rd}d}nd}d}|rkdj                  |D cg c]P  }d|j                  dd       d|j                  d	      xs |j                  d
d       d|j                  dd       R c}      nd}	t        j                  t        ||||	      }
t        |
      g}t        |      dkD  r|dd n|}|j                  |       |j                  t        |             t        j                         }t        j                  |      }t        j                         |z
  }|j                  }t        j                  d|ddt        |       d|dd  d       d|v r"|j!                  d      d   j#                         }|S c c}w )u   
        Genera respuesta cuando el usuario pidió X en promoción pero ningún producto
        disponible tiene promotion=True. Se informa al usuario y se muestran alternativas.
        u]   Es la PRIMERA interacción. Saluda brevemente (ej: '¡Hola!') y luego presenta los productos.r   uP   IMPORTANTE: Ya hay conversación previa. NO saludes ni digas 'Hola'. Ve directo.r   r   r~   r   r   r   r   r   r   r   zSin productos disponibles.)r   r   r   r3   r   r7   r   r   Nu@   ⏱️ [generate_no_promo_available_response] LLM respondió en rQ   rR   rS   rN   r   r8   r   )re   r   r   r   r	   r   r<   ra   r^   r   rg   rh   ri   r    r"   rc   r_   r`   )rj   r   r   r   r4   r   r   r   r   r   r   r   r   rs   r   ru   r   s                    r.   $generate_no_promo_available_responsez3ProductService.generate_no_promo_available_responseg  s     {MLMmL
   99!&
 v|,-\!%%:L:ePQPUPUV]_dPe9ffpqrqvqvw~  AF  rG  qH  I&
  != 	
 9??.'%!-
 &m<=367G3H23M)#$/ScN+L:;YY[;;|,))+"!!NwWZm \VT&#,t=	
 #f,\\"9:1=CCEF9&
s   AFproductdetail_datac                    t        j                  |r|j                  d      n|dd      }t        j                  t
        |      }t        |      g}|j                  t        |             t        j                  |      }|j                  j                         }d|v r"|j                  d      d	   j                         }|S )
zMGenera la respuesta conversacional para el detalle de un producto usando LLM.T)exclude_noneFr   ensure_asciiindent)r   product_detailr7   r8   r   )json_moddumps
model_dumpr   r   r	   r   r^   r   rh   ri   r    r`   r_   )	rj   r   r   r   product_jsonr   r   r   r   s	            r.   generate_detail_responsez'ProductService.generate_detail_response  s      ~~5<GD1+

 5;;.'
 &m<=L:;;;|,!!'')"f,\\"9:1=CCEFr0   r   r   	is_detailc                 >   |}|r|rJ|d   }|dz  }|d|j                    d|j                   d|j                   d|j                  xs d d	z  }|S d	}|D ]@  }|d|j                    d|j                   d|j                   d|j                  xs d d	z  }B ||z  }|S )
u   
        Construye el contenido del historial anotando los productos mostrados al usuario.
        Esto permite al LLM recordar qué productos se presentaron en turnos anteriores.
        r   z0

[CONTEXTO DEL SISTEMA - DETALLE DE PRODUCTO]:
r   z (ID: z) - Precio: $u    - Categoría: r   r   z;

[CONTEXTO DEL SISTEMA - PRODUCTOS MOSTRADOS AL USUARIO]:
)r~   r   r   r   )rj   r   r   r   history_contentr   product_detailss          r.   build_history_contentz$ProductService.build_history_content  s     !QK#XXRxvakk]-PQPWPWyXghihrhrh{v{g||~# 	 #c! DA#AFF86!++mTUT[T[S\\klmlvlvlz  lA  AC  (D  DOD?2r0   c                 X   t        t              g}|r
|t         d ng }|r|j                  |       |j	                  t        |             t        t              }t        d |D              }t        |      }||z   |z   }t        j                  d| d|dz   dt        |       d| d	| d
|dz   d       t        j                  d| d       |r;t        j                  dt        |       ddj                  d |D              z          t        d|       t        j                         }	t        j                  |      }
t        j                         |	z
  }|
j                  j!                         }t        |
j                        }t        j                  d|dd| d| d       |S )u   
        Extrae el término de búsqueda del mensaje del usuario usando LLM.
        Retorna "NO_PRODUCT" si no se detecta producto en el mensaje.
        r7   Nc              3   H   K   | ]  }t        t        |d d              ywr:   r;   r=   s     r.   r@   z7ProductService.extract_product_query.<locals>.<genexpr>  rA   rB   u:   📤 [extract_product_query] Enviando al LLM | sys_prompt=rC   rD   rE   rF   r   rG   rH   u4   📝 [extract_product_query] Pregunta del usuario: 'rI   u1   📜 [extract_product_query] Historial (últimos z msgs): rK   c           	   3   v   K   | ]1  }d |j                   j                  dd  dt        |dd      dd  3 yw)rM   Nr   r!   r    r   P   rO   r=   s     r.   r@   z7ProductService.extract_product_query.<locals>.<genexpr>  sH       ,,Ra01GAy"4Mcr4R3UVrP   zextract_product_query (PASO 5)u1   ⏱️ [extract_product_query] LLM respondió en rQ   rR   rS   )r   r
   r\   ra   r^   r   r<   rb   r"   rc   re   r/   rg   rh   ri   r    r`   )rj   r   r4   r   rl   rn   ro   rp   rq   rs   r   ru   r   rw   s                 r.   extract_product_queryz$ProductService.extract_product_query  s   
 *2MNOFV(*@)@)AB\^##M2X >?34	OOO
(m*,{:#DA 7]+,F:, ?#} %!1n%%6	8	
 	J8*TUVWKKCCDVCWW_`** *  	;=MNYY[;;/0))+"!!'')))*
?} M#D3	
 r0   c                 0   t        t              g}|j                  |dd        |j                  t	        |             t
        j                  |      }|j                  j                         }d|v r"|j                  d      d   j                         }|S )uO   Genera una respuesta contextual cuando el usuario no menciona ningún producto.r7   iNr8   r   )
r   r   ra   r^   r   rh   ri   r    r`   r_   )rj   r   r4   no_prod_messagesr   r   s         r.   generate_no_product_responsez+ProductService.generate_no_product_response  s    )2JKL 0 56X >?;;/0!!'')"f,\\"9:1=CCEFr0   c                 b   t        t        j                  t                    g}|j	                  |t
         d        |j                  t        |             t        j                  |      }|j                  j                         }d|v r"|j                  d      d   j                         }|S )zLGenera un saludo conversacional cuando el usuario ya tiene historial previo.)r   r7   Nr8   r   )r   r   r   r	   ra   r\   r^   r   rh   ri   r    r`   r_   )rj   r   r4   r   r   r   s         r.   generate_greeting_responsez)ProductService.generate_greeting_response  s    !*B*I*IYl*mno(*@)@)ABCX67;;x(!!'')"f,\\"9:1=CCEFr0   product1_dataproduct2_datac                    t        j                  |dd      }t        j                  |dd      }t        j                  t        ||      }t        |      g}|j                  t        |             t        j                  dt        |       dt        |      dz   d	       t        j                         }t        j                  |      }	t        j                         |z
  }
|	j                  j                         }t        j                  d
|
dd       d|v r"|j!                  d      d   j                         }|S )zBGenera la respuesta de comparativa entre dos productos usando LLM.Fr   r   )r   product1_detailproduct2_detailr7   uE   📤 [generate_compare_response] Comparando 2 productos | sys_prompt=rC   rD   ztok)u5   ⏱️ [generate_compare_response] LLM respondió en rQ   sr8   r   )r   r   r   r   r	   r   r^   r   r"   rc   r<   rg   rh   ri   r    r`   r_   )rj   r   r   r   product1_jsonproduct2_jsonr   r   rs   r   ru   r   s               r.   generate_compare_responsez(ProductService.generate_compare_response  s    !}5QRS }5QRS5<<.))

 &m<=L:;m,-T#m2Da2G1HN	
 YY[;;|,))+"!!'')KGTW=XYZ["f,\\"9:1=CCEFr0   products_textc                     t        j                  t        |      }t        |      g}t        j                  d|dd         t        j                  |      }|j                  j                         S )u  
        Genera un saludo con recomendación de los últimos productos vistos por el usuario.
        Se usa cuando la conversación es nueva y el usuario saluda o pide recomendaciones.
        products_text: string ya formateado con los nombres de los productos.
        )r   r   r7   uI   🛒 [generate_resume_purchase_greeting] Generando saludo con productos: Nd   )
r   r   r	   r   r"   rc   rh   ri   r    r`   )rj   r   r   r   r   s        r.   !generate_resume_purchase_greetingz0ProductService.generate_resume_purchase_greeting,  sk     8>>.*
 &m<=_`mnror`s_tuv;;|,%%''r0   )N)F)r&   
__module____qualname____doc__r   r   rx   intr   r   r   tupler   r   r   boolr   r   r   r   r   r   r   r   r    r0   r.   r2   r2   H   s5   _TS TD TS Tl5s 53 54 5@ #PT* `d @## # 
sTz3:%	&	#J4 D9J4K "NN N 	N
 N N #N 
N`// / 	/
 / #/ 
/b #T) 	
 
>  	 () 	
 
.*c *T *c *X	S 	D 	UX 		3 	$ 	SV 	  	
 
@(s (s (r0   r2   )*r   jsonr   loggingrg   langchain_core.messagesr   r   r   langchain_openair   mcp_integration.toolsr   agent.chat_products_nodesr   agent.promptsr	   r
   r   r   r   r   r   r   r   r   r   config.settingsr   modelsr   	getLoggerr&   r"   r   
MODEL_NAMErh   r\   r   r   r/   r2   r   r0   r.   <module>r	     s       J J ' + 9    % &			8	$' #. ++; c T q( q(r0   