§
    øžyj�4  ã                  ó‚  — d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ ddlmZmZ ddlmZ  ej        e¦  «        Zd?d@d„ZdAd„ZdBd„ZdCd„Z	 dDdEd„ZdFd„ZdFd„ZdFd „Z G d!„ d"¦  «        ZdGd$„ZdHd&„ZdId)„ZdJd*„Z dDdKd-„Z!dLd.„Z"e	 G d/„ d0¦  «        ¦   «         Z#dd1œdMd7„Z$dNd9„Z%dd1œdOd:„Z&dPd=„Z'dQd>„Z(dS )RzàCross-process active chat session leases.

The session database records persisted conversations.  This module records
currently open chat surfaces, including idle CLI/TUI sessions that have not
written a transcript row yet.
é    )ÚannotationsN)Ú	dataclass)ÚPath)ÚAnyÚOptional)Úget_hermes_homeÚmax_concurrent_sessionsÚvaluer   ÚkeyÚstrÚreturnúOptional[int]c                ó  — | €dS t          | t          ¦  «        rt                               d|| ¦  «         dS 	 t          | t          ¦  «        r3|                      ¦   «         st          | ¦  «        ‚t          | ¦  «        }nGt          | t          ¦  «        r#t          |  	                    ¦   «         d¦  «        }nt          | ¦  «        }n4# t          t          f$ r  t                               d|| ¦  «         Y dS w xY w|dk    rdS |S )z=Return a positive integer cap, or None when disabled/invalid.NzEIgnoring invalid %s=%r (expected a positive integer; 0/null disables)é
   r   )Ú
isinstanceÚboolÚloggerÚwarningÚfloatÚ
is_integerÚ
ValueErrorÚintr   ÚstripÚ	TypeError)r
   r   Úparseds      ú@/home/ragecks/.hermes/hermes-agent/hermes_cli/active_sessions.pyÚcoerce_max_concurrent_sessionsr      s  € à€}ØˆtÝ�%�ÑÔð Ý�ŠØSØØñ	
ô 	
ð 	
ð
 ˆtðÝ�e�UÑ#Ô#ð 	 Ø×#Ò#Ñ%Ô%ð (Ý  Ñ'Ô'Ð'Ý˜‘Z”ZˆFˆFÝ˜�sÑ#Ô#ð 	 Ý˜Ÿš™œ¨Ñ+Ô+ˆFˆFå˜‘Z”ZˆFøøÝ•zÐ"ð ð ð Ý�ŠØSØØñ	
ô 	
ð 	
ð
 ˆtˆtðøøøð �‚{€{ØˆtØ€Ms   ¹BC	 Ã	-C:Ã9C:Úconfigc                ó0  — d}d}t          | t          ¦  «        r\d| v r|                      d¦  «        }nS|                      d¦  «        }t          |t          ¦  «        r|                     d¦  «        }d}nt          | dd¦  «        }t	          ||¬¦  «        S )zBResolve top-level max_concurrent_sessions with gateway.* fallback.Nr	   Úgatewayzgateway.max_concurrent_sessions©r   )r   ÚdictÚgetÚgetattrr   )r   Úrawr   Úgateway_cfgs       r   Úresolve_max_concurrent_sessionsr'   8   s�   € à€CØ
#€CÝ�&�$ÑÔð 	?Ø$¨Ð.Ð.Ø—*’*Ð6Ñ7Ô7ˆCˆCà Ÿ*š* YÑ/Ô/ˆKÝ˜+¥tÑ,Ô,ð 8Ø!—o’oÐ&?Ñ@Ô@�Ø7�øå�fÐ7¸Ñ>Ô>ˆÝ)¨#°3Ð7Ñ7Ô7Ð7ó    Úsecondsr   c                óœ   — t          dt          | dz  ¦  «        ¦  «        }|dk     r|› d�S t          |d¦  «        \  }}|s|› d�n|› d|› d�S )Nr   é<   ÚmÚh)Úmaxr   Údivmod)r)   ÚminutesÚhourss      r   Ú
format_ager2   I   sk   € Ý�!•S˜ B™Ñ'Ô'Ñ(Ô(€GØ�‚|€|Øˆ}ˆ}ˆ}ÐÝ˜G RÑ(Ô(�N€Eˆ7Ø%Ð@ˆeˆ;ˆ;ˆ;ˆ;¨eÐ+@Ð+@°gÐ+@Ð+@Ð+@Ð@r(   Úentriesúlist[dict[str, Any]]c                ó¼  — | sdS i }| D ]B}t          |                     d¦  «        pd¦  «        }|                     |d¦  «        dz   ||<   ŒCd                     d„ t          |                     ¦   «         d„ ¬	¦  «        D ¦   «         ¦  «        }d
„ d„ | D ¦   «         D ¦   «         }|r7|dt          t          j        ¦   «         t          |¦  «        z
  ¦  «        › d�z  }|S )zDCompact "who is holding the slots" phrase, e.g. ``desktop x4, cli``.Ú ÚsurfaceÚunknownr   é   z, c              3  ó:   K  — | ]\  }}|d k    r|› d|› �n|V — ŒdS )r9   z xN© )Ú.0r7   Úns      r   ú	<genexpr>z$summarize_holders.<locals>.<genexpr>Y   sU   è è € ð ð áˆG�Qð  šU˜Uˆ7ÐÐ�aÐÐÐ¨ðð ð ð ð ð r(   c                ó$   — | d          | d         fS )Nr9   r   r;   )Úkvs    r   ú<lambda>z#summarize_holders.<locals>.<lambda>[   s   € À"ÀQÄ%ÀÈÈAÌÀ€ r(   r!   c                ó   — g | ]}|¯|‘ŒS r;   r;   )r<   Úts     r   ú
<listcomp>z%summarize_holders.<locals>.<listcomp>]   s   € ÐWÐWÐW�QÐUVÐWˆqÐWÐWÐWr(   c              3  óZ   K  — | ]&}t          |                     d ¦  «        ¦  «        V — Œ'dS )Ú
started_atN)Ú_optional_floatr#   )r<   Úes     r   r>   z$summarize_holders.<locals>.<genexpr>]   s6   è è € ÐQÐQÀA�?¨1¯5ª5°Ñ+>Ô+>Ñ?Ô?ÐQÐQÐQÐQÐQÐQr(   z	, oldest z ago)r   r#   ÚjoinÚsortedÚitemsr2   ÚtimeÚmin)r3   ÚcountsÚentryr7   ÚheldÚstarteds         r   Úsummarize_holdersrR   Q   s	  € àð ØˆrØ€FØð 5ð 5ˆÝ�e—i’i 	Ñ*Ô*Ð7¨iÑ8Ô8ˆØ Ÿ*š* W¨aÑ0Ô0°1Ñ4ˆˆw‰ˆØ�9Š9ð ð å  §¢¡¤Ð5OÐ5OÐPÑPÔPðñ ô ñ ô €Dð XÐWÐQÐQÈÐQÑQÔQÐWÑWÔW€GØð IØÐH�J¥t¤y¡{¤{µS¸±\´\Ñ'AÑBÔBÐHÐHÐHÑHˆØ€Kr(   Úactive_countr   Úmax_sessionsúOptional[list[dict[str, Any]]]c                óP   — t          |pg ¦  «        }|rd|› d�nd}d| › d|› d|› d�S )Nz
 Held by: ú.r6   z'Hermes is at the active session limit (ú/z).z) Try again when another session finishes.)rR   )rS   rT   r3   rP   Údetails        r   Úactive_session_limit_messagerZ   c   sd   € õ ˜W˜]¨Ñ+Ô+€DØ%)Ð1Ð!˜$Ð!Ð!Ð!Ð!¨r€Fð	=°,ð 	=ð 	=Àð 	=ð 	=Øð	=ð 	=ð 	=ðr(   r   c                 ó>   — t          t          ¦   «         ¦  «        dz  S )NÚruntime)r   r   r;   r(   r   Ú
_state_dirr]   u   s   € Ý•Ñ!Ô!Ñ"Ô" YÑ.Ð.r(   c                 ó$   — t          ¦   «         dz  S )Nzactive_sessions.json©r]   r;   r(   r   Ú_state_pathr`   y   ó   € Ý‰<Œ<Ð0Ñ0Ð0r(   c                 ó$   — t          ¦   «         dz  S )Nzactive_sessions.lockr_   r;   r(   r   Ú
_lock_pathrc   }   ra   r(   c                  ó"   — e Zd Zdd„Zd„ Zd„ ZdS )Ú	_FileLockÚpathr   c                ó"   — || _         d | _        d S ©N)rf   Ú_fh)Úselfrf   s     r   Ú__init__z_FileLock.__init__‚   s   € ØˆŒ	ØˆŒˆˆr(   c                óº  — | j         j                             dd¬¦  «         t          | j         d¦  «        | _        t
          j        dk    r•	 dd l}| j                             d¦  «         | 	                    | j         
                    ¦   «         |j        d¦  «         n¼# t          $ r5}| j                             ¦   «          d | _        t          d¦  «        |‚d }~ww xY w	 dd l}|                     | j         
                    ¦   «         |j        ¦  «         nB# t          $ r5}| j                             ¦   «          d | _        t          d¦  «        |‚d }~ww xY w| S )NT©ÚparentsÚexist_okza+bÚntr   r9   z$active session file lock unavailable)rf   ÚparentÚmkdirÚopenri   ÚosÚnameÚmsvcrtÚseekÚlockingÚfilenoÚLK_LOCKÚ	ExceptionÚcloseÚRuntimeErrorÚfcntlÚflockÚLOCK_EX)rj   rv   Úexcr~   s       r   Ú	__enter__z_FileLock.__enter__†   s_  € ØŒ	Ô×Ò t°dÐÑ;Ô;Ð;Ý˜œ	 5Ñ)Ô)ˆŒÝŒ7�dŠ?ˆ?ðTØ���à”—’˜aÑ Ô Ð Ø—’˜tœxŸšÑ0Ô0°&´.À!ÑDÔDÐDÐDøÝð Tð Tð TØ”—’Ñ Ô Ð Ø�”Ý"Ð#IÑJÔJÐPSÐSøøøøðTøøøð
TØ���à—’˜DœHŸOšOÑ-Ô-¨u¬}Ñ=Ô=Ð=Ð=øÝð Tð Tð TØ”—’Ñ Ô Ð Ø�”Ý"Ð#IÑJÔJÐPSÐSøøøøðTøøøð ˆs1   ÁAB Â
CÂ)0CÃCÃ"6D Ä
EÄ#0EÅEc                óè  — | j         €d S t          j        dk    rc	 dd l}| j                              d¦  «         |                     | j                              ¦   «         |j        d¦  «         nX# t          $ r Y nLw xY w	 dd l	}| 
                    | j                              ¦   «         |j        ¦  «         n# t          $ r Y nw xY w	 | j                              ¦   «          d | _         d S # d | _         w xY w)Nrp   r   r9   )ri   rt   ru   rv   rw   rx   ry   ÚLK_UNLCKr{   r~   r   ÚLOCK_UNr|   )rj   Úexc_typer�   Útbrv   r~   s         r   Ú__exit__z_FileLock.__exit__ž   s  € ØŒ8ÐØˆFÝŒ7�dŠ?ˆ?ðØ���à”—’˜aÑ Ô Ð Ø—’˜tœxŸšÑ0Ô0°&´/À1ÑEÔEÐEÐEøÝð ð ð Ø�ðøøøðØ���à—’˜DœHŸOšOÑ-Ô-¨u¬}Ñ=Ô=Ð=Ð=øÝð ð ð Ø�ðøøøð	ØŒH�NŠNÑÔÐàˆDŒHˆHˆHø�tˆDŒHˆOˆOˆOˆOs0   ›AA- Á-
A:Á9A:Á>6B5 Â5
CÃCÃC( Ã(	C1N)rf   r   )Ú__name__Ú
__module__Ú__qualname__rk   r‚   rˆ   r;   r(   r   re   re   �   sF   € € € € € ðð ð ð ðð ð ð0ð ð ð ð r(   re   rf   c                ó”  — 	 t          | dd¬¦  «        5 }t          j        |¦  «        }d d d ¦  «         n# 1 swxY w Y   n:# t          $ r g cY S t          $ r  t
                               d| ¦  «         g cY S w xY wt          |t          ¦  «        r| 	                    d¦  «        n|}t          |t          ¦  «        sg S d„ |D ¦   «         S )NÚrúutf-8©Úencodingz.Ignoring corrupt active session registry at %sr3   c                ó<   — g | ]}t          |t          ¦  «        ¯|‘ŒS r;   )r   r"   ©r<   rO   s     r   rD   z!_read_entries.<locals>.<listcomp>Â   s'   € ÐBÐBÐB�e­*°U½DÑ*AÔ*AÐBˆEÐBÐBÐBr(   )rs   ÚjsonÚloadÚFileNotFoundErrorr{   r   r   r   r"   r#   Úlist)rf   ÚfhÚdatar3   s       r   Ú_read_entriesr™   ¶   s"  € ðÝ�$˜ gÐ.Ñ.Ô.ð 	!°"Ý”9˜R‘=”=ˆDð	!ð 	!ð 	!ñ 	!ô 	!ð 	!ð 	!ð 	!ð 	!ð 	!ð 	!øøøð 	!ð 	!ð 	!ð 	!øøåð ð ð Øˆ	ˆ	ˆ	Ýð ð ð Ý�ŠÐGÈÑNÔNÐNØˆ	ˆ	ˆ	ðøøøõ &0°µdÑ%;Ô%;ÐEˆd�hŠh�yÑ!Ô!Ð!À€GÝ�g�tÑ$Ô$ð Øˆ	ØBÐB˜wÐBÑBÔBÐBs2   ‚A ”5©A µ9¹A ¼9½A ÁA8Á&A8Á7A8ÚNonec                ó‚  — | j                              dd¬¦  «         |                      | j        › dt	          j        ¦   «         › dt          j        ¦   «         j        › d�¦  «        }t          |dd¬¦  «        5 }t          j        d|i|d¬	¦  «         d d d ¦  «         n# 1 swxY w Y   t	          j        || ¦  «         d S )
NTrm   rW   z.tmpÚwrŽ   r�   r3   )Ú	sort_keys)rq   rr   Ú	with_nameru   rt   ÚgetpidÚuuidÚuuid4Úhexrs   r“   ÚdumpÚreplace)rf   r3   Útmpr—   s       r   Ú_write_entriesr¦   Å   só   € Ø„K×Ò˜d¨TÐÑ2Ô2Ð2Ø
�.Š.˜DœIÐLÐL­¬	©¬ÐLÐLµd´j±l´lÔ6FÐLÐLÐLÑ
MÔ
M€CÝ	ˆc�3 Ð	)Ñ	)Ô	)ð <¨RÝŒ	�9˜gÐ&¨°dÐ;Ñ;Ô;Ð;ð<ð <ð <ñ <ô <ð <ð <ð <ð <ð <ð <øøøð <ð <ð <ð <å„Jˆs�DÑÔÐÐÐs   Á9BÂB#Â&B#ÚpidúOptional[float]c                ó–   — 	 dd l }t          |                     | ¦  «                             ¦   «         ¦  «        S # t          $ r Y d S w xY w)Nr   )Úpsutilr   ÚProcessÚcreate_timer{   )r§   rª   s     r   Ú_process_start_timer­   Í   sX   € ðØˆˆˆå�V—^’^ CÑ(Ô(×4Ò4Ñ6Ô6Ñ7Ô7Ð7øÝð ð ð Øˆtˆtðøøøs   ‚7: º
AÁAc                óf   — | �| dk    rd S 	 t          | ¦  «        S # t          t          f$ r Y d S w xY w)Nr6   )r   r   r   )r
   s    r   rG   rG   Ø   sL   € Ø€}˜ š˜ØˆtðÝ�U‰|Œ|ÐøÝ•zÐ"ð ð ð Øˆtˆtðøøøs   Œ ›0¯0Úprocess_start_timer   c                óF  — 	 t          | ¦  «        }n# t          t          f$ r Y dS w xY w|dk    rdS 	 ddlm} t           ||¦  «        ¦  «        }n# t          $ r Y dS w xY w|sdS t          |¦  «        }|€dS t          |¦  «        }|€dS t          ||z
  ¦  «        dk     S )NFr   )Ú_pid_existsTgü©ñÒMbP?)
r   r   r   Úgateway.statusr±   r   r{   rG   r­   Úabs)r§   r¯   Úpid_intr±   ÚexistsÚexpected_startÚcurrent_starts          r   Ú
_pid_aliver¸   á   sñ   € ðÝ�c‘(”(ˆˆøÝ•zÐ"ð ð ð Øˆuˆuðøøøà�!‚|€|ØˆuðØ.Ð.Ð.Ð.Ð.Ð.å�k�k 'Ñ*Ô*Ñ+Ô+ˆˆøÝð ð ð Øˆuˆuðøøøàð ØˆuÝ$Ð%7Ñ8Ô8€NØÐØˆtÝ'¨Ñ0Ô0€MØÐØˆtÝˆ}˜~Ñ-Ñ.Ô.°Ò6Ð6s   ‚ ’'¦'³A Á
A ÁA c                ó   — d„ | D ¦   «         S )Nc                ó~   — g | ]:}t          |                     d ¦  «        |                     d¦  «        ¦  «        ¯8|‘Œ;S )r§   r¯   )r¸   r#   r’   s     r   rD   z_prune_dead.<locals>.<listcomp>ú   sQ   € ð ð ð àÝ�e—i’i Ñ&Ô&¨¯	ª	Ð2FÑ(GÔ(GÑHÔHðØðð ð r(   r;   )r3   s    r   Ú_prune_deadr»   ù   s#   € ðð àðñ ô ð r(   c                  óR   — e Zd ZU ded<   ded<   ded<   dZded<   dZded	<   dd„ZdS )ÚActiveSessionLeaser   Úlease_idÚ
session_idr7   Tr   ÚenabledFÚreleasedr   rš   c                óD   — | j         s| j        sd S t          | ¦  «         d S rh   )rÁ   rÀ   Úrelease_active_session)rj   s    r   ÚreleasezActiveSessionLease.release	  s.   € ØŒ=ð 	 ¤ð 	ØˆFÝ˜tÑ$Ô$Ð$Ð$Ð$r(   N)r   rš   )r‰   rŠ   r‹   Ú__annotations__rÀ   rÁ   rÄ   r;   r(   r   r½   r½     sg   € € € € € € à€M€M�MØ€O€O�OØ€L€L�LØ€GÐÐÐÑØ€HÐÐÐÑð%ð %ð %ð %ð %ð %r(   r½   )Úmetadatar¿   r7   rÆ   úOptional[dict[str, Any]]ú2tuple[Optional[ActiveSessionLease], Optional[str]]c                ó.  — t          |¦  «        }t          j        ¦   «         j        }|€t	          || |d¬¦  «        dfS t          j        ¦   «         }|t          | ¦  «        t          |¦  «        t          j        ¦   «         t          t          j        ¦   «         ¦  «        ||dœ}|r!d„ | 
                    ¦   «         D ¦   «         |d<   t          ¦   «         }t          t          ¦   «         ¦  «        5  t          |¦  «        }	t          |	¦  «        }
t!          |	¦  «        t!          |
¦  «        z
  }|rt"                               d|¦  «         t!          |
¦  «        }||k    rLt'          ||
¦  «         t"                               d|||¦  «         dt)          |||
¦  «        fcddd¦  «         S |
                     |¦  «         t'          ||
¦  «         ddd¦  «         n# 1 swxY w Y   t	          |t          | ¦  «        t          |¦  «        ¬	¦  «        dfS )
z½Acquire an active-session slot.

    Returns ``(lease, None)`` on success.  When the cap is disabled, the lease is
    a no-op object so callers can unconditionally call ``release()``.
    NF)r¾   r¿   r7   rÀ   )r¾   r¿   r7   r§   r¯   rF   Ú
updated_atc                ó^   — i | ]*\  }}t          |t          ¦  «        ¯t          |¦  «        |“Œ+S r;   ©r   r   ©r<   ÚkÚvs      r   ú
<dictcomp>z.try_acquire_active_session.<locals>.<dictcomp>0  sC   € ð 
ð 
ð 
Ù˜!˜QµjÀÅCÑ6HÔ6Hð
Ý�‰FŒF�Að
ð 
ð 
r(   rÆ   z'Pruned %d stale active session lease(s)z9Active session limit reached: active=%d max=%d surface=%s)r¾   r¿   r7   )r'   r    r¡   r¢   r½   rL   r   rt   rŸ   r­   rK   r`   re   rc   r™   r»   Úlenr   Úinfor¦   rZ   Úappend)r¿   r7   r   rÆ   rT   r¾   ÚnowrO   Ú
state_pathÚraw_entriesr3   ÚprunedrS   s                r   Útry_acquire_active_sessionrØ     sƒ  € õ 3°6Ñ:Ô:€LÝŒz‰|Œ|Ô€HØÐÝ!ØØ!ØØð	
ñ 
ô 
ð
 ðð 	õ Œ)‰+Œ+€CàÝ˜*‘o”oÝ�w‘<”<ÝŒy‰{Œ{Ý1µ"´)±+´+Ñ>Ô>ØØðð €Eð ð 
ð
ð 
Ø"*§.¢.Ñ"2Ô"2ð
ñ 
ô 
ˆˆjÑõ ‘”€JÝ	•:‘<”<Ñ	 Ô	 ð ,ð ,Ý# JÑ/Ô/ˆÝ˜kÑ*Ô*ˆÝ�[Ñ!Ô!¥C¨¡L¤LÑ0ˆØð 	KÝ�KŠKÐAÀ6ÑJÔJÐJÝ˜7‘|”|ˆØ˜<Ò'Ð'Ý˜: wÑ/Ô/Ð/Ý�KŠKØKØØØñ	ô ð ð Õ5Ø˜l¨Gñô ð ð,ð ,ð ,ð ,ñ ,ô ,ð ,ð ,ð$ 	�Š�uÑÔÐÝ�z 7Ñ+Ô+Ð+ð',ð ,ð ,ñ ,ô ,ð ,ð ,ð ,ð ,ð ,ð ,øøøð ,ð ,ð ,ð ,õ* ØÝ�z‘?”?Ý�G‘”ðñ ô ð ð	ð s   Ã1B/GÆ-%GÇG"Ç%G"Úleasec                óf  ‡ — t          ¦   «         }	 t          t          ¦   «         ¦  «        5  t          t	          |¦  «        ¦  «        }ˆ fd„|D ¦   «         }t          |¦  «        t          |¦  «        k    rt          ||¦  «         d d d ¦  «         n# 1 swxY w Y   d‰ _        d S # d‰ _        w xY w)Nc                ón   •— g | ]1}t          |                     d ¦  «        pd¦  «        ‰j        k    ¯/|‘Œ2S )r¾   r6   )r   r#   r¾   )r<   rO   rÙ   s     €r   rD   z*release_active_session.<locals>.<listcomp>V  sI   ø€ ð ð ð àÝ�u—y’y Ñ,Ô,Ð2°Ñ3Ô3°u´~ÒEÐEð àEÐEÐEr(   T)r`   re   rc   r»   r™   rÑ   r¦   rÁ   )rÙ   rÕ   r3   Úkepts   `   r   rÃ   rÃ   Q  sþ   ø€ Ý‘”€JðÝ•z‘|”|Ñ$Ô$ð 	1ð 	1Ý!¥-°
Ñ";Ô";Ñ<Ô<ˆGðð ð ð à$ðñ ô ˆDõ
 �4‰yŒy�C ™LœLÒ(Ð(Ý˜z¨4Ñ0Ô0Ð0ð	1ð 	1ð 	1ñ 	1ô 	1ð 	1ð 	1ð 	1ð 	1ð 	1ð 	1øøøð 	1ð 	1ð 	1ð 	1ð ˆŒˆˆø˜ˆŒÐÐÐÐs/   ‘B' ¬ABÂB' ÂBÂB' ÂBÂB' Â'	B0c               ó<  — t          |pd¦  «        }|sdS | j        rdS | j        s	|| _        dS t	          ¦   «         }t          t          ¦   «         ¦  «        5  t          t          |¦  «        ¦  «        }d}|D ]p}t          | 	                    d¦  «        pd¦  «        | j
        k    rŒ0||d<   t          j        ¦   «         |d<   |r!d„ |                     ¦   «         D ¦   «         |d<   d} |rt          ||¦  «         || _        |cd	d	d	¦  «         S # 1 swxY w Y   d	S )
zEMove an existing lease to a new session id without dropping the slot.r6   FTr¾   r¿   rÊ   c                ó^   — i | ]*\  }}t          |t          ¦  «        ¯t          |¦  «        |“Œ+S r;   rÌ   rÍ   s      r   rÐ   z+transfer_active_session.<locals>.<dictcomp>{  sC   € ð %ð %ð %Ù"& ! Q½jÈÍCÑ>PÔ>Pð%Ý˜‘F”F˜Að%ð %ð %r(   rÆ   N)r   rÁ   rÀ   r¿   r`   re   rc   r»   r™   r#   r¾   rL   rK   r¦   )rÙ   r¿   rÆ   Únew_session_idrÕ   r3   ÚupdatedrO   s           r   Útransfer_active_sessionrá   a  s–  € õ ˜Ð) rÑ*Ô*€NØð ØˆuØ„~ð ØˆuØŒ=ð Ø)ˆÔØˆtå‘”€JÝ	•:‘<”<Ñ	 Ô	 ð ð Ý�m¨JÑ7Ô7Ñ8Ô8ˆØˆØð 
	ð 
	ˆEÝ�5—9’9˜ZÑ(Ô(Ð.¨BÑ/Ô/°5´>ÒAÐAØØ"0ˆE�,ÑÝ"&¤)¡+¤+ˆE�,ÑØð ð%ð %Ø*2¯.ª.Ñ*:Ô*:ð%ñ %ô %��jÑ!ð ˆGØØð 	.Ý˜: wÑ/Ô/Ð/Ø-ˆEÔØð#ð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð s   ÁB,DÄDÄDÚlive_lease_idsúset[str]c                ó–  ‡ ‡— t          j        ¦   «         Št          ¦   «         }|                     ¦   «         sdS t	          t          ¦   «         ¦  «        5  t          t          |¦  «        ¦  «        }ˆ ˆfd„|D ¦   «         }t          |¦  «        t          |¦  «        z
  }|rt          ||¦  «         ddd¦  «         n# 1 swxY w Y   |S )u÷  Drop this process's registry entries that no live session owns.

    ``_prune_dead`` only reclaims leases whose owning process died. A server
    that runs for days (``hermes dashboard`` / ``serve``) never trips that
    check, so a lease whose session skipped teardown is held until restart.
    The owning process is the only authority on which of its own leases are
    real, so it drops the rest itself â€” exact, with no heartbeat write on the
    turn path and no staleness threshold to tune.
    r   c                ó’   •— g | ]C}|                      d ¦  «        ‰k    s&t          |                      d¦  «        pd¦  «        ‰v ¯A|‘ŒDS )r§   r¾   r6   )r#   r   )r<   rO   râ   r§   s     €€r   rD   z+release_orphaned_leases.<locals>.<listcomp>˜  sa   ø€ ð 
ð 
ð 
àØ�yŠy˜ÑÔ 3Ò&Ð&Ý�5—9’9˜ZÑ(Ô(Ð.¨BÑ/Ô/°>ÐAÐAð ð BÐAÐAr(   N)
rt   rŸ   r`   rµ   re   rc   r»   r™   rÑ   r¦   )râ   rÕ   r3   rÜ   Údroppedr§   s   `    @r   Úrelease_orphaned_leasesrç   †  s  øø€ õ Œ)‰+Œ+€CÝ‘”€Jð ×ÒÑÔð ØˆqÝ	•:‘<”<Ñ	 Ô	 ð 
-ð 
-Ý�m¨JÑ7Ô7Ñ8Ô8ˆð
ð 
ð 
ð 
ð 
à ð
ñ 
ô 
ˆõ �g‘,”,¥ T¡¤Ñ*ˆØð 	-Ý˜: tÑ,Ô,Ð,ð
-ð 
-ð 
-ñ 
-ô 
-ð 
-ð 
-ð 
-ð 
-ð 
-ð 
-øøøð 
-ð 
-ð 
-ð 
-ð €Ns   ÁAB>Â>CÃCc                 óä   — t          ¦   «         } t          t          ¦   «         ¦  «        5  t          t	          | ¦  «        ¦  «        }t          | |¦  «         |cddd¦  «         S # 1 swxY w Y   dS )z@Return the pruned active-session registry for diagnostics/tests.N)r`   re   rc   r»   r™   r¦   )rÕ   r3   s     r   Ú active_session_registry_snapshotré   ¤  s©   € å‘”€JÝ	•:‘<”<Ñ	 Ô	 ð ð Ý�m¨JÑ7Ô7Ñ8Ô8ˆÝ�z 7Ñ+Ô+Ð+Øðð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð s   ª.A%Á%A)Á,A))r	   )r
   r   r   r   r   r   )r   r   r   r   )r)   r   r   r   )r3   r4   r   r   rh   )rS   r   rT   r   r3   rU   r   r   )r   r   )rf   r   r   r4   )rf   r   r3   r4   r   rš   )r§   r   r   r¨   )r
   r   r   r¨   )r§   r   r¯   r   r   r   )r3   r4   r   r4   )
r¿   r   r7   r   r   r   rÆ   rÇ   r   rÈ   )rÙ   r½   r   rš   )rÙ   r½   r¿   r   rÆ   rÇ   r   r   )râ   rã   r   r   )r   r4   ))Ú__doc__Ú
__future__r   r“   Úloggingrt   rL   r    Údataclassesr   Úpathlibr   Útypingr   r   Úhermes_constantsr   Ú	getLoggerr‰   r   r   r'   r2   rR   rZ   r]   r`   rc   re   r™   r¦   r­   rG   r¸   r»   r½   rØ   rÃ   rá   rç   ré   r;   r(   r   ú<module>rò      sÐ  ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø 	€	€	€	Ø €€€Ø €€€Ø !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ø  Ð  Ð  Ð  Ð  Ð  Ð  Ð  à ,Ð ,Ð ,Ð ,Ð ,Ð ,à	ˆÔ	˜8Ñ	$Ô	$€ðð ð ð ð ð@8ð 8ð 8ð 8ð"Að Að Að Aðð ð ð ð* /3ðð ð ð ð ð$/ð /ð /ð /ð1ð 1ð 1ð 1ð1ð 1ð 1ð 1ð2ð 2ð 2ð 2ð 2ñ 2ô 2ð 2ðjCð Cð Cð Cðð ð ð ðð ð ð ðð ð ð ð7ð 7ð 7ð 7ð 7ð0ð ð ð ð ð
%ð 
%ð 
%ð 
%ð 
%ñ 
%ô 
%ñ „ð
%ð$ *.ð?ð ?ð ?ð ?ð ?ð ?ðDð ð ð ð( *.ð	"ð "ð "ð "ð "ð "ðJð ð ð ð<ð ð ð ð ð r(   