+
    lHàj�  ã                  óv  € 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	 ^ RI
Ht ^ RIHt ]P                  ! ]4      tR#t^ tRt]P(                  ! 4       t]P,                  ! 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R R lt R^ RRRR/R R llt!R R  lt"R! R" lt#R# )$u-  Durable interrupted-turn markers for the desktop/TUI auto-continue path. A running turn's progress
lives only in process memory (the agent flushes to SQLite at turn end), so a marker is written at turn
start and cleared on any conclusion â€” only a process death leaves one behind, and ``session.resume``
reads it (``_maybe_schedule_auto_continue``). Stored per ``HERMES_HOME`` (profile-aware); writes prune
entries older than ``_MAX_AGE_SECS`` and cap the count so a crash streak can't grow the file. Every
function is best-effort â€” marker bookkeeping must never break a turn â€” so I/O errors degrade to "no
marker" instead of raising. A marker also carries its writer's pid + start time (``marker_writer_state``): "a
marker exists" only implies the writer died when no live sibling backend wrote it (#94778).)ÚannotationsN©ÚPath)ÚAny)Úatomic_json_writei ú  c               ó    € V ^8„  d   QhRRRR/# )é   Úhomeú
Path | strÚreturnr   © )Úformats   "Ú</home/ubuntu/.hermes/hermes-agent/tui_gateway/turn_marker.pyÚ__annotate__r       s   € ÷ =ñ =�zð = dñ =ó    c                ó4   € \        V 4      R ,          R,          # )Údesktopzinterrupted_turns.jsonr   )r	   s   &r   Ú_marker_pathr       s   € Ü�‹:˜	Õ!Ð$<Õ<Ð<r   c               ó   € V ^8„  d   QhRR/# )r   Úpathr   r   )r   s   "r   r   r   $   s   € ÷ Nñ N˜dñ Nr   c                ól   € ^ RI Hp V! V P                  V P                   R24      \        RRV  R24      # )uÄ   Sibling backends on one HERMES_HOME (#94778) don't share ``_lock``; without this flock one's stale
load â†’ store resurrects a marker the other just cleared (a finished turn auto-continues again).)Ú
_file_lockz.lockg      @z,Timed out waiting for the turn-marker lock (Ú))Úhermes_cli.authr   Ú	with_nameÚnameÚ_file_lock_holder)r   r   s   & r   Ú_cross_process_lockr   $   s=   € õ +Ù�d—n‘n¨¯	©	 {°%Ð%8Ó9Ô;LÈcØDÀTÀFÈ!ÐLóNð Nr   c               ó    € V ^8„  d   QhRRRR/# )r   ÚentryÚdictr   Úfloatr   )r   s   "r   r   r   ,   s   € ÷ /ñ /�tð / ñ /r   c                óJ   € \        V P                  R 4      ;'       g    ^ 4      # )Ú
started_at)r!   Úget)r   s   &r   Ú_started_atr%   ,   s   € Ü�—‘˜<Ó(×-Ð-¨AÓ.Ð.r   c               ó   € V ^8„  d   QhRR/# )r   r   r    r   )r   s   "r   r   r   0   s   € ÷ ñ ˜$ñ r   c                 ó˜   € R\         P                  ! 4       /p  ^ RIHp V! 4       pVe   \	        V4      V R&   V #   \
         d     T # i ; i)aj  Best-effort identity of the process writing this marker. ``writer_pid`` alone already answers "who wrote
this, and are they still alive?" (``marker_writer_state``); ``writer_start_time`` pairs the pid with its create
time so a recycled pid cannot pass as the original writer. Identity is bookkeeping, never turn-critical, so
every failure degrades to a bare pid.Ú
writer_pid)Ú_own_start_timeÚwriter_start_time)ÚosÚgetpidÚhermes_cli.active_sessionsr)   r!   Ú	Exception)Úidentityr)   Ústarts      r   Ú_writer_identityr1   0   sY   € ð
 œbŸiši›kÐ*€HðÝ>ÙÓ!ˆØÒÜ,1°%«LˆHÐ(Ñ)ð €Oøô ô ØØ€Oðús   ™: ºA	ÁA	c               ó    € V ^8„  d   QhRRRR/# )r   r   r    r   Ústrr   )r   s   "r   r   r   @   s   € ÷ Hñ H˜tð H¨ñ Hr   c                óB  € \        V \        4      '       g   R# V P                  R4      p\        V\        4      '       d   \        V\        4      '       g   V^ 8:  d   R#  ^ RIHp V! WP                  R4      4      pTf   R# T'       d   R# R#   \         d     R# i ; i)u6  ``"alive"`` / ``"dead"`` / ``"unknown"``: is the process that wrote this marker still running?

A marker is durable proof a turn started â€” never proof its writer died. Two backends sharing one HERMES_HOME
break that assumption: A is mid-turn on session S while B resumes S, and B used to read A's marker as crash
evidence and start a second turn over it (#94778). Liveness comes from ``active_sessions._pid_liveness``
(pid + start time, so a reused pid reads dead), and "unknown" is the safe answer: it leaves the marker alone
without claiming its writer is gone.
Úunknownr(   )Ú_pid_livenessr*   ÚaliveÚdead)Ú
isinstancer    r$   ÚintÚboolr-   r6   r.   )r   Úpidr6   Úlives   &   r   Úmarker_writer_stater>   @   sŒ   € ô �eœT×"Ò"ÙØ
�)‰)�LÓ
!€CÜ�cœ3×Ò¤:¨c´4×#8Ò#8¸CÀ1¼HÙðÝ<Ù˜S§)¡)Ð,?Ó"@ÓAˆð šˆ9ÐG·d¨7ÐGÀÐGøô ô Úðús   Á B ÂBÂBc               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   údict[str, dict]r   )r   s   "r   r   r   V   s   € ÷ 	dñ 	d�ð 	d˜ñ 	dr   c                ó¸  €  \        V R R7      ;_uu_ 4       p\        P                  ! V4      pRRR4       \        X\        4      '       d=   TP                  4        UUu/ uF  w  r4\        T\        4      '       g   K  Y4bK!  	  upp# / #   + '       g   i     Ld; i  \         d    / u # \         d    \
        P                  RT RR7       / u # i ; iu uppi )zutf-8)ÚencodingNz.unreadable turn-marker file %s; starting freshT©Úexc_info)
ÚopenÚjsonÚloadÚFileNotFoundErrorr.   ÚloggerÚdebugr9   r    Úitems)r   ÚfÚdataÚkÚvs   &    r   Ú_loadrP   V   s¬   € ðÜ�$ ×)Õ)¨QÜ—9’9˜Q“<ˆD÷ *ô FPÐPTÔVZ×E[ÒE[˜TŸZ™Zœ\ÔA™\‘T�Q¬Z¸¼4×-@ŒDˆAŠD™\ÒAÐcÐacÐc÷ *×)ûäô ØŠ	Üô Ü�‰ÐEÀtÐVZˆÔ[ØŠ	ðüó BsE   ‚B —B
®B ÁCÁ>CÂ
B	ÂB ÂB ÂCÂ,CÂ5CÃCc               ó$   € V ^8„  d   QhRRRRRR/# )r   Úentriesr@   Únowr!   r   r   )r   s   "r   r   r   b   s&   € ÷ kñ k�Oð k¨%ð k°Oñ kr   c                ó  € V P                  4        UUu/ uF$  w  r#V\        V4      ,
          \        8:  g   K"  W#bK&  	  ppp\        V4      \        8:  d   V# \        \        VP                  4       R  RR7      R\         4      # u uppi )c                ó&   € \        V ^,          4      # )é   )r%   )Úitems   &r   Ú<lambda>Ú_prune.<locals>.<lambda>f   s   € ´{À4ÈÅ7Ô7Kr   T)ÚkeyÚreverseN)rK   r%   Ú_MAX_AGE_SECSÚlenÚ_MAX_ENTRIESr    Úsorted)rR   rS   rN   ÚeÚfreshs   &&   r   Ú_prunerb   b   sn   € Ø%Ÿm™mœoÔW™o‘d�a°´{À1³~Õ1EÌÑ1VŒTˆQŠT™o€EÑWÜ
ˆ5ƒz”\Ô!ØˆÜ”�u—{‘{“}Ñ*KÐUYÔZÐ[hÔ\hÐiÓjÐjùó Xs
   ”B¸Bc               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rR   r@   r   ÚNoner   )r   s   "r   r   r   i   s!   € ÷ >ñ >�ð > ð >°Dñ >r   c                óZ   € V'       g   V P                  R R7       R# \        WRRR7       R# )T)Ú
missing_okNi€  )ÚindentÚmode)Úunlinkr   )r   rR   s   &&r   Ú_storerj   i   s"   € ßØ�‰˜tˆÔ$ÙÜ�d¨D°u×=r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r	   r
   Úsession_keyr3   Úwhatr   rd   r   )r   s   "r   r   r   p   s.   € ÷ 	Zñ 	Z�*ð 	Z¨3ð 	Z¸cð 	ZÀdñ 	Zr   c           	     óf  €  \        V 4      p\        ;_uu_ 4        \        V4      ;_uu_ 4        V! \        V4      4      pVe   \	        WE4       RRR4       RRR4       R#   + '       g   i     L; i  + '       g   i     R# ; i  \
         d    \        P                  RY1RR7        R# i ; i)ua   Load â†’ ``mutate(entries)`` â†’ store under the lock; ``mutate`` returns None to skip the write.Nzfailed to %s turn marker for %sTrC   )r   Ú_lockr   rP   rj   r.   rI   rJ   )r	   rl   Úmutaterm   r   rR   s   &&&&  r   Ú_updaterq   p   s{   € ðZÜ˜DÓ!ˆßŽUÔ'¨×-Õ-ÙœU 4›[Ó)ˆGØÒ"Ü�tÔ%÷ .�U‰U×-×-ú�U�UˆUûô ô ZÜ�‰Ð6¸ÐTXˆ×YðZúsE   ‚B	 ›A5¯!A"	ÁA5ÁB	 Á"A2Á-A5Á5B	Â B	 ÂB	 Â	#B0Â/B0ÚattemptsÚauto_continueTÚnotification_categoryc               ó4   € V ^8„  d   QhRRRRRRRRRR	R
RRR/# )r   r	   r
   rl   r3   Úpromptrr   r:   rs   r;   rt   z
str | Noner   rd   r   )r   s   "r   r   r   |   sJ   € ÷ gñ g˜Jð g°Sð gÀ#ð gÐTWð gØ%)ðgØISðgØ_cñgr   c          
     óD  aaa€ S'       d	   V'       g   R# \         P                   ! 4       oR\        ^ \        V4      4      RVR\         RSR\	        V4      /\        4       CoVR8X  d   VSR&   \        P                  RSSR	,          4       \        V SVVV3R
 lR4       R# )zÂPersist the marker for a turn that is about to run. ``attempts`` = how many auto-continues led to
this run (0 for a user-initiated turn); the crash-loop breaker reads it back on the next resume.Nrr   rv   r#   rs   Ú
diagnosticrt   z4turn marker recorded for session %s by writer pid %sr(   c                ó(   <€ / \        V S4      CSS/C# ©N)rb   )rR   r   rS   rl   s   &€€€r   rX   Ú#record_turn_start.<locals>.<lambda>‰   s   ø€ Ð/[´&¸À#Ó2FÐ/[ÈÐUZÒ/[r   Úrecord)	ÚtimeÚmaxr:   Ú_MAX_PROMPT_CHARSr;   r1   rI   rJ   rq   )r	   rl   rv   rr   rs   rt   r   rS   s   &f&$$$@@r   Úrecord_turn_startr€   |   s”   ú€ ÷ ŸfÙÜ
�)Š)‹+€CØœ˜Q¤ H£Ó.°¸&ÐASÔBSÐ:TÐVbÐdgØœd =Ó1ðIÜ5EÓ5GðI€Eà Ô,Ø)>ˆÐ%Ñ&ä
‡L�LÐGÈÐV[Ð\hÕViÔjÜˆD�+Ö[Ð]eÖfr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r	   r
   rl   r3   r   rd   r   )r   s   "r   r   r   Œ   s&   € ÷ Fñ F˜Jð F°Sð F¸Tñ Fr   c                ó@   a€ S'       d   \        V SV3R lR4       R# R# )zGRemove the marker once its turn concluded (any outcome the client saw).c                ó|   <€ SV 9   d.   V P                  4        UUu/ uF  w  rVS8w  g   K  WbK  	  upp# R # u uppi rz   )rK   )r`   rN   rO   rl   s   &  €r   rX   Ú#clear_turn_marker.<locals>.<lambda>�   s=   ø€ ÐalÐpqÔaq¸q¿w¹w¼yÔ-]¹y±t°qÈAÐQ\ÑL\¬d¨aªd¹yÒ-]Ð-{Ðw{Ð-{ùÓ-]s   œ8¬8ÚclearN)rq   )r	   rl   s   &fr   Úclear_turn_markerr†   Œ   s"   ø€ çÜ��kÔ#{ð  ~Eö  	Fñ r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r	   r
   rl   r3   r   zdict[str, Any] | Noner   )r   s   "r   r   r   ’   s"   € ÷ ñ ˜:ð °Cð Ð<Qñ r   c                óÎ  € V'       g   R#  \         ;_uu_ 4        \        \        V 4      4      P                  V4      pRRR4       \	        X\
        4      '       d%   \        VP                  R4      ;'       g    R4      MRpVP                  4       '       g   R# R\        ^ \        VP                  R4      ;'       g    ^ 4      4      RVR\        V4      R\        VP                  RR4      4      /R
 Uu/ uF   qBP                  V4      f   K  WBV,          bK"  	  upCVP                  R4      R	8X  d   RR	/C# / C#   + '       g   i     EL; iu upi   \         d     R# i ; i)z8The marker left by a turn that never concluded, or None.Nrv   Ú rr   r#   rs   Trt   rx   )r(   r*   )ro   rP   r   r$   r9   r    r3   Ústripr~   r:   r%   r;   r.   )r	   rl   r   rv   rN   s   &&   r   Úread_turn_markerr‹   ’   sD  € çÙðßŽUÜœ, tÓ,Ó-×1Ñ1°+Ó>ˆE÷ ä3=¸eÄT×3JÒ3J”�U—Y‘Y˜xÓ(×.Ð.¨BÔ/ÐPRˆØ�|‰|�~Š~ÙØœC ¤3 u§y¡y°Ó'<×'AÐ'AÀÓ#BÓCÀXÈvÐWcÔepÐqvÓewØ¤ e§i¡i°ÀÓ&FÓ!GðSñ )LÓhÑ(K 1ÏyÉyÐYZË|”;�1˜A•h’;Ñ(KÑhðSð
 —i‘iÐ 7Ó8¸LÔHð ,¨\Ð:ð	Sð 	Sð
 OQðSð 	S÷ �UˆUüò iøô ô ÚðúsQ   ŒE š$D<¾:E Á9E Â#E Â>7E Ã5EÄEÄE Ä9E Ä<E	ÅE ÅE$Å#E$i€Q )$Ú__doc__Ú
__future__r   rF   Úloggingr+   Ú	threadingr}   Úpathlibr   Útypingr   Úutilsr   Ú	getLoggerÚ__name__rI   r\   r^   r   ÚLockro   Úlocalr   r   r   r%   r1   r>   rP   rb   rj   rq   r€   r†   r‹   r   r   r   Ú<module>r—      s¿   ðñ_õ #ã Û Û 	Û Û Ý Ý Ý #à	×	Ò	˜8Ó	$€à€Ø€àÐ à�ŠÓ€Ø—O’OÓ%Ð õ=õNõ/õõ Hõ,	dõkõ>õ	ZðgÐZ[ð gØ,0ðgØVZ÷gõ F÷r   