+
    lHàj¸  ã                   óè   € R t ^ RIt^ RIHtHtHt ^ RIHt ]P                  ! ]	4      t
]]].]3,          ,          tR R ltRRRRR/R	 R
 ll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# )aÖ  Session ``/yolo``: the one toggle / restore / carry contract every surface calls.

The bypass itself is ``tools.approval``'s in-memory per-key set, so every process starts with it empty.
Each surface persists it where its session identity lives: CLI, TUI and Desktop on the session row
(``model_config.yolo_mode``), the messaging gateway on the routing entry, whose key outlives compression
rotations; sessions the gateway owns for CLI/TUI/Desktop clients (``config.set key=yolo``) and their managed
workers use that same routing entry. The surface hands its writer in as ``persist(enabled)``; everything else
is decided here, so the CLI ``/yolo``, the TUI Shift+Tab, the Desktop zap and a Telegram ``/yolo`` behave the same.
N)ÚAnyÚCallableÚOptional)Úapprovalc                ó@   € V ^8„  d   QhR\         R\        R\        RR/# )é   ÚpersistÚenabledÚsession_keyÚreturnN)ÚPersistÚboolÚstr)Úformats   "Ú8/home/ubuntu/.hermes/hermes-agent/tools/approval_yolo.pyÚ__annotate__r      s.   € ÷ hñ h”gð h¬ð h¼3ð hÀ4ñ hó    c                 óx   € V f   R #  V ! V4       R #   \          d    \        P                  RYRR7        R # i ; i)Nz(failed to persist session yolo=%s for %sT)Úexc_info)Ú	ExceptionÚloggerÚwarning)r   r	   r
   s   &&&r   Ú_persistr      s=   € à‚ÙðhÙ�ÖøÜô hÜ�‰ÐAÀ7Ðbfˆ×gðhús   ˆ ’#9¸9Ú	persistedFr   c          
      ój   € V ^8„  d   QhR\         R\        \        ,          R\        R\        R\        /# )r   r
   r	   r   r   r   )r   r   r   r   )r   s   "r   r   r      s6   € ÷ ñ ¤Sð ´8¼Dµ>ð ÔX\ð Ü!(ðÜ48ñr   c               óÌ   € Vf&   T;'       g    \         P                  ! V 4      '       * p\        W1V 4       V'       d   \         P                  M\         P                  ! V 4       V# )aA  Flip (``enabled=None``) or set the bypass for *session_key*; returns the new state.

*persisted* is the stored flag: after a restart only it is set and the user still sees ON, so a toggle
turns it OFF. The write runs BEFORE the live flip, so a turn restoring in between never revives a
bypass that is being switched off.
)r   Úis_session_yolo_enabledr   Úenable_session_yoloÚdisable_session_yolo)r
   r	   r   r   s   &&$$r   Útoggle_session_yolor      sO   € ð ‚Ø ×QÐQ¤H×$DÒ$DÀ[Ó$QÔRˆÜˆW˜{Ô+ß%,„X×!Ò!´(×2OÑ2OÐOÐQ\Ô]Ø€Nr   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   r
   r   r   )r   r   )r   s   "r   r   r   .   s!   € ÷ 
ñ 
¤cð 
´dð 
¼tñ 
r   c                óº   € V '       d;   V'       d3   \         P                  '       g   \         P                  ! V 4      '       d   R# \         P                  ! V 4       R# )a  Re-arm a persisted bypass in a fresh process; True when this call turned it on.

Key it on the id approvals are checked under (the stored session id / routing key), never a
transport-local id. Skipped under the frozen process ``--yolo``, which already bypasses everything.
FT)r   Ú_YOLO_MODE_FROZENr   r   )r
   r   s   &&r   Úrestore_session_yolor#   .   s9   € ÷ Ÿy¬H×,F×,FÐ,FÜ×/Ò/°×<Ò<ÙÜ× Ò  Ô-Ùr   c                ó(   € V ^8„  d   QhR\         RR/# )r   r
   r   N©r   )r   s   "r   r   r   ;   s   € ÷ .ñ .¤3ð .¨4ñ .r   c                óX  € V '       d   \         P                  '       d   R# \         P                  ;_uu_ 4        V \         P                  9   d    RRR4       R# \         P                  P	                  V 4       RRR4       \         P
                  ! V 4       R#   + '       g   i     L(; i)a%  Seed a gateway-owned session's launch ``--yolo`` policy once per session boundary.

Called every turn of such a route; only the first call (or the first after ``clear_session``) arms it,
so a later ``/yolo`` off sticks instead of lasting one turn. Skipped under the frozen process ``--yolo``.
N)r   r"   Ú_lockÚ_launch_yolo_appliedÚaddr   )r
   s   &r   Úapply_launch_yolor*   ;   si   € ÷ œ(×4×4Ð4ÙÜ	��‹Øœ(×7Ñ7Ô7Ø÷ 
‰ô 	×%Ñ%×)Ñ)¨+Ô6÷ 
ô × Ò  Ö-÷	 
�ús   ¹BÁBÂB)	Úlaunchc                óV   € V ^8„  d   QhR\         R\        \        ,          R\        RR/# )r   r
   r   r+   r   N)r   r   r   )r   s   "r   r   r   J   s4   € ÷ cñ c¤cð c´h¼tµnð cÔQUð cÐbfñ cr   c               ó¸  € V '       g   R# Vf   V'       d   \        V 4       R# \        P                  ;_uu_ 4        V \        P                  9   d    RRR4       R# \        P                  P	                  V 4       V'       d   \        P
                  P                  M\        P
                  P                  ! V 4       RRR4       R#   + '       g   i     R# ; i)a  Restore the authoritative routing value, including OFF, before frozen launch seeding.

``persisted`` None means nobody toggled this route: the ``--yolo`` launch policy (*launch*) is seeded
once per boundary instead, so an untouched entry never reads as a revocation.
N)r*   r   r'   r(   r)   Ú_session_yoloÚdiscard)r
   r   r+   s   &&$r   Úrestore_gateway_yolor0   J   s‰   € ÷ ÙØÒßÜ˜kÔ*ÙÜ	��‹Øœ(×7Ñ7Ô7Ø÷ 
‰ô 	×%Ñ%×)Ñ)¨+Ô6ß'0Œ×	Ñ	×	#Ò	#´h×6LÑ6L×6TÑ6TÐ	TÐVaÔb÷	 
��Šús   ¼CÁ&CÂ:CÃC	c                ó4   € V ^8„  d   QhR\         R\         RR/# )r   Úold_keyÚnew_keyr   Nr%   )r   s   "r   r   r   ]   s!   € ÷ 
+ñ 
+¤3ð 
+´ð 
+¸ñ 
+r   c                óâ   € ^ RI Hp V! W4       V '       d+   V'       d#   W8X  g   \        P                  ! V 4      '       g   R# \        P                  ! V4       \        P
                  ! V 4       R# )aR  Move the live bypass when the conversation continues under a new id (compression rotation, /branch).
The new row records it at creation (``with_session_yolo``), so nothing is written here. Every
continuation site calls this, so it also moves the chat's MCP spend total: a rotation must not hand a
chat that spent its limit a fresh budget.)Útransfer_sessionN)Útools.mcp_tool_costsr5   r   r   r   r   )r2   r3   r5   s   && r   Útransfer_session_yolor7   ]   sI   € õ
 6Ù�WÔ&ßŸ' WÔ%7¼x×?_Ò?_Ð`g×?hÒ?hÙÜ× Ò  Ô)Ü×!Ò! 'Ö*r   c                óh   € V ^8„  d   QhR\         \        ,          R\        R\         \        ,          /# )r   Úmodel_configr
   r   )r   Údictr   )r   s   "r   r   r   j   s*   € ÷ 7ñ 7¤H¬T¥Nð 7Äð 7ÌÔRVÍñ 7r   c                ób   € \         P                  ! V4      '       g   V # / T ;'       g    / CRR/C# )z¹``model_config`` for a session row being created, carrying a live bypass. Rows are created lazily on
the first turn, so this is where a toggle made before the row existed gets recorded.Ú	yolo_modeT)r   r   )r9   r
   s   &&r   Úwith_session_yolor=   j   s5   € ô ×+Ò+¨K×8Ò8ØÐØ6ˆ|×!Ð!˜rÐ6 K°Ñ6Ð6r   )N)Ú__doc__ÚloggingÚtypingr   r   r   Útoolsr   Ú	getLoggerÚ__name__r   r   r   r   r   r#   r*   r0   r7   r=   © r   r   Ú<module>rE      s€   ðñó ß *Ñ *å à	×	Ò	˜8Ó	$€à
�8˜T˜F C˜KÕ(Õ
)€õhñÐ_dð Ø+/÷ð õ
õ.ðcÐX]÷ cõ&
+÷7r   