+
    iHàj„\  ã                   óL  € R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t
 ^ RIHt ]P                  ! R4      tRtRtR	t]! ]]]04      tR
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R R ltR R ltR R  ltR! R" lt R# R$ lt! ! R% R&4      t"R# )'zûInterrupt / steer / redirect control surface for ``AIAgent``.

Soft/hard interrupt requests, tool-thread interrupt propagation, pending steer/redirect queues.
Extracted from ``run_agent.py``; every method resolves through ``AIAgent``'s MRO unchanged.
N)ÚOptional)Úrequest_hard_interrupt)Úrequest_yield)Úset_interruptÚ	run_agentzexplicit stop requestedzuser sent a new messagezuser interruptzgateway shutdownc                ó:   € V ^8„  d   QhR\         \        ,          /# ©é   Úreturn©r   Ústr)Úformats   "Ú</home/ubuntu/.hermes/hermes-agent/agent/interrupt_control.pyÚ__annotate__r      s   € ÷ 1ñ 1œx¬�}ñ 1ó    c                ó˜   € \        V RR4      pV'       d   V\        9   d   R# \        V4      P                  4       P	                  RR4      # )zWSlug of the system producer behind the pending interrupt, or ``None`` for a human stop.Ú_tool_interrupt_reasonNÚ Ú_)ÚgetattrÚUSER_INTERRUPT_REASONSr   ÚstripÚreplace©ÚagentÚreasons   & r   Úinterrupt_issuerr      s?   € ä�UÐ4°dÓ;€Fß�VÔ5Ô5ÙÜˆv‹;×ÑÓ×&Ñ& s¨CÓ0Ð0r   c                ó$   € V ^8„  d   QhR\         /# r   ©r   )r   s   "r   r   r   %   s   € ÷ 
?ñ 
?¤Sñ 
?r   c                ó¢   € \        V RR4      pV'       g   R# V\        9   d   VP                  4       # R\        V4      P	                  RR4       2# )zðReason a tool call was skipped/cancelled, in words safe for tool output.

Derived from the RECORDED reason rather than the call site, so a system-initiated
abort reads as one instead of asserting a user message that never existed (#130207).r   NzTurn interruptedu   Turn aborted â€” r   r   )r   r   Ú
capitalizer   r   r   s   & r   Úinterrupt_skip_wordingr!   %   sP   € ô
 �UÐ4°dÓ;€FßÙ!ØÔ'Ô'Ø× Ñ Ó"Ð"Øœs 6›{×2Ñ2°3¸Ó<Ð=Ð>Ð>r   c                ó$   € V ^8„  d   QhR\         /# r   r   )r   s   "r   r   r   2   s   € ÷ añ a´ñ ar   c                ó8   € \        V 4      pV'       d   RV R2# R# )zdTurn exit reason for an API call cut short by an interrupt (``turn_explainers`` matches the prefix).zinterrupted_during_api_call(Ú)Úinterrupted_during_api_call)r   )r   Úissuers   & r   Ú"interrupted_during_api_call_reasonr'   2   s$   € ä˜eÓ$€Fß7=Ð)¨&¨°Ð3Ð`ÐC`Ð`r   c                ó4   € V ^8„  d   QhR\         R\        RR/# )r	   Úwhen_in_flightÚfailure_logr
   N)Úboolr   )r   s   "r   r   r   8   s"   € ÷ 5ñ 5¼$ð 5ÌSð 5ÐUYñ 5r   c               óü   € V e   \        \        V RR4      4      VJd   R# \        \        V 4      RR4      p\        V4      '       d    V! V 4       R# R#   \         d    \
        P                  TRR7        R# i ; i)u!  Call ``type(fence).cancel_before_commit(fence)`` when ``commit_in_flight`` matches.

Hard-cancel admission has two halves (#99758 P1). BEFORE the generation claim is
consumed only a commit already in flight is waited out (the call blocks on the fence
lock and returns False WITHOUT setting ``_cancelled``) â€” cancelling a still-pending
fence there would be irreversible for an abort that may yet be declined. AFTER the
claim survived, only a still-pending commit is cancelled; one that started meanwhile
owns the fence and completes on its own.NÚcommit_in_flightFÚcancel_before_commitT©Úexc_info)r+   r   ÚtypeÚcallableÚ	ExceptionÚloggerÚdebug)Úfencer)   r*   r.   s   &$$ r   Ú_fence_cancel_before_commitr7   8   su   € ð ‚}œœW UÐ,>ÀÓFÓGÈ~Ó]ÙÜ"¤4¨£;Ð0FÈÓMÐÜÐ$×%Ò%ð	5Ù  Ö'ñ &øô ô 	5Ü�L‰L˜¨tˆL×4ð	5ús   Á	A Á"A;Á:A;c                ó$   € V ^8„  d   QhR\         /# )r	   Úattrr   )r   s   "r   r   r   K   s   € ÷ >ñ >œ#ñ >r   c                óP   € \        WR4      pVf   \        P                  ! 4       # T# )zY``with`` the lock stored at ``attr`` when present; __init__-less test stubs run unlocked.N)r   Ú
contextlibÚnullcontext)r   r9   Úlocks   && r   Ú_ic_lockr>   K   s&   € ä�5 Ó%€DØ'+¢|Œ:×!Ò!Ó#Ð=¸Ð=r   c                ó0   € V ^8„  d   QhR\         R\         /# )r	   Ú	lock_attrÚslotr   )r   s   "r   r   r   Q   s   € ÷  ñ  œsð  ¬#ñ  r   c                óL   € \        WR4      f   \        WR4      # \        W4      # )a
  Read the pending-text ``slot`` guarded by ``lock_attr``. An initialized agent always has both
attributes, so under the lock the slot is read directly and a missing one fails loud (a real bug);
only ``__init__``-less test stubs (no lock) get the ``getattr`` fallback.N)r   )r   r@   rA   s   &&&r   Ú_ic_slotrC   Q   s)   € ô ˆu Ó&Ò.Ü�u DÓ)Ð)Ü�5ÓÐr   c                ó$   € V ^8„  d   QhR\         /# r   ©Úlist)r   s   "r   r   r   Z   s   € ÷ ñ œ4ñ r   c                óæ   € \        V RR4      p\        V 4      P                  R4      ;'       g    . pRP                  R V 4       4      T;'       g    R8w  d   V'       d   RV3.# . # \	        V4      # )zËThe buffered steers as ``(ticket, text)`` pairs; ``_pending_steer`` is their newline join. A ticket
names one submission (a gateway transfer). A buffer another writer set directly is one ticketless part.Ú_pending_steer_lockÚ_pending_steerÚ_pending_steer_partsÚ
c              3   ó*   "  € T F	  w  rVx € K  	  R # 5i©N© ©Ú.0r   Útexts   &  r   Ú	<genexpr>Ú_steer_parts.<locals>.<genexpr>_   s   é € Ð+¡U™'˜!•£Uùó   ‚Ú N)rC   ÚvarsÚgetÚjoinrF   )r   ÚpendingÚpartss   &  r   Ú_steer_partsr[   Z   sj   € ô �uÐ3Ð5EÓF€GÜ�‹K�O‰OÐ2Ó3×9Ð9°r€EØ‡y�yÑ+¡UÓ+Ó+°·°¸2Ô>ß$+��w�Ð Ð3°Ð3Ü�‹;Ðr   c                ó(   € V ^8„  d   QhR\         RR/# )r	   rZ   r
   NrE   )r   s   "r   r   r   d   s   € ÷ Hñ H¤4ð H¨Dñ Hr   c                 ó`   € Wn         R P                  R V 4       4      ;'       g    RV n        R# )rK   c              3   ó*   "  € T F	  w  rVx € K  	  R # 5irM   rN   rO   s   &  r   rR   Ú#_set_steer_parts.<locals>.<genexpr>f   s   é € Ð$?¹©g¨a¥T»ùrT   N)rJ   rX   rI   )r   rZ   s   &&r   Ú_set_steer_partsr`   d   s'   € Ø!&ÔØŸ9™9Ñ$?¹Ó$?Ó?×GÐGÀ4€EÖr   c                ó$   € V ^8„  d   QhR\         /# r   )Údict)r   s   "r   r   r   i   s   € ÷ =ñ =œ4ñ =r   c                ó8   € \        V 4      P                  R/ 4      # )z¹``{ticket: consumed}`` for ticketed steers that left the buffer: True when a drain handed the text
to the turn, False when it was dropped unread. ``withdraw_steer`` reads each one once.Ú_steer_ticket_fates)rV   Ú
setdefault)r   s   &r   Ú_steer_fatesrf   i   s   € ô �‹;×!Ñ!Ð"7¸Ó<Ð<r   c                ó(   € V ^8„  d   QhR\         RR/# )r	   Ú
steer_textr
   Nr   )r   s   "r   r   r   o   s   € ÷ 	=ñ 	=¬Sð 	=°Tñ 	=r   c                óL  € \        V R4      ;_uu_ 4        \        V 4      P                  RR4      w  r#W!8w  g	   V'       g   RV3.pV F   w  rE\        V 4      P                  VR4       K"  	  \	        V \        V 4      V,           4       RRR4       R#   + '       g   i     R# ; i)z¢Put drained steer text back (nothing took it). When it is the last drain's text, its parts go back
with their tickets, so a transfer in it reads unconsumed again.rH   Ú_steer_last_drainN)NN)r>   rV   Úpoprf   r`   r[   )r   rh   ÚdrainedrZ   Úticketr   s   &&    r   Úrequeue_drained_steerrn   o   s‚   € ô 
�%Ð.×	/Õ	/Ü˜e›Ÿ™Ð)<¸lÓK‰ˆØÔ ¯Ø˜JÐ'Ð(ˆEÛ‰IˆFÜ˜Ó×#Ñ# F¨DÖ1ñ ä˜¤¨UÓ 3°eÕ ;Ô<÷ 
0×	/×	/Ò	/ús   •+BÁABÂB#	c                ó$   € V ^8„  d   QhR\         /# )r	   Únamer   )r   s   "r   r   r   {   s   € ÷ 0ñ 0¤#ñ 0r   c                ó„   € \        V RR4      R8w  d   R# \        \        V RR4      VR4      p\        V4      '       d   V# R# )zLCodex app-server owns its model/tool loop; return its ``name`` hook or None.Úapi_modeNÚcodex_app_serverÚ_codex_session)r   r2   )r   rp   Úmethods   && r   Ú_ic_codex_methodrv   {   sD   € äˆu�j $Ó'Ð+=Ô=ÙÜ”W˜UÐ$4°dÓ;¸TÀ4ÓH€FÜ˜f×%Ò%ˆ6Ð/¨4Ð/r   c                ó4   € V ^8„  d   QhR\         R\         RR/# )r	   r   r*   r
   Nr   )r   s   "r   r   r   ƒ   s!   € ÷ 5ñ 5¬Cð 5¼cð 5Àdñ 5r   c                óª   € \        V RR4      p\        V4      '       d    V! V4       R# R#   \         d    \        P	                  TRR7        R# i ; i)zXShut the registered in-flight request's sockets (cron turns register their client here).Ú_active_request_abortNTr/   )r   r2   r3   r4   r5   )r   r   r*   Úaborts   &&& r   Ú_ic_abort_active_requestr{   ƒ   sL   € ä�EÐ2°DÓ9€EÜ�‡‚ð	5Ù�&ŽMñ øô ô 	5Ü�L‰L˜¨tˆL×4ð	5ús    , ¬"AÁAc                ó(   € V ^8„  d   QhR\         RR/# )r	   Úactiver
   N©r+   )r   s   "r   r   r   �   s   € ÷ ñ ¬4ð ¸$ñ r   c                ó   € \        V RR4      p\        V RR4      pVe   Vf   R# V;_uu_ 4        \        V4      pRRR4       X F  p \        W3/ VB  K  	  R#   + '       g   i     L(; i  \         d     K7  i ; i)a!  Fan the tool interrupt bit out to concurrent-tool worker tids.

``is_interrupted()`` inside a tool only sees its own tid, so without this a hung
concurrent tool runs to its own timeout (and a stale bit could survive a turn
boundary onto a recycled tid). getattr covers __init__-less stubs.Ú_tool_worker_threadsNÚ_tool_worker_threads_lock)r   rF   Ú_set_interruptr3   )r   r}   ÚkwÚtrackerÚtracker_lockÚworker_tidsÚtids   &&,    r   Ú_ic_signal_tool_workersrˆ   �   sy   € ô �eÐ3°TÓ:€GÜ˜5Ð"=¸tÓD€LØ‚˜,Ò.Ùß	ŠÜ˜7“mˆ÷ 
ãˆð	Ü˜6Ñ-¨"Ô-ó ÷ 
�ûô
 ô 	Úð	ús   ¯AÁ	A.ÁA+	Á.A=Á<A=c                   ó  a € ] tR t^ t o RtRRRRRRR/V 3R lR llltRRR/V 3R	 lR
 llltRRRR/V 3R lR lltRR/V 3R lR lltV 3R lR lt	V 3R lR lt
V 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltRtV tR# )ÚInterruptControlMixinzYinterrupt()/hard_interrupt()/clear_interrupt()/steer()/redirect() (see module docstring).NÚhard_cancelFÚtool_reasonÚrequire_generationc          
      óh   <€ V ^8„  d   QhRS[ S[,          RS[RS[ S[,          RS[ S[,          RS[/# )r	   Úmessager‹   rŒ   r�   r
   )r   r   r+   Úint)r   Ú__classdict__s   "€r   r   Ú"InterruptControlMixin.__annotate__£   sJ   ø€ ÷ kñ kÙ¡•}ðkÙ=Aðká™c•]ðká?GÉ½}ðkñ 
ñkr   c          	     ó$  a aaaa€ VeF   S P                  4       ;_uu_ 4        \        S R^ 4      V8w  d    RRR4       R# VS n        RRR4       S'       d   S;'       g    \        MS;'       g    S'       d   \        M\
        oR VVV VV3R llpVV 3R lp\        S R4      ;_uu_ 4        \        V! 4       RR	R
7       Vf	   V! 4        MTS P                  4       ;_uu_ 4        \        S RR4      V8w  d    RRR4       RRR4       R# RS n        V! 4        RRR4       \        V! 4       RRR
7       RS n        RRR4       \        S R4      pVe	    V! 4        \        S RR4       S P                  e!   \        RS P                  SR7       RS n        MRS n        \#        S RSR7       S P$                  ;_uu_ 4        \'        S P(                  4      pRRR4       X F-  p	 S'       d   \+        V	SSR7       K  V	P-                  S4       K/  	  S P.                  '       gF   \1        RS'       d   \3        S4      ^(8”  d   RSR,           R2MS'       d   RS R2MR,           4       R#   + '       g   i     EL+; i  + '       g   i     ELm; i  + '       g   i     EL_; i  \         d    \        P                  RRR7        ELoi ; i  + '       g   i     EL; i  \         d#   p
\        P                  RT
4        Rp
?
EK+  Rp
?
ii ; i)u²  Request the agent to interrupt its current tool-calling loop (call from another thread).

``hard_cancel``: explicit stop; compression may honor it even while ordinary interrupts are masked.
``tool_reason``: trusted fixed category safe for tool output. ``require_generation``: activity-
generation claim â€” published only if the turn's generation still matches at the final mutation edge;
returns False if the turn resumed meanwhile.
NÚ"_turn_liveness_activity_generationFc                ó   € V ^8„  d   QhRR/# )r	   r
   NrN   )r   s   "r   r   Ú5InterruptControlMixin.interrupt.<locals>.__annotate__À   s   € ÷ 	"ñ 	"¨$ñ 	"r   c                  óD  <€ S\         8X  d*   \        SR R4      '       d   \        SRR4      \        9   g   SSn        SSn        RSn        RSn        \        P                  RS'       d   RMRS4       S'       d   \        SRR4      MRp V e   V P                  4        R# R# )	Ú_interrupt_requestedFr   NTzInterrupt requested (%s): %sÚhardÚsoftÚ_hard_interrupt_requested)
Ú_REASON_GATEWAY_SHUTDOWNr   r   Ú_interrupt_messager   r˜   Ú_turn_user_intervenedr4   ÚinfoÚset)Ú_hard_eventr‹   r�   ÚselfÚtool_interrupt_reasonrŒ   s    €€€€€r   Ú_publish_interrupt_stateÚAInterruptControlMixin.interrupt.<locals>._publish_interrupt_stateÀ   s‘   ø€ ð  Ô#;Ô;ÄÈÐNdÐfk×@lÒ@lÜ Ð&>ÀÓEÔI_Ô_Ø*1�Ô'Ø.C�Ô+Ø(,ˆDÔ%Ø)-ˆDÔ&ä�K‰KÐ6Ç+¹ÐSYÐ[pÔqßNYœ' $Ð(CÀTÔJÐ_cˆKØÒ&Ø—‘Ö!ñ 'r   c                  óL   <€ S '       d   \        S4      P                  R 4      # R# )Ú _active_compression_commit_fenceN)rV   rW   )r‹   r¢   s   €€r   Ú_fenceÚ/InterruptControlMixin.interrupt.<locals>._fenceÐ   s   ø€ ßIT”4˜“:—>‘>Ð"DÓEÐ^ÐZ^Ð^r   Ú_pending_redirect_lockTz)Compression hard-cancel fence wait failed)r)   r*   Ú_turn_liveness_abort_claimz.Compression hard-cancel fence admission failedÚrequest_interruptz)Failed to interrupt Codex app-server turnr/   Úinterrupt_abortz%Failed to abort active inline request)r   )rŒ   z0Failed to propagate interrupt to child agent: %su   
âš¡ Interrupt requestedz: ':Né(   Nz...'Ú'rU   )Ú_liveness_activity_lockr   r«   Ú_REASON_HARD_STOPÚ_REASON_NEW_MESSAGEÚ_REASON_USER_INTERRUPTr>   r7   Ú_pending_redirectrv   r3   r4   r5   r{   Ú_execution_thread_idr‚   Ú _interrupt_thread_signal_pendingrˆ   Ú_active_children_lockrF   Ú_active_childrenr   Ú	interruptÚ
quiet_modeÚprintÚlen)r¢   r�   r‹   rŒ   r�   r¤   r¨   Ú_request_interruptÚchildren_copyÚchildÚer£   s   ffdd$      @r   r¹   ÚInterruptControlMixin.interrupt£   s¹  ü€ ð Ò)ð ×-Ñ-×/Õ/Ü˜4Ð!EÀqÓIÐM_Ô_Ø ÷ 0Ñ/ð 3E�Ô/÷ 0÷ 3>ˆ[×-Ð-Ô-øØ×]Ð]¿Õ"5ÔF\ð 	÷
	"ô 	"ö 	_ô �dÐ4×5Õ5Ü'Ù“¨Ð;fõð "Ò)ñ )Õ*ð
 ×1Ñ1×3Õ3Ü˜tÐ%AÀ4ÓHÐL^Ô^Ø$÷ 4÷ 6Ñ5ð 7;�DÔ3Ù,Ô.÷	 4ô
 (Ù“¨Ð<lõð &*ˆDÔ"÷) 6ô. .¨dÐ4GÓHÐØÒ)ðYÙ"Ô$ô 	! Ð'8Ð:aÔbà×$Ñ$Ò0Ü˜4 ×!:Ñ!:ÐCXÕYØ49ˆDÕ1ð 59ˆDÔ1Ü  dÐ3HÕIà×'×'Ó'Ü  ×!6Ñ!6Ó7ˆM÷ (ã"ˆEðTßÜ*¨5°'ÐG\×]à—O‘O GÖ,ñ #ð ��ˆÜÐ-ÏWÔY\Ð]dÓYeÐhjÔYj°3°w¸sµ|°nÀDÑ1I÷  ELÐruÐv}Ðu~Ð~ñ  qAð  RTõ  Uô  VÙ÷{ 0×/Ð/ú÷d 4×3Ð3ú÷ 6×5Ð5ûô6 ô YÜ—‘ÐHÐSW�×XðYú÷  (×'Ð'ûô ô TÜ—‘ÐOÐQR×SÓSûðTús}   ¢I)Á I)Â-8JÃ%I=	Ã9JÄI=	Ä"JÅJ% Æ?KÇ#K"Ç;K"É)I:	É=JÊ	JÊJ"	Ê%"KË
KËK	Ë"LË-L
Ì
Lc                óJ   <€ V ^8„  d   QhRS[ S[,          RS[ S[,          RR/# )r	   r�   rŒ   r
   Nr   )r   r‘   s   "€r   r   r’     s1   ø€ ÷ bñ b¡h©s¥mð bÉHÑUXÍMð bÐeiñ br   c               ó6   € \         P                  WRVR7       R# )z÷Explicit stop preserving the ``interrupt()`` ABI (frontends feature-detect this and fall back to
legacy ``interrupt()`` for third-party agents). Bypasses dynamic dispatch: legacy subclasses may
override interrupt(message=None) without hard_cancel.T)r‹   rŒ   N)rŠ   r¹   )r¢   r�   rŒ   s   &&$r   Úhard_interruptÚ$InterruptControlMixin.hard_interrupt  s   € ô 	×'Ñ'¨À4ÐU`Ð'Öar   Úpreserve_redirectc                ó,   <€ V ^8„  d   QhRS[ RS[ RS[ /# )r	   rÆ   r‹   r
   r~   )r   r‘   s   "€r   r   r’     s#   ø€ ÷ ñ ±Dð Étð Ñ`dñ r   c               ó¢  € \        V R4      ;_uu_ 4        V'       d   \        V RR4      '       g    RRR4       R# RV n        R;V n        V n        \        V R\        P                  ! 4       4      P                  4        V'       g   RV n	        RRR4       RV n
        V P                  e   \        RV P                  4       \        V R4       V'       dT   \        V R4      ;_uu_ 4        \        V 4       F  w  r4Vf   K  R\        V 4      V&   K  	  \!        V . 4       RRR4       R# R#   + '       g   i     L¤; i  + '       g   i     R# ; i)uÐ  Clear the interrupt request and per-thread tool signal. ``preserve_redirect`` is only for the
conversation loop rebuilding the same logical turn after cancelling a model request.
``hard_cancel`` also drops an unconsumed pending steer: the aborted turn's next tool iteration
will no longer happen, and re-injecting the note into the post-stop turn would surprise the
user. Every other caller (redirect rebuild, error recovery, turn-boundary hygiene) continues
this session, so the already-accepted steer must survive: it stays buffered for the existing
drains â€” the pre-API inject, the post-batch append, or the finalizer's leftover handoff â€”
instead of silently vanishing after the surface was told it was delivered.rª   r´   NFr›   rH   T)r>   rC   r˜   r�   r   r   Ú	threadingÚEventÚclearr´   r¶   rµ   r‚   rˆ   r[   rf   r`   )r¢   rÆ   r‹   rm   r   s   &$$  r   Úclear_interruptÚ%InterruptControlMixin.clear_interrupt  s  € ô �dÐ4×5Õ5ß ¬°$Ð8PÐRe×)fÒ)fØ÷ 6Ñ5ð ).ˆDÔ%ØDHÐHˆDÔ# dÔ&AÜ�DÐ5´y·²Ó7HÓI×OÑOÔQß$Ø)-�Ô&÷ 6ð 16ˆÔ-Ø×$Ñ$Ò0Ü˜5 $×";Ñ";Ô<Ü  eÔ,ßô ˜$Ð 5×6Õ6Ü!-¨dÖ!3‘I�FØÔ)Ø5:œ TÓ*¨6Ó2ñ "4ô !  rÔ*÷	 7ó
 ÷+ 6×5ú÷  7Ö6ñ
 ús#   •D*¼AD*Ã)D=Ä D=Ä*D:	Ä=E	rm   c                ó&   <€ V ^8„  d   QhRS[ RS[/# ©r	   rQ   r
   ©r   r+   )r   r‘   s   "€r   r   r’   6  s   ø€ ÷ ñ ™#ð ±$ñ r   c               ó  € V'       d   VP                  4       '       g   R# VP                  4       p\        V R4      ;_uu_ 4        \        V \        V 4      W#3.,           4       RRR4       RV n        R#   + '       g   i     L; i)a  Queue user text for delivery as its own user row after the current tool batch finishes (no
interrupt); multiple calls concatenate with newlines. Returns False for empty text. ``ticket``
names the submission, so ``withdraw_steer`` can settle exactly it, whatever text others carry.FrH   NT)r   r>   r`   r[   rž   )r¢   rQ   rm   Úcleaneds   &&$ r   ÚsteerÚInterruptControlMixin.steer6  sb   € ÷ ˜4Ÿ:™:Ÿ<š<ÙØ—*‘*“,ˆÜ�dÐ1×2Õ2Ü˜T¤<°Ó#5¸&Ð9JÐ8KÕ#KÔL÷ 3ð &*ˆÔ"Ù÷	 3×2ús   ÁA5Á5B	c                ó&   <€ V ^8„  d   QhRS[ RS[/# rÏ   rÐ   )r   r‘   s   "€r   r   r’   C  s   ø€ ÷ =ñ =™Sð =¡Tñ =r   c                óØ  € V'       d   VP                  4       '       g   R# VP                  4       p\        V R4      pVe_   \        V R4      ;_uu_ 4        V P                  '       d    RRR4       R#  RRR4        \	        V! V4      4      pV'       d   RV n        V# \        V RR4      '       dp   V P                  V4      pV'       dU   \        V R	R4      p\        V R
R4      pVe7   Ve3   V;_uu_ 4        \        V4      pRRR4       X F  p\        V4       K  	  V# \        V RR4      p	\        V R4      ;_uu_ 4        V	e   V	P                  4       '       g    RRR4       R# \        V RR4      p
V P                  '       d   V
'       g    RRR4       R# V
'       d   V
 RV 2MTV n        RV n        RV n        RV n        RRR4       \        V RR4      pVe   \#        RV4       RV n        MRV n        \'        V RR4       R#   + '       g   i     EL�; i  \         d    \        P                  RRR7        R# i ; i  + '       g   i     ELK; i  + '       g   i     Lœ; i)a‡  Redirect the active turn without converting it into a new task: during a model request only that
request is cancelled (completed messages kept, partial reasoning becomes assistant context, the
correction is appended as a real user message, the loop retries); during tool execution it degrades
to ``steer()``; Codex app-server uses native ``turn/steer``. False when no live turn / empty text.FÚrequest_steerNrª   Tz"Codex app-server turn/steer failedr/   Ú_executing_toolsr€   r�   Ú_model_request_activer´   z

[Additional user correction]
rµ   Úredirect_abortz$Failed to abort request for redirect)r   rv   r>   r˜   r+   rž   r3   r4   r5   r   rÓ   rF   Ú_request_yieldÚis_setrC   r´   r�   r‚   r¶   r{   )r¢   rQ   rÒ   Ú_native_steerÚacceptedr„   r…   r†   r‡   Ú_model_activeÚexistingrµ   s   &&          r   ÚredirectÚInterruptControlMixin.redirectC  s&  € ÷
 ˜4Ÿ:™:Ÿ<š<ÙØ—*‘*“,ˆä(¨¨Ó?ˆØÒ$Ü˜$Ð 8×9Õ9Ø×,×,Ð,Ø ÷ :Ñ9Ø,÷ :ðÜ¡¨gÓ 6Ó7�ßØ15�DÔ.Ø�ô �4Ð+¨U×3Ò3Ø—z‘z 'Ó*ˆHßÜ! $Ð(>ÀÓE�Ü& tÐ-HÈ$ÓO�ØÒ&¨<Ò+Cß%šÜ&*¨7£m˜÷ &ã*˜Ü& sÖ+ñ  +àˆOä Ð&=¸tÓDˆÜ�dÐ4×5Õ5ØÒ$¨M×,@Ñ,@×,BÒ,BØ÷ 6Ñ5ô   Ð&>Ð@SÓTˆHØ×(×(Ð(·Ø÷ 6Ñ5÷ MU�8�*Ð>¸w¸iÑHÐZað Ô"ð )-ˆDÔ%Ø&*ˆDÔ#Ø)-ˆDÔ&÷ 6ô  ' tÐ-CÀTÓJÐØÒ+Ü˜4Ð!5Ô6Ø49ˆDÕ1à48ˆDÔ1Ü  Ð'7Ð9_Ô`Ù÷e :×9Ð9ûô ô Ü—‘ÐAÈD�ÔQÚðú÷ &Ÿ˜ú÷ 6×5úsT   ÁHÁ=!H Ã7IÅIÅIÅ(&IÆIÆIÆ"#IÈH	È"IÉIÉI	ÉI)	c                ó    <€ V ^8„  d   QhRS[ /# r   r~   )r   r‘   s   "€r   r   r’   ‚  s   ø€ ÷ Wñ W¡tñ Wr   c           	     ó”   € \        V R4      ;_uu_ 4        \        \        V RR4      4      uuRRR4       #   + '       g   i     R# ; i)z@Return whether an active-turn redirect is waiting to be applied.rª   r´   N)r>   r+   rC   )r¢   s   &r   Ú_has_pending_redirectÚ+InterruptControlMixin._has_pending_redirect‚  s2   € ä�dÐ4×5Õ5Üœ Ð'?ÐATÓUÓV÷ 6×5×5Ó5ús	   •6¶A	c                ó0   <€ V ^8„  d   QhRS[ S[,          /# r   r   )r   r‘   s   "€r   r   r’   ‡  s   ø€ ÷ ñ ©±#­ñ r   c                ó�   € \        V R4      ;_uu_ 4        \        V RR4      pRV n        RRR4       V#   + '       g   i     X# ; i)z5Return and clear pending active-turn correction text.rª   r´   N)r>   rC   r´   )r¢   rQ   s   & r   Ú_drain_pending_redirectÚ-InterruptControlMixin._drain_pending_redirect‡  sD   € ä�dÐ4×5Õ5Ü˜DÐ":Ð<OÓPˆDØ%)ˆDÔ"÷ 6ð ˆ÷ 6Ö5ð ˆús	   •4´A	c                ó0   <€ V ^8„  d   QhRS[ S[,          /# r   r   )r   r‘   s   "€r   r   r’   Ž  s   ø€ ÷ 
ñ 
¡h©s¥mñ 
r   c                óþ   € \        V R4      ;_uu_ 4        \        V RR4      p\        V 4      p\        V . 4       V F  w  r4Vf   K  R\	        V 4      V&   K  	  W3V n        RRR4       V#   + '       g   i     X# ; i)zXReturn the pending steer text (if any) and clear the slot; None when nothing is pending.rH   rI   NT)r>   rC   r[   r`   rf   rj   )r¢   rQ   rZ   rm   r   s   &    r   Ú_drain_pending_steerÚ*InterruptControlMixin._drain_pending_steerŽ  s}   € ä�dÐ1×2Õ2Ü˜DÐ"7Ð9IÓJˆDÜ  Ó&ˆEÜ˜T 2Ô&Û"‘	�ØÔ%Ø15”L Ó& vÓ.ñ #ð '+ ]ˆDÔ"÷ 3ð ˆ÷ 3Ö2ð ˆús   •-A+ÁA+Á+A<	c                ó0   <€ V ^8„  d   QhRS[ S[,          /# r   r   )r   r‘   s   "€r   r   r’   š  s   ø€ ÷ Sñ S¡x±¥}ñ Sr   c           
     ó  € \        V R4      ;_uu_ 4        \        V 4      p\        Y Uu. uF  q"^ ,          f   K  VNK  	  up4       RRR4       RP                  R X 4       4      ;'       g    R# u upi   + '       g   i     L7; i)a  The turn finalizer's drain: return and clear the ticketless steers (they become the next user
turn) and keep each ticketed one buffered. A transfer is never a follow-up a restart may discard:
settlement withdraws it and its admission goes back to its own queue place.rH   NrK   c              3   ó6   "  € T F  w  rVe   K  Vx € K  	  R # 5irM   rN   )rP   rm   rQ   s   &  r   rR   Ú>InterruptControlMixin._drain_leftover_steer.<locals>.<genexpr>¡  s   é € ÐJ±%¡, &¸6Ÿš³%ùs   ‚�
)r>   r[   r`   rX   )r¢   rZ   Úparts   &  r   Ú_drain_leftover_steerÚ+InterruptControlMixin._drain_leftover_steerš  sn   € ô �dÐ1×2Õ2Ü  Ó&ˆEÜ˜T°UÓ#R±U¨TÀ1½g§D D±UÑ#RÔS÷ 3ð �y‰yÑJ±%ÓJÓJ×RÐRÈdÐRùò $S÷ 3×2ús!   •A7ªA2»A2ÁA7Á2A7Á7B	c                ó    <€ V ^8„  d   QhRS[ /# r   r~   )r   r‘   s   "€r   r   r’   £  s   ø€ ÷ ñ ©ñ r   c                ón  € Vf   R# \        V R4      ;_uu_ 4        \        V 4      pV Uu. uF  q3^ ,          V8w  g   K  VNK  	  pp\        V 4      P                  VR4      p\	        V4      \	        V4      8X  d   VRJ uuRRR4       # \        W4       RRR4       R# u upi   + '       g   i     R# ; i)a%  Settle one ``steer(text, ticket=...)`` by identity (the gateway's transfer of a queued prompt):
True when no drain handed it to the turn, either still buffered (taken out now; every other steer
stays, whatever its text) or dropped unread; False once a drain consumed it, or for an unknown one.NFrH   T)r>   r[   rf   rk   r¼   r`   )r¢   rm   rZ   ró   ÚkeptÚconsumeds   &&    r   Úwithdraw_steerÚ$InterruptControlMixin.withdraw_steer£  s¢   € ð Š>ÙÜ�dÐ1×2Õ2Ü  Ó&ˆEÙ%*Ó@¡U˜T°1­g¸Ñ.?—D�D¡UˆDÐ@Ü# DÓ)×-Ñ-¨f°dÓ;ˆHÜ�4‹yœC ›JÔ&Ø 5Ð(÷ 3Ò2ô ˜TÔ(÷ 3ñ ùò A÷ 3Ö2ñ ús'   ›B#«B¿BÁ9B#Â	B#ÂB#Â#B4	)r�   r˜   r¶   r´   rj   r   r«   rž   rM   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r¹   rÄ   rÌ   rÓ   rá   rå   ré   rí   rô   rú   Ú__static_attributes__Ú__classdictcell__)r‘   s   @r   rŠ   rŠ       s±   ø‡ € ÙcñkØDIðkà%)ðkàOS÷kó kñZbÐ\`÷ bó bð¸5ð ÐV[÷ ò ð@¨÷ ò ÷=ð =÷~Wð W÷
ð ÷
ð 
÷Sð S÷ö r   rŠ   )#r   r;   ÚloggingrÉ   Útypingr   Úagent.interrupt_compatr   Útools.interruptr   rÛ   r   r‚   Ú	getLoggerr4   r±   r²   r³   Ú	frozensetr   rœ   r   r!   r'   r7   r>   rC   r[   r`   rf   rn   rv   r{   rˆ   rŠ   rN   r   r   Ú<module>r	     s±   ðñó
 Û Û Ý å 9Ý ;Ý ;ð 
×	Ò	˜;Ó	'€ð
 .Ð Ø/Ð Ø)Ð Ù"Ð$5Ð7JÐLbÐ#cÓdÐ à-Ð õ1õ
?õaõ5õ&>õ õõHõ
=õ	=õ0õ5õ÷&Pó Pr   