+
    iHàjš#  ã                  ó  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt	^ RI
Ht ^ RIHtHtHtHt ]P"                  ! ]4      tRtRtRtR R ltR	 R
 ltR R lt]! RR7       ! R R4      4       t ! R R4      tR R lt]! 4       tR# )a  Idle deferral for background reviews on the managed local runtime.

On the managed llama-server the post-turn review fork monopolizes the GPU the next prompt
needs and the next live turn cancels it (decode cost paid, learning lost). Reviews bound for
the managed endpoint are therefore queued and dispatched when the machine is quiet
(``auxiliary.background_review.defer``: ``auto`` = exactly that case, ``never`` = old behavior;
explicit /refine never defers). One slot per session, newest snapshot wins (a review replays
the whole conversation, so coalescing is dedup, not loss); aged-out items (defer_max_age_s,
default 30 min) dispatch regardless of idleness; in-memory best-effort like the immediate
fork. Idle truth is the supervisor's /slots held for a settle window.
)ÚannotationsN)Ú	dataclass)ÚAnyÚCallableÚDictÚOptionalg      .@g      @c               ó    € V ^8„  d   QhRRRR/# )é   Útask_cfgúOptional[dict[str, Any]]ÚreturnÚstr© )Úformats   "Ú</home/ubuntu/.hermes/hermes-agent/agent/review_idle_queue.pyÚ__annotate__r      s   € ÷ 7ñ 7Ð1ð 7°cñ 7ó    c                óš   € \        T ;'       g    / P                  RR4      4      P                  4       P                  4       pVR9   d   V# R# )zC'auto' (default) or 'never' from auxiliary.background_review.defer.ÚdeferÚauto)r   Únever)r   ÚgetÚstripÚlower)r
   Úraws   & r   Ú
defer_moder      sD   € ä
ˆx�~ˆ~˜2×"Ñ" 7¨FÓ3Ó
4×
:Ñ
:Ó
<×
BÑ
BÓ
D€CØÐ*Ô*ˆ3Ð6°Ð6r   c               ó    € V ^8„  d   QhRRRR/# )r	   r
   r   r   Úfloatr   )r   s   "r   r   r   %   s   € ÷ 6ñ 6Ð6ð 6¸5ñ 6r   c                ó®   €  \        T ;'       g    / P                  R \        4      4      pT^ 8”  d   T# \        #   \        \        3 d
    \        u # i ; i)Údefer_max_age_s)r   r   Ú_MAX_AGE_DEFAULT_SÚ	TypeErrorÚ
ValueError)r
   Úvalues   & r   r   r   %   sV   € ð"Ü�x—~�~ 2×*Ñ*Ð+<Ô>PÓQÓRˆð ˜A”Iˆ5Ð5Ô#5Ð5øô ”zÐ"ô "Ü!Ò!ð"ús   ‚: �: ºAÁAc               ó$   € V ^8„  d   QhRRRRRR/# )r	   Úagentr   r
   r   r   Úboolr   )r   s   "r   r   r   -   s#   € ÷ ñ ¨ð Ð7Oð ÐTXñ r   c                ó    €  ^ RI HpHp V! 4       '       g   R# ^ RIHp V! W4      pV! VP                  R4      4      #   \         d     R# i ; i)a!  Would this review fork decode on the llama-server WE manage? Exact netloc match against the
supervisor state file; any failure reads False (immediate spawn is the safe default). The cheap
TTL-cached netloc probe runs FIRST so cloud-only installs skip runtime resolution on the turn's tail.)Ú_is_managed_local_endpointÚ_managed_local_netlocF)Ú_resolve_review_runtimeÚbase_url)Úagent.auxiliary_managed_localr(   r)   Úagent.background_reviewr*   r   Ú	Exception)r%   r
   r(   r)   r*   Úruntimes   &&    r   Úreview_targets_managed_localr0   -   sI   € ð
ßcá$×&Ò&ÙÝCá)¨%Ó:ˆÙ)¨'¯+©+°jÓ*AÓBÐBøÜô Úðús   ‚> ™$> ¾AÁAT)Úslotsc                  óJ   € ] tR t^>t$ R]R&   R]R&   R]R&   R]R&   R	]R
&   RtR# )Ú_PendingReviewr   r%   r   Úsession_keyúdict[str, Any]Úkwargsr   Úenqueued_atzcontextvars.ContextÚcontextr   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__Ú__static_attributes__r   r   r   r3   r3   >   s   ‡ àƒJØÓØÓØÓØ × r   r3   c                  ó¨   € ] tR t^Gt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4       tRtR# )ÚReviewIdleQueuez8Session-coalescing queue + idle-gated dispatcher thread.c               ó   € V ^8„  d   QhRR/# ©r	   r   ÚNoner   )r   s   "r   r   ÚReviewIdleQueue.__annotate__J   s   € ÷ 	Eñ 	E˜$ñ 	Er   c                	óæ   € \         P                  ! 4       V n        / V n        \         P                  ! 4       V n        R V n        ^ V n        R V n        \        P                  V n        \        V n        R # ©N)Ú	threadingÚLockÚ_lockÚ_pendingÚEventÚ_wakeÚ_threadÚ_live_turnsÚ_quiet_sinceÚtimeÚ	monotonicÚ_nowÚ_managed_server_idleÚ_server_idle©Úselfs   &r   Ú__init__ÚReviewIdleQueue.__init__J   sO   € Ü—^’^Ó%ˆŒ
Ø35ˆŒÜ—_’_Ó&ˆŒ
Ø37ˆŒØˆÔØ-1ˆÔä)-¯©ˆŒ	Ü0DˆÖr   c               ó   € V ^8„  d   QhRR/# rB   r   )r   s   "r   r   rD   U   s   € ÷ %ñ % 4ñ %r   c                	ó¨   € V P                   ;_uu_ 4        V ;P                  ^,          un        RV n        RRR4       R#   + '       g   i     R# ; i)é   N)rI   rN   rO   rU   s   &r   Únote_turn_startedÚ!ReviewIdleQueue.note_turn_startedU   s0   € Ø�Z�Z‹ZØ×Ò Õ!ÕØ $ˆDÔ÷ �Z�ZŠZús   •!A Á A	c               ó   € V ^8„  d   QhRR/# rB   r   )r   s   "r   r   rD   Z   s   € ÷ ñ  Dñ r   c                	ó*  € V P                   ;_uu_ 4        \        ^ V P                  ^,
          4      V n        V P                  ^ 8X  d   V P                  4       V n        RRR4       V P
                  P                  4        R#   + '       g   i     L,; i)é    N)rI   ÚmaxrN   rR   rO   rL   ÚsetrU   s   &r   Únote_turn_finishedÚ"ReviewIdleQueue.note_turn_finishedZ   s^   € Ø�Z�Z‹ZÜ" 1 d×&6Ñ&6¸Õ&:Ó;ˆDÔØ×Ñ 1Ô$Ø$(§I¡I£K�Ô!÷ ð 	�
‰
�‰Ö÷	 �Zús   •A	BÂB	c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r	   r%   r   r4   r   r6   r5   r   rC   r   )r   s   "r   r   rD   a   s.   € ÷ 
qñ 
q˜Sð 
q¨sð 
q¸Nð 
qÈtñ 
qr   c           
     óä  € V P                   ;_uu_ 4        V P                  P                  V4      pVe   VP                  MV P	                  4       p\        WW5\        P                  ! 4       4      V P                  V&   RRR4       V P                  4        V P                  P                  4        \        P                  RVRR \        V P                  4      4       R#   + '       g   i     Li; i)u¦   Add (or replace â€” newest snapshot wins) a session's pending review, keeping the ORIGINAL
enqueue time on coalesce so a busy session cannot push its age-out forever.Nz2Background review deferred (session=%s, queued=%d)éôÿÿÿ)rI   rJ   r   r7   rR   r3   ÚcontextvarsÚcopy_contextÚ_ensure_threadrL   rb   ÚloggerÚinfoÚlen)rV   r%   r4   r6   Úexistingr7   s   &&&&  r   ÚenqueueÚReviewIdleQueue.enqueuea   s­   € ð �Z�Z‹ZØ—}‘}×(Ñ(¨Ó5ˆHØ2:Ò2F˜(×.Ò.ÈDÏIÉIËKˆKÜ)7Ø F¼×9QÒ9QÓ9Só*UˆD�M‰M˜+Ñ&÷ ð
 	×ÑÔØ�
‰
�‰ÔÜ�‰ÐHÈ+ÐVYÐVZÐJ[Ô]`Ðae×anÑanÓ]oÖp÷ �Zús   •A)CÃC/	c               ó   € V ^8„  d   QhRR/# )r	   r   Úintr   )r   s   "r   r   rD   m   s   € ÷ &ñ &˜sñ &r   c                	ó’   € V P                   ;_uu_ 4        \        V P                  4      uuR R R 4       #   + '       g   i     R # ; irF   )rI   rm   rJ   rU   s   &r   Úpending_countÚReviewIdleQueue.pending_countm   s#   € Ø�Z�Z‹ZÜ�t—}‘}Ó%÷ �Z�Z‹Zús	   •5µA	c               ó   € V ^8„  d   QhRR/# rB   r   )r   s   "r   r   rD   q   s   € ÷ %ñ % ñ %r   c                	óH  € V P                   ;_uu_ 4        V P                  e!   V P                  P                  4       '       gC   \        P                  ! V P
                  RRR7      V n        V P                  P                  4        R R R 4       R #   + '       g   i     R # ; i)NTzbg-review-idle-queue)ÚtargetÚdaemonÚname)rI   rM   Úis_aliverG   ÚThreadÚ_runÚstartrU   s   &r   rj   ÚReviewIdleQueue._ensure_threadq   s^   € Ø�Z�Z‹ZØ�|‰|Ò#¨4¯<©<×+@Ñ+@×+BÒ+BÜ(×/Ò/°t·y±yÈÐTjÔk�”Ø—‘×"Ñ"Ô$÷ �Z�ZŠZús   •.BÁABÂB!	c               ó   € V ^8„  d   QhRR/# )r	   r   r   r   )r   s   "r   r   rD   w   s   € ÷ 3ñ 3˜Eñ 3r   c                óþ   € V P                   ;_uu_ 4        V P                  ^ 8”  g   V P                  f    RRR4       R# V P                  4       V P                  ,
          uuRRR4       #   + '       g   i     R# ; i)z>Seconds this process has been turn-free (0 while a turn runs).Ng        )rI   rN   rO   rR   rU   s   &r   Ú
_quiet_forÚReviewIdleQueue._quiet_forw   sP   € à�Z�Z‹ZØ×Ñ !Ô# t×'8Ñ'8Ò'@Ø÷ ‰Zð —9‘9“; ×!2Ñ!2Õ2÷ �Z�Z‹Zús   •!A+Á  A+Á+A<	c               ó   € V ^8„  d   QhRR/# )r	   r   zOptional[_PendingReview]r   )r   s   "r   r   rD   ~   s   € ÷ Bñ BÐ#;ñ Br   c                óh  € V P                   ;_uu_ 4        V P                  '       g    RRR4       R# V P                  4       pV P                  P                  4        Uu. uF@  pWP                  ,
          \        VP                  P                  R4      4      8¼  g   K>  VNKB  	  ppV'       d   \        VR R7      MRpRRR4       Xf2   V P                  4       \        8  g   V P                  4       '       g   R# V P                   ;_uu_ 4        VfD   V P                  '       g    RRR4       R# \        V P                  P                  4       R R7      pV P                  P                  VP                  R4      uuRRR4       # u upi   + '       g   i     LÖ; i  + '       g   i     R# ; i)z@Oldest aged-out item, else the oldest item once quiet+idle hold.Nr
   c                ó   € V P                   # rF   ©r7   ©Úps   &r   Ú<lambda>Ú3ReviewIdleQueue._pop_dispatchable.<locals>.<lambda>†   s   € °·²r   )Úkeyc                ó   € V P                   # rF   r‡   rˆ   s   &r   rŠ   r‹   �   s   € ÀaÇmÂmr   )rI   rJ   rR   Úvaluesr7   r   r6   r   Úminr‚   Ú_IDLE_SETTLE_SrT   Úpopr4   )rV   Únowr‰   ÚagedÚ	candidates   &    r   Ú_pop_dispatchableÚ!ReviewIdleQueue._pop_dispatchable~   s.  € à�Z�Z‹ZØ—=—=�=Ø÷ ‰Zð —)‘)“+ˆCØ#Ÿ}™}×3Ñ3Ô5ó YÑ5˜!ØŸ]™]Õ*¬o¸a¿h¹h¿l¹lÈ:Ó>VÓ.WÑW÷ �AÑ5ˆDð YçBFœ˜DÑ&=Õ>ÈDˆI÷ ð Ò $§/¡/Ó"3´nÔ"DÈD×L]ÑL]×L_ÒL_ÙØ�Z�Z‹ZØÒ Ø—}—}�}Ø÷ ‰Zô   §¡× 4Ñ 4Ó 6Ñ<SÔT�	Ø—=‘=×$Ñ$ Y×%:Ñ%:¸DÓA÷ ŠZùòY÷	 �Zú÷ �ZˆZúsA   •F³,FÁ;FÂFÂ%FÄF Ä'F Ä2AF ÆFÆF	Æ F1	c               ó   € V ^8„  d   QhRR/# rB   r   )r   s   "r   r   rD   �   s   € ÷ -ñ -�dñ -r   c                	ó  €  V P                   P                  4        V P                  ;_uu_ 4        V P                  '       g&   V P                   P	                  4         RRR4       Kg   RRR4       Rp V P                  4       pVe'   VP                  P                  V P                  V4       Te   K³  \        P                  ! \        4       KÏ    + '       g   i     Lo; i  \         d    \        P                  RR R7        LYi ; i)TNzDeferred review dispatch failed)Úexc_info)rL   ÚwaitrI   rJ   Úclearr•   r8   ÚrunÚ	_dispatchr.   rk   ÚwarningrP   ÚsleepÚ_POLL_INTERVAL_S©rV   Úitems   & r   r}   ÚReviewIdleQueue._run�   sÁ   € ØØ�J‰J�O‰OÔØ——“Ø—}—}�}Ø—J‘J×$Ñ$Ô&Ø÷ ‘Ø$÷ ð ˆDðQØ×-Ñ-Ó/�ØÒ#ð —L‘L×$Ñ$ T§^¡^°TÔ:ð Œ|Ü—
’
Ô+Ö,÷ —ûô ô QÜ—‘Ð@È4�ÖPðQús   °.CÁ4:C# ÃC 	Ã#"DÄDc               ó    € V ^8„  d   QhRRRR/# )r	   r¢   r3   r   rC   r   )r   s   "r   r   rD   £   s   € ÷ 	?ñ 	?˜nð 	?°ñ 	?r   c                	ón  € V P                  V4      '       g&   \        P                  R VP                  RR 4       R# \        P                  RVP                  RR V P	                  4       VP
                  ,
          V P                  4       4       VP                  P                  ! R/ VP                  B  R# )zZDeferred background review dropped: reviews were disabled while it was queued (session=%s)NzLDispatching deferred background review (session=%s, waited=%.0fs, queued=%d)rg   r   )
Ú_still_enabledrk   rl   r4   rR   r7   rt   r%   Ú_spawn_background_review_nowr6   r¡   s   &&r   r�   ÚReviewIdleQueue._dispatch£   s�   € Ø×"Ñ" 4×(Ò(Ü�K‰KØlØ× Ñ   Ð&ô(ñ Ü�‰ØZØ×Ñ˜S˜TÐ" D§I¡I£K°$×2BÑ2BÕ$BÀD×DVÑDVÓDXô	Zð 	�
‰
×/Ò/Ñ>°$·+±+Ô>r   c               ó    € V ^8„  d   QhRRRR/# )r	   r¢   r3   r   r&   r   )r   s   "r   r   rD   ¯   s   € ÷ ñ ˜^ð °ñ r   c                óP   €  ^ RI Hp V! 4       ^ ,          #   \         d     R# i ; i)zbRe-check the enabled gate at DISPATCH time (disabling reviews while queued must stick). Fail-open.)Úload_background_review_settingsT)r-   r«   r.   )r¢   r«   s   & r   r¦   ÚReviewIdleQueue._still_enabled®   s*   € ð	ÝOá2Ó4°QÕ7Ð7øÜô 	Úð	ús   ‚ –%¤%)rN   rI   rR   rJ   rO   rT   rM   rL   N)r9   r:   r;   r<   Ú__doc__rW   r\   rc   ro   rt   rj   r‚   r•   r}   r�   Ústaticmethodr¦   r>   r   r   r   r@   r@   G   sN   † ÙBõ	Eõ%õ
õ
qõ&õ%õ3õBõ$-õ&	?ð ôó ôr   r@   c               ó   € V ^8„  d   QhRR/# )r	   r   r&   r   )r   s   "r   r   r   ¹   s   € ÷ ñ ˜dñ r   c                 ó¶  aaaa€  ^ RI Hp  ^ RIHo \        P
                  ! V ! 4       P                  RR7      4      p\        VP                  RR4      4      P                  R^4      ^ ,          oRR	VP                  R
R4       2/oS'       g   R# R VV3R lloS! R4      P                  R. 4       Uu. uF=  pVP                  R4      ;'       g    / P                  R4      R9   g   K4  VR,          NK?  	  pp\        ;QJ d*    VV3R lV 4       F  '       g   K   R'       * # 	  R'       * # ! VV3R lV 4       4      '       * # u upi   \         d     R# i ; i)zcNo processing slot on any loaded model of the managed router; unreachable/no state file reads idle.)Ú
state_path)Úquotez	utf-8-sig)Úencodingr+   Ú z/v1ÚAuthorizationzBearer Úapi_keyTc               ó    € V ^8„  d   QhRRRR/# )r	   Úpathr   r   r   r   )r   s   "r   r   Ú*_managed_server_idle.<locals>.__annotate__Å   s   € ÷ 	,ñ 	,�sð 	,˜sñ 	,r   c                ó"  <€ \         P                  P                  \         P                  P                  S V  2SR 7      ^R7      ;_uu_ 4       p\        P
                  ! VP                  4       4      uuRRR4       #   + '       g   i     R# ; i))Úheaders)ÚtimeoutN)ÚurllibÚrequestÚurlopenÚRequestÚjsonÚloadsÚread)r¸   ÚrÚbaser»   s   & €€r   Ú_getÚ"_managed_server_idle.<locals>._getÅ   s`   ø€ Ü—‘×'Ñ'¬¯©×(>Ñ(>À$ÀÈÀv¸ÐX_Ð(>Ó(`ÐjkÐ'×lÔlÐpqÜ—z’z !§&¡&£(Ó+÷ m×l×lÓlús   Á$A=Á=B	z/modelsÚdataÚstatusr#   Úidc              3  ó¨   <"  € T FG  pS! R S! V4       R24       F.  p\        V\        4      '       g   K  VP                  R4      x € K0  	  KI  	  R# 5i)z/slots?model=z&autoload=falseÚis_processingN)Ú
isinstanceÚdictr   )Ú.0ÚmidÚsrÆ   r²   s   &  €€r   Ú	<genexpr>Ú'_managed_server_idle.<locals>.<genexpr>Ë   sO   øé € ð 
á.4 sÙ˜M©%°«*¨°_ÐEÖF�Ì*ÐUVÔX\×J]ô #ˆA�E‰E�/×"Ð"ÙFñ #«fùs
   ƒ-AµAF)ÚloadedÚready)Ú#hermes_cli.local_runtime.supervisorr±   Úurllib.parser²   rÁ   rÂ   Ú	read_textr   r   ÚrsplitÚanyr.   )r±   ÚstateÚmrÔ   rÆ   rÅ   r»   r²   s       @@@@r   rS   rS   ¹   sB  û€ ðÝBÝ&ä—
’
™:›<×1Ñ1¸;Ð1ÓGÓHˆÜ�5—9‘9˜Z¨Ó,Ó-×4Ñ4°U¸AÓ>¸qÕAˆØ" g¨e¯i©i¸	À2Ó.FÐ-GÐ$HÐIˆßÙ÷	,ñ 	,ñ $(¨	£?×#6Ñ#6°v¸rÔ#Bó RÑ#B˜aØ—e‘e˜H“o×+Ð+¨×0Ñ0°Ó9Ð=PÑPô �!�D—'�'Ñ#Bˆð Rç“3õ 
á.4ó
—3”3ô 
ð 	
’3ô 
ð 	
�3õ 
á.4ó
ó 
ô 
ð 	
ùòRøô ô ÚðúsH   †BE	 Â$E	 Â4EÃEÃ*EÃ7"E	 ÄE	 Ä$E	 Ä-E	 ÅE	 Å	EÅEg      œ@)r­   Ú
__future__r   rh   rÁ   ÚloggingrG   rP   Úurllib.requestr½   Údataclassesr   Útypingr   r   r   r   Ú	getLoggerr9   rk   r�   r    r    r   r   r0   r3   r@   rS   ÚQUEUEr   r   r   Ú<module>rä      s”   ðñ
õ #ã Û Û Û Û Û Ý !ß 0Ó 0à	×	Ò	˜8Ó	$€à€ØÐ Ø Ð õ7õ6õñ" �Ô÷!ð !ó ð!÷oñ oõdñ8 	Ó‚r   