
    
{j                       S r SSKJr  SSKJr  SSKJr  SSKJr  SSK	J
r
  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJrJrJrJrJrJrJrJrJ r J!r!  SSK"J#r#J$r$J%r%J&r&J'r'J(r(  SSK)J*r*J+r+J,r,  SSK-J.r.J/r/  SSK0J1r1J2r2J3r3  SSK4J5r5J6r6J7r7J8r8  S S jr9S S jr:S!S jr;SSS.                   S"S jjr<S#S jr=SSSS.                   S$S jjr>        S%S jr? " S S5      r@      S&S jrAg)'z7Agents chat via DeepSeek (OpenAI-compatible streaming).    )annotations)Iterator)Any)Session)AgentsClass)AgentsLlmModelsClass)AgentsMcpClass)AgentsUsageClass)settings)
AgentModel)
FAMILIA_DOCUMENT_IDMAX_BULK_STUDENTSPSYCHOPED_DOCUMENT_IDbulk_confirm_askbulk_document_labelfiles_mention_studentlooks_like_bulk_requestresolve_bulk_planuser_confirmed_bulkzip_generated_files)resolve_document_id_for_agentresolve_student_idstudent_identification_hintwants_document_generationbuild_ask_rut_replybuild_invalid_rut_reply)CODE_REJECT_REPLYmessage_is_html_or_codestrip_html_and_code_blocks)SCOPE_REJECT_REPLYmessage_is_off_topic)estimate_tokens_from_textnormalize_usagestream_chat_completion)extract_fields_from_replyis_content_too_thinsanitize_psychoped_fieldsstrip_fields_json_from_replyc                      g)Nu6  No es posible elaborar el Informe de Evaluación Psicopedagógica: no dispongo de antecedentes documentales del estudiante en Files (cuestionarios, pautas, anamnesis u otras evidencias) ni de respuestas en Formularios (Inf. Eval. Psicopedagógica).

Sin esa información no puedo redactar ni emitir el informe. r*       WC:\Users\jesus\Desktop\proyecto_pie360\backend\app\backend\classes\agents_chat_class.py_missing_psychoped_files_replyr-   9   s    	Gr+   c                      g)Nu   No es posible elaborar el Informe a la Familia: no dispongo de antecedentes documentales del estudiante en Files ni de un informe psicopedagógico en su ficha.

Sin esa información no puedo redactar ni emitir el informe.r*   r*   r+   r,   _missing_family_sources_replyr/   C   s    	Gr+   c           
        SSK JnJn  U R                  U5      R	                  UR
                  [        U5      :H  5      R                  5       nU R                  U5      R	                  UR                  [        U5      :H  5      R                  5       nS nS nU(       a  SR                  S [        USS 5      [        USS 5      [        USS 5      4 5       5      R                  5       =(       d    S n[        USS 5      =(       d    S	R                  5       =(       d    S nU(       d4  U(       a-  [        USS 5      =(       d    S	R                  5       =(       d    S nXg4$ )
Nr   )StudentModelStudentPersonalInfoModel c              3  8   #    U  H  nU(       d  M  Uv   M     g 7fNr*   .0ps     r,   	<genexpr>)_load_student_name_rut.<locals>.<genexpr>X   s"      

  A   	namesfather_lastnamemother_lastnameidentification_number )app.backend.db.models.pie_corer1   r2   queryfilter
student_idintfirstidjoingetattrstrip)dbrD   r1   r2   personalstudentnameruts           r,   _load_student_name_rutrP   L   s(   U 	)*	(33s:F	G	 
 hh|$++LOOs:,NOUUWGD
Cxx 
 '40"3T:"3T:
 
 %'  	 x!8$?E2LLNVRV7w 7>D"KKMUQU9r+   N)	school_idperiod_yearc        	   	     n   Sn	 SSK Jn
  U
R                  U=(       d    SU=(       d    SUU[        U5      S9u  p[        X=(       d    SU5      (       a  gU(       a  [        U5      OS nU[        :X  a?   SSKJn  U" U [        U5      U(       a  [        U5      OS U(       a  [        U5      S9$ S S9$  SS	K	J
n  U" U [        U5      U=(       d    [        U	=(       d    SUUS
9n[        U=(       d    SR                  5       5      $ ! [         a    Sn	 Nf = f! [         a     gf = f! [         a     gf = f)Nr@   r   agents_derived_storagerB   student_rutstudent_namecustomer_idT student_has_dynamic_form_answersrD   rQ   rR   F!maybe_build_ficha_psychoped_blockrD   document_idfiles_blockrX   rW   )app.backend.utilsrU   build_selective_files_contextrE   	Exceptionr   _PSYCHOPED_DOCUMENT_ID-app.backend.utils.agents_dynamic_form_contextr[   /app.backend.utils.agents_student_folder_contextr^   _FAMILIA_DOCUMENT_IDboolrJ   )rK   
agent_namerY   rD   rX   rW   r`   rQ   rR   ra   derived_ndocr[   r^   fichas                   r,   _student_has_report_sourcesro   g   sL    KG!??"$"#%K( @ 
 [*<"kJJ)#k
tC
$$	 4z?,5#i.40;C,	  BF	 	
 2:33#)r%#
 U[b'')**I  &  		$  s<   6D 49D .D 3AD' DD
D$#D$'
D43D4c                t    U=(       d    SR                  5       =(       d    Sn[        U 5       SU S3nSU S3$ )Nr@   agente/uB   Google Drive del agente:
- Ruta bajo la carpeta raíz de Agentes: u   
- Usa esos archivos cuando necesites plantillas, anexos o contexto del agente.
- No uses el Drive de colegios (school_id/año/…).)rJ   rE   )rY   rj   rN   paths       r,   _drive_path_blockrt      sK    "##%1D+qa(D	4486 :?	?r+   r@   )messagerQ   rR   c        	        "	   / n	UR                   =(       d    SR                  5       n
U
(       a  U	R                  U
5        U	R                  S5        U	R                  S5        U	R                  S5        U	R                  S5        [        R                  =(       d    SR                  S5      nU(       a  U S3OSnU	R                  [        U 5      R                  U[        U5      UUUUS	95        U	R                  [        [        U5      UR                  =(       d    SS
95         SSKJn  S nU(       a   SSKJn  U R                  U5      R!                  UR"                  [        U5      :H  5      R%                  5       nU(       aS  SR'                  S [)        USS 5      [)        USS 5      [)        USS 5      4 5       5      R                  5       =(       d    S nUR-                  UR                  =(       d    SU=(       d    SUU[        U5      S9u  nnU(       a  U	R                  U5        Ub  [        U5      OS nU(       a  U[.        :X  a   [        U 5      R1                  [3        UR4                  5      [        U5      [        U5      U(       a  [        U5      OS U(       a  [        U5      OS UUS9nUR7                  S5      S:X  ax  UR7                  S5      =(       d    0 R7                  S5      =(       d    Sn[3        U5      R                  5       (       a(  U	R                  [3        U5      R                  5       5         SSKJn  U" U UUU=(       d    SUUS9nU(       a  U	R                  U5        U(       a&   U	R                  [=        U [        U5      U5      5        / nU(       a  UR                  SU 35        U(       a  UR                  SU 35        U(       a  UR                  SU 35        U(       a#  U	R                  SSR'                  U5      -   5        S R'                  U	5      R                  5       $ ! [*         a    S n GNtf = f! [*         a     GNf = f! [*         a     Nf = f! [*         a     GN
f = f! [*         a     Nf = f)!Nr@   u%  RUT (ambos informes: familia y psicopedagógico): coincidencia exacta con PIE360. Si el usuario entrega un RUT que no existe, responde que el RUT es incorrecto y no identifiques a nadie ni generes el documento. Prohibido completar, prefijar o corregir dígitos con la nómina u otros archivos.u  SIN INTERNET / SIN BÚSQUEDA WEB (regla dura, ambos agentes): está PROHIBIDO buscar en internet, navegar la web, usar buscadores, citar sitios externos o consultar fuentes online. Solo puedes usar: (1) archivos del agente y su texto derivado en el contexto, (2) mensajes del chat, (3) datos PIE360 / ficha inyectados. Si falta un dato, dilo y deja el campo vacío; no lo busques en la red.u  SIN HTML NI CÓDIGO (regla dura, ambos agentes): está PROHIBIDO escribir, aceptar o devolver HTML, CSS, JavaScript, Python, SQL u otro lenguaje de programación. Responde solo en español, prosa profesional. El único JSON permitido es el bloque `fields` al final cuando hay que generar el documento (eso lo consume el servidor, no es código para el usuario). Nunca uses etiquetas <p>, <div>, <script> ni fences de código (```html, ```python, etc.).u  ÁMBITO PIE CHILE (regla dura, ambos agentes): solo atiendes el Programa de Integración Escolar de Chile y PIE360: informes psicopedagógicos, informes a la familia, estudiantes, NEE, Decreto 170 y documentación del establecimiento. Si preguntan cualquier otra cosa (clima, recetas, noticias, cultura general, programación, deporte, etc.), NO respondas el contenido: indica con profesionalismo que solo contestas temas de PIE Chile y ofrece continuar con un informe o un dato de un estudiante del programa.rr   z/mcpz/api/mcp)agentrY   r`   rD   rW   mcp_url)rY   rj   r   rT   )r2   r3   c              3  8   #    U  H  nU(       d  M  Uv   M     g 7fr5   r*   r6   s     r,   r9   '_build_system_prompt.<locals>.<genexpr>   s"      ,"A
  "r;   r<   r=   r>   rV   )agent_idrY   rD   rQ   rR   rX   rW   statussuccessdatacontextr]   r_   zstudent_id=zstudent_rut=zdocument_id=zContexto PIE360: , 

)role_instructionsrJ   appendr   api_public_baserstripr	   build_store_data_prompt_blockrE   rt   rN   rb   rU   rA   r2   rB   rC   rD   rF   rH   rI   rd   rc   re   *get_student_psychopedagogical_form_answersstrrG   getrg   r^   r   )rK   rw   rY   rD   rW   r`   ru   rQ   rR   partsinstructionsmcp_baserx   rk   rX   r2   spira   rl   doc_intmcp_formctxr^   ficha_blockextrass                            r,   _build_system_promptr      s    E++1r88:L\"	LL	] 
LL	^ 
LL	1 
LL	) ((.B66s;H#+
$G	LLr88K(#!# 	9 	
	 
LL"s;/?EJJL\Z\]^LG$S HH56V4??3z?RSUW 
 #&88 , $C$7#C):DA#C):DA", $ eg$& "& ! "??JJ"-R#%K( @ 
R LL% '2&=#k"4'%;;)"-XX ] #K 0":09c)nt4?K 0T!- + Y  <<)Y6#<</52::9EKC3x~~''SX^^%56
	 <%''-2)'K [) 	LL+BJM FJ<01[M23[M23(499V+<<=;;u##%%S  $#$>  &  		   		s   #Q0 3B$P< A4Q0 C4Q 2Q  ;%R <QQ0 QQ0 
QQ0 QQ0  
Q-*Q0 ,Q--Q0 0
Q>=Q>
RRc                   / nU (       a  UR                  SU S.5        U=(       d    /  Hw  nUR                  S5      =(       d    SR                  5       nUR                  S5      =(       d    SR                  5       nUS;   d  M[  U(       d  Md  UR                  XVS.5        My     UR                  SU=(       d    SR                  5       S.5        U$ )Nsystemrolecontentr   r@   r   >   user	assistantr   )r   r   rJ   )system_promptru   historymessagesitemr   r   s          r,   _build_messagesr   R  s     &(HmDE2 &B--/88I&,"335((WWOOT>?	  OOVB0E0E0GHIOr+   c                      \ rS rSrSSSSS.           S
S jjr    S             SS jjr            SS jr                  SS jr            SS jrS	r	g)AgentsChatClassif  N)rY   rQ   user_idrR   c               @    Xl         X l        X0l        X@l        XPl        g r5   )rK   rY   rQ   r   rR   )selfrK   rY   rQ   r   rR   s         r,   __init__AgentsChatClass.__init__g  s     &"&r+   c              #    #    U R                   (       d	  SSSS.v   g [        U R                  5      R                  U[	        U R                   5      5      nU(       d	  SSSS.v   g U=(       d    SR                  5       nU(       d	  SSS	S.v   g [        U5      (       a  [        n	S
U	S.v   SU	S S / S S.S.v   g [        U5      (       a  [        n	S
U	S.v   SU	S S / S S.S.v   g [        U R                  UUR                  UUUS9n
[        X5      n[        X5      nU(       a  U R                  UUUUU
S9 S h  vN   g [        U R                  UUUUU R                   (       a  [	        U R                   5      OS U R                   (       a  [	        U R                   5      OS U R"                  (       a  [	        U R"                  5      OS S9u  pnU=(       d    U=(       d    SR                  5       =(       d    S nS nU(       a-  [%        U R                  [	        U5      5      u  nnU=(       d    UnSnU(       a  U(       a  ['        U R                  UR                  =(       d    S[	        U R                   5      [	        U5      UUU
U R                   (       a  [	        U R                   5      OS U R"                  (       a  [	        U R"                  5      OS S9	nU(       d4  U
[(        :X  a  [+        5       n	O
[-        5       n	S
U	S.v   SU	S S / S S.S.v   g OU(       a  ['        U R                  UR                  =(       d    S[	        U R                   5      [	        U5      UUU
U R                   (       a  [	        U R                   5      OS U R"                  (       a  [	        U R"                  5      OS S9	nUS:X  a'  U(       d   [/        U5      n	S
U	S.v   SU	S S / S S.S.v   g U(       a7  U(       d0  US:X  a*  [1        UU
UR                  S9n	S
U	S.v   SU	S S / S S.S.v   g [3        U R                  5      nUR5                  5       nSSS.v   [7        U R                  U[	        U R                   5      UUU
UU R                   (       a  [	        U R                   5      OS U R"                  (       a  [	        U R"                  5      OS S9	n[9        UUUS9nSSS.v   [        X5      nU(       a  SOSnU(       a  SOS nSnS nS n[;        UUU R                  UUS!9 H  nUR=                  S"5      S
:X  a3  U(       a	  SnSS#S.v   UUR=                  S$5      =(       d    S-  nUv   MK  UR=                  S"5      S:X  av  UR=                  S%5      =(       d    0 nUR=                  S&5      =(       d    Un[?        [A        UR=                  S'5      [B        5      (       a  UR=                  S'5      OS 5      nM  UR=                  S"5      S:X  a  Uv     g Uv   M     Un / n!S n"[E        U5      n#U(       Ga  U#(       Gd  U(       Ga  U
(       Ga  U(       Ga  SS(S.v   S)n$[G        U5      S*U=(       d    S+S,.S-U$S,./-   n%Sn&[;        U%UU R                  UUS!9 GHf  nUR=                  S"5      S
:X  a%  UR=                  S$5      =(       d    Sn'U&U'-  n&Uv   M>  UR=                  S"5      S:X  Ga  UR=                  S%5      =(       d    0 nUR=                  S&5      =(       d    U&n&[?        [A        UR=                  S'5      [B        5      (       a  UR=                  S'5      OS 5      n(U((       Gal  U(       Gad  [	        UR=                  S.5      =(       d    S/5      [	        U(R=                  S.5      =(       d    S/5      -   [	        UR=                  S05      =(       d    S/5      [	        U(R=                  S05      =(       d    S/5      -   [	        UR=                  S15      =(       d    S/5      [	        U(R=                  S15      =(       d    S/5      -   [	        UR=                  S25      =(       d    S/5      [	        U(R=                  S25      =(       d    S/5      -   [	        UR=                  S35      =(       d    S/5      [	        U(R=                  S35      =(       d    S/5      -   S4.nGM<  U((       a  U(nGMH  GMK  UR=                  S"5      S:X  d  GMc  Uv     g    U&(       aL  U=(       d    SRI                  5       S5-   U&-   R                  5       nUn [E        U&5      =(       d    [E        U5      n#U(       d  U#(       Ga  U(       d  S n"GOU
(       d  S6n"GO[	        U
5      [(        :X  a  U(       d  [+        5       n S n"GOU#(       d  S7n"GOSS8S.v    SS9S.v   U#n)[	        U
5      [(        :X  a  [K        U#5      n)[M        U R                  5      RO                  U[	        U R                   5      [	        U5      [	        U
5      U)S:9n*U*R=                  S;5      S:X  a  U*R=                  S<5      =(       d    S=n"OU*R=                  S%5      =(       d    0 n[G        UR=                  S>5      =(       d    / 5      n![Q        U5      n UR=                  S?5      (       a!  US?   R=                  S@5      (       a  SSAS.v   O%UR=                  SB5      (       a  SSCS.v   OSSDS.v   [S        U#5      (       a  SEn"O)UR=                  SF5      (       a  U RI                  5       SG-   n U#(       d  [E        U 5      (       a  [Q        U 5      n O7SIU =(       d    SRW                  5       ;   d  SJU =(       d    S;   a  [Q        U 5      n [Y        U 5      n U UUU!SK.n,U"(       a  U"U,SL'   SU,S.v   U R                   (       d  g U(       d9  SMR[                  SN U 5       5      n-[]        U-5      n.[]        U5      n/U.U/U.U/-   S/U.S4.n [_        U R                  5      Ra                  [	        U R                   5      U R                   (       a  [	        U R                   5      OS U Rb                  (       a  [	        U Rb                  5      OS UU[	        UR=                  S.5      =(       d    S/5      [	        UR=                  S05      =(       d    S/5      [	        UR=                  S15      =(       d    S/5      [	        UR=                  S25      =(       d    S/5      [	        UR=                  S35      =(       d    S/5      UU SO9  g  GN! [T         a  n+SHU+ 3n" S n+A+GNS n+A+ff = f! [T         a    U R                  Re                  5          g f = f7f)PNerrorz4customer_id es requerido para chatear con el agente.missing_customer)typeru   codezAgente no encontrado.agent_not_foundr@   u   El mensaje está vacío.empty_message
text_deltar   deltadonereplyusagemodelresponseFileswarningr   r~   )r{   rj   requested_document_idru   r   )r{   	agent_rowtextr   r`   )rD   rW   ru   r   rY   rQ   rR   F)	rK   rj   rY   rD   rX   rW   r`   rQ   rR   	not_found	needs_rut)r`   rj   stepu%   Preparando contexto del estudiante…r   ru   	rK   rw   rY   rD   rW   r`   ru   rQ   rR   r   ru   r   u   Redactando respuesta…   x       Tr   rK   timeout
max_tokensr   u   Escribiendo respuesta…r   r~   r   r   u/   Completando campos del documento (reintento)…uS  Tu respuesta anterior NO incluyó el bloque JSON `fields` y por eso NO se generó el documento. Responde AHORA solo con el bloque ```json
{"fields": {...}}
``` completo (todos los campos de la plantilla, narrativos detallados). Prohibido intro larga; máximo 1 oración antes del JSON. Usa Files, formulario MCP y ficha; no inventes datos.r   
(sin JSON)r   r   prompt_tokensr   completion_tokenstotal_tokensprompt_cache_hit_tokensprompt_cache_miss_tokensr   r   r   r   r   r   zRFalta document_id / plantilla del agente. Sube el modelo en Documentos del agente.uv   El agente redactó pero no envió el bloque JSON de fields. Pide de nuevo «genera el informe» o completa los campos.u   Creando documento…u1   Rellenando plantilla y guardando en la carpeta…r{   rY   rD   r`   fieldsr|   ru   z No se pudo generar el documento.r   googleDrive
drive_pathu"   Documento subido a Google Drive…googleDriveErroru(   Documento listo (Drive no disponible)…u   Documento listo…u  El documento se generó, pero el contenido narrativo quedó corto o incompleto. Pide de nuevo: «reescribe todos los campos narrativos con párrafos detallados (2 a 5 oraciones cada uno) usando el archivo de evaluación del estudiante y genera el documento».
formFilledzS

Documento generado y datos del formulario guardados en la carpeta del estudiante.zError al generar documento: z```jsonz	{"fields")r   r   r   r   r   
c              3     #    U  H?  n[        U[        5      (       d  M  [        UR                  S 5      =(       d    S5      v   MA     g7f)r   r@   N)
isinstancedictr   r   )r7   ms     r,   r9   .AgentsChatClass.stream_chat.<locals>.<genexpr>  s5      %5=AtAT+AEE)$*++Xs
   A	*A	rY   rQ   r   r{   r   r   r   r   r   r   
input_textoutput_text)3rY   r   rK   
_get_agentrE   rJ   r   r   r!   r    r   rN   r   r   _stream_bulk_reportsr   rQ   rR   rP   ro   re   r-   r/   r   r   r   get_selected_model_coder   r   r$   r   r#   r   r   r%   listr   r'   r	   create_documentr(   r&   rd   lowerr   rH   r"   r
   record_chatr   rollback)0r   r{   ru   rD   rW   r`   r   r   r   askresolved_document_idwant_doc_earlybulk_requestresolved_student_idrut_usedstudent_issueeffective_rutrX   personal_ruthas_report_sourcesllm
model_coder   r   want_docllm_timeoutllm_max_tokens
reply_textr   first_tokeneventr~   visible_replyresponse_filesr   r   	retry_msgretry_messagesretry_replyr   retry_usagepayload_fieldscreatedexc	done_dataprompt_charsptcts0                                                   r,   stream_chatAgentsChatClass.stream_chatv  sx     Q* 
 (33Hc$BRBR>ST	2) 
 2$$&5' 
 "4((#C'#66 !!%'#	 	 %%$C'#66 !!%'#	 	 <GG ~~"- 
 34A.t= 00!#0 1     8JGG!#151A1AD,,-t-1^^c$..)151A1AD,,-t	8
4} %66B==?G4#')?01*&L, *9\M #1!<77$>>/R 0 0123))015#dnn-T595E5EC 0 014
" &'+AA8:C79C+c::"!$!%!%)+#'	 	 ! &" !!<77$>>/R 0 0123))015#dnn-T595E5EC 0 014
" K'0C)(3C'#66 !!%'#	 	  ',%0$>>C
 (#66 !!%'#	 	 "477+002
*QRR,wwD,,-*%,-1^^c$..)151A1AD,,-t

 #'
 *CDD,T;%c3!)t
'++ww%
E yy L0"'K#)6PQQeii06B6
6"f,yy(.B!XXg.<*
')3DHHW4Et)L)LDHHW%RV 6"g-/
2 #/1"*:6 #$" L 
%  "(^$1K|LI6/ N K/ 77#) 99V$4!IIg.4"E5(KKYYv&&0 99V,2D"&((7"3"B{K"1%dhhw&7>> )!#K
 #u-0?1K1Pq-Q!+///"B"GaH.I14UYY?R5S5XWX1Y!+//2E"F"K!L2M,/		.0I0NQ,O!+//."A"FQG-H7: %		*C D I8 "+//2K"L"QPQR8S 9< %		*D E J9 "+//2L"M"RQRS9T!  % + %YYv&'1KQR )/R779FB[PWWY
 *2;? C\D v&)? 
 ()-CC* > @Q 
  &2HII0C &#V  &,N/04JJ)B6)J,TWW5EE!)$'(8(8$9#&':#;$'(<$=- F G {{8,7")++i"8"^<^&{{628b)-dhh.G.M2)N(DZ(P88M22tM7J7N7N|7\7\(.+O#  "XX&899(.+U# 
 ,2>R"SS.v66!; $ "XXl33 - 4 4 6#@!@ * .}==8GM=.B5577;R<
 9GM2=A #+	%
	 #*Ii y1199 %5=% L +<8B*:6B!#%' "R+,,.E	TWW%11 0 0115#dnn-T-1\\DLL)t! !%))O"<"AB"%eii0C&D&I"J >!:!?a@(+EII6O,P,UTU(V),UYY7Q-R-WVW)X) 2 Gv	 ! C <SEBGCl  	GG	s   D7u09t&:^&u0%B:u0 B!t) u0B6t) 8u09)t) "Cu04D1u %u0)
u3t>8u0>uu0$u-*u0,u--u0c             #    #    [        U R                  [        U R                  5      UUUUR                  U R
                  (       a  [        U R
                  5      OS U R                  (       a  [        U R                  5      OS S9nUc  SnSUS.v   SUS S / S S.S.v   g UR                  (       a:  UR                  (       d)  SUR                  S.v   SUR                  S S / S S.S.v   g U(       d  SnSUS.v   SUS S / S S.S.v   g [        UR                  =(       d    / 5      n[        U5      [        :  a  [        U5      (       d  [        UR                  =(       d    S	R                  5       =(       d    S
UR                   =(       d    S	R                  5       =(       d    S[        UR"                  =(       d    S5      [        U5      S9nSUS.v   SUS S / S S.S.v   g US [         n	[%        XRR                  5      n
UR                  =(       d    S	R                  5       =(       d    S
nUR                   =(       d    S	R                  5       nUR"                  nSR'                  S [)        U	SS9 5       5      nSU SU(       a	  SU SU S3OS	 S[        U	5       SU
 SU S3n[        U5      [        :  a   US[         S[        U5      [        -
   S3-  nSUS.v   SS[        U	5       S3S .v   [+        U R                  5      nUR-                  5       n/ n/ n/ nS n[)        U	SS9 GH  u  nn[        UR/                  S!5      =(       d    S5      nUR/                  S"5      =(       d    S#U 3R                  5       nUR/                  S$5      =(       d    S	R                  5       =(       d    S nSU S%[        U	5       S&U S'3S .v   U(       d  UR1                  US(45        M  U R3                  UUUUU[        U5      U
US)9n[5        UUR/                  S*5      5      nUR/                  S+5      (       aR  UR/                  S,5      =(       d    S-nSS.U 3S.v   SUS-   U-   UU/ US.S.v   U R7                  UUUUUS-   U-   S/9    g UR/                  S05      (       aW  UR1                  U5        UR/                  S15      =(       d    S	R                  5       nU(       a  UR1                  U5        GM  GM  UR1                  UUR/                  S,5      =(       d    S245        GM     [9        U5      nU(       a  U/O/ nUS3[        U5       3/nU(       a   UR1                  SR'                  U5      5        U(       a@  UR1                  S4[        U5       35        U H  u  n n!UR1                  S5U  S6U! 35        M     U(       a  UR1                  S75        O*U(       a  UR1                  S85        OUR1                  S95        SR'                  U5      R                  5       n"SS.U"[        U5      S  R;                  5       -   S.v   SU"UUUS S.S.v   U R7                  UUUUU"S/9  g 7f):N)rY   ru   r   r`   rj   default_yearsession_school_idul   Para continuar con los informes del curso, indica el liceo, el año (ej. 2026) y el curso (ej. 1° Medio A).r   r   r   r   r   ug   No hay plantilla asociada a este agente. Sube el modelo en Documentos del agente e inténtalo de nuevo.r@   cursoestablecimientor   )course_nameschool_nameyeartotalr   c           	   3     #    U  HA  u  pU S UR                  S5      =(       d    S[        UR                  S5      5      -    3v   MC     g7f)z. rN   Estudiante rG   N)r   r   )r7   iss      r,   r9   7AgentsChatClass._stream_bulk_reports.<locals>.<genexpr>  sD      
1 cAEE&MGmc!%%+6F&FHI1s   A	A   )startzCurso **z**z (r   )z: **u   ** estudiante(s). Generaré el u*    uno a uno y lo guardaré en cada ficha.

z
(Tanda 1 de z	; quedan z para otra tanda.)
r   z0/u    preparando generación…r   rG   rN   r  rO   rr   r3   u   …zficha incompleta)r{   r   rD   rX   rW   r`   labelr   r   template_missingreasonz*No hay plantilla en Documentos del agente.r   )r{   r   r   r   r   okfilenamezno se pudo generarz**Generados:** z
**Omitidos:** z- z: uj   
ZIP con los Word generados listo para descargar. Cada informe quedó también en la ficha del estudiante.z:
Los informes se guardaron en la ficha de cada estudiante.u-   
No se generó ningún informe en esta tanda.)r   rK   rE   rY   rN   rR   rQ   r   studentsr   lenr   r   r   r  rJ   r  r  r   rH   	enumerater   r   r   r   _generate_one_bulk_document_merge_usage_record_bulk_usager   lstrip)#r   r{   r   r   r   r`   planr   r  batchr  course_titleschool_title
year_titlerosterheaderr   r   ok_namesomitted	filenames	usage_accindexrM   sidsnamesrutresultfnamezip_filer   linesrN   r  r   s#                                      r,   r   $AgentsChatClass._stream_bulk_reports9  s     !GGD,,-# ~~262B2BT--.59^^c$..1	
 <C  (#66 !!%'#	 	 88DMM'$((;;!XX!!%'#	 	 Q  (#66 !!%'#	 	 +,x=,,5H5N5N"!--3::<G!--3::<Q@Qa((m	C (#66 !!%'#	 	 ++,#K@((.B557B7((.B557YY
 
!%q1
 

 |nB5AL>J<q1rJ KU;E7 C0hb	 	 x=,, !2 39x=#4455IKF $f55Bs5zl:T*UVV"477+002
 )+!	+/	'Q7NE7gkk$',1-C[[(?k#,?FFHEKK&,"335=D#WAc%j\5'=  '9:;55!#" ,% 6 	F %Y

70CDIzz,--jj*Z.Z+SElCC"!'$!4!*!+)+#&	 	 ''%)## & 3 (  zz$&J/52<<>$$U+  vzz(';'S?STUe 8h 'y1'/(Rc(m_-
 LL8,-LL+CL>:; 'fr$r&23 !(LLK LLM LLIJ		% &&(#fuS[]7K7R7R7T.TUU"#!/	
 		
 	! 	  	
s   Y!Y#c               D   SS S S SS.n	U[         :X  a  Sn
 SSKJn  UR                  UR                  =(       d    SUUU[        U R                  5      S9u  p[        XU5      nSnU(       do   SSK	J
n  U" U R                  [        U5      U R                  (       a  [        U R                  5      OS U R                  (       a  [        U R                  5      OS S9nU(       d  U(       d  S	U	S
'   U	$ [        U R                  U[        U R                  5      UUUSU SU 3U R                  (       a  [        U R                  5      OS U R                  (       a  [        U R                  5      OS S9	nSU SU U(       a  SU S3OS SU S3n[        UUS S9nSnS n[!        UUU R                  SSS9 H  nUR#                  S5      S:X  a  UUR#                  S5      =(       d    S-  nM7  UR#                  S5      S:X  av  UR#                  S5      =(       d    0 nUR#                  S5      =(       d    Un[%        ['        UR#                  S5      [(        5      (       a  UR#                  S5      OS 5      nM  UR#                  S5      S:X  d  M  UR#                  S5      =(       d    S U	S
'   UU	S'   U	s  $    [+        U5      nU(       Gd  S!n[-        U5      S"U=(       d    S#S$.S%US$./-   nSn[!        UUU R                  SSS9 GH  nUR#                  S5      S:X  a  UUR#                  S5      =(       d    S-  nM8  UR#                  S5      S:X  Ga  UR#                  S5      =(       d    0 nUR#                  S5      =(       d    Un[%        ['        UR#                  S5      [(        5      (       a  UR#                  S5      OS 5      nU(       Gal  U(       Gad  [        UR#                  S&5      =(       d    S5      [        UR#                  S&5      =(       d    S5      -   [        UR#                  S'5      =(       d    S5      [        UR#                  S'5      =(       d    S5      -   [        UR#                  S(5      =(       d    S5      [        UR#                  S(5      =(       d    S5      -   [        UR#                  S)5      =(       d    S5      [        UR#                  S)5      =(       d    S5      -   [        UR#                  S*5      =(       d    S5      [        UR#                  S*5      =(       d    S5      -   S+.nGM6  U(       a  UnGMB  GME  UR#                  S5      S:X  d  GM]  UR#                  S5      =(       d    S U	S
'   UU	S'   U	s  $    [+        U5      nU(       d  S,U	S
'   UU	S'   U	$  Un[        U5      [         :X  a  [/        U5      n[1        U R                  5      R3                  U[        U R                  5      [        U5      [        U5      US-9nUR#                  S/5      S:X  a?  UR#                  S5      =(       d    S0nUU	S
'   UU	S'   S1UR5                  5       ;   a  S2U	S3'   U	$ UR#                  S5      =(       d    0 n[-        UR#                  S45      =(       d    / 5      n Sn!U (       a&  [7        U S   R#                  S55      =(       d    S5      n!S2U!S USS.$ ! [         a    Sn
 GNf = f! [         a    Sn GNf = f! [         a  nS.U 3U	S
'   UU	S'   U	s S nA$ S nAff = f)6NF)r  r  r  r   r  r@   r   rT   rV   rZ   r\   zMsin antecedentes en Files ni respuestas de formulario; no se emite el informer  z
Genera el z de r   zGenera ahora el z (RUT r  z (student_id=zx). Incluye el bloque JSON con "fields" para rellenar la plantilla. Usa Files, formulario MCP y ficha; no inventes datos.r   r   r   r   r   r   r   r   r~   r   r   r   ru   zerror del modelozResponde AHORA solo con ```json {"fields": {...}} ``` completo para la plantilla. Sin intro. Narrativos detallados; no inventes datos.r   r   r   r   r   r   r   r   r   r   u,   el modelo no entregó los campos del informer   zerror al guardar: r|   zno se pudo generar el documento	plantillaTr  r   rN   )re   rb   rU   rc   rN   rE   rY   rd   r   rf   r[   rK   rQ   rR   r   r   r$   r   r#   r   r   r%   r   r'   r	   r   r   r   )"r   r{   r   rD   rX   rW   r`   r  r   emptyra   rk   rl   	has_fileshas_formr[   r   user_msgr   r   r   r   r~   r   r   r   r   r   r   r   r   msgfilesr  s"                                     r,   r   +AgentsChatClass._generate_one_bulk_document  s     %!
 00K!O")"G"GNN(b& +!- #D$4$4 5 #H # .kUIH%  @#&z?9=#dnn"5T=A=M=MC(8(8$9SW	 H Xc h ,wwD,,-!## tL>:-1^^c$..)151A1AD,,-t

 ugT,*5}A&2> ?%, 'DD 	 #'

 
'++ww
E yy L0eii06B6
6"f,yy(.B!XXg.<*
')3DHHW4Et)L)LDHHW%RV 6"g-"'))I"6"L:Lh!&g%
( +:6Z  "(^$1K|LI6/ N K/ 77 99V$4599W#5#;;KYYv&&0 99V,2D"&((7"3"B{K"1%dhhw&7>> )!#K
 #u-0?1K1Pq-Q!+///"B"GaH.I14UYY?R5S5XWX1Y!+//2E"F"K!L2M,/		.0I0NQ,O!+//."A"FQG-H7: %		*C D I8 "+//2K"L"QPQR8S 9< %		*D E J9 "+//2L"M"RQRS9T!  % + %YYv&'1&+ii	&:&P>PE(O%*E'N LOP /{;FLE(O"E'NL	#N;#99!:6!B$TWW-==! 0 01z?,% > G ;;x G+++i(M,MC!E(O"E'Nciik),0()L{{6"(bTXXo.4"558<</526H  %
 	
y  ! !  ! %$H%t  	 23%8E(O"E'NL	sD   A[ -A.[) #A+[< [&%[&)[98[9<
\\\\c                  U R                   (       a  U(       d  g  [        U R                  5      R                  [	        U R                   5      U R
                  (       a  [	        U R
                  5      OS U R                  (       a  [	        U R                  5      OS UU[	        UR                  S5      =(       d    S5      [	        UR                  S5      =(       d    S5      [	        UR                  S5      =(       d    S5      [	        UR                  S5      =(       d    S5      [	        UR                  S5      =(       d    S5      UUS9  g ! [         a    U R                  R                  5          g f = f)Nr   r   r   r   r   r   r   )
rY   r
   rK   r   rE   rQ   r   r   rd   r   )r   r{   r   r   r   r   s         r,   r"  "AgentsChatClass._record_bulk_usage  s	    u	TWW%11 0 0115#dnn-T-1\\DLL)t! !%))O"<"AB"%eii0C&D&I"J >!:!?a@(+EII6O,P,UTU(V),UYY7Q-R-WVW)X%' 2   	GG	s   D1E $E43E4)rY   rK   rR   rQ   r   )rK   r   rY   
int | NonerQ   rC  r   rC  rR   rC  returnNone)NNNN)r{   r   ru   r   rD   rC  rW   
str | Noner`   rC  r   list[dict[str, str]] | NonerD  Iterator[dict[str, Any]])r{   r   r   r   r   r   r   rG  r`   rC  rD  rH  )r{   r   r   r   rD   rE   rX   r   rW   rF  r`   rE   r  r   r   r   rD  zdict[str, Any])r{   r   r   r   r   dict[str, Any] | Noner   r   r   r   rD  rE  )
__name__
__module____qualname____firstlineno__r   r  r   r   r"  __static_attributes__r*   r+   r,   r   r   f  s   
 #' $""&''  	'
 ' '  ' 
'& "&"&"&/3AA A 	A
  A  A -A 
"AFW
 W
 	W

 W
 -W
  W
 
"W
rA
 A
 	A

 A
 A
  A
 A
 A
 A
 
A
F  	
 %   
r+   r   c           	     $   U(       d  U $ U (       d  [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      [        UR                  S5      =(       d    S5      S.$ S HL  n[        U R                  U5      =(       d    S5      [        UR                  U5      =(       d    S5      -   X'   MN     U $ )Nr   r   r   r   r   r   r   )rE   r   )accextrakeys      r,   r!  r!    s     
 ?!;!@qA!$UYY/B%C%Hq!I		. 9 >Q?'*5995N+O+TST'U(+EII6P,Q,VUV(W
 	
 swws|(q)C		#0C!,DD Jr+   )rD  r   )rK   r   rD   rE   rD  ztuple[str | None, str | None])rK   r   rj   r   rY   rE   rD   rE   rX   rF  rW   rF  r`   rC  rQ   rC  rR   rC  rD  ri   )rY   rE   rj   r   rD  r   )rK   r   rw   r   rY   rE   rD   rC  rW   rF  r`   rC  ru   r   rQ   rC  rR   rC  rD  r   )r   r   ru   r   r   rG  rD  zlist[dict[str, str]])rP  rI  rQ  rI  rD  rI  )B__doc__
__future__r   collections.abcr   typingr   sqlalchemy.ormr    app.backend.classes.agents_classr   +app.backend.classes.agents_llm_models_classr   $app.backend.classes.agents_mcp_classr	   &app.backend.classes.agents_usage_classr
   app.backend.core.configr   app.backend.db.models.agentr   %app.backend.utils.agents_bulk_reportsr   rh   r   r   re   r   r   r   r   r   r   r   %app.backend.utils.agents_chat_contextr   r   r   r   r   r   #app.backend.utils.agents_code_guardr   r   r   $app.backend.utils.agents_scope_guardr    r!   #app.backend.utils.agents_llm_clientr"   r#   r$   #app.backend.utils.agents_mcp_fieldsr%   r&   r'   r(   r-   r/   rP   ro   rt   r   r   r   r!  r*   r+   r,   <module>rd     s   = " $  " 8 L ? C , 2    
 
 H !"== = 	=
 = = = = = = 
=@&  "]&]& ]& 	]&
 ]& ]& ]& ]& ]& ]& 	]&@  )	
 (J JZ	'<r+   