+
    iHàjÇ'  ã                  ót  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
Ht ^ RIHt ^ RIHt ^ RIHt ^ RIHtHt ]P*                  ! ]4      t]! RR	7       ! R
 R4      4       t]].]3,          t]
! RRR7      tR]R&   ]! ^4      t0 R3mtRtRt Rt!]PD                  ! R]PF                  4      t$]PD                  ! R]PF                  4      t%R R lt&R R lt'R R lt(R R lt)R R lt*R R  lt+R! R" lt,R# R$ lt-R4]*R5]+R6]-/t.R% R& lt/R' R( lt0R7R) R* llt1R+ R, lt2R- R. lt3R/ R0 lt4R8R1 R2 llt5R# )9a  Pre-execution ACP edit approval helpers.

Intentionally isolated from the generic tool registry: ACP binds an edit
approval requester in a ContextVar for the duration of one ACP agent run; CLI,
gateway, and other sessions leave it unset and therefore bypass this guard.
)ÚannotationsN)Ú
ContextVarÚToken)Ú	dataclass)Úcount)ÚPath)ÚAnyÚCallableT)Úfrozenc                  ó\   € ] tR t^t$ RtR]R&   R]R&   R]R&   R]R&   R]R	&   RtR
]R&   RtR# )ÚEditProposalz?A proposed single-file edit that can be shown to an ACP client.ÚstrÚ	tool_nameÚpathú
str | NoneÚold_textÚnew_textúdict[str, Any]Ú	argumentsztuple[str, ...]Úpaths© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r   Ú__static_attributes__r   ó    Ú>/home/ubuntu/.hermes/hermes-agent/acp_adapter/edit_approval.pyr   r      s,   ‡ áIàƒNØ
ƒIØÓØƒMØÓð  €Eˆ?×r   r   ÚACP_EDIT_APPROVAL_REQUESTER)Údefaultz(ContextVar[EditApprovalRequester | None]Ú_EDIT_APPROVAL_REQUESTERÚaskÚworkspace_sessionÚsessionz/^\*\*\*\s+(?:Update|Add|Delete)\s+File:\s*(.+)$z+^\*\*\*\s+Move\s+File:\s*(.+?)\s*->\s*(.+)$c               ó    € V ^8„  d   QhRRRR/# )é   Ú	requesterzEditApprovalRequester | NoneÚreturnr   r   )Úformats   "r   Ú__annotate__r+   5   s   € ÷ 3ñ 3Ð+Gð 3ÈEñ 3r   c                ó,   € \         P                  V 4      # )z<Bind an ACP edit approval requester for the current context.)r"   Úset)r(   s   &r   Úset_edit_approval_requesterr.   5   s   € ä#×'Ñ'¨	Ó2Ð2r   c               ó    € V ^8„  d   QhRRRR/# )r'   Útokenr   r)   ÚNoner   )r*   s   "r   r+   r+   :   s   € ÷ *ñ *¨ð *°4ñ *r   c                ó0   € \         P                  V 4       R# )z3Restore a previous edit approval requester binding.N)r"   Úreset)r0   s   &r   Úreset_edit_approval_requesterr4   :   s   € ä×"Ñ" 5Ö)r   c               ó    € V ^8„  d   QhRRRR/# )r'   r   r   r)   r   r   )r*   s   "r   r+   r+   ?   s   € ÷ ñ ˜sð  zñ r   c                óÒ   € \        V 4      P                  4       pVP                  4       '       d   VP                  R RR7      # VP	                  4       '       d   \        RV  24      hR# )z	utf-8-sigÚreplace)ÚencodingÚerrorszCannot edit non-file path: N)r   Ú
expanduserÚis_fileÚ	read_textÚexistsÚOSError)r   Úps   & r   Ú_read_text_if_existsr@   ?   sS   € ÜˆT‹
×ÑÓ€AØ‡y�y‡{‚{Ø�{‰{ K¸	ˆ{ÓBÐBØ‡x�x‡z‚zÜÐ3°D°6Ð:Ó;Ð;Ùr   c               ó    € V ^8„  d   QhRRRR/# )r'   r   r   r)   r   r   )r*   s   "r   r+   r+   H   s   € ÷ -ñ -˜nð -°ñ -r   c                óž   € \        V P                  R 4      ;'       g    R4      pV'       g   \        R4      h^ RIHp \        V! V4      4      # )r   Ú zpath required)Ú_resolve_path_for_task)r   ÚgetÚ
ValueErrorÚtools.file_tools_pathsrD   )r   r   rD   s   &  r   Ú_required_pathrH   H   s?   € Üˆy�}‰}˜VÓ$×*Ð*¨Ó+€DßÜ˜Ó)Ð)Ý=ÜÑ% dÓ+Ó,Ð,r   c               ó    € V ^8„  d   QhRRRR/# ©r'   r   r   r)   r   r   )r*   s   "r   r+   r+   P   s   € ÷ gñ g¨ð g¸<ñ gr   c           	     ó¬   € \        V 4      pV P                  R 4      pVf   \        R4      h\        RV\	        V4      \        V4      \        V 4      4      # )Úcontentzcontent requiredÚ
write_file)rH   rE   rF   r   r@   r   Údict)r   r   rL   s   &  r   Ú_proposal_for_write_filerO   P   sO   € Ü˜)Ó$€DØ�m‰m˜IÓ&€GØ‚ÜÐ+Ó,Ð,Ü˜ dÔ,@ÀÓ,FÌÈGËÔVZÐ[dÓVeÓfÐfr   c               ó    € V ^8„  d   QhRRRR/# rJ   r   )r*   s   "r   r+   r+   X   s   € ÷ Lñ L¨>ð L¸lñ Lr   c                ó´  € \        V 4      pV P                  R 4      V P                  R4      r2Ve   Vf   \        R4      h\        V4      pVf   \        RV 24      h^ RIHp V! V\        V4      \        V4      \        V P                  RR4      4      4      w  rgr‰V	'       g   V^ 8X  d   \        T	;'       g    RV 24      h\        RWV\        V 4      4      # )	Ú
old_stringÚ
new_stringz"old_string and new_string requiredzFailed to read file: )Úfuzzy_find_and_replaceÚreplace_allFz'Could not find match for old_string in Úpatch)
rH   rE   rF   r@   Útools.fuzzy_matchrT   r   Úboolr   rN   )
r   r   rR   rS   r   rT   r   Úmatch_countÚ	_strategyÚerrors
   &         r   Ú_proposal_for_patch_replacer\   X   sÎ   € Ü˜)Ó$€DØ&Ÿ]™]¨<Ó8¸)¿-¹-ÈÓ:U�
ØÒ˜ZÒ/ÜÐ=Ó>Ð>Ü# DÓ)€HØÒÜÐ0°°Ð7Ó8Ð8å8á.DØ”#�j“/¤3 z£?´D¸¿¹À}ÐV[Ó9\Ó4]ó/_Ñ+€H˜9ç�˜qÔ Ü˜×RÐRÐ$KÈDÈ6Ð"RÓSÐSÜ˜ °¼4À	»?ÓKÐKr   c               ó    € V ^8„  d   QhRRRR/# )r'   Ú
patch_bodyr   r)   z	list[str]r   )r*   s   "r   r+   r+   j   s   € ÷ #ñ #¨ð #°ñ #r   c                ó<  a€ \         P                  V 4       Uu. uF!  qP                  ^4      P                  4       NK#  	  pp\        P                  V 4       F  oVP                  V3R lR 4       4       K   	  V Uu. uF  q3'       g   K  VNK  	  up# u upi u upi )é   c              3  ób   <"  € T F$  pSP                  V4      P                  4       x € K&  	  R # 5i©N)ÚgroupÚstrip)Ú.0ÚiÚmatchs   & €r   Ú	<genexpr>Ú+_extract_v4a_patch_paths.<locals>.<genexpr>m   s%   øé € Ð<±V°�U—[‘[ “^×)Ñ)×+Ð+³Vùs   ƒ,/)r`   r'   )Ú_V4A_FILE_REÚfinditerrc   rd   Ú_V4A_MOVE_REÚextend)r^   Úmr   r?   rg   s   &   @r   Ú_extract_v4a_patch_pathsro   j   s~   ø€ Ü)5×)>Ñ)>¸zÔ)JÓKÑ)J A�W‰W�Q‹Z×ÑÖÑ)J€EÐKÜ×&Ñ& zÖ2ˆØ�‰Ô<±VÓ<Ö<ñ 3áÓ"‘u�!£�AˆA‘uÑ"Ð"ùò Lùò #s   ™'BÁ=	BÂBc               ó    € V ^8„  d   QhRRRR/# rJ   r   )r*   s   "r   r+   r+   q   s   € ÷ ñ  ~ð ¸,ñ r   c           
     óÄ  € V P                  R 4      p\        V\        4      '       d	   V'       g   \        R4      h\	        V4       Uu. uF  p\        RV/4      NK  	  ppV'       g   \        R4      h\        V4      ^8H  p\        R V'       d
   V^ ,          MRP                  V4      V'       d   \        V^ ,          4      MRV\        V 4      \        V4      4      # u upi )rV   zpatch content requiredr   z no file paths found in V4A patchz, N)rE   Ú
isinstancer   rF   ro   rH   Úlenr   Újoinr@   rN   Útuple)r   r^   r   r   Úsingles   &    r   Ú_proposal_for_patch_v4arw   q   s·   € Ø—‘˜wÓ'€JÜ�j¤#×&Ò&¯jÜÐ1Ó2Ð2Ü8PÐQ[Ô8\Ó]Ñ8\°Œ^˜V T˜NÖ+Ñ8\€EÐ]ßÜÐ;Ó<Ð<Ü�‹Z˜1‰_€Fô ØŸV��q–¨¯©°5Ó)9ß*0Ô˜U 1�XÔ&°d¸JÌÈYËÜˆe‹óð ùò ^s   ÁCc               ó$   € V ^8„  d   QhRRRRRR/# )r'   r   r   r   r   r)   zEditProposal | Noner   )r*   s   "r   r+   r+   ‰   s"   € ÷ 3ñ 3 3ð 3°>ð 3ÐFYñ 3r   c                óˆ   € V R8X  d   VP                  RR4      MRp\        P                  W34      pV'       d	   V! V4      # R# )z:Return an edit proposal for supported file mutation calls.rV   Úmoder7   N)rE   Ú_PROPOSAL_BUILDERS)r   r   rz   Úbuilders   &&  r   Úbuild_edit_proposalr}   ‰   s@   € à/8¸GÔ/Cˆ9�=‰=˜ Ô+È€DÜ ×$Ñ$ iÐ%6Ó7€Gß!(‰7�9ÓÐ2¨dÐ2r   c               ó    € V ^8„  d   QhRRRR/# )r'   r   r   r)   rX   r   )r*   s   "r   r+   r+   �   s   € ÷ gñ g¨#ð g°$ñ gr   c                ó  € \        V 4      P                  4       P                   Uu0 uF  qP                  4       kK  	  pp\	        VR R0,          4      ;'       g+    \        V 4      P
                  P                  4       \        9   # u upi )z.gitz.ssh)r   r:   ÚpartsÚlowerrX   ÚnameÚSENSITIVE_AUTO_APPROVE_NAMES)r   ÚpartÚlowereds   &  r   Ú_is_sensitive_auto_approve_pathr†   �   si   € Ü(,¨T«
×(=Ñ(=Ó(?×(EÒ(EÓFÑ(E �z‰zŽ|Ñ(E€GÐFÜ�˜6 6Ð*Õ*Ó+×fÐf¬t°D«z¯©×/DÑ/DÓ/FÔJfÑ/fÐfùò Gs   ¦Bc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r'   Úproposalr   Úpolicyr   Úcwdr   r)   rX   r   )r*   s   "r   r+   r+   •   s)   € ÷ ñ  |ð ¸Sð Àzð Ð]añ r   c                ó  aa€ \        T;'       g    \        4      P                  4       pV P                  ;'       g    V P                  3pV\        8X  g;   \
        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   R# V Uu. uF,  p\        V4      P                  4       P                  RR7      NK.  	  ppV\        8X  d   R# V\        8X  dž   \        \        P                  ! 4       4      P                  RR7      oV'       d*   \        V4      P                  4       P                  RR7      MRo\        ;QJ d     VV3R lV 4       F  '       d   K   R# 	  R# ! VV3R lV 4       4      # R# u upi )z¢Return whether an ACP edit proposal may bypass the prompt for this session.

Session-scoped and conservative: sensitive paths still ask under autonomous policies.c              3  ó8   "  € T F  p\        V4      x € K  	  R # 5irb   )r†   )re   r?   s   & r   rh   Ú+should_auto_approve_edit.<locals>.<genexpr>�   s   é € Ð([ÑUZÐPQÔ)HÈ×)KÐ)KÓUZùs   ‚TF)ÚstrictNc              3  ó�   <"  € T F;  pVP                  S4      ;'       g    SR J;'       d    VP                  S4      x € K=  	  R # 5irb   )Úis_relative_to)re   r   ÚtmpÚwss   & €€r   rh   r�   §   sF   øé € ð "á �ð ×Ñ Ó$×TÐT¨°4¨×)SÐ)S¸D×<OÑ<OÐPRÓ<SÔTÛ ùs   ƒA A¬A)r   ÚAUTO_APPROVE_ASKrd   r   r   Úanyr   r:   ÚresolveÚAUTO_APPROVE_SESSIONÚAUTO_APPROVE_WORKSPACEÚtempfileÚ
gettempdirÚall)rˆ   r‰   rŠ   r   r?   Úresolvedr‘   r’   s   &&&   @@r   Úshould_auto_approve_editrœ   •   s:  ù€ ô �×+Ð+Ô+Ó,×2Ñ2Ó4€Fð �N‰N×.Ð.˜xŸ}™}Ð.€EØÔ!Ô!§S£SÑ([ÑUZÓ([§S§S¢SÑ([ÑUZÓ([×%[Ò%[ÙÙDIÓJÁE¸q”�Q“×"Ñ"Ó$×,Ñ,°EÐ,Ö:ÁE€HÐJØÔ%Ô%ÙØÔ'Ô'ô ”8×&Ò&Ó(Ó)×1Ñ1¸Ð1Ó?ˆß=@ŒT�#‹Y×!Ñ!Ó#×+Ñ+°5Ð+Ô9Àdˆß‹sõ "á ó"�sŒsð 	"Šsð 	"ˆsõ "á ó"ó "ð 	"ñ ùò Ks   Â2Fc               ó    € V ^8„  d   QhRRRR/# )r'   Úmessager   r)   r   )r*   s   "r   r+   r+   ­   s   € ÷ >ñ >�Sð >˜Sñ >r   c                ó6   € \         P                  ! R V /RR7      # )r[   F)Úensure_ascii)ÚjsonÚdumps)rž   s   &r   Ú_deniedr£   ­   s   € Ü�:Š:�w Ð(°uÔ=Ð=r   c               ó$   € V ^8„  d   QhRRRRRR/# )r'   r   r   r   r   r)   r   r   )r*   s   "r   r+   r+   ±   s&   € ÷ gñ g¨3ð g¸>ð gÈjñ gr   c                ó‚  € \         P                  4       pVf   R#  \        W4      pTf   R#  \        T! T4      4      pT'       d   R# \        R4      #   \         d0   p\        P                  RY4       \        RT R24      u Rp?# Rp?ii ; i  \         d#   p\        P                  RT4       Rp Rp?LzRp?ii ; i)z´Run ACP edit approval if bound.

Returns a JSON tool-error string when the edit must be blocked, otherwise
``None`` so dispatch can continue.  Requester exceptions deny by default.Nz5Could not build ACP edit approval proposal for %s: %sz.Edit approval denied: could not prepare diff (Ú)z&ACP edit approval requester failed: %sFz:Edit approval denied by ACP client; file was not modified.)r"   rE   r}   Ú	ExceptionÚloggerÚwarningr£   rX   )r   r   r(   rˆ   ÚexcÚapproveds   &&    r   Úmaybe_require_edit_approvalr¬   ±   s½   € ô
 )×,Ñ,Ó.€IØÒÙðPÜ& yÓ<ˆð ÒÙðÜ™	 (Ó+Ó,ˆ÷ ˆ4Ðf¤Ð)eÓ!fÐføô ô PÜ�‰ÐNÐPYÔ_ÜÐGÈÀuÈAÐNÓOÕOûðPûô ô Ü�‰Ð?ÀÔEØ�ûðús4   œA ®B ÁBÁ$B	ÂBÂ	BÂB>ÂB9Â9B>c               ó   € V ^8„  d   QhRR/# )r'   rˆ   r   r   )r*   s   "r   r+   r+   È   s   € ÷ 	ñ 	 |ñ 	r   c                ó  € ^ RI pVP                  R\        \        4       2RV P                   2RRVP                  V P                  V P                  V P                  R7      .RV P                  RV P                  /R	7      # )
z<Build the ToolCallUpdate payload for ACP request_permission.Nzedit-approval-zApprove edit: ÚeditÚpending)r   r   r   Útoolr   )ÚtitleÚkindÚstatusrL   Ú	raw_input)
ÚacpÚupdate_tool_callÚnextÚ_PERMISSION_REQUEST_IDSr   Útool_diff_contentr   r   r   r   )rˆ   r¶   s   & r   Úbuild_acp_edit_tool_callr»   È   s†   € ãà×ÑØ
œÔ5Ó6Ð7Ð8À.ÐQY×Q^ÑQ^ÐP_Ð@`ÐgmØØ×&Ñ&¨H¯M©MÀH×DUÑDUÐ`h×`qÑ`qÐ&ÓrÐsØ˜8×-Ñ-¨{¸H×<NÑ<NÐOð	  ó ð r   c               ó4   € V ^8„  d   QhRRRRRRRRR	R
RRRR/# )r'   Úrequest_permission_fnr	   Úloopzasyncio.AbstractEventLoopÚ
session_idr   Útimeoutzfloat | NoneÚauto_approve_getterz+Callable[[], tuple[str, str | None]] | NoneÚsend_updatezCallable[[object], None] | Noner)   ÚEditApprovalRequesterr   )r*   s   "r   r+   r+   Ô   sH   € ÷ ñ Ø#ðØ+DðØRUðàðà7bðð 1ðð ñ	r   c                ó.   a aaaaa€ R VVV VVV3R llpV# )zGReturn a sync requester that bridges edit proposals to ACP permissions.c               ó    € V ^8„  d   QhRRRR/# )r'   rˆ   r   r)   rX   r   )r*   s   "r   r+   Ú6make_acp_edit_approval_requester.<locals>.__annotate__Û   s   € ÷ wñ w˜\ð w¨dñ wr   c                óÊ  <€ ^ RI Hp ^ RIHpHp S	e@    S	! 4       w  rE\        WV4      '       d#   \        P                  RW@P                  4       R#  V! SS
S\        V 4      V! RRR	R
7      V! RRRR
7      .V! S4      RSR7      w  rg\        VRR4      p\        VRR4      R8H  ;'       d    \        VRR4      R8H  #   \         d    \        P                  RRR7        LŽi ; i)é    )ÚPermissionOption)Úawait_permissionÚresolve_permission_timeoutNz*Auto-approved ACP edit under policy %s: %sTz*ACP edit auto-approval policy check failed)Úexc_infoÚ
allow_oncez
Allow edit)Ú	option_idr³   r‚   ÚdenyÚreject_onceÚDenyzEdit approval request)Ú	tool_callÚoptionsrÀ   ÚwhatrÂ   ÚoutcomeÚselectedrÎ   )Ú
acp.schemarÉ   Úacp_adapter.permissionsrÊ   rË   rœ   r¨   Úinfor   r§   Údebugr»   Úgetattr)rˆ   rÉ   rÊ   rË   r‰   rŠ   ÚresponseÚ
_timed_outrÕ   rÁ   r¾   r½   rÂ   r¿   rÀ   s   &        €€€€€€r   Ú
_requesterÚ4make_acp_edit_approval_requester.<locals>._requesterÛ   sù   ø€ Ý/ßXàÒ*ðZÙ1Ó3‘�Ü+¨H¸c×BÒBÜ—K‘KÐ LÈf×VcÑVcÔdÙð Cñ  0Ø! 4¨Ô?WÐX`Ó?aÙ%°À<ÐVbÔcÙ%°¸]ÐQWÔXðZá.¨wÓ7Ð>UÐcnô	 
Ñˆô ˜( I¨tÓ4ˆÜ�w 	¨4Ó0°JÑ>×vÐvÄ7È7ÐT_ÐaeÓCfÐjvÑCvÐvøô ô ZÜ—‘ÐIÐTX�ÖYðZús   •;B= Â="C"Ã!C"r   )r½   r¾   r¿   rÀ   rÁ   rÂ   rÞ   s   ffffff r   Ú make_acp_edit_approval_requesterrà   Ô   s   ý€ ÷wõ wð, Ðr   >   Úid_rsaÚ
id_ed25519ú.envú
.env.localú.env.production)rM   N)rV   r7   )rV   rV   rb   )NNN)6Ú__conditional_annotations__r   Ú
__future__r   Úasyncior¡   ÚloggingÚrer˜   Úcontextvarsr   r   Údataclassesr   Ú	itertoolsr   Úpathlibr   Útypingr   r	   Ú	getLoggerr   r¨   r   rX   rÃ   r"   r   r¹   rƒ   r“   r—   r–   ÚcompileÚ	MULTILINErj   rl   r.   r4   r@   rH   rO   r\   ro   rw   r{   r}   r†   rœ   r£   r¬   r»   rà   )ræ   s   @r   Ú<module>ró      sA  øðôõ #ã Û Û Û 	Û ß )Ý !Ý Ý ß  à	×	Ò	˜8Ó	$€ñ �$Ô÷ ð  ó ð ð ! , °Ð!5Õ6Ð áEOÐPmÐw{ÔE|Ð ÐBÓ |Ù ›(Ð â`Ð ØÐ Ø,Ð Ø Ð à�zŠzÐLÈbÏlÉlÓ[€Ø�zŠzÐHÈ"Ï,É,ÓW€õ3õ
*õ
õ-õgõLõ$#õð& Ð2Ð4HÐJeØÐ/ðÐ õ3õg÷
õ0>õgõ.	÷ñ r   