+
    jHàj¯Z  ã                  óø  € R t ^ RIHt ^ RIHtHt ^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHt ^ RIHtHt ]P                   ! ]4      tRsRsRsR R	 ltR
 R 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 R ltR R ltR R ltR R lt R9R  R! llt!R:R"R/R# R$ lllt"R;R% R& llt#]$! 0 R<m4      t%R' R( lt&R=t'R) R* lt(R+ R, lt)R- R. lt*]R>R/ R0 ll4       t+R?R1 R2 llt,R3 R4 lt-R5 t.R6 t/^xt0^t1R7 R8 lt2R# )@ar  Bootstrap for the managed runtime: config -> installed binaries -> running supervised server.

One public call, ``ensure_local_runtime(config)``, safe at any session start: disabled or
already-running -> no-op; enabled -> serve the installed build under a supervisor. Kept
import-light: callers gate on config before importing so disabled sessions never pay the import.
)Úannotations)ÚcontextmanagerÚsuppressN)ÚPath)Úruntimes_root)ÚSPLIT_PART_REÚmodel_id_from_stemFc               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚNone© )Úformats   "ÚG/home/ubuntu/.hermes/hermes-agent/hermes_cli/local_runtime/bootstrap.pyÚ__annotate__r      s   € ÷ 
ñ 
�tñ 
ó    c                 óX   € \         '       g   ^ RIp V P                  \        4       Rs R# R# )a3  The process that boots the server stops it on a clean exit, whatever surface it is (the
desktop backend also stops it in its shutdown handler; the second call is a no-op). Processes
that only adopted another's server never stop it. A hard kill still leaves an orphan, which the
next boot adopts or replaces.NT)Ú_EXIT_HOOKEDÚatexitÚregisterÚshutdown_local_runtime)r   s    r   Ú_stop_at_exitr      s#   € ÷ ‹<Ûà�‰Ô.Ô/ØŠñ	 r   c               ó   € V ^8„  d   QhRR/# )r   r   ú
str | Noner   )r   s   "r   r   r   )   s   € ÷ Hñ H˜Jñ Hr   c                 ó¢   € ^ RI Hp  ^ RIHp V ! 4       pVe(   VP	                  R4      '       d   RVR,          ,           # V! 4       pVR9   d   V# R# )zÇBest-effort GPU vendor for backend selection.

Preserve NVIDIA's detailed name when nvidia-smi is available, then use the
platform host facts so Intel and AMD do not silently demote ``auto`` to CPU.
)Ú_cached_nvidia_gpu_query)Ú	gpu_classNÚgpu_nameznvidia >   ÚamdÚintelÚnvidia)Ú!hermes_cli.local_runtime.hardwarer   Úhermes_platform.host.factsr   Úget)r   r   ÚqueryÚdetecteds       r   Ú_detect_gpu_vendorr'   )   sQ   € õ KÝ4á$Ó&€EØÒ˜UŸY™Y z×2Ò2Ø˜5 Õ,Õ,Ð,Ù‹{€HØÐ#=Ô=ˆ8ÐGÀ4ÐGr   c               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r   s   "r   r   r   9   s   € ÷ 0ñ 0�Dñ 0r   c                 ó*   € ^ RI Hp  V ! 4       R,          # )z°Machine-scoped, deliberately NOT profile-scoped: a 20 GB GGUF is a machine asset, and every
profile shares the one managed server that serves it (same rule as runtimes_root()).©Úget_default_hermes_rootÚmodels)Úhermes_constantsr,   r+   s    r   Ú
models_dirr/   9   s   € õ 9á"Ó$ xÕ/Ð/r   c               ó   € V ^8„  d   QhRR/# r)   r   )r   s   "r   r   r   A   s   € ÷ #ñ #�Dñ #r   c                 ó$   € \        4       R,          # )u¹   Non-model companion files (mmproj projectors, spec-decode drafts). A subdirectory so the
router's model listing â€” and staged_models() â€” never mistakes an asset for a servable model.Úassets)r/   r   r   r   Ú
assets_dirr3   A   s   € ô ‹<˜(Õ"Ð"r   Úrequire_completeTc               ó$   € V ^8„  d   QhRRRRRR/# )r   r/   r   r4   Úboolr   ú
list[Path]r   )r   s   "r   r   r   G   s!   € ÷ ñ ˜$ð °Tð ÀZñ r   c          	     óª  aaa€ \        V P                  R4      4      pV Uu0 uF  q3P                  kK  	  upo. pV EF  p\        P                  ! VP                  4      oSf   VP                  V4       K;  SP                  ^4      R8w  d   KS  VP                  RSP                  4        \        SP                  ^4      4      uopV'       di   \        ;QJ d2    VVV3R l\        ^V^,           4       4       F  '       d   K   RM'	  RM#! VVV3R l\        ^V^,           4       4       4      '       g   Kû  VP                  V4       EK  	  V# u upi )uó   Servable GGUFs in a directory: single files, plus split GGUFs once by their first part.
With ``require_complete`` a split counts only when EVERY part is on disk â€” a mid-download split
is not servable and must not surface anywhere as a model.ú*.ggufNÚ00001c              3  ó`   <"  € T F#  pS R VR RSP                  ^4       R2S9   x € K%  	  R# 5i)Ú-Ú05dz-of-z.ggufN)Úgroup)Ú.0ÚiÚmÚnamesÚstems   & €€€r   Ú	<genexpr>Ústaged_in.<locals>.<genexpr>V   s<   øé € ð 'EÙ0C¨1ð +/¨¨q°°3°°t¸A¿G¹GÀA»J¸<ÀuÐ'MÐQVÖ'VÛ0Cùs   ƒ+.FT)ÚsortedÚglobÚnamer   ÚsearchÚappendr>   ÚstartÚintÚallÚrange)	r/   r4   ÚfilesÚpÚoutÚtotalrA   rB   rC   s	   &$    @@@r   Ú	staged_inrS   G   s  ú€ ô �:—?‘? 8Ó,Ó-€EÙ"Ó#™U˜�VŒV™UÑ#€EØ
€CÜˆÜ× Ò  §¡Ó(ˆØŠ9Ø�J‰J�qŒMÙØ�7‰7�1‹:˜Ô ÙØ—f‘f˜[˜qŸw™w›yÐ)¬3¨q¯w©w°q«z«?ˆˆˆeß§3£3ö 'EÜ05°a¸À½Ô0Có'E§3§3¢3ö 'EÜ05°a¸À½Ô0Có'E÷ $Eô $Eà�J‰J�q�Mñ ð €Jùò $s   ¢Ec               ó   € V ^8„  d   QhRR/# ©r   r   r7   r   )r   s   "r   r   r   \   s   € ÷ )ñ )˜Zñ )r   c            
     ó\  € ^ RI Hp Hp V ! 4       R,          pVP                  4       '       g   . # . p\	        VP                  4       4       EFZ  pVR,          pVP                  P                  R4      '       g%   VP                  4       '       d   V! V4      '       g   KT  V\        4       3VR,          \        4       33 F¡  w  rg\	        VP                  R4      4       F~  pWxP                  ,          p	V	P                  4       '       d   \        P                  RW‰4       KC   VP                  RRR	7       \        P                   ! W‰4       TP'                  T	4       K€  	  K£  	  VR,          V3 F3  p\)        \$        4      ;_uu_ 4        VP+                  4        RRR4       K5  	  EK]  	  V'       d)   \        P-                  R\/        V4      \        4       4       V#   \"         d     EK  \$         d$   p
\        P                  R
Y‡T
4        Rp
?
EK6  Rp
?
ii ; i  + '       g   i     K¾  ; i)a  Move GGUFs left in the old per-profile ``<profile home>/models`` layout (and its assets/)
into the machine-scoped dirs, so everything downstream keeps reading one directory.

``os.rename`` only: within one filesystem it is instant even for a 20 GB model, while
``shutil.move`` silently degrades to a copy across devices. A cross-device profile dir is left
in place with a warning rather than copying tens of GB at session start. A name that already
exists in the destination is left alone (check-then-rename: the only window is two processes
adopting two profiles' same-named file at once, and a same name is the same catalog variant).
Two processes racing on one file are harmless: the loser's rename finds the source gone and
skips it. Returns the new paths of the moved files.)r,   Únamed_profile_has_identityÚprofilesr-   Ú.r2   r9   z,legacy model %s not moved: %s already existsT©ÚparentsÚexist_okz#legacy model %s not moved to %s: %sNz%moved %d legacy model file(s) into %s)r.   r,   rW   Úis_dirrF   ÚiterdirrH   Ú
startswithr/   r3   rG   ÚexistsÚloggerÚwarningÚmkdirÚosÚrenameÚFileNotFoundErrorÚOSErrorrJ   r   ÚrmdirÚinfoÚlen)r,   rW   Úprofiles_rootÚmovedÚhomeÚoldÚsrc_dirÚdest_dirÚsrcÚdestÚexcÚemptieds               r   Úadopt_legacy_modelsru   \   s£  € ÷ Uá+Ó-°
Õ:€MØ×Ñ×!Ò!Øˆ	Ø€EÜ�}×,Ñ,Ó.×/ˆØ�X�oˆØ�9‰9×Ñ ×$Ò$¨C¯J©J¯LªLÑ@ZÐ[_×@`Ò@`ÙØ#&¬
«Ð"5¸¸h½Ì
ËÐ7UÓ!VÑˆGÜ˜gŸl™l¨8Ó4Ö5�Ø§(¡(Õ*�Ø—;‘;—=’=Ü—N‘NÐ#QÐSVÔ]ÙðØ—N‘N¨4¸$�NÔ?Ü—I’I˜cÔ(ð —‘˜TÖ"ó 6ñ "Wð ˜h�¨Ó,ˆGÜœ'×"Õ"Ø—‘”÷ #Ñ"ô -ñ' 0÷, Ü�‰Ð;¼SÀ»ZÌËÔVØ€Løô )ô ÛÜô Ü—N‘NÐ#HÈ#ÐY\Ô]Þûðú÷
 #×"Ð"ús0   Ä )GÆH	ÇH	Ç*H	Ç3H	Ç4H	ÈH	ÈH+c               ó   € V ^8„  d   QhRR/# rU   r   )r   s   "r   r   r   ˆ   s   € ÷ #ñ #�zñ #r   c                 ó(   € \        \        4       4      # )zWServable staged models (continuation parts, incomplete splits and assets/ never count).)rS   r/   r   r   r   Ústaged_modelsrx   ˆ   s   € ä”Z“\Ó"Ð"r   c               ó   € V ^8„  d   QhRR/# )r   r   z	list[str]r   )r   s   "r   r   r   �   s   € ÷ Añ A˜)ñ Ar   c                 óf   € \        4        U u. uF  p \        V P                  4      NK  	  up # u up i ©N)rx   r   rC   )rP   s    r   Ústaged_model_idsr|   �   s&   € Ü0=´Ó@±¨1Ô˜qŸv™vÖ&±Ñ@Ð@ùÒ@s   �.c               ó   € V ^8„  d   QhRR/# ©r   r   r6   r   )r   s   "r   r   r   ‘   s   € ÷ 	ñ 	˜ñ 	r   c                 ó  a€ \        \        4      ;_uu_ 4        ^ RIHp  V ! 4       o\        ;QJ d'    V3R l\        4        4       F  '       g   K   RM	  RM! V3R l\        4        4       4      uuRRR4       #   + '       g   i     R# ; i)u|   True when a staged model has no section in the preset INI â€” it would autoload with stock
fit instead of a policy decision.)Úread_preset_decisionsc              3  óà   <"  € T Fc  pVS9  ;'       gR    SV,          P                   '       * ;'       d2    SV,          P                  ;'       g    / P                  R 4      '       * x € Ke  	  R# 5i)ÚmodelN)ÚrefusalÚkeysr$   )r?   ÚmidÚknowns   & €r   rD   Ú!_presets_stale.<locals>.<genexpr>˜   s]   øé € ð 2Ù0�sð ˜eÑ#×lÐl¨E°#­J×,>Ñ,>Ô(>×(kÐ(kÈÈcÍ
ÏÉ×H]ÐH]Ð[]×GbÑGbÐcjÓGkÔCkÔlÛ0ùs   ƒA.”A.´A.ÁA.TFN)r   Ú	ExceptionÚ hermes_cli.local_runtime.presetsr€   Úanyr|   )r€   r†   s    @r   Ú_presets_staler‹   ‘   s_   ø€ ô 
”)×	Õ	ÝJá%Ó'ˆß‹sô 2Ü.Ô0ó2�s�sŠsô 2Ü.Ô0ó2ó 2÷	 
×	×	Ñ	ñ ús   ™5A;ÁA;Á;B	c               ó   € V ^8„  d   QhRR/# r
   r   )r   s   "r   r   r   �   s   € ÷ `ñ `˜Dñ `r   c                 óŒ  € ^ RI Hp HpHpHpHp ^ RIHp V! 4       pV! V4      '       d?   V ! V4      '       g(   \        P                  RVP                  R4      4       R# V! V4      pMV! V4      pVf   R#  VP                  VRR7       R#   \         d-   p\        P                  RTP                  T4        Rp?R# Rp?ii ; i)	ur  Stop the server the state file points at before this process boots a replacement, but only
an orphan (recorded owner gone): a live owner's watchdog would respawn its router, so that one
is left running and the replacement boots beside it, as it always has. The process comes from
the identity-guarded reader, never a bare PID â€” the endpoint dict callers hold has none.)Ú_owner_is_deadÚ	is_modernÚlegacy_recorded_processÚ
read_stateÚrecorded_process©ÚLlamaServerSupervisorz@llama-server pid=%s belongs to a live Hermes process; leaving itÚpidNT)Úverified_rootz6could not stop the incumbent llama-server (pid=%s): %s)Ú!hermes_cli.local_runtime.recoveryrŽ   r�   r�   r‘   r’   Ú#hermes_cli.local_runtime.supervisorr”   ra   ri   r$   Ú_terminate_treerˆ   rb   r•   )	rŽ   r�   r�   r‘   r’   r”   ÚstateÚprocrs   s	            r   Ú_stop_state_serverrœ   �   s±   € ÷
õ õ Já‹L€EÙ�×ÒÙ˜e×$Ò$Ü�K‰KÐZÐ\a×\eÑ\eÐfkÓ\lÔmÙÙ Ó&‰á& uÓ-ˆØ‚|Ùð`à×-Ñ-¨dÀ$Ð-ÖGøÜô `Ü�‰ÐOÐQU×QYÑQYÐ[^×_Ò_ûð`ús   Á7B ÂCÂ!B>Â>Cc               ó   € V ^8„  d   QhRR/# r~   r   )r   s   "r   r   r   ¼   s   € ÷ ñ ˜tñ r   c                 óö   €  ^ RI Hp  \        f   ^ RIHp V! 4       pVf   R# \        4        M
\        4        \        V ! 4       RR7      RJ#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)a   Restart the managed server so it rescans the models directory. The router's model list is
SPAWN-ONLY: a GGUF added after start is invisible to GET /models and 400s on completion, so
anything that changes the staged set while the server runs must bounce it.)Úload_configN©Ú_state_endpointFT)Úforcez local runtime refresh failed: %s)Úhermes_cli.configrŸ   Ú_SUPERVISORÚ!hermes_cli.local_runtime.endpointr¡   rœ   r   Úensure_local_runtimerˆ   ra   rb   )rŸ   r¡   rš   rs   s       r   Úrefresh_local_runtimer§   ¼   se   € ð
Ý1äÒÝIá#Ó%ˆEØŠ}ÙÜÕ ä"Ô$Ü#¡K£M¸Ô>ÀdÐJÐJøÜô Ü�‰Ð9¸3Ô?Ýûðús   ‚A £(A ÁA8ÁA3Á3A8c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úmdirr   Ú
configuredrL   Ú
engine_tagr   r   r   )r   s   "r   r   r   Ó   s)   € ÷ ñ ˜tð °ð À*ð ÐX[ñ r   c                ó  €  ^ RI Hp ^ RIHp V! RR7      pVP                  '       d   \        V4      MRpV! WWVR7      pYq8w  d   \        P                  RYq4       T#   \         d#   p\        P                  RY�4       Tu Rp?# Rp?ii ; i)	uÈ  Residency cap to hand the router: derived from the hardware budget, ``models_max`` as a ceiling.

A cap of "four" on a card that holds one model is how a second child ends up paged (WDDM) and
silently slow â€” llama.cpp evicts its LRU before an incoming load only when the cap says the
card is full. A probe miss or an unpriceable model keeps the configured count: this must never
block a boot. On Windows unified memory, free commit bounds the count too.
©Úprobe_budget)Úadmitted_residency_countT©ÚplanningN)Úliver«   z4residency cap probe failed (%s); using models_max=%sz@residency cap: %s resident model(s) on this card (models_max=%s))
r"   r®   r‰   r¯   ÚumaÚ_launch_budgetrˆ   ra   rb   ri   )	r©   rª   r«   r®   r¯   Úcapacityr²   Úcaprs   s	   &&&      r   Ú_admitted_models_maxr·   Ó   s€   € ð	ÝBÝMá¨Ô.ˆØ+3¯<¯<¨<Œ~˜hÔ'¸TˆÙ& t°zÐYcÔdˆð ÔÜ�‰ÐVØô	%à€Jøô ô Ü�‰ÐMÈsÔ_ØÕûðús"   ‚&A ©A ÁBÁ*BÂBÂBr«   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   r©   r   Úpreset_pathÚ	residentsrL   r«   r   r   zPath | Noner   )r   s   "r   r   r   ë   s1   € ÷ $ñ $˜Dð $¨tð $Àð $Ø",ð$Ø8Cñ$r   c          	     ó–  € ^ RI Hp ^ RIHp  V! RR7      pV! WV\	        V4      W#R7       F7  pVP
                  '       g   K  \        P                  RVP
                  4       K9  	  V#   \         dU   pTP                  4       '       d   \        P                  RT4       Tu Rp?# \        P                  R	T4        Rp?R# Rp?ii ; i)
u„  Write the launch-policy INI for every staged model; returns the path to hand the router.

Priced against CAPACITY, not live free VRAM: this runs while the outgoing server instance may
still hold the card (restart, refresh after a download), and its memory is freed before the new
instance loads anything. Pricing against live-free once pinned a fitting model's weights to CPU.

The window is then narrowed to what fits beside other programs' GPU memory
(``hardware.launch_budget``), which never moves weights to the CPU.

Degradation ladder on failure: a STALE policy still beats no policy â€” stock fit (f16 KV at max
context, no placement) is the silent-busy-wait failure on Windows. Keep serving with the
previous INI when one exists; only a first boot with no INI at all falls to stock fit.
``residents`` is the router's model count, which splits the prompt-cache room on Windows
unified memory.
r­   )Úgenerate_presetsTr°   ©r²   rº   r«   z"model refused by physics check: %su¡   preset generation failed (%s); serving with the PREVIOUS launch policies â€” models staged since the last successful generation run unpoliced until this is fixedNzWpreset generation failed (%s) and no previous policy file exists; router runs stock fit)r"   r®   r‰   r¼   r´   rƒ   ra   rb   rˆ   r`   Úerror)	r©   r¹   rº   r«   r®   r¼   rµ   Úentryrs   s	   &&&$     r   Ú_generate_presetsrÀ   ë   s³   € õ" ?ÝAðÙ¨Ô.ˆÙ% d°kÌÐW_ÓH`Ø09÷RˆEà�}�}Š}Ü—‘ÐCÀUÇ]Á]ÖSñRð ÐøÜô 	Ø×Ñ×ÒÜ�L‰Lð /ð 14ô5ð ÕÜ�‰ð AØBEô	Gåûð	ús)   Ž0A) Á%A) Á)CÁ4-CÂ!CÂ'CÃCc               ó   € V ^8„  d   QhRR/# )r   Ú	own_bytesrL   r   )r   s   "r   r   r     s   € ÷ ñ ¨ñ r   c                ó€   € ^ RI Hp  V! WR7      #   \         d"   p\        P	                  RT4        Rp?R# Rp?ii ; i)zS``hardware.launch_budget``, or None when the probe fails: a boot never waits on it.)Úlaunch_budget)rÂ   z>free GPU memory probe failed (%s); launch windows use capacityN)r"   rÄ   rˆ   ra   rb   )rµ   rÂ   rÄ   rs   s   &&  r   r´   r´     s8   € å?ðÙ˜XÔ;Ð;øÜô Ü�‰ÐWÐY\Ô]Ýûðús   ˆ ‘=œ8¸=c               ó   € V ^8„  d   QhRR/# r~   r   )r   s   "r   r   r   "  s   € ÷ &ñ &˜tñ &r   c           
     óª  € ^ RI Hp ^ RIHpHp V P
                  pVe(   VP                  4       '       d   \        V 4      '       d   R# V! RR7      p\        V4      pVf   R# V P                  pVe(   \        VP                  V,
          4      \        8  d   R# T! T! \        4       YVV P                  \        e   \        P                   MRR7      4      pV P"                  ;_uu_ 4        V P$                  e.   V P$                  P'                  4       f   \        V 4      '       d    RRR4       R# VP                  V n	        W„P)                  RR	7      8X  d    RRR4       R# ^ R
IHp	 V	! WHRVP.                   R2RR7       V P1                  4        RRR4       \2        P5                  RVP                  R,          4       R#   + '       g   i     L9; i)aÇ  Re-plan launch windows against free GPU memory while no model is loaded.

Boot plans every window once, but models load later (on demand, after an idle unload), and by
then other programs may hold more or less of the card. Returns True when the router was given
new presets. A request that starts a load between the last status check and the reload is
unloaded by the router and fails once; that gap is a few milliseconds, and only when a window
changes.
r­   )Úplan_presetsÚrender_presetsNFTr°   r½   z	utf-8-sig)Úencoding)Úatomic_write_textrY   Ú_é€  )Ú
tmp_prefixÚmodez9launch windows re-planned for %.1f GiB of free GPU memoryi   @)r"   r®   r‰   rÇ   rÈ   r¹   r`   Ú_any_holds_memoryr´   Ú_refit_usableÚabsÚusable_vram_bytesÚ_REFIT_STEP_BYTESr/   Ú
models_maxÚ_SERVING_ENGINEÚtagÚ_lifecycle_lockr›   ÚpollÚ	read_textÚutilsrÊ   rH   Úreload_presetsra   ri   )
Úsupr®   rÇ   rÈ   Úpathrµ   r²   ÚlastÚtextrÊ   s
   &         r   Úrefit_idle_presetsrà   "  so  € õ ?ßMà�?‰?€DØ‚|˜4Ÿ;™;Ÿ=š=Ô,=¸c×,BÒ,BÙÙ TÔ*€HÜ˜(Ó#€DØ‚|ÙØ×Ñ€DØÒœC × 6Ñ 6¸Õ =Ó>ÔARÔRÙÙ™,¤z£|°XÐTW×TbÑTbÜIXÒId´/×2EÒ2EÐjnôpó q€Dð 
×	×	Ó	Ø�8‰8Ò˜sŸx™xŸ}™}›Ò:Ô>OÐPS×>TÒ>TØ÷ 
Ñ	ð !×2Ñ2ˆÔØ—>‘>¨;�>Ó7Ô7Ø÷ 
Ñ	õ 	,á˜$°1°T·Y±Y°K¸qÐ1AÈÕNØ×ÑÔ÷ 
ô ‡K�KÐKØ×&Ñ&¨'Õ2ô4á÷ 
×	ús   Ã)=GÄ0(GÅ"/GÇG	c               ó   € V ^8„  d   QhRR/# r~   r   )r   s   "r   r   r   P  s   € ÷ Wñ W˜dñ Wr   c                óâ   € \         ;QJ d:    R  V P                  ^R7      P                  4        4       F  '       g   K   R# 	  R# ! R  V P                  ^R7      P                  4        4       4      # )c              3  ó2   "  € T F  q\         9   x € K  	  R # 5ir{   )Ú_HOLDS_MEMORY)r?   Ústatuss   & r   rD   Ú$_any_holds_memory.<locals>.<genexpr>Q  s   é € ÐVÑ5U¨6œÖ&Ó5Uùs   ‚)Ú	timeout_sTF)rŠ   r-   Úvalues)rÜ   s   &r   rÏ   rÏ   P  sS   € ß‹3ÑV°S·Z±ZÈ!°ZÓ5L×5SÑ5SÔ5UÓV�3Œ3ÐVŠ3ÐVˆ3ÑV°S·Z±ZÈ!°ZÓ5L×5SÑ5SÔ5UÓVÓVÐVr   c               ó    € V ^8„  d   QhRRRR/# )r   ÚfdrL   r   r6   r   )r   s   "r   r   r   T  s   € ÷ ñ ˜#ð  $ñ r   c                óä  € \         P                  R8X  d†   ^ RIp\         P                  ! V 4      P                  ^ 8X  d   \         P
                  ! V R4       \         P                  ! V ^ \         P                  4        VP                  WP                  ^4       R# ^ RIp VP                  WP                  VP                  ,          4       R#   \         d     R# i ; i  \         d     R# i ; i)z=Non-blocking exclusive attempt; portable across fcntl/msvcrt.ÚntNó    TF)rd   rH   ÚmsvcrtÚfstatÚst_sizeÚwriteÚlseekÚSEEK_SETÚlockingÚLK_NBLCKrg   ÚfcntlÚflockÚLOCK_EXÚLOCK_NB©rê   rî   rö   s   &  r   Ú_try_lock_boot_fdrû   T  s¯   € ä	‡w�w�$„Ûä�8Š8�B‹<×Ñ 1Ô$Ü�HŠH�R˜ÔÜ
�Š��QœŸ™Ô$ð	Ø�N‰N˜2Ÿ™°Ô2Ùó 	ð	Ø�K‰K˜ŸM™M¨E¯M©MÕ9Ô:Ùøô ô 	Úð	ûô ô 	Úð	ús$   Á=C Â ,C  ÃCÃCÃ C/Ã.C/c               ó    € V ^8„  d   QhRRRR/# )r   rê   rL   r   r   r   )r   s   "r   r   r   k  s   € ÷ 	'ñ 	'˜ð 	' ñ 	'r   c                óþ   € \         P                  R 8X  dI   ^ RIp\         P                  ! V ^ \         P                  4       VP                  WP                  ^4       R# ^ RIpVP                  WP                  4       R# )rì   N)
rd   rH   rî   rò   ró   rô   ÚLK_UNLCKrö   r÷   ÚLOCK_UNrú   s   &  r   Ú_unlock_boot_fdr   k  sI   € Ü	‡w�w�$„Ûä
�Š��QœŸ™Ô$Ø�‰�rŸ?™?¨AÖ.ãà�‰�BŸ™Ö&r   c               ó   € V ^8„  d   QhRR/# )r   rç   Úfloatr   )r   s   "r   r   r   x  s   € ÷ ñ ¨ñ r   c           	   #  ó¤  "  € \        4       R,          p VP                  P                  RRR7       \        P                  ! V\        P
                  \        P                  ,          R4      p \        P                  ! 4       T ,           p\        T4      '       gJ   \        P                  ! 4       T8¼  d   \        P                  RT 4       M\        P                  ! R4       KZ   Rx € \        \        4      ;_uu_ 4        \        T4       RRR4       \        P                   ! T4       R#   \         d&   p\        P                  RT4       Rx €  Rp?R# Rp?ii ; i  + '       g   i     L[; i  \        \        4      ;_uu_ 4        \        T4       RRR4       i   + '       g   i     i ; i; i  \        P                   ! T4       i ; i5i)	u­  Serialize the state-check-then-spawn sequence across every Hermes process on this
machine â€” the ``_SUPERVISOR`` singleton above only rules out a race within ONE process.
Two profiles booting in the same second each see no ``server.json`` yet and each spawn a
router on the stable port (#116682); an OS-held lock makes the second caller wait for the
first to publish its state file, so it re-checks and adopts instead of spawning a duplicate.
Bounded, not indefinite: never hang session start dead if the lock is somehow stuck, and
never raise into session start: an unwritable runtimes dir (or a foreign-owned lock file)
proceeds unlocked with a warning, like the contention timeout.z	boot.lockTrZ   rÌ   z1boot lock unavailable (%s); proceeding without itNz5boot lock contended past %.0fs; proceeding without itgš™™™™™É?)r   Úparentrc   rd   ÚopenÚO_CREATÚO_RDWRrg   ra   rb   ÚtimeÚ	monotonicrû   Úsleepr   r   Úclose)rç   rÝ   rê   rs   Údeadlines   &    r   Ú_cross_process_boot_lockr  w  s'  é € ô ‹?˜[Õ(€DðØ�‰×Ñ $°ÐÔ6Ü�WŠW�Tœ2Ÿ:™:¬¯	©	Õ1°5Ó9ˆð
Ü—>’>Ó# iÕ/ˆÜ# B×'Ò'Ü�~Š~Ó 8Ô+Ü—‘ÐVÐXaÔbØÜ�JŠJ�sŽOð	$Ûäœ'×"Õ"Ü Ô#÷ #ô 	�Š�Žøô# ô Ü�‰ÐJÈCÔPÛÝûðú÷ #×"û”œ'×"Õ"Ü Ô#÷ #×"×"Ð"þô 	�Š��üsŠ   ‚G•AD, Á.A6F5 Ã%E2 Ã)F5 Ä EÄF5 ÄGÄ,EÄ7EÅGÅEÅGÅE/	Å*F5 Å2F2Æ
F	Æ	F2ÆF/Æ*F2Æ2F5 Æ5GÇGc               ó$   € V ^8„  d   QhRRRRRR/# )r   ÚconfigÚdictr¢   r6   r   zobject | Noner   )r   s   "r   r   r   ™  s&   € ÷ Mñ M ð M¨dð M¸}ñ Mr   c                óh  € T ;'       g    / P                  R4      ;'       g    / pV'       g   VP                  R4      '       g   R# \        e   \        #  \        4        V'       g(   \        4       '       g   \        P                  R4       R# ^ RIH	p \        4       ;_uu_ 4        V! 4       pVeP   \        4       '       g!   \        P                  R4        RRR4       R# \        P                  R4       \        4         ^ R	IHp ^ R
IHp V! VP                  RR4      4      pVf!   \        P                  R4        RRR4       R# Vs\%        4       p	V	P'                  RRR7       \)        V	\+        VP                  R^4      4      VP,                  4      p
\/        V	\1        4       R,          V
VP,                  R7      pT! VP2                  Y›T
\+        VP                  R^ 4      4      ;'       g    RR7      p VP5                  4        Ts\=        4        \        P                  RTP>                  TP@                  TP,                  4       \C        T4       TuuRRR4       #   \         d"   p\        P                  RT4        Rp?EL,Rp?ii ; i  \6         dF    \9        \6        4      ;_uu_ 4        TP;                  4        RRR4       h   + '       g   i     h ; ii ; i  \6         d,   pRs\        P                  RT4        Rp?RRR4       R# Rp?ii ; i  + '       g   i     R# ; i)uÐ   Idempotent boot of the managed runtime. Returns the supervisor (or None when
disabled/unavailable). Never raises into a session start â€” failures log and return None; chat
falls back to configured providers.Úlocal_runtimeÚenabledNz legacy model adoption failed: %sz7local runtime enabled but no models staged; not bootingr    z6managed llama-server already running (another process)zfrunning server's presets predate the staged models; replacing it so every model launches with a policy)Úinstalled_enginer“   ÚbackendÚautozKlocal runtime enabled but no PM engine installed; use the Local Models paneTrZ   rÔ   zpresets.ini)r«   Úport)r¹   rÔ   r  z1managed llama-server up at %s (backend=%s tag=%s)z%managed local runtime unavailable: %s)"r$   r¤   ru   rg   ra   rb   rx   ri   r¥   r¡   r  r‹   rœ   Ú!hermes_cli.local_runtime.binariesr  r˜   r”   rÕ   r/   rc   r·   rL   rÖ   rÀ   r   ÚbinaryrK   rˆ   r   Ústopr   Úbase_urlr  Ú_start_idle_sweeper)r  r¢   Úsectionrs   r¡   rš   r  r”   Úenginer©   rÔ   r¹   rÜ   s   &&           r   r¦   r¦   ™  s‰  € ð
 �|ˆ|˜× Ñ  Ó1×7Ð7°R€Gß˜Ÿ™ Y×/Ò/ÙÜÒÜÐð@ÜÔ÷
 œŸšÜ�‰ÐMÔNÙõ Bä	!×	#Õ	#ÙÓ!ˆØÒÜ!×#Ò#Ü—‘ÐTÔUØ÷ 
$Ñ	#ô �K‰Kð Mô NäÔ ð#	ÝJÝQá% g§k¡k°)¸VÓ&DÓEˆFØŠ~Ü—‘ÐiÔjØ÷# 
$Ñ	#ð$ %ˆOä“<ˆDØ�J‰J˜t¨dˆJÔ3Ü-¨d´C¸¿¹ÀLÐRSÓ8TÓ4UÐW]×WaÑWaÓbˆJÜ+¨D´-³/ÀMÕ2QÐS]Ø7=·z±zôCˆKñ (¨¯©°tØ3=Ü-0°·±¸VÀQÓ1GÓ-H×-PÐ-PÈDôRˆCðØ—	‘	”ð ˆKÜŒOÜ�K‰KÐKÈSÏ\É\Ð[a×[iÑ[iÐkq×kuÑkuÔvÜ Ô$Ø÷S 
$Ò	#øô' ô @Ü�‰Ð9¸3×?Ò?ûð@ûôd ô ô œi×(Õ(Ø—H‘H”J÷ )à÷ )Ö(àúðûô ô 	Ø"ˆOÜ�N‰NÐBÀCÔHÛ÷[ 
$Ñ	#ûðT	ú÷U 
$×	#Ð	#ús†   Á
I% Â'2L Ã#L Ä=K'ÅB0K'Ç<JÈAK'É%JÉ0JÊJÊ"K$Ê6KË	K$ËK Ë	K$Ë$K'Ë'LË2LÌ
L ÌLÌL Ì L1	c               ó   € V ^8„  d   QhRR/# r
   r   )r   s   "r   r   r   é  s   € ÷ ñ  ñ r   c                 óF   € \         e   \         P                  4        R s R sR # r{   )r¤   r  rÕ   r   r   r   r   r   é  s   € äÒÜ×ÑÔØˆØ‚Or   c                 ó   € \         # )un   The process-local supervisor, or None (a server may still run under another process â€”
check the state file).)r¤   r   r   r   Úget_supervisorr"  ñ  s
   € ô Ðr   c                 ó   € \         # )zSThe engine the process-local server runs or is booting, or None when there is none.)rÕ   r   r   r   Úserving_enginer$  ÷  s   € äÐr   c               ó   € V ^8„  d   QhRR/# r
   r   )r   s   "r   r   r      s   € ÷ Yñ Y ñ Yr   c                ó`   a € ^ RI pV 3R lpVP                  VRRR7      P                  4        R# )u  Idle-residency loop: every couple of minutes, unload models idle past the supervisor's
threshold; every 30 s with nothing loaded, re-plan launch windows against free GPU memory.
Daemon thread tied to the supervisor's lifetime â€” exits when the server stops.Nc                 ó*  <€ \         P                  ! 4       p SP                  e’   SP                  P                  4       ft   \         P                  ! \
        4       \         P                  ! 4       V ,
          \        8¼  d'   \         P                  ! 4       p  SP                  4         \        S4       K�  R # R #   \         d!   p\        P                  RT4        R p?L8R p?ii ; i  \         d"   p\        P                  RT4        R p?Kö  R p?ii ; i)Nzidle sweep skipped: %sz!launch window re-plan skipped: %s)r  r	  r›   rØ   r
  Ú_REFIT_EVERY_SÚ_SWEEP_EVERY_SÚ
sweep_idlerˆ   ra   Údebugrà   )Ú
last_sweeprs   rÜ   s     €r   Ú_loopÚ"_start_idle_sweeper.<locals>._loop  sÅ   ø€ Ü—^’^Ó%ˆ
Ø�h‰hÒ" s§x¡x§}¡}£Ò'>Ü�JŠJ”~Ô&Ü�~Š~Ó *Õ,´Ô>Ü!Ÿ^š^Ó-�
ð@Ø—N‘NÔ$ðGÜ" 3Ö'ñ (?Ñ"øô !ô @Ü—L‘LÐ!9¸3×?Ñ?ûð@ûô ô GÜ—‘Ð@À#×FÒFûðGús0   ÂB8 Â'C& Â8C#ÃCÃC#Ã&DÃ1DÄDTzlocal-runtime-idle-sweep)ÚtargetÚdaemonrH   )Ú	threadingÚThreadrK   )rÜ   r1  r-  s   f  r   r  r     s/   ø€ ó õGð ×Ñ˜E¨$Ð5OÐÓP×VÑVÖXr   r{   )é   )é    >   ÚreadyÚloadedÚloadingÚsleepingi   )g     @`@)F)3Ú__doc__Ú
__future__r   Ú
contextlibr   r   Úloggingrd   r  Úpathlibr   r  r   Úhermes_cli.local_runtime.ggufr   r   Ú	getLoggerÚ__name__ra   r¤   rÕ   r   r   r'   r/   r3   rS   ru   rx   r|   r‹   rœ   r§   r·   rÀ   r´   Ú	frozenseträ   rà   rÓ   rÏ   rû   r   r  r¦   r   r"  r$  r)  r(  r  r   r   r   Ú<module>rB     s  ðñõ #ç /Û Û 	Û Ý å ;ß Kà	×	Ò	˜8Ó	$€à€ð €Ø€õ
õHõ 0õ#ð¸D÷ õ*)õX#õ
Aõ	õ`õ>÷.ñ0$Ø/3÷$ð $÷Nñ ÒDÓE€õ&ðV Ð õWõõ.	'ð öó ð÷BMõ`òòð
 €Ø€÷Yr   