+
    lHàjZ7  ã                  ó  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIH	t	H
t
 ^ RIHtHtHtHt ]P                   ! ]4      t]	 ! R R4      4       t]P(                  ! 4       t/ tR]R&   / tR	]R
&   / tR]R&   RtRtRtRtRtRtRt R<R R llt!R R lt"R R lt#R R lt$RR/R R llt%R  R! lt&R" R# lt'R$ R% lt(R=R& R' llt)R( R) lt*R* R+ lt+R, R- lt,R. R/ lt-R0 R1 lt.R2 R3 lt/R4 R5 lt0R6 R7 lt1R8 R9 lt2R: R; lt3R# )>aã  Gateway-side clarify primitive (blocking event-based queue). The agent runs on a worker
thread while the event loop handles the user's reply, so a pending clarify is stored
module-level (same shape as ``tools.approval``) and the agent thread blocks on an ``Event``
until an adapter button callback or the gateway text-intercept resolves it, or the timeout
fires. Adapters render inline buttons (an "Other" row flips the entry into text-capture
mode) or a numbered-list text fallback.)ÚannotationsN)Ú	dataclassÚfield)ÚCallableÚDictÚListÚOptionalc                  óž   € ] tR t^t$ RtR]R&   R]R&   R]R&   R]R&   RtR	]R
&   ]! ]P                  R7      t
R]R&   RtR]R&   RtR	]R&   RtR# )Ú_ClarifyEntryz5One pending clarify request inside a gateway session.ÚstrÚ
clarify_idÚsession_keyÚquestionúOptional[list[str]]ÚchoicesFÚboolÚmulti_select)Údefault_factoryzthreading.EventÚeventNúOptional[str]ÚresponseÚawaiting_text© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r   r   Ú	threadingÚEventr   r   r   Ú__static_attributes__r   ó    Ú:/home/ubuntu/.hermes/hermes-agent/tools/clarify_gateway.pyr
   r
      sL   ‡ á?ØƒOØÓØƒMØ Ó Ø€L�$ÓÙ"°9·?±?ÔC€Eˆ?ÓCØ"€HˆmÓ"Ø€M�4×r"   r
   zdict[str, _ClarifyEntry]Ú_entrieszdict[str, list[str]]Ú_session_indexz*dict[str, Callable[[_ClarifyEntry], None]]Ú_notify_cbsÚresolvedÚrejected_proseÚrejected_selectionÚ
no_pendingÚskipz skippedz
 cancelledFc               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )é   r   r   r   r   r   r   r   r   Úreturnr
   r   )Úformats   "r#   Ú__annotate__r0   1   s9   € ÷ 	ñ 	˜ð 	¨3ð 	¸#ð 	ÐH[ð 	Øð	Ø,9ñ	r"   c           
     óP  € \        YY#'       d   \        V4      MR\        V4      ;'       d    \        V4      \        V4      '       * R7      p\        ;_uu_ 4        V\        V &   \
        P                  V. 4      P                  V 4       RRR4       V#   + '       g   i     T# ; i)z¦Register a pending clarify request; caller then blocks on ``wait_for_response``.
Open-ended (no choices) entries start in text mode: the next message IS the response.N)r   )r
   Úlistr   Ú_lockr$   r%   Ú
setdefaultÚappend)r   r   r   r   r   Úentrys   &&&&& r#   Úregisterr7   1   sƒ   € ô ˜*°8Îg¼TÀ'¼]Ð[_Ü˜|Ó,×>Ð>´°g³ÔRVÐW^ÓR_ÔN_ôa€Eç	ŽØ$Œ�ÑÜ×!Ñ! +¨rÓ2×9Ñ9¸*ÔE÷ 
ð €L÷ 
Žð €Lús   Á/BÂB%	c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r   r   ÚtimeoutÚfloatr.   r   r   )r/   s   "r#   r0   r0   =   s!   € ÷ 'ñ ' #ð '°ð '¸-ñ 'r"   c                óè  € \         ;_uu_ 4        \        P                  V 4      pRRR4       Xf   R#  ^ RIHp ^ RIHp Ve   \        V4      R8:  d   RM$\        P                  ! 4       \        V4      ,           pR\        P                  ! 4       R\        P                  ! 4       /p Vf   RMV\        P                  ! 4       ,
          pV^ 8:  g-   VP                  P                  \        RV4      R7      '       d   MaV! 4       '       dD   \         ;_uu_ 4        VP                  P                  4       '       g   \        Vn        RRR4       MVf   K­  V! VR	4       K¸  \         ;_uu_ 4        \        P#                  V R4       VP                  P%                  4        \&        P                  VP(                  4      ;'       g    . pW9   d:   VP+                  V 4       V'       g!   \&        P#                  VP(                  R4       RRR4       VP                   #   + '       g   i     ELþ; i  \
         d    Rp ELi ; i  + '       g   i     EL; i  + '       g   i     TP                   # ; i)
z÷Block until the entry resolves or ``timeout`` (``<= 0`` = unlimited) elapses; None on
timeout/unknown id. Polls in 1s slices so the inactivity heartbeat keeps firing (a
single long ``Event.wait`` would let the gateway watchdog kill a live prompt).N)Útouch_activity_if_due)Úis_interruptedg        Ú
last_touchÚstartg      ð?)r9   z!waiting for user clarify response)r3   r$   ÚgetÚtools.environments.baser<   Ú	ExceptionÚtools.interruptr=   r:   ÚtimeÚ	monotonicr   ÚwaitÚminÚis_setÚ	CANCELLEDr   ÚpopÚsetr%   r   Úremove)	r   r9   r6   r<   r=   ÚdeadlineÚactivity_stateÚ	remainingÚidss	   &&       r#   Úwait_for_responserQ   =   sº  € ÷ 
ŽÜ—‘˜ZÓ(ˆ÷ 
à‚}Ùð%ÝAõ /Ø’¬%°«.¸CÔ*?‰tÄTÇ^Â^ÓEUÔX]Ð^eÓXfÕEf€HØ"¤D§N¢NÓ$4°g¼t¿~º~Ó?OÐP€NØ
Ø#Ò+‘C°¼D¿NºNÓ<LÕ1Lˆ	Ø˜Œ>˜UŸ[™[×-Ñ-´c¸#¸yÓ6IÐ-×JÒJØÙ×Ò÷ –Ø—{‘{×)Ñ)×+Ò+Ü%.�E”N÷ ð ð !Ô,Ù! .Ð2UÖVß	ŽÜ�‰�Z Ô&Ø�‰�‰ÔÜ× Ñ  ×!2Ñ!2Ó3×9Ð9°rˆØÔØ�J‰J�zÔ"ßÜ×"Ñ" 5×#4Ñ#4°dÔ;÷ 
ð �>‰>Ð÷G 
�ˆûô ô %Ø $Óð%ú÷ —�ú÷ 
Žð �>‰>Ðús;   �H´H. Ä,IÅ-A8IÇ& IÈH+	È.H?È>H?ÉI	ÉI1	c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r   r   r   r.   r   r   )r/   s   "r#   r0   r0   g   s!   € ÷ ñ ¨ð °sð ¸tñ r"   c                óF  € \         ;_uu_ 4        \        P                  V 4      pVe!   VP                  P	                  4       '       d    RRR4       R# Ve   \        V4      MRVn        VP                  P                  4         RRR4       R#   + '       g   i     R# ; i)zPUnblock the waiter on ``clarify_id``; False if already resolved/expired/unknown.NFÚ T)r3   r$   r@   r   rH   r   r   rK   )r   r   r6   s   && r#   Úresolve_gateway_clarifyrU   g   sg   € ç	ŽÜ—‘˜ZÓ(ˆØŠ=˜EŸK™K×.Ñ.×0Ò0Ø÷ 
‰ð +3Ò*>œ˜XœÀBˆŒØ�‰�‰ÔØ÷ 
��Šús   �9BÁ	BÁ1BÂB 	c               ó    € V ^8„  d   QhRRRR/# )r-   r   r   r.   úOptional[_ClarifyEntry]r   )r/   s   "r#   r0   r0   r   s   € ÷ Qñ Q˜Cð QÐ$;ñ Qr"   c                óÖ   € \         ;_uu_ 4        \        P                  V 4      pVe#   VP                  P	                  4       '       g   TMRuuRRR4       #   + '       g   i     R# ; i)aT  The entry for ``clarify_id`` while it is still awaiting an answer, else None (unknown,
answered, timed out or cleared). Read-only: adapters rendering native choice cards compare it
by identity with the entry they rendered and read ``session_key`` / ``choices`` /
``multi_select`` from it; answering goes through ``resolve_gateway_clarify``.N)r3   r$   r@   r   rH   ©r   r6   s   & r#   Úget_pendingrZ   r   s?   € ÷
 
ŽÜ—‘˜ZÓ(ˆØÒ)°%·+±+×2DÑ2D×2FÒ2F‰uÈD÷ 
��‹ús   �9AÁ	AÁA(	Úinclude_choice_promptsc               ó$   € V ^8„  d   QhRRRRRR/# )r-   r   r   r[   r   r.   rW   r   )r/   s   "r#   r0   r0   |   s"   € ÷ 	ñ 	¨ð 	Èð 	ÐZqñ 	r"   c               ó0  € \         ;_uu_ 4        \        P                  V 4      ;'       g    .  FF  p\        P                  V4      pVf   K  V'       g   VP                  '       g   K:  Vu uuRRR4       # 	   RRR4       R#   + '       g   i     R# ; i)zïOldest pending entry awaiting free text (open-ended, or after "Other");
``include_choice_prompts=True`` returns the oldest unresolved entry of any kind (user
typed at an active choice prompt: resolve it rather than queue a follow-up turn).N)r3   r%   r@   r$   r   )r   r[   Úcidr6   s   &$  r#   Úget_pending_for_sessionr_   |   sf   € ÷ 
ŽÜ!×%Ñ% kÓ2×8Ð8°bÒ8ˆCÜ—L‘L Ó%ˆEØÔ ×&<À×@S×@SÒ@SØ‘÷	 
ŠÙ8ð ÷ 
��Šús#   �9BÁBÁBÁ)BÁ7BÂB	c               ó$   € V ^8„  d   QhRRRRRR/# )r-   Útextr   r   z	list[str]r.   r   r   )r/   s   "r#   r0   r0   ˆ   s!   € ÷ ñ �sð  Yð °=ñ r"   c                óÎ   € ^ RI Hp V! V 4      P                  4       pV FB  pV! \        V4      4      P                  4       V8X  g   K)  \        V4      P	                  4       u # 	  R# )zªStripped choice text matching ``text`` case-insensitively, ignoring the '(Recommended)'
suffix the first choice carries by the time it reaches adapters; None if no match.)Ústrip_recommendedN)Útools.clarify_toolrc   Úcasefoldr   Ústrip)ra   r   rc   ÚwantedÚchoices   &&   r#   Ú_match_labelri   ˆ   sV   € õ 5Ù˜tÓ$×-Ñ-Ó/€FÛˆÙœS ›[Ó)×2Ñ2Ó4¸Ö>Ü�v“;×$Ñ$Ó&Ò&ñ ñ r"   c               ó    € V ^8„  d   QhRRRR/# )r-   ra   r   r.   r   r   )r/   s   "r#   r0   r0   “   s   € ÷ Qñ Q˜ð QÐ 3ñ Qr"   c                ób  € RV 9   dG   V P                  R4       Uu. uF*  qP                  4       '       g   K  VP                  4       NK,  	  up# V P                  4       p\        V4      ^8”  d=   \        ;QJ d    R V 4       F  '       d   K   RM	  RM! R V 4       4      '       d   V# R# u upi )zQComma-separated tokens, or space-separated all-numeric tokens ("1 3"); else None.Ú,c              3  ó@   "  € T F  qP                  4       x € K  	  R # 5i©N)Úisdigit)Ú.0Úps   & r#   Ú	<genexpr>Ú _split_tokens.<locals>.<genexpr>˜   s   é € Ð*FÁ¸1¯9©9¯;¨;Ãùs   ‚FTN)Úsplitrf   ÚlenÚall)ra   ÚtÚpartss   &  r#   Ú_split_tokensry   “   sz   € à
ˆd„{Ø#'§:¡:¨c¤?Ó@¡?˜a·g±g·i”	�—‘–	¡?Ñ@Ð@Ø�J‰J‹L€EÜ˜“J ”N§s£sÑ*FÁÓ*F§s§s¢sÑ*FÁÓ*F×'FÒ'Fˆ5ÐPÈDÐPùò As
   ›B,·B,c               ó    € V ^8„  d   QhRRRR/# )r-   ra   r   r.   r   r   )r/   s   "r#   r0   r0   ›   s   € ÷ ñ �#ð ˜$ñ r"   c                óB   €  \        V 4       R #   \         d     R# i ; i)TF)ÚintÚ
ValueError)ra   s   &r#   Ú_is_intr~   ›   s#   € ðÜˆDŒ	ÙøÜô Úðús   ‚ ��c               ó$   € V ^8„  d   QhRRRRRR/# )r-   ra   r   r   r   r.   r   )r/   s   "r#   r0   r0   £   s(   € ÷ _ñ _ Cð _Ð2Eð _ÐQdñ _r"   c                óð  a€ \        V 4      P                  4       pV'       g   R# \        V4      pVf>   VP                  R4      pVP	                  4       '       g   \        V4      '       d   V.# R# RV9  g	   V'       g   T;'       g    R# \        ^\        R T;'       g    .  4       ^R7      4      o\        ;QJ d    V3R lV 4       F  '       d   K   RM	  RM! V3R lV 4       4      '       d   V# R# )	zßTokens when ``text`` looks like a typed selection (bare int, comma list,
all-numeric space list); None for free prose so the gateway can release the
clarify. Comma-list labels may span up to the longest choice's word count.NÚ-rl   c              3  óf   "  € T F'  p\        \        V4      P                  4       4      x € K)  	  R # 5irn   )ru   r   rt   )rp   Úcs   & r#   rr   Ú,_selection_attempt_tokens.<locals>.<genexpr>°   s"   é € ÐG¹°AœC¤ A£§¡£×/Ð/»ùs   ‚/1)Údefaultc              3  óŠ   <"  € T F8  qP                  4       ;'       g    \        VP                  4       4      S8*  x € K:  	  R # 5irn   )ro   ru   rt   )rp   rw   Ú	max_wordss   & €r#   rr   r„   ±   s/   øé € ÐTÉVÈŸ™›×CÐC¬¨A¯G©G«I«¸)Ñ(CÔCËVùs
   ƒAž%AFT)r   rf   ry   Úremoveprefixro   r~   Úmaxrv   )ra   r   ÚstrippedÚtokensÚdigitsr‡   s   &&   @r#   Ú_selection_attempt_tokensr�   £   sÁ   ø€ ô �4‹y�‰Ó €HßÙÜ˜8Ó$€FØ‚~Ø×&Ñ& sÓ+ˆØ#Ÿ^™^×-Ò-´¸×1BÒ1B�ˆzÐLÈÐLØ
�(Ô§&Ø�~ˆ~˜ÐÜ�A”sÑG¸¿¸ÀB¸ÓGÐQRÔSÓT€Iß“SÔTÉVÓT—S—S’SÔTÉVÓT×TÒTˆ6Ð^ÐZ^Ð^r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r6   r
   r   r   r.   r   r   )r/   s   "r#   r0   r0   ´   s!   € ÷ >ñ > ð >¸#ð >À-ñ >r"   c                ó&   € \        W4      ^ ,          # )z;Accepted value for a typed reply, or None on any rejection.)Ú_coerce_text_response_detailed)r6   r   s   &&r#   Ú_coerce_text_responser‘   ´   s   € ä)¨%Ó:¸1Õ=Ð=r"   c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r6   r
   r   r   r.   z#tuple[Optional[str], Optional[str]]r   )r/   s   "r#   r0   r0   ¹   s'   € ÷ Fñ F¨-ð FÀ3ð FÐKnñ Fr"   c                óz  € \        V4      P                  4       pVP                  4       \        8H  pV P                  '       g   V'       d	   \
        R3# TR3# V P                  '       d$   \        W4      p\        W P                  4      RJpMt\        V4      pV'       d   \        V4      ^,
          MRp^ Tu;8:  d   \        V P                  4      8  d   M MV P                  V,          M\        W P                  4      pVe   VR3# V'       d	   \
        R3# V P                  '       d   VR3# RV'       d   R3# R3# )u#  Map a typed reply to ``(value, None)`` or ``(None, reason)``: ``"invalid_selection"``
(selection-shaped but out of range/unrecognised â€” keep the clarify armed for a retry) or
``"prose"`` (free text on a native choice prompt â€” the gateway may cancel and route normally
so a redirect-to-steer path cannot deadlock behind the waiting tool). Open-ended entries and
``awaiting_text`` accept any text; numeric picks and exact labels always resolve; multi-select
returns a JSON array string (decoded tool-side); one bad token rejects the whole reply.NÚinvalid_selectionÚproseéÿÿÿÿ)r   rf   re   Ú	SKIP_WORDr   ÚSKIPPEDr   Ú_coerce_multi_select_textr�   r~   r|   ru   ri   r   )r6   r   ra   Úis_skipÚcoercedÚselection_shapedÚidxs   &&     r#   r�   r�   ¹   s	  € ô ˆx‹=×ÑÓ €DØ�m‰m‹o¤Ñ*€GØ�=�=ˆ=ß"”¨tÐ3Ð3¨¨tÐ3Ð3Ø××ÐÜ+¨EÓ8ˆÜ4°T¿=¹=ÓIÐQUÐUÑô # 4›=Ðß/Œc�$‹i˜!Žm°RˆØ()¨SÖ(E´3°u·}±}Ó3E×(E�%—-‘- Ö$Ì<ÐX\×^kÑ^kÓKlˆØÒØ˜ˆ}ÐßÜ˜ˆ}ÐØ××ÐØ�TˆzÐØ×(8Ð$ÐEÐE¸gÐEÐEr"   c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r6   r
   ra   r   r.   r   r   )r/   s   "r#   r0   r0   Õ   s&   € ÷ Jñ J ]ð J¸#ð JÀ-ñ Jr"   c                óÞ  € V P                   ;'       g    . . r2V'       g   R# \        V4      pVf   V.MT F“  pVP                  4       '       dP   \        V4      ^,
          p^ Tu;8:  d   \	        V4      8  d#   M M\        W&,          4      P                  4       MRpM\        WR4      pVf    R# Ws9  g   K‚  VP                  V4       K•  	  V'       d   \        P                  ! VRR7      # R# )z—Parse "1,3" / "1 3" / "staging, prod" into a JSON array of choice labels;
None when any token is out of range or unrecognised (reject the whole reply).NF)Úensure_ascii)r   ry   ro   r|   ru   r   rf   ri   r5   ÚjsonÚdumps)r6   ra   r   Úselectedr‹   Útokenr�   Úlabels   &&      r#   r™   r™   Õ   sº   € ð Ÿ™×+Ð+¨¨RˆXßÙÜ˜4Ó €FØ!š>�$‘¨vÒ5ˆØ�=‰=�?Š?Ü�e“*˜q•.ˆCØ12°cÖ1H¼CÀ»L×1H”C˜�Ó%×+Ñ+Ô-Èd‰Eä  Ó0ˆEØŠ=ÚØÖ Ø�O‰O˜EÖ"ñ 6÷ 8@Œ4�:Š:�h¨UÔ3ÐIÀTÐIr"   c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r   r   r   r.   r   )r/   s   "r#   r0   r0   é   s!   € ÷ 
ñ 
°3ð 
À#ð 
È#ñ 
r"   c                óÈ   € \        V RR7      pVf   \        # \        W!4      w  r4Vf   VR8X  d   \        # \        # \        VP                  V4      '       d   \        # \        # )zTTry to resolve the oldest pending clarify from typed text; returns a TEXT_* outcome.T)r[   r”   )r_   ÚTEXT_NO_PENDINGr�   ÚTEXT_REJECTED_SELECTIONÚTEXT_REJECTED_PROSErU   r   ÚTEXT_RESOLVED)r   r   r6   r›   Úreasons   &&   r#   Ú!attempt_text_response_for_sessionr­   é   s^   € ä# KÈÔM€EØ‚}ÜÐÜ4°UÓE�O€GØ‚Ø*0Ð4GÔ*GÔ&Ð`ÔM`Ð`Ü˜u×/Ñ/°×9Ò9ÜÐÜÐr"   c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r   r   r   r.   r   r   )r/   s   "r#   r0   r0   ö   s&   € ÷ Uñ U°3ð UÀ#ð UÈ$ñ Ur"   c                ó&   € \        W4      \        8H  # )zETrue only when the typed reply was accepted and the waiter unblocked.)r­   r«   )r   r   s   &&r#   Ú!resolve_text_response_for_sessionr°   ö   s   € ä,¨[ÓCÄ}ÑTÐTr"   c               ó    € V ^8„  d   QhRRRR/# )r-   r   r   r.   r   r   )r/   s   "r#   r0   r0   û   s   € ÷ !ñ ! 3ð !¨4ñ !r"   c                ó¤   € \         ;_uu_ 4        \        P                  V 4      pVe   RVn        VRJuuRRR4       #   + '       g   i     R# ; i)zMFlip an entry into text-capture mode (user picked 'Other'); False if unknown.NT)r3   r$   r@   r   rY   s   & r#   Úmark_awaiting_textr³   û   s7   € ç	ŽÜ—‘˜ZÓ(ˆØÒØ"&ˆEÔØ˜DÐ ÷	 
��‹ús	   �$>¾A	c               ó    € V ^8„  d   QhRRRR/# )r-   r   r   r.   r   r   )r/   s   "r#   r0   r0     s   € ÷ cñ c˜Sð c Tñ cr"   c                ó8  € \         ;_uu_ 4        \        ;QJ d9    R \        P                  V 4      ;'       g    .  4       F  '       g   K   RM.	  RM*! R \        P                  V 4      ;'       g    .  4       4      uuRRR4       #   + '       g   i     R# ; i)z>True when this session has at least one pending clarify entry.c              3  óP   "  € T F  p\         P                  V4      R Jx € K  	  R # 5irn   )r$   r@   ©rp   r^   s   & r#   rr   Úhas_pending.<locals>.<genexpr>  s    é € ÐbÑ<a°S”8—<‘< Ó$¨DÕ0Ó<aùs   ‚$&TFN)r3   Úanyr%   r@   )r   s   &r#   Úhas_pendingrº     s_   € ç	Žß‹sÑb¼N×<NÑ<NÈ{Ó<[×<aÐ<aÐ_aÐ<aÓb�s�sŠsÑb¼N×<NÑ<NÈ{Ó<[×<aÐ<aÐ_aÐ<aÓbÓb÷ 
��‹ús   �*BºBÁ%BÁ2BÂB	c               ó    € V ^8„  d   QhRRRR/# )r-   r   r   r.   r|   r   )r/   s   "r#   r0   r0   
  s   € ÷ ñ ˜sð  sñ r"   c           	     óv  € \         ;_uu_ 4        ^ pR \        \        P                  V . 4      ;'       g    . 4       4        FW  pVe!   VP                  P                  4       '       d   K)  \        Vn        VP                  P                  4        V^,          pKY  	  RRR4       V#   + '       g   i     X# ; i)a¿  Drop every pending clarify for a session (``/new``, shutdown, cached-agent eviction) so
blocked agent threads don't outlive it; returns how many were cancelled. First-writer-wins: an already-set entry was answered for
real, so it is dropped but its response preserved. The loop stays inside the lock so a button
callback cannot slip between pop and check; entries go regardless of state so a cleared
session is never resurrected by late callbacks.c              3  óN   "  € T F  p\         P                  VR 4      x € K  	  R # 5irn   )r$   rJ   r·   s   & r#   rr   Ú clear_session.<locals>.<genexpr>  s    é € ÐiÑ9h°#”h—l‘l 3¨×-Ð-Ó9hùs   ‚#%N)	r3   r2   r%   rJ   r   rH   rI   r   rK   )r   Ú	cancelledr6   s   &  r#   Úclear_sessionrÀ   
  s�   € ÷ 
ŽØˆ	Ùi¼¼n×>PÑ>PÐQ\Ð^`Ó>a×>gÐ>gÐegÔ9hÖiˆEØŠ} §¡× 2Ñ 2× 4Ò 4ÙÜ&ˆEŒNØ�K‰K�O‰OÔØ˜�NŠIñ j÷ 
ð Ð÷ 
Žð Ðús   �AB'Á)4B'Â'B8	c               ó    € V ^8„  d   QhRRRR/# )r-   ÚconfigÚdictr.   r|   r   )r/   s   "r#   r0   r0     s   € ÷ 
ñ 
 Dð 
¨Sñ 
r"   c                óü   € V P                  R4      ;'       g    / P                  R4      pVf,   V P                  R4      ;'       g    / P                  RR4      p \        V4      #   \        \        3 d     R# i ; i)uô   Clarify timeout (seconds): legacy ``clarify.timeout`` if explicitly set, else
``agent.clarify_timeout``, else 3600 â€” the single source of truth for every surface
(gateway, CLI, TUI). ``<= 0`` is kept verbatim (unlimited); non-numeric -> 3600.Úclarifyr9   ÚagentÚclarify_timeouté  )r@   r|   Ú	TypeErrorr}   )rÂ   Úraws   & r#   Úresolve_clarify_timeoutrË     ss   € ð �:‰:�iÓ ×&Ð& B×
+Ñ
+¨IÓ
6€CØ
‚{Ø�z‰z˜'Ó"×(Ð( b×-Ñ-Ð.?ÀÓFˆðÜ�3‹xˆøÜ”zÐ"ô Úðús   Á
A& Á&A;Á:A;c               ó   € V ^8„  d   QhRR/# )r-   r.   r|   r   )r/   s   "r#   r0   r0   (  s   € ÷ ñ ˜Sñ r"   c                 óh   €  ^ RI Hp  \        V ! 4       ;'       g    / 4      #   \         d     R# i ; i)a�  Clarify timeout from config.yaml; 0/negative = unlimited. Default 3600: long enough
that a user who stepped away still finds a live entry when they tap, short enough that
an abandoned prompt eventually unblocks the agent thread instead of pinning the guard.

The old 600s default evicted the entry mid-think, so a late tap landed on a dead entry and the agent
hung on ``running: clarify`` (#32762).
©Úload_configrÈ   )Úhermes_cli.configrÏ   rË   rB   rÎ   s    r#   Úget_clarify_timeoutrÑ   (  s1   € ðÝ1Ü&¡{£}×':Ð':¸Ó;Ð;øÜô Úðús   ‚" ›" ¢1°1)Frn   )4Ú__conditional_annotations__r   Ú
__future__r   r¡   Úloggingr   rD   Údataclassesr   r   Útypingr   r   r   r   Ú	getLoggerr   Úloggerr
   ÚRLockr3   r$   r   r%   r&   r«   rª   r©   r¨   r—   r˜   rI   r7   rQ   rU   rZ   r_   ri   ry   r~   r�   r‘   r�   r™   r­   r°   r³   rº   rÀ   rË   rÑ   )rÒ   s   @r#   Ú<module>rÚ      s  øðô+õ #Û Û Û Û ß (ß 1Ó 1à	×	Ò	˜8Ó	$€ð ÷	 ð 	 ó ð	 ð 	�ŠÓ€Ø%'€Ð
"Ó 'Ø')€Ð$Ó )à:<€Ð7Ó <ð €Ø&Ð Ø.Ð Ø€Ø€	Ø
€Ø€	÷	õ'õTõQð	ÐPU÷ 	õõQõ÷_õ">õ
Fõ8Jõ(
õUõ
!õcõõ"
÷r"   