Ë
    ãß²jàD  ã                   óê  — d Z ddlZddlZddlZddlZddlmZmZ	 ddl
mZmZ ddlmZ  ej                  d«      Z	 	 d4dddd	œd
edededz  dededededz  defd„Z G d„ de«      ZdddddddœZdddddœZdedededz  fd„Zd edefd!„Z	 d5d
edededededededz  defd"„Zd#„ Zd$edefd%„Zd
eded&ed'ee   d(ed)edededefd*„Zd+ed&edefd,„Z d-edefd.„Z!dd/d0d1œd2edededz  d)ededefd3„Z"y)6aS  Human prompt surfaces for :mod:`tools.approval`.

The interactive CLI prompt (callback panel or ``input()`` fallback) and the
operator-selected plugin approval transport. Detection, allowed scopes,
persistence, timeout policy and the final authorization stay host-owned in
``tools.approval``; this module only asks and reports the answer.
é    N)Úapproval_contextÚapproval_gateway_wait)Úactivity_heartbeatÚhuman_wait_window)Úis_interruptedztools.approvalTF)Úallow_sessionÚsmart_deniedÚtitleÚcommandÚdescriptionÚtimeout_secondsÚallow_permanentr   r	   r
   Úreturnc                ó”   — |€t        j                  «       }t        «       5  t        | |||||||¬«      cddd«       S # 1 sw Y   yxY w)um  Prompt the user to approve a dangerous command (CLI only).

    allow_permanent=False hides [a]lways (tirith warnings present: broad permanent
    allowlisting is wrong for content-level findings). allow_session=False hides
    [s]ession too â€” the caller grants one operation and re-asks next time (the
    protected agent-instruction gate in ``tools/file_tools.py``); offering a scope
    the caller discards makes every later write re-prompt and reads as broken.
    smart_denied: owner override of a Smart DENY, offer only once/deny.
    title: header for the plain-input prompt when the question is not a dangerous command
    ("Save to memory?", "<server> is asking"); the default header stays the dangerous-command one.
    approval_callback: CLI prompt_toolkit callback ``(command, description, *,
    allow_permanent=True, allow_session=True, smart_denied=False) -> str``; legacy
    signatures keep working while both keywords hold their defaults.

    Returns 'once', 'session', 'always', 'deny', 'timeout', or 'cancelled'. 'timeout'
    means no user response â€” still blocked (fail-closed), but callers report "no
    response" rather than an explicit denial. 'cancelled' is an :class:`Unanswered`
    sentinel: the prompt never reached a human (callback raised, no callback under
    prompt_toolkit, interrupted read) and ``.cause`` says why (#22992).

    See #81887.
    N)r
   )Ú_ctxÚ_get_approval_timeoutr   Ú
_ask_human)r   r   r   r   Úapproval_callbackr   r	   r
   s           ú:/home/ubuntu/.hermes/hermes-agent/tools/approval_prompt.pyÚprompt_dangerous_approvalr      sT   € ð4 ÐÜ×4Ñ4Ó6ˆô 
Ó	ñ WÜ˜' ;°ÀØ+¨]¸LÐPUôW÷W÷ Wò Wús	   ¡>¾Ac                   ó,   ‡ — e Zd ZdZdZdefˆ fd„Zˆ xZS )Ú
UnansweredzãChoice ``"cancelled"`` carrying the reason nobody answered. Compares equal to the gateway's
    withdrawn-prompt choice so every consumer already handling ``cancelled`` fails closed without
    attributing a denial to the user.)Úcauser   c                 ó6   •— t         ‰| �  | d«      }||_        |S )NÚ	cancelled)ÚsuperÚ__new__r   )Úclsr   ÚselfÚ	__class__s      €r   r   zUnanswered.__new__>   s   ø€ Ü‰w‰˜s KÓ0ˆØˆŒ
Øˆó    )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__Ústrr   Ú__classcell__)r    s   @r   r   r   8   s    ø„ ñ)ð €Ið˜C÷ ñ r!   r   ÚonceÚsessionÚalways)Úor)   Úsr*   Úar+   zapproval.allowed_oncezapproval.allowed_sessionzapproval.allowed_alwayszapproval.denied)r)   r*   r+   ÚdenyÚpromptc                 óº   ‡ ‡— ddiŠˆ ˆfd„}t        j                  |d¬«      }|j                  «        |j                  |¬«       |j	                  «       rdS ‰d   S )zFRead one answer on a daemon thread; None when the user never answered.ÚchoiceÚ c                  ó�   •— 	 t        ‰ «      j                  «       j                  «       ‰d<   y # t        t        f$ r d‰d<   Y y w xY w)Nr2   r3   )ÚinputÚstripÚlowerÚEOFErrorÚOSError)r0   Úresults   €€r   Ú	get_inputz_read_choice.<locals>.get_inputV   sF   ø€ ð	"Ü$ V›}×2Ñ2Ó4×:Ñ:Ó<ˆF�8ÒøÜœ'Ð"ò 	"Ø!ˆF�8Óð	"ús   ƒ*. ®AÁAT)ÚtargetÚdaemon)ÚtimeoutN)Ú	threadingÚThreadÚstartÚjoinÚis_alive)r0   r   r;   Úthreadr:   s   `   @r   Ú_read_choicerE   R   sU   ù€ à˜ˆ^€Fõ"ô ×Ñ Y°tÔ<€FØ
‡L�L„NØ
‡K�K˜€KÔ(Ø—?‘?Ô$ˆ4Ð:¨&°Ñ*:Ð:r!   Úkeywordc                 ó¾   ‡— ddl Š	 ‰j                  | «      j                  }||v xs" t        ˆfd„|j                  «       D «       «      S # t        t        f$ r Y yw xY w)zœTrue when *callback* takes ``keyword`` (or ``**kwargs``); approval callbacks predate ``title``
    and a TypeError inside the callback would read as a deny.r   NFc              3   ób   •K  — | ]&  }|j                   ‰j                  j                  u –— Œ( y ­w©N)ÚkindÚ	ParameterÚVAR_KEYWORD)Ú.0ÚpÚinspects     €r   ú	<genexpr>z#callback_accepts.<locals>.<genexpr>j   s'   øè ø€ Ò#eÐPQ A§F¡F¨g×.?Ñ.?×.KÑ.KÔ$KÑ#eùs   ƒ,/)rO   Ú	signatureÚ
parametersÚ	TypeErrorÚ
ValueErrorÚanyÚvalues)ÚcallbackrF   ÚparamsrO   s      @r   Úcallback_acceptsrY   b   sc   ø€ ó ðØ×"Ñ" 8Ó,×7Ñ7ˆð �fÐÒe¤Ó#eÐU[×UbÑUbÓUdÔ#eÓ eÐeøô ”zÐ"ò Ùðús   ‡A
 Á
AÁAc           
      ó"  — ddl m}  || «      }	 ||«      }
|xs | }|�3	 d|i|sddini ¥|rddini ¥|rt        |d«      rd|ini ¥} ||	|
fi |¤ŽS 	 ddl	m
}  |«       �"t        j                  d| |«       t        d«      S 	 dt        j                  d<   	 ddlm} |rdn|rdnd}d|› �d|› �}}|xs
  |d|
¬«      }t!        d|› d|	› d ||«      › d�«       t"        j$                  j'                  «        t)         ||«      |«      }|€pt!        d |d'i t+        j,                  «       ¤Žz   «       	 t        j                  j/                  dd «       t!        «        t"        j$                  j'                  «        y|rii t0        j3                   |d«      j5                  d«      d «      ¥t0        j3                   |d!«      j5                  d«      d"«      ¥j7                  |d"«      }nt8        j7                  |d"«      }|d#k(  r|sd$}t!         |t:        |   «      «       |t        j                  j/                  dd «       t!        «        t"        j$                  j'                  «        S # t        $ rC}t        j                  d	|d¬
«       t        dt        |«      j                  › �«      cY d }~S d }~ww xY w# t        $ r Y �Œ@w xY w# t<        t>        f$ rj t!        d d%«      z   «       t        d&«      cY t        j                  j/                  dd «       t!        «        t"        j$                  j'                  «        S w xY w# t        j                  j/                  dd «       t!        «        t"        j$                  j'                  «        w xY w)(Nr   ©Úredact_sensitive_textr   r   Fr	   Tr
   zApproval callback failed: %s©Úexc_infozthe approval callback failed: )Úget_app_or_nonez¬Dangerous-command approval requested on a thread with no approval callback while prompt_toolkit is active; failing closed to avoid stdin deadlock. command=%r description=%rzzno approval callback is registered on this thread while prompt_toolkit owns the terminal, so the prompt could not be shownÚ1ÚHERMES_SPINNER_PAUSE)ÚtÚ
smart_denyÚlongÚshortzapproval.prompt_zapproval.choose_zapproval.dangerous_header)r   z
  z
      z

Ú
r>   zapproval.smart_deny_once_inputsú,r)   zapproval.smart_deny_deny_inputsr/   r+   r*   zapproval.cancelledz5the prompt was interrupted before an answer was given)zapproval.timeout) Úagent.redactr\   rY   Ú	ExceptionÚloggerÚerrorr   Útyper"   Ú"prompt_toolkit.application.currentr_   ÚwarningÚosÚenvironÚ
agent.i18nrb   ÚprintÚsysÚstdoutÚflushrE   r   Úapproval_timeout_notice_kwargsÚpopÚdictÚfromkeysÚsplitÚgetÚ_CLI_CHOICE_ALIASESÚ_CLI_CHOICE_I18Nr8   ÚKeyboardInterrupt)r   r   r   r   r   r   r	   r
   r\   Údisplay_commandÚdisplay_descriptionÚ	once_onlyÚcallback_kwargsÚer_   rb   ÚshapeÚ
prompt_keyÚmenu_keyÚheaderr2   Údecisions                         r   r   r   m   sz  € õ 3Ù+¨GÓ4€OÙ/°Ó<ÐàÒ1 MÐ 1€IàÐ$ð		Sà0°/ð wÙBO ?°EÑ":ÐUWðwá<H >°4Ñ"8Èbðwñ 7<Ô@PÐQbÐdkÔ@l 7¨EÑ"2ÐrtðwˆOñ % _Ð6IÑ]È_Ñ]Ð]ðõ 	GÙÓÐ(Ü�N‰Nð PàQXÐZeôgô ð Oó Pð Pð	 )ð *-„B‡J�JÐ%Ñ&ðÝ á )‘¹©vÈgˆØ!1°%°Ð9Ð=MÈeÈWÐ;U�Hˆ
ØÒY™!Ð7ÐEXÔYˆÜ��V�HØ˜Ð)¨©a°«k¨]¸"ð>ô 	?ä�
‰
×ÑÔÜ™a 
›m¨_Ó=ˆØˆ>Ü�$™ÑW´×1TÑ1TÓ1VÑWÑWÔXØô 	�
‰
�‰Ð-¨tÔ4ÜŒÜ�
‰
×ÑÕñ! ðœ$Ÿ-™-©Ð*KÓ(L×(RÑ(RÐSVÓ(WÐY_Ó`ð ÜŸ-™-©Ð*KÓ(L×(RÑ(RÐSVÓ(WÐY_Ó`ðç™#˜f fÓ-ñ ô +×.Ñ.¨v°vÓ>ˆHØ˜8Ò#©OØ$�Ü‰aÔ  Ñ*Ó+Ô,Øô
 	�
‰
�‰Ð-¨tÔ4ÜŒÜ�
‰
×ÑÕøôm ò 	SÜ�L‰LÐ7¸ÀTˆLÔJÜÐ >¼tÀA»w×?OÑ?OÐ>PÐQÓRÕRûð	Sûô* ò Úðûô6 Ô'Ð(ò SÜˆd‘QÐ+Ó,Ñ,Ô-ÜÐQÓRÑRä
�
‰
�‰Ð-¨tÔ4ÜŒÜ�
‰
×ÑÕðSûô 	�
‰
�‰Ð-¨tÔ4ÜŒÜ�
‰
×ÑÕús\   ¡1I) Á.J8 ÂBK Å=B#K É)	J5É28J0Ê*J5Ê0J5Ê8	KËKË.MË6M Í MÍM ÍA
Nc                  ó.   — ddl m} m}  | «         |«       S )zCLazy plugin-manager seam used by tests and early tool-only imports.r   )Údiscover_pluginsÚget_plugin_manager)Úhermes_cli.pluginsrŠ   r‹   )rŠ   Ú_get_managers     r   r‹   r‹   ¸   s   € çWñ ÔÙ‹>Ðr!   Únamec                 ó   — d|||| dœS )zVResult shape of :func:`_present_with_selected_transport` once a transport is selected.T)Úselectedr2   ÚfailureÚfallbackrŽ   © )rŽ   r2   r‘   r’   s       r   Ú_attemptr”   Á   s   € à¨¸7ÐPXÐbfÑgÐgr!   Úpattern_keyÚpattern_keysÚsession_keyÚsurfacec                 ó&  — t        j                  «       \  }}	|dk(  rddiS 	 t        «       j                  |«      }
|
€$t
        j                  d|«       t        |dd|	«      S 	 d	d
lm	} d	dl
m}m} t        j                  «       }|j                   || d¬«       ||d¬«      |t        |«      |||||¬«	      }t!        |j"                  |j$                  |t'        |«      |d|› �|j(                  |j*                  ¬«      }t        j,                  di |¤Ž t/        |«      5   ||
j0                  ||t3        d«      t4        ¬«      }ddd«       j6                  €|j8                  nd|j6                  › �}t        j,                  di |¤d|i¤Ž t        ||j8                  |j6                  |	«      S # t        $ r t
        j                  d|«       d}
Y �Œ–w xY w# t        $ r& t
        j                  d«       t        |ddd«      cY S w xY w# 1 sw Y   ŒÅxY w)aU  Present through an explicitly selected plugin transport, if any. A selected
    transport replaces every built-in prompt surface; detection, allowed scopes,
    persistence, timeout, and final authorization stay host-owned. A failed
    transport reaches a built-in surface only under the explicit
    ``transport_fallback: builtin`` opt-in.Úbuiltinr�   Fz0Could not resolve selected approval transport %rNz-Selected approval transport %r is unavailabler/   Úunavailabler   r[   )ÚApprovalRequestÚinvoke_approval_transportT)Úforce)	r   r   r•   r–   r—   r˜   r   r   r   z0Could not build redacted plugin approval requestrk   z
transport:)r   r   r•   r–   r—   r˜   Ú
request_idÚrequest_digestz%waiting for plugin approval transport)r   Úon_pollr   Ú
transport_r2   )Úpre_approval_request)Úpost_approval_response)r   Ú_get_approval_transport_configr‹   Úget_approval_transportri   rj   rn   r”   rh   r\   Úhermes_cli.approval_transportrœ   r�   r   ÚcreateÚtuplerx   r   r   ÚlistrŸ   ÚdigestÚ_fire_approval_hookr   Úpresentr   r   r‘   r2   )r   r   r•   r–   r—   r˜   r   r   rŽ   r’   Ú
registeredr\   rœ   r�   r   ÚrequestÚhook_kwargsr:   Úhook_choices                      r   Ú _present_with_selected_transportr²   Æ   sý  € ô ×8Ñ8Ó:�N€Dˆ(ØˆyÒØ˜EÐ"Ð"ðÜ'Ó)×@Ñ@ÀÓFˆ
ð
 ÐÜ�‰ÐFÈÔMÜ˜˜f m°XÓ>Ð>ð5Ý6ß\ä×4Ñ4Ó6ˆØ!×(Ñ(Ù)¨'¸Ô>Ù-¨kÀÔFÐT_Ü˜|Ó,¸+ÈwÐfsØ+¸_ð	 )ó 
ˆô Ø—‘¨W×-@Ñ-@ÈkÜ˜,Ó'°[ÈJÐW[ÐV\ÐJ]Ø×%Ñ%°g·n±nô€Kô
 	×ÑÑC°{ÒCÜ	˜;Ó	'ñ 
Ù*Ø×Ñ ¸Ü&Ð'NÓOÜ)ô
ˆ÷
ð $*§>¡>Ð#9�&—-’-ÀÈFÏNÉNÐK[Ð?\€KÜ×ÑÑY¸ÑYÈ[ÓYÜ�D˜&Ÿ-™-¨¯©¸ÓBÐBøôM ò ä�‰ÐIÈ4ÔPØ‹
ðûô& ò 5ô 	�‰ÐIÔJÜ˜˜f g¨tÓ4Ò4ð	5ú÷
ð 
ús0   ¢F- Á"AG Ä%HÆ-!GÇGÇ,HÈHÈHÚattemptc                óz  — | j                  d«      sy| j                  d«      }|s| j                  d«      dfS | j                  d«      dk(  r't        j                  d| j                  d	«      |«       yd
dlm} |j                  t        j                  «       «      }d|j                  d|› d|› �||d|› �¬«      fS )a  Interpret a ``_present_with_selected_transport`` attempt into
    ``(choice, denied_result)``: both None when the built-in surfaces should run
    (no transport selected, or a failure with the explicit builtin fallback); a
    denied result for any other failure; else the user's choice.r�   )NNr‘   r2   Nr’   rš   zBApproval transport %r failed (%s); using explicit builtin fallbackrŽ   r   ©Úapprovalz-BLOCKED: Selected approval transport failed (zz); the user has NOT consented to this action. Do NOT retry this command or attempt the same outcome through another route.r¢   )r•   r   Úoutcome)	r{   rj   rn   Útoolsr¶   Ú_denial_breaker_addendumr   Úget_current_session_keyÚ_denied)r³   r•   r   r‘   Ú_aÚbreaker_addendums         r   Ú_transport_choicer¾   ý   sÌ   € ð
 �;‰;�zÔ"ØØ�k‰k˜)Ó$€GÙØ�{‰{˜8Ó$ dÐ*Ð*Ø‡{�{�:Ó )Ò+Ü�‰Ð[Ø—{‘{ 6Ó*¨Gô	5àÝ$Ø×2Ñ2´4×3OÑ3OÓ3QÓRÐØ�—‘Ø
7¸°yð A:à:JÐ9Kð	Mð  ¨[ÀJÈwÈiÐBXð	 ó ð ð r!   Ú
unresolvedc                 ó   — | dv ry| dv r|S dS )zXMap an approval choice to an elicitation verdict; *unresolved* is the no-answer outcome.)r)   r*   r+   Úaccept)r>   r   Údecliner“   )r2   r¿   s     r   Ú_consentrÃ     s!   € àÐ.Ñ.ØØÐ#;Ñ;ˆ:ÐJÀÐJr!   zmcp-elicitationzConfirm this action?)r   r˜   r
   Úmessagec          	      ól  — ddl m} 	 t        j                  «       }t        j                  «       dk(  xr, t        j                  «        xr t        j                  «        }t        j                  «       s|rš|j                  |«      }	|	€t
        j                  d|«       y	 t        j                  ||	| |ddgd	œ|¬
«      }
|
j                  d«      ry|
j                  d«      r|
j                  d«      ryt!        |
j                  d«      d«      S 	 t#        | ||d|¬«      }t!        |d«      S # t        $ r }t
        j                  d|«       Y d}~yd}~ww xY w# t        $ r"}t
        j                  d|d¬«       Y d}~yd}~ww xY w# t        $ r"}t
        j                  d|d¬«       Y d}~yd}~ww xY w)a°  Route an MCP elicitation request to the surface owning the active session:
    gateway sessions through ``_await_gateway_decision``, CLI/TUI through
    ``prompt_dangerous_approval``. Always fails closed: a missing notify_cb in a
    gateway session, timeouts, and exceptions map to ``"decline"`` so a server
    treats them as "user did not approve" rather than retrying or hanging.
    Returns ``"accept" | "decline" | "cancel"``.r   rµ   z.Elicitation consent: session lookup failed: %sNrÂ   Ú
api_serveru]   Elicitation requested in gateway session %s but no notify_cb is registered â€” failing closedÚmcp_elicitation)r   r   r•   r–   )r˜   z'Elicitation gateway dispatch failed: %sTr]   Únotify_failedÚresolvedr   Úcancelr2   F)r   r   r
   z!Elicitation CLI prompt failed: %s)r¸   r¶   r   rº   ri   rj   rn   Ú_get_session_platformÚ_is_cron_approval_contextÚ!_is_single_query_approval_contextÚ_is_gateway_approval_contextÚ_gateway_notify_cbÚ_gwÚ_await_gateway_decisionrk   r{   rÃ   r   )rÄ   r   r   r˜   r
   r¼   r—   ÚexcÚapi_run_contextÚ	notify_cbrˆ   r2   s               r   Úrequest_elicitation_consentrÕ     sª  € õ %ðÜ×2Ñ2Ó4ˆô 	×"Ñ"Ó$¨Ñ4ò 	9Ü×.Ñ.Ó0Ð0ò	9ä×6Ñ6Ó8Ð8ð ô
 ×(Ñ(Ô*©oØ×)Ñ)¨+Ó6ˆ	ØÐÜ�N‰Nð HØITôVàð	Ü×2Ñ2Ø˜Y°GÈKØ8IØ:KÐ9Lñ)NàW^ô`ˆHð �<‰<˜Ô(ØØ�|‰|˜JÔ'¨8¯<©<¸Ô+DØÜ˜Ÿ™ XÓ.°	Ó:Ð:ðÜ*¨7°KÐQ`Ø;@ÈôOˆô
 �F˜HÓ%Ð%øôQ ò Ü�‰ÐGÈÔMÜûðûô0 ò 	Ü�L‰LÐBÀCÐRVˆLÔWÜûð	ûô ò Ü�‰Ð8¸#ÈˆÔMÜûðúsG   ˆD. Â"E ÄF Ä.	EÄ7EÅEÅ	FÅ#F Æ FÆ	F3ÆF.Æ.F3)NTNrI   )#r%   Úloggingro   rs   r?   r¸   r   r   r   rÐ   Útools.approval_human_waitr   r   Útools.interruptr   Ú	getLoggerrj   r'   ÚintÚboolr   r   r|   r}   rE   rY   r   r‹   rx   r”   rª   r²   r¾   rÃ   rÕ   r“   r!   r   ú<module>rÜ      sV  ðñó Û 	Û 
Û ß Hß KÝ *à	ˆ×	Ñ	Ð+Ó	,€ð ]aØNRð!Wà7;ÐRWØ26ò!W sð !W¸ð !WÈsÐUYÉzð !WØ/3ð!Wà04ð!WàKOð!Wð &)¨4¡Zð!Wð <?ó!WôH	�ô 	ð 
˜Ø	˜yØ	˜XñÐ ð $Ø)Ø'Øñ	Ð ð;˜ð ;¨sð ;°s¸T±zó ;ð f¨ð f°ó fð `dñH˜ð H¨#ð HÀð HÐVZð HØ15ðHØEIðHØRUÐX\ÑR\ðHØhkóHòVðh�3ð h°dó hð
4C°ð 4CÀ3ð 4CÐUXð 4CØ37¸±9ð4CØKNð4CØY\ð4Cà48ð4CàKOð4CàTXó4Cðn˜tð °Sð Àsó ð0K ð K¨ó Kð ?CØ/@ÐOeò4&¨ð 4&¸3ð 4&Ø14°t±ð4&à),ð4&àILð4&àjmô4&r!   