
    {j                        S r SSKJr  SSK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 jrSS jr " S S5      rg)zDMCP store_data: persist agent field payloads and generate documents.    )annotationsN)datetime)Any)Session)generate_and_save_document)
AgentModel)AgentDocumentTemplateModel)AgentsMcpSaveModel)fields_from_jsonc                   U R                   U R                  U R                  U R                  U R                  U R
                  U R                  U R                  U R                  U R                  U R                  (       a  U R                  R                  5       OS U R                  (       a  U R                  R                  5       S.$ S S.$ )N)idagentId
customerId	studentId
documentIdoriginstatusfolderIddownloadUrlfileName	createdAt	updatedAt)r   agent_idcustomer_id
student_iddocument_idr   r   	folder_iddownload_url	file_name
created_at	isoformat
updated_at)rows    VC:\Users\jesus\Desktop\proyecto_pie360\backend\app\backend\classes\agents_mcp_class.py_serialize_saver%      s    ff<<oo^^oo****MM''MM36>>S^^--/t36>>S^^--/  HL     c                F   U (       a  [        U 5      R                  5       (       d  g [        U 5      R                  5       n UR                  S5      (       a  US S S-   n[        R                  " U5      nUR
                  b  UR                  S S9nU$ ! [         a     g f = f)NZz+00:00)tzinfo)strstripendswithr   fromisoformatr*   replace
ValueError)sincerawdts      r$   _parse_sincer4   #   s    E
((**
e*


C<<cr(X%C##C(99 4(B	 s   AB 
B B c                     \ rS rSrSS jrSS.             SS jjrSSSSS.             SS jjr        SS	 jrSS
.         SS jjrSS.         SS jjr	SSSSS.               SS jjr
SS.             SS jjrSSS.             SS jjrSS jrSSSS.             S S jjrSrg)!AgentsMcpClass2   c                    Xl         g )Ndb)selfr:   s     r$   __init__AgentsMcpClass.__init__3   s    r&   N)metac                  U=(       d    SR                  5       nU(       d  SSSS.$ [        U5      S:  a  SSSS.$ [        U5      S:  a  SSSS.$ [        U5      S:  a  SS	SS.$ [        U[        5      (       a  U(       d  SS
SS.$ U R                  R                  [        5      R                  [        R                  U:H  [        R                  [        U5      :H  5      R                  5       nU(       d  SSSS.$ UR                  5        V	V
s0 s H  u  p[        U	5      U
c  SOU
_M     sn
n	[        U[        5      (       a  UO0 S.n[        R                  " 5       n[        U[        U5      [        U5      [        U5      [         R"                  " USS9SSUUS9	nU R                  R%                  U5        U R                  R'                  5         U R                  R)                  U5        SS[+        U5      S.$ s  sn
n	f )N erroragent_id es requerido.  r   messagehttp_status      customer_id inválido.   student_id inválido.u   document_id inválido.z0fields debe ser un objeto con al menos un campo.Agente no encontrado.  )fieldsr>   Fensure_asciiagentpending)	r   r   r   r   payload_jsonr   r   r    r"   successzDatos guardados (pending).r   rE   data)r,   int
isinstancedictr:   queryr   filterr   r   firstitemsr+   r   utcnowr
   jsondumpsaddcommitrefreshr%   )r;   r   r   r   r   rL   r>   aidrO   kvpayloadnowr#   s                 r$   
store_dataAgentsMcpClass.store_data6   s    ~2$$&%2J[^__{a%2J[^__z?Q%2IZ]^^{a%2J[^__&$''v!M"  GGMM*%V$&&#k*:: UW 	 %2IZ]^^ EKLLNSNDAs1vaiQ6NS&tT22D
 oo K(:K(G%@

 	C3#C(
 	
% Ts   G>
   )r   r   r1   limitc                  U R                   R                  [        5      R                  [        R                  U=(       d    SR                  5       :H  [        R                  [        U5      :H  [        R                  S:H  [        R                  S:H  5      nUb:  [        U5      S:  a+  UR                  [        R                  [        U5      :H  5      nUb:  [        U5      S:  a+  UR                  [        R                  [        U5      :H  5      n[        U5      nUb"  UR                  [        R                  U:  5      nUR                  [        R                  R                  5       5      R!                  [#        S[%        [        U=(       d    S5      S5      5      5      R'                  5       n	SU	 V
s/ s H  n
[)        U
5      PM     sn
S	.$ s  sn
f )
Nr@   rO   rP   r   rG   ri   r7   rR   )r   rT   )r:   rX   r
   rY   r   r,   r   rU   r   r   r   r   r4   r    order_byascrj   maxminallr%   )r;   r   r   r   r   r1   rj   qsince_dtrowsrs              r$   list_pendingAgentsMcpClass.list_pendingt   se    GGMM,-44''HN+A+A+CC**c+.>>%%0%%2	
 !c*o&9+66#j/IJA"s;'7!';+773{;KKLA&+66(BCAJJ)4488:;U3q#c%+2.345SU 	
 $$-O$Qoa.@$-OPP-Os   5Gc          	     	   U R                   R                  [        5      R                  [        R                  [        U5      :H  [        R                  U=(       d    SR                  5       :H  [        R                  [        U5      :H  [        R                  S:H  5      R                  5       nU(       d  SSSS.$ UR                  S:X  al  UR                  (       a[  SS	[        U5      [        UR                  =(       d    UR                  5      UR                   =(       d    SS UR                  S
./S.S.$ UR                  S:w  a  SSUR                   S3SS.$ U R                   R                  ["        5      R                  ["        R                  UR                  :H  ["        R$                  UR$                  :H  5      R                  5       nU(       dA  SUl        [&        R(                  " 5       Ul        U R                   R-                  5         SSSS.$  [.        R0                  " UR2                  =(       d    S5      n[7        U[8        5      (       a  UR;                  S5      O0 n[7        U[8        5      (       d  0 nUR=                  5        VV	s0 s H  u  p[        U5      U	c  SO
[        U	5      _M!     n
nn	[?        U R                   U[        UR@                  5      U
5      nUR;                  S5      S:X  ae  SUl        [&        R(                  " 5       Ul        U R                   R-                  5         SUR;                  S5      =(       d    SSS[        U5      0S.$ UR;                  S5      =(       d    SnUR;                  S5      =(       d    U(       a  SU 3OS nSUl        UR;                  S5      Ul        U=(       d    S Ul        Xl        [&        R(                  " 5       Ul        U R                   R-                  5         U R                   RC                  U5        SS[        U5      [        UR                  =(       d    UR                  5      UR                   =(       d    UUR;                  S5      UR                  S
./[E        UR;                  S 5      5      UR;                  S!5      UR;                  S"5      S#.S.$ ! [.        R4                   a    0 n GNf = fs  sn	nf )$Nr@   rO   rA   Save no encontrado.rK   rD   	generatedrR   zDocumento ya generado.)r   namedocumentNamer   )saveresponseFilesrS   rP   zSave en estado 'z', no se puede generar.  z7Plantilla del documento no encontrada para este agente.z{}rL   r   rE   zError al generar documento.rC   r|   r   rE   rF   rT   filenamer   z/files/system/students/r   zDocumento generado.r{   
formFilledfamilyReportIdpsychopedEvaluationId)r|   r}   r   r   r   )#r:   rX   r
   rY   r   rU   r   r,   r   r   rZ   r   r   r%   r+   r   r   r	   r   r   r\   r"   r`   r]   loadsrQ   JSONDecodeErrorrV   rW   getr[   r   r   ra   bool)r;   r   r   save_idr#   templatere   
fields_rawrc   rd   replacementsresultr   r   s                 r$   generate_saveAgentsMcpClass.generate_save   s    GGMM,-V"%%W5"++B/E/E/GG"..#k2BB"))W4	 UW 	 %2GX[\\::$)9)9#3+C0 #&cmm&=svv">$'MM$7R,0+.+;+;	&
  ::"!-cjj\9PQ"  GGMM45V*33s||C*66#//I UW 	  CJ%__.CNGGNN!T" 	jj!1!1!9T:G /9$.G.GW[[*R
*d++JHRHXHXHZ[HZAaiSV;HZ[+GGXs3>>2L
 ::h7* CJ%__.CNGGNN!!::i0Q4Q"!56	  ::j)/Rzz-0 
4<%hZ0$ 	 !


:. (D'!*  ,', "#--"9366: # 9(.

>(B'*'7'7	" #6::l#;<"(**-=">)/4K)L
 	
C ## 	G	
 \s   )S &S!SS)student_rutc          	        U=(       d    SR                  5       nU(       d  SSSS.$ [        U5      S:  a  SSSS.$ U R                  R                  [        5      R                  [        R                  U:H  [        R                  [        U5      :H  5      R                  5       nU(       d  SSS	S.$ S
SK	J
n  UR                  UR                  =(       d    SU=(       d    SU[        U5      S9u  pSSUR                  UR                  U	U=(       d    SR                  5       U=(       d    SR                  5       =(       d    SUS.S.$ )z?Retrieval barato sobre textos derivados del agente (_derived/).r@   rA   rB   rC   rD   rG   rH   rJ   rK   r   )agents_derived_storage)rX   r   r   rR   u!   Búsqueda en archivos del agente.N)r   	agentName	fileCountrX   
studentRutcontextrS   )r,   rU   r:   rX   r   rY   r   r   rZ   app.backend.utilsr   build_selective_files_contextrz   )
r;   r   r   rX   r   rb   rO   derivedtext
file_counts
             r$   search_agent_files!AgentsMcpClass.search_agent_files  s,    ~2$$&%2J[^__{a%2J[^__ GGMM*%V$&&#k*:: UW 	 %2IZ]^^G"@@JJ"+2#K(	 A 
  : 88"ZZ'+2,,.*0b779AT
 	
r&   )r   c                  U=(       d    SR                  5       nU(       d  SSSS.$ [        U5      S:  a  SSSS.$ [        U5      S:  a  SSSS.$ U R                  R                  [        5      R                  [        R                  U:H  [        R                  [        U5      :H  5      R                  5       nU(       d  SS	S
S.$ SSK	J
nJn  U(       a  [        U5      S:  a  [        U5      OUn	U" U R                  [        U5      U	S9n
U
R                  S5      (       dg  SU
R                  S5      =(       d    S[        U
R                  S5      =(       d    S
5      UR                  [        U5      U	U
R                  S5      S.S.$ SU
R                  S5      =(       d    SUR                  UR                  U
R                  S5      U
R                  S5      U
R                  S5      U
R                  S5      U
R                  S5      U
R                  S5      U
R                  S5      U
R                  S5      U
R                  S5      SS U
R                  S!5      U
R                  S"5      S#.S$.$ )%u   
Lee el informe psicopedagógico (u otro document_id) desde la ficha/carpeta
del estudiante (tabla folders → files/system/students), no desde Files del agente.
r@   rA   rB   rC   rD   rG   rH   rI   rJ   rK   r   )PSYCHOPED_CATALOG_DOCUMENT_ID%extract_student_catalog_document_text)r   r   okrE   u)   No se encontró el documento en la ficha.rF   r   )r   r   r   r   r   rR   OKr   r   r   	versionIdr   	truncatedcharsr   student_folderT	addedDateupdatedDate)r   r   r   r   r   r   r   r   r   r   r   sourceisLatestr   r   rS   )r,   rU   r:   rX   r   rY   r   r   rZ   /app.backend.utils.agents_student_folder_contextr   r   r   rz   )r;   r   r   r   r   rb   rO   r   r   doc_idr   s              r$   (get_student_psychopedagogical_evaluation7AgentsMcpClass.get_student_psychopedagogical_evaluation3  s    ~2$$&%2J[^__{a%2J[^__z?Q%2IZ]^^ GGMM*%V$&&#k*:: UW 	 %2IZ]^^	

 &1S5E5I[!Ol6GG:

 zz$!!::i0_4_"6::m#<#CD$xx!$Z"( &

: 6		
 
  zz),4 88"ZZ#ZZ4$jj6"JJz2#ZZ4"JJz2%zz-8#ZZ4G,!::i0* #ZZ4%zz-8
 	
r&   )	school_idperiod_yearstudent_namer   c          
        U=(       d    SR                  5       nU(       d  SSSS.$ [        U5      S:  a  SSSS.$ [        U5      S:  a  SSSS.$ U R                  R                  [        5      R                  [        R                  U:H  [        R                  [        U5      :H  5      R                  5       n	U	(       d  SS	S
S.$ SSK	J
n
  U
" U R                  [        U5      UUU(       a  [        U5      OSU(       a  [        U5      OSS9nU(       d  SSS
U	R                  [        U5      SS.S.$ SSU	R                  U	R                  S.UES.$ )u   
Lee respuestas de formularios dinámicos (Inf. Eval. Psicopedagógica → Formularios).

Usar cuando el cuestionario/Excel en Files del agente no trae la fila del estudiante.
r@   rA   rB   rC   rD   rG   rH   rI   rJ   rK   r   )$collect_dynamic_form_answers_payloadN)r   r   r   r   r   z5No hay respuestas de formulario para este estudiante.dynamic_forms)r   r   r   r   rR   z#Respuestas de formulario obtenidas.)r   r   rS   )r,   rU   r:   rX   r   rY   r   r   rZ   -app.backend.utils.agents_dynamic_form_contextr   rz   )r;   r   r   r   r   r   r   r   rb   rO   r   re   s               r$   *get_student_psychopedagogical_form_answers9AgentsMcpClass.get_student_psychopedagogical_form_answers  sU     ~2$$&%2J[^__{a%2J[^__z?Q%2IZ]^^ GGMM*%V$&&#k*:: UW 	 %2IZ]^^	
 7GG:%#(1c)nt,7K(T
 !R"$xx!$Z-		 	  < 88"ZZ 
 	
r&   c                  SSK Jn  0 nU=(       d    0 R                  5        H=  u  p[        U
[        5      (       a  U" U
5      U[	        U	5      '   M0  X[	        U	5      '   M?     UnU=(       d    SR                  5       nU R                  R                  [        5      R                  [        R                  U:H  [        R                  [        U5      :H  5      R                  5       nU(       d  SS[        U5       S3SS.$ U R                  UUUUUUS	9nUR                  S
5      S:X  a  U$ UR                  S5      =(       d    0 nUR                  S5      nU(       d  SSSS.$ U R!                  UU[        U5      S9nUR                  S
5      S:X  a  U$ UR                  S5      =(       d    0 nUR                  S5      =(       d    0 nSnSn U R#                  UUUU[        U5      S9nUR                  S
5      S:X  a  UR                  S5      nOUR                  S5      n SUR&                   SUR                   S3nU(       a/  UR                  S5      (       a  USUR                  S5       S3-  nOU(       a	  USU S3-  nSUUUR                  S5      =(       d    / [)        UR                  S5      =(       dD    UR                  S5      =(       d,    UR                  S 5      =(       d    UR                  S
5      S!:H  5      [        UR                  5      UR&                  UR                  S5      UR                  S 5      UUS".	S#.$ ! [$         a  n[	        U5      n SnAGNDSnAff = f)$u  
Genera con la plantilla cargada en Documentos del agente.

Asociación obligatoria:
- document_id = tipo de documento PIE360 (catálogo)
- plantilla .docx/.pdf subida en Agente → Documentos para ese document_id
- al generar: rellena Word/PDF + guarda en carpeta del estudiante
  + persiste el formulario asociado a ese tipo
    (familia → family_reports; psicoped → psychopedagogical_evaluation_info)
r   )strip_html_tagsr@   rA   z;No hay plantilla en Documentos del agente para document_id=z?. Sube el modelo (.docx/.pdf) asociado a ese tipo de documento.rK   rD   )r   r   r   r   rL   r>   r   rT   r   z%No se pudo crear el registro pending.  )r   r   r   r|   N)r   r   r   r   r   rE   u   Documento «u   » (document_id=zP) generado con su plantilla, guardado en el estudiante y formulario actualizado.
drive_pathz Subido a Google Drive: .z (Drive no subido: )rR   r}   r   r   r   ry   )	r|   r}   r   r   r{   r   r   googleDrivegoogleDriveErrorrS   )#app.backend.utils.agents_code_guardr   r[   rV   r+   r,   r:   rX   r	   rY   r   r   rU   rZ   rg   r   r   save_document_to_google_drive	Exceptiondocument_namer   )r;   r   r   r   r   rL   r>   r   clean_fieldskeyvalrb   r   store	save_datar   ry   rT   r|   
drive_infodrive_errordrive_resultexcmsgs                           r$   create_documentAgentsMcpClass.create_document  st   ( 	H')2,,.HC#s##)8)=SX&),SX&	 /
 ~2$$&GGMM45V*33s:*66#k:JJ UW 	 !QRUVaRbQc dT T  #  #!#   
 99X')LIIf%+	--%!B" 
 &&#L ' 
	
 =="g-}}V$*xx%2,0
"&	#==!'%'G > L )W4*..y9)--f5

 81122B8CWCWBX Y] ] 	 *..66-jnn\.J-K1MMC(Q77C  !%/!:!@b"HH\* 9xx 019xx 789 xx)[8	 "("6"67 ( 6 6"&((+;"<)-2I)J)$/
 	
  	#c(K	#s   AM M 
M+M&&M+)r   r   c                  SSK J nJn  SSKJn	  SSKJn
  SSKJnJnJ	nJ
nJnJn  SSKJn  U=(       d    SR                  5       nU(       a-  [!        U5      S:  d  [!        U5      S:  d  [!        U5      S:  a  S	S
SS.$ U R"                  R%                  [&        5      R)                  [&        R*                  U:H  [&        R,                  [!        U5      :H  5      R/                  5       nU(       d  S	SSS.$ U=(       d    SR                  5       =(       d    SnUGb:  [!        U5      S:  Ga*  U R"                  R%                  [0        5      R)                  [0        R*                  [!        U5      :H  [0        R2                  U:H  [0        R,                  [!        U5      :H  [0        R4                  [!        U5      :H  5      R/                  5       nU(       d  S	SSS.$ UR6                  S:w  d(  UR8                  =(       d    SR                  5       (       d  S	SSS.$ UR8                  =(       d    SR                  5       n[!        UR:                  =(       d    U5      nU(       d  S	SSS.$ U	" U
R<                  5      S-  S-  U	" U5      R>                  -  nURA                  5       (       d  S	SUR>                   3SS.$ U R"                  R%                  U5      R)                  UR*                  [!        U5      :H  5      R/                  5       nU R"                  R%                  U5      R)                  UR4                  [!        U5      :H  5      R/                  5       nU R"                  R%                  U5      R)                  UR4                  [!        U5      :H  5      RC                  UR*                  RE                  5       5      R/                  5       nSnU(       aL  URF                  =(       d    SR                  5       (       a$  URF                  =(       d    SR                  5       nORU(       aK  URF                  =(       d    SR                  5       (       a#  URF                  =(       d    SR                  5       nU(       a  [I        USS5      OSnU(       a  [I        USS5      OSnSnU(       a  U R"                  R%                  U5      R)                  UR*                  [!        U5      :H  5      R/                  5       nU(       aK  URJ                  =(       d    SR                  5       (       a#  URJ                  =(       d    SR                  5       nSnSn U(       a  U R"                  R%                  U5      R)                  UR*                  [!        U5      :H  5      R/                  5       n!U!(       aX  U!RL                  =(       d    SR                  5       (       a#  U!RL                  =(       d    SR                  5       n[I        U!SS5      n U c  Ub  [I        USS5      n  U b%  [!        [O        U 5      R                  5       SS 5      OSn U b  U S:  d  U S:  a&  URT                  " URV                  5      RX                  n U R"                  R%                  U5      R)                  UR*                  [!        U5      :H  5      R/                  5       n"U"(       aK  U"RZ                  =(       d    SR                  5       (       a#  U"RZ                  =(       d    SR                  5       OS [!        U5       3n#U R"                  R%                  [\        5      R)                  [\        R2                  U:H  [\        R:                  [!        U5      :H  5      R/                  5       n$[I        U$S!S5      =(       d$    UR^                  Ra                  S"5      =(       d    S#Rc                  5       n% URe                  U R"                  [!        U5      U[!        U 5      UUU#URg                  5       U%S$9	n&S&S'U&Rk                  S(5       3U&S).$ ! [P        [R        4 a    Sn  GN f = f! [R         a  n'S	[O        U'5      SS.s Sn'A'$ Sn'A'f[h         a  n'S	[O        U'5      S%S.s Sn'A'$ Sn'A'ff = f)*uf   
Sube el documento generado a Drive:
Liceo > Año > Curso > RUT numérico > RUT_Tipo de documento.ext
r   )r   timezone)Path)settings)CourseModelDocumentModelSchoolModelStudentAcademicInfoModelStudentModelStudentPersonalInfoModel)google_drive_storager@   rG   rA   zAagent_id, customer_id, student_id y document_id son obligatorios.rC   rD   rJ   rK   Nrx   ry   uA   El documento aún no está generado. Usa create_document primero.r~   z6No hay archivo local para subir (file_name / save_id).systemstudentsu4   No se encontró el archivo generado en el servidor: r   	course_idLiceoCursor      i  i4  
Documento_format_typer   docx)	r:   r   school_nameyearcourse_namer   document_type_namerT   file_extensionr   rR   z!Documento subido a Google Drive: r   rS   )6r   r   pathlibr   app.backend.core.configr   app.backend.db.models.pie_corer   r   r   r   r   r   r   r   r,   rU   r:   rX   r   rY   r   r   rZ   r
   r   r   r   r   r   	files_dirrz   is_filerl   descidentification_numbergetattrr   r   r+   	TypeErrorr0   rf   utcr   documentr	   suffixlstriplowerupload_student_document_tree
read_bytesr   r   )(r;   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   gdriverb   rO   
local_namer#   
local_pathstudentpersonalacademicrutr   r   r   schoolr   r   coursedoc_rowr   r   extre   r   s(                                           r$   r   ,AgentsMcpClass.save_document_to_google_drive>  s    	0 4	
 	
 	E~2$$&c+&*c*o.ASEUXYEY!^"  GGMM*%V$&&#k*:: UW 	 %2IZ]^^  o2,,.6$
3w<!#301&))S\9&//36&22c+6FF&11S_D	   ")6K\_``zz[(1D"0K0K0M0M%b#& 
 ---2446Jcoo<=K!S"  (,,-8:EZHXH]H]]
!!##!QR\RaRaQbc"  ''---44\__J5WX^^`GGMM23V,773z?JKUW 	 GGMM23V,773z?JKX.116689UW	 	 77=2DDFF117R>>@C'77=2DDFF006B==?C;BGG[$7	<DGHk48$	WW]];/66{~~Y7WX^^`F6--3::<<%117R>>@WW]];/66{~~Y7WX^^`F&&,"3355#)#5#5#;"B"B"DK%fmTB7#6!'=$?K	?J?V#c+.446r:;\`K +"4d8J",,x||499K GGMM-(VM$$K(889UW 	 G,,299;; #**,c+./0 	 GGMM45V*33s:*66#k:JJ UW 	 x5`9J9J9Q9QRU9V`Z`ggi	P9977,'%'#5**," : 
G"  :7;;|;T:UV
 	
W :& 	K	L  	P%#c(3OO 	P%#c(3OO	PsC   *`! A`: !`76`7:
a>aa>a>%a93a>9a>c                >    Ub  [        U5      OSnUS:X  a  / SQ$ / SQ$ )uK   Reglas de contenido según tipo de documento (familia vs psicopedagógico).N   )FuS   Contenido obligatorio del INFORME DE EVALUACIÓN PSICOPEDAGÓGICA (document_id=27):uS   - AUTORIDAD DE CAMPOS: usa SOLO los nombres listados en «Plantillas configuradas»uT     (tags de la plantilla Word cargada en Agente → Documentos). Esos son los únicosu'     nombres válidos en el JSON `fields`.zL- NO inventes ni uses nombres del formulario web si la plantilla tiene otroszS  (ej. no uses `diagnosis` si la plantilla pide `diagnostic`; no uses `social_name`zQ  / `age` si pide `student_social_name` / `student_age`; no uses `admission_type`zK  si pide `admission_type_1`/`_2`/`_3`; no uses `pedagogical_scale_*` si laz  plantilla no los lista).zL- Rellena los campos NARRATIVOS de ESA plantilla con texto respaldado en loszP  ARCHIVOS del agente / texto derivado (cuestionarios, pautas, anamnesis, etc.).uM   - REDACCIÓN HUMANA (obligatorio): está PROHIBIDO copiar etiquetas de escalauP     del cuestionario: no escribas «LOGRADO», «EN PROCESO», «REQUIERE APOYO»,uG     «NO OBSERVADO» ni las pongas entre paréntesis. Tradúcelas a prosauK     profesional: describe cómo se desempeña ESTE estudiante (qué logra conuN     autonomía, dónde necesita mediación, con qué frecuencia, en qué tipo deuM     tarea). El informe debe leerse como evaluación cualitativa, no como pauta.uC   - DETALLE DEL CASO: nombra al estudiante, ancla cada párrafo a SUSuK     características (memoria de trabajo, planificación, impulsos, lenguaje,uM     socioemocional, motricidad, autonomía, sensorial). Evita textos genéricosuI     que servirían para cualquier alumno. No copies los títulos largos delu7     cuestionario (listas entre paréntesis) como relleno.uI   - VARIAS ÁREAS / ESPECIALIDADES (obligatorio si hay más de una fuente):zM  Si el Excel o el formulario traen VARIAS observaciones del mismo estudianteuK     (p. ej. Fonoaudiología y Terapia Ocupacional, o docente + especialista),uM     el informe DEBE integrar TODAS: en análisis/síntesis/conclusión mencionauK     explícitamente lo observado desde cada área (quién/especialidad), quéuM     coincide y qué difiere. Prohibido redactar como si hubiera una sola pauta.u?     En `instruments_applied` lista cada cuestionario/área usada.uT   - EXTENSIÓN: cada narrativo DETALLADO (aprox. 120–220 palabras; 3 a 6 oraciones).zB  Prohibido una sola frase corta si hay evidencia en los archivos.uQ   - INSTRUMENTOS: si el campo existe en la plantilla, lista con guion (-), un ítemu     por línea.zV- SUGERENCIAS / RECOMENDACIONES (suggestions_to_school, suggestions_to_classroom_team,zD  suggestions_to_student, suggestions_to_family, other_suggestions):uG     formato OBLIGATORIO lista con guion medio, un ítem por línea, así:u&     - Primera recomendación concreta…u&     - Segunda recomendación concreta…uW     Prohibido numerar (1.- 2.-) o un solo párrafo. Cada ítem específico al estudiante.uD   - ANÁLISIS / SÍNTESIS / CONCLUSIÓN: completa cada campo narrativozP  que aparezca en la lista de la plantilla cuando haya evidencia o datos PIE360.uG   - FECHAS (evaluación, emisión de diagnóstico, nacimiento y cualquierzD  campo fecha): formato obligatorio **dd-mm-YYYY** (ej. 07-04-2026).u<     No uses 2026-04-07, 07/04/2026 ni «07 de abril de 2026».uG   - DATOS DEL SISTEMA: si el cuestionario no trae identificación, curso,zF  establecimiento, NEE, fechas, profesional o apoderado, USA el bloqueuK     «DATOS DEL SISTEMA PIE360» / ficha (equivalente a consultar MCP/ficha).u7     No dejes esos campos vacíos si están en ese bloque.zG- Checkboxes / tipos de ingreso / escalas de la PLANTILLA Word: solo sizN  aparecen en la lista de tags; no uses las escalas del Excel en el narrativo.zI- NO uses campos de Informe a la Familia (agreements, collaborative_work,z  supports de hogar).zO- Si en ESTE turno hay bloque ARCHIVOS / Excel / texto derivado del estudiante,uT     ÚSALO: no digas que faltan cuestionarios si las respuestas están en el contexto.zN- Si el cuestionario/Excel de Files NO trae la fila de ESTE estudiante, PIE360zH  consulta MCP get_student_psychopedagogical_form_answers (respuestas enuB     Inf. Eval. Psicopedagógica → Formularios) e inyecta el bloqueuI     «RESPUESTAS DEL FORMULARIO PIE360». Si aparece, úsalo como fuente deuK     observación en aula (traduce LOGRADO/EN PROCESO/REQUIERE APOYO a prosa).uF     Si hay Excel Y formulario, o varias áreas en cualquiera de los dos,u:     integra TODAS las áreas/especialidades en el narrativo.M- NO dejes el informe solo con datos personales (nombre, RUT, curso, fechas).uR   - No inventes evaluaciones que no estén en Files, formulario MCP ni ficha PIE360.U   - FIDELIDAD DOCUMENTAL: nunca presentes como hecho algo que no esté en los archivos;z9  nunca mezcles antecedentes entre estudiantes distintos.O   - REDACCIÓN: español latino, formal e inclusivo; sin lenguaje estigmatizante;uT     en TDA/TEA/DIL describe cualitativamente (sin puntuaciones numéricas inventadas).uD     Diagnósticos documentados con Mayúscula Inicial En Cada Palabra;uO     «años»/«meses» en minúscula. Tipografía la define la plantilla PIE360.u5   - Tú solo entregas fields; PIE360 genera el archivo.)Zz"Contenido obligatorio del informe:zN- Debes rellenar los campos NARRATIVOS de la plantilla (motivos, instrumentos,uP     diagnóstico general, fortalezas, apoyos, acuerdos, etc.) con texto respaldadoz.  en los ARCHIVOS del agente / texto derivado.uO   - EXTENSIÓN: cada campo narrativo debe ir DETALLADO (aprox. 80–180 palabras;zQ  2 a 5 oraciones). Prohibido responder con una sola frase corta si hay evidenciauP     en los archivos. Integra hallazgos concretos (áreas, instrumentos, ejemplos).uM   - SEPARACIÓN: fortalezas ≠ necesidades. No mezcles dificultades dentro delzM  campo de fortalezas; las necesidades van en su campo de apoyos/necesidades.z7- INSTRUMENTOS APLICADOS (campo `applied_instruments`):u>     lista con guion (-), **un instrumento por línea**. Ejemplo:uH     - Cuestionario de Observación Psicopedagógica en el Contexto Escolarz'  - Entrevista a la familia / AnamnesisuY     - Pauta de Evaluación y Observación Pedagógica del Estudiante en el Contexto EscolaruC     Prohibido juntarlos en un solo párrafo separados solo por comas.zB- TRABAJO COLABORATIVO EN LA ESCUELA (campo `collaborative_work`):uR     «Trabajo colaborativo y apoyos educativos para la inclusión» en aula regular,uP     sala de recursos, comunidad educativa, articulación entre profesionales, etc.uX     Formato: lista 1) 2) 3) 4)… o guiones; mínimo 4 ítems extensos (40–80 palabras).u&     NUNCA pongas aquí apoyos del hogar.uR     ESPECÍFICO AL CASO (obligatorio): cada ítem debe nombrar la dificultad o áreauL     documentada del estudiante (p. ej. cálculo/DEA, resolución de problemas,uR     funciones ejecutivas, comprensión lectora, escritura, motivación) y la acciónzQ  concreta (estrategia, material, frecuencia, asignatura). Prohibido rellenar conuR     solo «coordinación semanal», «reuniones periódicas», «trabajo en aula» ouP     «articulación con convivencia» sin vincularlo a SU problema de aprendizaje.u\     Un texto que sirva para cualquier alumno = incorrecto; reescríbelo anclado al expediente.zT- APOYOS EN EL HOGAR (campo `supports` / `home_based_description` / `home_support`):zL  Solo lo que la familia debe hacer en casa (autoestima, asistencia regular,uO     apoyo escolar en el hogar, apoyo afectivo, hábitos, higiene, participación,uL     controles de salud / redes externas, etc.). Formato: lista 1) 2) 3) 4)…;uO     mínimo 4 ítems extensos. NUNCA pongas aquí aula regular, sala de recursos,zQ  adecuaciones curriculares ni trabajo de la educadora diferencial en la escuela.uN     Cada ítem debe vincularse a su dificultad real (p. ej. matemática en casa,uD     rutina de estudio por pasos, refuerzo afectivo ante frustración).uD   - ACUERDOS Y COMPROMISOS (campo `agreements` — escuela y familia):u>     Exactamente 3 viñetas (1 escuela, 2 familia, 3 compartida).uP     Cada ítem MUY extenso y detallado (aprox. 60–120 palabras) y ESPECÍFICO aluM     estudiante: cita sus dificultades/fortalezas documentadas (p. ej. cálculo,uU     resolución de problemas, funciones ejecutivas, comprensión lectora, motivación).uP     Prohibido texto genérico tipo «apoyos psicopedagógicos», «adecuaciones»,uH     «comunicación fluida» sin decir QUÉ harán concreto para ESE caso.uO     Cada viñeta debe nombrar al estudiante y vincular la acción a su necesidad.u;     No uses mínimo 5: son exactamente 3, una por cada parte.z;- INFORME DE FAMILIA: Contrasta con la normativa del agenteuO     («Normativa Informe para la familia.pdf») si está en el contexto derivado.zE  PIE360 aplica la plantilla: no inventes secciones ni omitas campos.uU   - FECHAS DE AVANCES (`evaluation_date_1`…): solo la fecha, sin notas. Si el informeuT     es antes de julio → 4 fechas: Junio año actual, Dic. año actual, Junio año+1,uO     Dic. año+1. Si es después de julio → Junio año+1 y Dic. año+1. Fecha deuV     evaluación del informe = fecha del psicopedagógico del mismo estudiante si existe.zN- DATOS COMPLEMENTARIOS: las fuentes son el TEXTO DERIVADO / JSON del contextouS     (no se «abre» el Excel). Educadora que entrega (`professional_*`) = nómina PIEuF     del estudiante; si no está, déjala en blanco. Apoderado que recibez9  (`received_person_*`) = reporte interactivo de la sede.uS   - RUT DEL ESTUDIANTE: solo el que escribió el usuario o el de PIE360, coincidenciauM     exacta. PROHIBIDO completar o corregir dígitos con la nómina o el reportezI  (p. ej. no pases 3.012.603-8 a 23.012.603-8). Si no coincide, el RUT esu=     incorrecto: no identifiques a nadie ni envíes JSON fields.uT     Curso y RUT de plantilla: usa ficha PIE360 si el estudiante ya está identificado.uO   - Si en ESTE turno hay bloque ARCHIVOS / texto derivado del estudiante, ÚSALO:uY     no digas que «no se adjuntó» el documento de evaluación ni que faltan antecedentes.uQ   - Si NO hay psicopedagógico usable en Files del agente, PIE360 busca en la fichaz5  del estudiante (document_id=27) e inyecta el bloqueuR     «INFORME PSICOPEDAGÓGICO DESDE FICHA DEL ESTUDIANTE». Si aparece, úsalo comozU  fuente principal de narrativos. Tool MCP: get_student_psychopedagogical_evaluation.r  z   Eso no es un informe completo.uM   - Si un dato no está en los archivos, ese campo va "" (vacío). No inventes.r  zS  nunca mezcles antecedentes entre estudiantes distintos. Si hay varios estudiantesuN     en los archivos, sepáralos y un informe por cada uno. Sin RUT/ficha claros,uR     pide el RUT; no adivines ni completes el número. Si el RUT no existe en PIE360,z1  di que es incorrecto y no generes el documento.uV   - ANÁLISIS DE ANTECEDENTES: con una sola fuente, igual elabora con rigor. Con varias,zM  cruza informantes (coincidencias, diferencias, complementariedades). Si hayuO     discrepancias, expónlas con profesionalismo; no elijas una versión al azar.zO  En historia escolar / `enter_evaluation`: solo cuestionario familiar; no usesuY     fórmulas administrativas tipo «NEEP año 2» / «año 2»; diagnóstico solo si estáz  respaldado en los archivos.r  uQ     necesidades en perspectiva funcional/contextual; sin diagnósticos clínicos nozJ  documentados; en TDA/TEA/DIL describe cualitativamente (sin puntuacionesuQ     numéricas). Diagnósticos documentados con Mayúscula Inicial En Cada Palabra;uS     «años»/«meses» en minúscula. No escribas tipografía (Arial) en los fields:z$  eso lo define la plantilla PIE360.zK- No digas errores del sistema (plantilla, disco, etc.) salvo que el propiou[     contexto te lo indique en ESTE turno: tú solo entregas fields; PIE360 genera el archivo.u\   - Si en un mensaje anterior falló la plantilla pero ahora el usuario pide generar de nuevo,zX  vuelve a enviar el JSON fields completo (con narrativo); no asumas que sigue fallando.)rU   )r;   r   docs      r$   "_prompt_content_rules_for_document1AgentsMcpClass._prompt_content_rules_for_document  s3    "-"9c+t"9G GT[
 [	
r&   )r   r   r   c          
        U R                   R                  [        5      R                  [        R                  UR
                  :H  5      nUR                  [        R                  R                  5       5      R                  5       nU V	s1 s H  n	[        U	R                  5      iM     n
n	Ub  [        U5      S:  a  [        U5      OSnU(       a3  X;   a.  U V	s/ s H   n	[        U	R                  5      U:X  d  M  U	PM"     nn	OUn[        U
5      S:X  a  [        [        U
5      5      nOFU(       a  X;   a  UnO7UR                  =(       d    SR!                  5       nSU;   a  SnOSU;   a  SnOUn/ S	QnUR#                  U R%                  U5      5        UR#                  / SPS
PSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPSPS PS!PS"PS#PSPS$UR
                   S%[        U5       3PS&U 3P5        U(       a  UR'                  S'[        U5       35        U(       a  UR'                  S(U 35        UR#                  / S)Q5        U(       d  U(       d  UR#                  / S*Q5        U(       a  UR'                  S+[        U5       35        UR'                  S5        UR'                  S,5        U(       d*  US:X  a  UR'                  S-5        OUR'                  S.5        OU H  n[)        UR*                  5      nUR'                  S/UR                   S0UR                   S1UR,                   S235        U(       a/  U H  nUR'                  S3U 35        M     UR'                  S45        OUR'                  S55        U(       a  USS6 OS7/ Vs0 s H
  nUS8U S93_M     nnUR'                  S:[.        R0                  " S;U0S<S=9-   5        M     S>R3                  U5      $ s  sn	f s  sn	f s  snf )?uC   Instrucciones: plantilla Documentos ↔ document_id ↔ formulario.Nr   rG   r@   psicopedr  familia   )z#Documentos del agente (regla fija):u0   - Cada MODELO se carga en Agente → Documentos.uH   - Cada modelo está asociado a UN tipo de documento PIE360 (document_id)z;  y a SU formulario (al generar se rellena ese formulario).zQ- create_document SIEMPRE usa la plantilla de ese document_id (no inventes otra).r@   zFuentes (regla dura):zA- PROHIBIDO buscar en internet, navegar la web o usar buscadores.zO- Solo archivos del agente / texto derivado, el chat, datos PIE360 del contextozB  y tools MCP (p. ej. get_student_psychopedagogical_form_answers).uP   - PROHIBIDO HTML y código (CSS, JS, Python, SQL, etc.). Solo prosa en español.uI     El único JSON permitido es el bloque fields para generar el documento.zL- Solo atiendes PIE Chile (informes, estudiantes, NEE, Decreto 170, PIE360).zK  Si el tema no es de PIE Chile, no respondas el contenido: indica que soloz#  contestas consultas de PIE Chile.zFlujo:zF1) Lee tu ROL y los ARCHIVOS/JSON del agente / formulario MCP / ficha.z32) Si el usuario pide generar el informe/documento:zJ   a) PRIORIDAD ABSOLUTA: entrega YA el bloque JSON completo con TODOS loszL      campos de la plantilla (mismos nombres EXACTOS; narrativos incluidos).uK         El JSON debe ir PRIMERO o, como máximo, tras 1–2 oraciones cortas.z```jsonz3{"fields": {"nombre_campo": "texto completo", ...}}z```zN   b) PROHIBIDO quedarte en una intro anunciando el informe sin enviar el JSONuL         (p. ej. «A continuación se redacta el contenido de cada campo…»).zE      Eso NO genera el documento. Sin `fields` el informe no se crea.zP   c) El contenido largo va DENTRO de cada campo del JSON, no como prosa previa.zO3) Si solo es una consulta (sin generar documento), responde en prosa sin JSON.uI      El servidor ejecuta create_document → Word/PDF con esa plantilla →u9      carpeta del estudiante → formulario → Google Driveu0      (Liceo/Año/Curso/RUT/RUT_TipoDocumento.ext).zIDs: agent_id=z, customer_id=zMCP create_document URL: z- student_id del contexto: z- student_rut del contexto: )r@   zRUT (regla dura):uF   - Usa el RUT tal como lo escribió el usuario o el que entrega PIE360.zM- PROHIBIDO completar, prefijar, acortar o 'corregir' un RUT (p. ej. no pasesuB     de 3.012.603-8 a 23.012.603-8 porque 'parece' el de la nómina).uT   - Si el número no coincide exactamente con un estudiante de PIE360, no identifiquesu;     a nadie, no redactes el informe y no envíes JSON fields.)r@   u   Identificación del estudiante:zF- Si NO hay student_id ni RUT en el contexto, NO generes el informe niuA     envíes el JSON fields. Pregunta el RUT con dígito verificadorz@  (ej. 12.345.678-9) para identificar al estudiante con certeza.u3   - El nombre solo no basta (puede haber homónimos).z;- document_id prioritario (tipo + formulario + plantilla): ur   Plantillas configuradas (document_id → CAMPOS OBLIGATORIOS del Word; usa exactamente estos nombres en `fields`):u   - (ninguna plantilla subida aún) Sube el modelo en Agente → Documentos (document_id=27). Sin plantilla no hay lista de campos fiable.zR- (ninguna) Sube el modelo en Documentos del agente asociado al tipo de documento.z- document_id=u    | «u   » | :u     · uK     → El JSON `fields` debe usar ESTOS nombres (no los del formulario web).u,     · (sin campos detectados en la plantilla)   campo<>z  Ejemplo: rL   FrM   
)r:   rX   r	   rY   r   r   rl   r   rm   rp   rU   r   lennextiterrz   r   extendr
  appendr   detected_fieldsr   r]   r^   join)r;   rO   r   r   r   r   mcp_urlrq   all_templatesttemplate_ids	requested	templateseffective_docanamelinestplrL   fieldfexample_fieldss                        r$   build_store_data_prompt_block,AgentsMcpClass.build_store_data_prompt_block  s    GGMM45<<&//588;
 

#=#K#K#O#O#QRVVX4ABMqAMM*MB(3(?CDTWXDXC$^b	2$1UMqS5G95TMIUI%I |! l!34M94%MZZ%2,,.EU" "e# ! )
 	T<<]KL  '  T  b	 
 U  c  \  _  ^  6      Y  F  ]   _! " ^# $ % & F' ( ) * a+ , _- . X/ 0 c1 2 b3 4 \5 6 L7 8 C9 : ; < !
.[9I8JK= > ,G95? "	
F LL6s:6GHILL7}EF
	
 +LL	 LLMcR_N`Mab 	R;	
 "V
 h !)#*=*=>$S__$5U3;L;L:MUSVSbSbRccde !'uUG_5 "(LLe LL!OPFLr
SZR[8[!]8[!!q1X+8[!]!jj(N!;%PQ !& yyG C Vt "^s   	O$O):O)O.r9   )r:   r   returnNone)r   r+   r   rU   r   rU   r   rU   rL   dict[str, Any]r>   zdict[str, Any] | Noner,  r.  )r   r+   r   rU   r   
int | Noner   r/  r1   
str | Nonerj   rU   r,  r.  )r   r+   r   rU   r   rU   r,  r.  )
r   r+   r   rU   rX   r+   r   r0  r,  r.  )
r   r+   r   rU   r   rU   r   r/  r,  r.  )r   r+   r   rU   r   rU   r   r/  r   r/  r   r0  r   r0  r,  r.  )r   r+   r   rU   r   rU   r   rU   r   r/  r   r0  r,  r.  )r   r/  r,  z	list[str])rO   r   r   rU   r   r/  r   r/  r   r0  r  r+   r,  r+   )__name__
__module____qualname____firstlineno__r<   rg   ru   r   r   r   r   r   r   r
  r*  __static_attributes__ r&   r$   r6   r6   2   s    '+<
 <
 	<

 <
 <
 <
 $<
 
<
F "&"& Q Q 	Q
 Q  Q Q Q 
Q<p
 p
 	p

 p
 
p
p #'-
 -
 	-

 -
  -
 
-
j #'J
 J
 	J

 J
  J
 
J
d !%"&#'"&B
 B
 	B

 B
 B
  B
 !B
  B
 
B
X '+y
 y
 	y

 y
 y
 y
 $y
 
y
D # $k
 k
 	k

 k
 k
 k
 k
 
k
Zi
` #'!%"&R  R  	R 
  R  R   R  R  
R  R r&   r6   )r#   r
   r,  r.  )r1   r0  r,  zdatetime | None)__doc__
__future__r   r]   r   typingr   sqlalchemy.ormr   +app.backend.classes.agents_document_servicer   app.backend.db.models.agentr   &app.backend.db.models.agents_documentsr	   &app.backend.db.models.agents_mcp_savesr
   +app.backend.utils.agents_template_inspectorr   r%   r4   r6   r6  r&   r$   <module>r@     s<    J "    " R 2 M E H"v  v r&   