+
    lHàjÂM  ã                  ó  € R t ^ RIHt ^ RIt^ RIHt ^RIHt R R ltR R lt	R	 t
R
 R ltR!tR R ltR R ltR R lt ! R R]4      t ! R R]4      t]P&                  R R l4       tR"R R lltRRRR/R R lltR R  ltR# )#a  Live compression: config hot-reload onto a running agent, pending model switch apply, /compress
(CompressionLockHeld when a turn holds the lock), session-key sync after compress. Bodies are rebound
onto server.py's globals (method_ctx.bind_module) and reference them bare.)ÚannotationsN)Úis_truthy_value)Úbind_modulec               ó    € V ^8„  d   QhRRRR/# )é   Úcfgúdict | NoneÚreturnÚtuple© )Úformats   "ÚD/home/ubuntu/.hermes/hermes-agent/tui_gateway/session_compression.pyÚ__annotate__r      s   € ÷ )ñ )¨;ð )¸5ñ )ó    c           	     ó  € ^ RI Hp VP                  V 4      pVP                  4        UUu/ uF'  w  r4VP	                  R4      '       g
   VR8X  g   K%  W4bK)  	  ppp\        V \        4      '       d7   \        V P                  R4      \        4      '       d   V P                  R4      M/ pTP                  R Uu/ uF  pRV 2VP                  V4      bK  	  up4       \        \        VP                  4       4      4      # u uppi u upi )zºStable snapshot of compression/context keys that must apply next turn: the messaging-gateway
cache-busting extract plus ``idle_compact_after_seconds``/``tail_mode`` (live-TUI-only keys).)ÚGatewayRunnerzcompression.zmodel.context_lengthÚcompression)Úidle_compact_after_secondsÚ	tail_mode)Úgateway.runr   Ú_extract_cache_busting_configÚitemsÚ
startswithÚ
isinstanceÚdictÚgetÚupdater
   Úsorted)r   r   ÚkeysÚkÚvÚpickedr   s   &      r   Ú!_tui_compression_config_signaturer"      sÖ   € õ *Ø×6Ñ6°sÓ;€DØ#Ÿz™zœ|Ôk™|‘t�q¨q¯|©|¸N×/KÒ/KÈqÐTjÑOjŒdˆaŠd™|€FÑkÜ,6°s¼D×,AÒ,AÄjÐQT×QXÑQXÐYfÓQgÔim×FnÒFn�#—'‘'˜-Ô(Ðtv€KØ
‡M�MÑCnÓoÑCn¸a�\ ! Ð% {§¡°qÓ'9Ò9ÑCnÑoÔpÜ”˜Ÿ™›Ó'Ó(Ð(ùó lùâos   «"C?ÁC?Â8Dc               ó$   € V ^8„  d   QhRRRRRR/# )r   ÚnameÚstrÚfallbackÚAnyr	   r   )r   s   "r   r   r      s!   € ÷ ñ  3ð °#ð ¸#ñ r   c                óä   €  ^ RI p^ RIHp VP                  VP                  4      P
                  V ,          P                  pWBP                  P                  J d   V# T#   \         d    Tu # i ; i)u�  Default read off ContextCompressor.__init__'s REAL signature, so unset-key restoration uses the
construction path's derivation instead of a hardcoded copy that could drift.

Unset restoration must go through the same derivation the construction path uses (#94724 review finding
on #95980) â€” pulling the default off ``ContextCompressor.__init__`` itself instead of hardcoding copies
keeps the two from drifting.
N)ÚContextCompressor)
ÚinspectÚagent.context_compressorr)   Ú	signatureÚ__init__Ú
parametersÚdefaultÚ	ParameterÚemptyÚ	Exception)r$   r&   r*   r)   r/   s   &&   r   Ú_compressor_ctor_defaultr3      se   € ðÛÝ>Ø×#Ñ#Ð$5×$>Ñ$>Ó?×JÑJÈ4ÕP×XÑXˆØ"×&7Ñ&7×&=Ñ&=Ó=ˆxÐJÀ7ÐJøÜô ØŠðús   ‚AA ÁA ÁA/Á.A/c                 ób   € ^ RI Hp  V P                  R4      ;'       g    / P                  R4      # )uÈ  The cap a fresh agent build installs when the key is absent: DEFAULT_CONFIG's
``compression.threshold_tokens``. agent_init reads the MERGED config, so "no key in
config.yaml" installs that default at construction; key removal here must restore the
same value, or a live session would diverge from a rebuilt one after the first turn
(#117093). An explicit ``threshold_tokens: null`` stays ratio-only â€” the key is present,
so ``.get`` returns it untouched.©ÚDEFAULT_CONFIGr   Úthreshold_tokens)Úhermes_cli.config_defaultsr6   r   r5   s    r   Ú_default_threshold_tokens_capr9   *   s,   € õ :à×Ñ˜}Ó-×3Ð3°×8Ñ8Ð9KÓLÐLr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úagentr'   r   r   r	   Úfloatr   )r   s   "r   r   r   6   s!   € ÷ ñ ¨cð Àð Èñ r   c           	     ó°  €  \        \        RR4      4      p ^ RIHp ^ RIHpHpH	p \        V RR4      ;'       g    R\        V RR4      ;'       g    Rr‡\        VP                  RR	4      4      P                  4       R9   p	T! Y$! WxV	R
7      Yu! Wx4      ;'       g	    V! Wx4      R7      w  r*V#   \        \        3 d    Rp L«i ; i  \         d     T# i ; i)u  Default compaction threshold when ``compression.threshold`` is unset. Mirrors agent_init: ctor
global default, then per-model resolution (Codex autoraise etc.) via the SAME
``_resolve_compression_threshold`` â€” removing the key restores the model-derived value.Úthreshold_percentg      à?)Ú_resolve_compression_threshold)Ú _compression_threshold_for_modelÚ_is_codex_gpt54_or_gpt55Ú_is_codex_sparkÚmodelÚ ÚproviderÚcodex_gpt55_autoraiseT)Úallow_codex_gpt55_autoraise)rC   Úis_codex_autoraise>   Ú1ÚyesÚtrue)r<   r3   Ú	TypeErrorÚ
ValueErrorÚagent.agent_initr?   Úagent.auxiliary_clientr@   rA   rB   Úgetattrr%   r   Úlowerr2   )r;   r   Úpctr?   r@   rA   rB   rC   rE   Úautoraise_enabledÚ_notices   &&         r   Ú"_derived_default_threshold_percentrU   6   sç   € ðÜÔ,Ð-@À$ÓGÓHˆð
ÝCßvÑvÜ! %¨°"Ó5×;Ð;¸¼WÀUÈJÐXZÓ=[×=aÐ=aÐ_aˆxÜ §¡Ð0GÈÓ NÓO×UÑUÓWÐ[oÑoÐÙ5ØÐ1°%Ð_pÔqØÐ,DÀUÓ,U×,yÐ,yÑYhÐinÓYyô
‰ˆð €Jøô ”zÐ"ô ØŠðûô ô ØØ€Jðús.   ‚B- ˜#C ¼C ÁAC Â-CÃCÃCÃCc               ó$   € V ^8„  d   QhRRRRRR/# )r   r;   r'   r   r   r	   ÚNoner   )r   s   "r   r   r   V   s&   € ÷ U8ñ U8¨#ð U8°Kð U8ÀDñ U8r   c                ó\  € \        V\        4      '       d   TM/ p\        VP                  R4      \        4      '       d   VP                  R4      M/ p^ RIHpHp VP                  RR4      p\        V\        4      '       d   TM\        V4      P                  4       R9   V n	        \        VP                  RR4      4      V n        VP                  RR4      p \        V\        4      '       g   \        V4      ;p^ 8:  d   \        h Wpn        \$        P&                  ! \        \        4      ;_uu_ 4        \)        ^ \        VP                  R
^ 4      ;'       g    ^ 4      4      V n        RRR4       \-        V RR4      pVf   R# \        \/        RR4      4      p	\        VP                  RV	4      ;'       g    T	4      P1                  4       P                  4       p
V
R9   d   T
MT	Vn        \4         F  w  r¼p\        \/        W¼4      4      pVP                  W¾4      p\$        P&                  ! \        \        4      ;_uu_ 4        \7        Y‹\)        Yßf   TM
\        V4      4      4       RRR4       K�  	  \$        P&                  ! \        \        4      ;_uu_ 4        VP                  R\/        RR4      4      p\)        R\9        \;        V4      R4      4      Vn        RRR4       VP                  R4      p\        V\        4      '       do   VP?                  4        UUu/ uFQ  w  pp\        V\        \:        34      '       g   K$  \        V\        4      '       d   K<  \        V4      \;        V4      bKS  	  uppM/ Tn         ^ RI!H"p RpRV9   dC   \$        P&                  ! \        \        4      ;_uu_ 4        \;        VR,          4      pRRR4       Vf   \G        W4      pV;Vn$        Vn%        T! \-        V RR4      ;'       g    RVP@                  T\-        V RR4      ;'       g    R4      ;pVn&         VPO                  VPP                  V4      Vn)        V! W4      pVe=   V! V V4       \$        P&                  ! \T        4      ;_uu_ 4        VVn(        RRR4       M\-        VRR4      e   V! V R4       RVn+        VPY                  VP                  R\[        4       4      4      Vn.        R;Vn/        Vn0        R#   \        \        3 d    \        P!                  R	T4       Rp ELi ; i  + '       g   i     ELÊ; i  + '       g   i     EK`  ; i  + '       g   i     EL�; iu uppi   + '       g   i     EL®; i  \T         d    TTn)         ELAi ; i  + '       g   i     Lî; i)u   Update a live session's compressor in place from config.yaml. Every adopted key has UNSET semantics:
a removed key restores the normalized default (or model-derived value) through the construction
path's own derivation â€” acting only on PRESENT keys would leave stale values active forever.

Every adopted key has UNSET semantics (#94724 review finding on the merged #95980): removing a key from
config.yaml restores the normalized default â€” or the model-derived value â€” on the next turn, through the
same derivation the construction path uses (ContextCompressor ctor defaults read off its real signature,
the Codex threshold autoraise via ``_resolve_compression_threshold``, context-length re-inference via
the deferred ``get_model_context_length`` resolution).
r   )Ú!config_context_length_for_runtimeÚset_config_context_lengthÚenabledTÚcodex_responses_nativeFÚ!codex_responses_compact_thresholdi@ zGInvalid compression.codex_responses_compact_threshold=%r; using 200000.r   NÚcontext_compressorr   ÚleanÚtarget_ratioÚsummary_target_ratiogš™™™™™É?gš™™™™™¹?gš™™™™™é?Úmodel_thresholds)Úresolve_model_thresholdÚ	thresholdrC   rD   rE   Ú_config_context_lengthr7   >   rI   rJ   rK   )Úlegacyr_   )1r   r   r   rN   rY   rZ   Úboolr%   rQ   Úcompression_enabledr   Ú!codex_responses_native_compactionÚintrM   rL   ÚloggerÚwarningr]   Ú
contextlibÚsuppressÚmaxÚ&compression_idle_compact_after_secondsrP   r3   Ústripr   Ú_COMPRESSION_INT_KEYSÚsetattrÚminr<   ra   r   rb   r+   rc   rU   Ú_config_threshold_percentÚ_configured_threshold_percentÚ_base_threshold_percentÚ_effective_threshold_percentÚcontext_lengthr>   r2   Ú_resolved_context_lengthÚ_coerce_threshold_tokens_capr9   Úthreshold_tokens_capÚ_threshold_tokensÚ_tail_token_budget)r;   r   r   rY   rZ   Úenabled_rawÚnative_threshold_rawÚnative_thresholdÚccÚdefault_tailÚmodeÚkeyr&   Ú	min_valuer/   ÚrawÚ	ratio_rawÚraw_thresholdsr   r    rc   rR   ÚbaseÚnew_ctxs   &&                      r   Ú_apply_live_compression_configrŒ   V   s£  € ô ˜C¤×&Ò&‰#¨B€CÜ,6°s·w±w¸}Ó7MÌt×,TÒ,T�#—'‘'˜-Ô(ÐZ\€Kß]Ø—/‘/ )¨TÓ2€KÜ/9¸+Ät×/LÒ/L¡ÔRUÐVaÓRb×RhÑRhÓRjð  oCñ  SC€EÔÜ.=¸k¿o¹oÐNfÐhmÓ>nÓ.o€EÔ+Ø&Ÿ?™?Ð+NÐPWÓXÐð#ÜÐ*¬D×1Ò1Ì#ÐNbÓJcÐ6cÐ6FÐhiÔ5iÜÐð 6jð
 /?Ô+ä	×	Ò	œY¬
×	3Õ	3Ü7:¸1¼cÀ+Ç/Á/ÐRnÐpqÓBr×BwÐBwÐvwÓ>xÓ7yˆÔ4÷ 
4ä	�Ð,¨dÓ	3€BØ	‚zÙäÔ/°¸VÓDÓE€LÜˆ{�‰˜{¨LÓ9×IÐI¸\ÓJ×PÑPÓR×XÑXÓZ€DØÐ#5Ô5‘4¸<€B„Lß$9Ñ ˆ�yÜÔ.¨sÓ=Ó>ˆØ�o‰o˜cÓ+ˆÜ× Ò ¤¬J×7Õ7Ü�BœS ²{©GÌÈCËÓQÔR÷ 8Ñ7ñ %:ô
 
×	Ò	œY¬
×	3Õ	3Ø—O‘O NÔ4LÐMcÐeiÓ4jÓkˆ	Ü"% d¬C´°iÓ0@À$Ó,GÓ"HˆÔ÷ 
4ð !—_‘_Ð%7Ó8€Nô 
�N¤D×	)Ò	)ð &4×%9Ñ%9Ô%;ôÙ%;™T˜Q ¼zÈ!ÌcÔSXÈ\×?ZÔÔcmÐnoÔqu×cvÔŒˆA‹”�a“ÒÑ%;óà/1ð Ôõ
 AØ€CØ�kÔ!Ü× Ò ¤¬J×7Õ7Ü˜ KÕ0Ó1ˆC÷ 8à
‚{Ü0°ÓDˆØFIÐI€BÔ  2Ô#CÙ(?Ü��w Ó#×)Ð) r¨2×+>Ñ+>ÀÄWÈUÐT^Ð`bÓEc×EiÐEiÐgió)ð €Dˆ2Ô%ð#Ø!×>Ñ>¸r×?PÑ?PÐRVÓWˆÔñ 0°Ó;€GØÒñ 	" %¨Ô1Ü× Ò ¤×+Õ+Ø 'ˆBÔ÷ ,Ð+ä	�Ð-¨tÓ	4Ò	@ñ 	" %¨Ô.Ø&*ˆÔ#Ø ×=Ñ=Ø�‰Ð*Ô,IÓ,KÓLó€BÔð 48Ð7€BÔ˜2Ö0øôA ”zÐ"ô #Ü�‰Ð`ÐbvÔwØ"Óð#ú÷
 
4×	3Ð	3ú÷ 8×7Ñ7úç	3×	3Ð	3üó
÷ 8×7Ð7ûô ô #Ø"ˆ×ð#ú÷ ,×+úss   Ã.S; Ä55T+É%T?ÊAUÌ!U(ÍU(ÍU(Î6U.Ð5!V ÒVÓ;)T(Ô'T(Ô+T<	Ô?UÕU%	Õ.U?	ÖVÖVÖV+	c               ó$   € V ^8„  d   QhRRRRRR/# ©r   Úsidr%   Úsessionr   r	   rW   r   )r   s   "r   r   r   ®   s&   € ÷ Uñ U¨Sð U¸4ð UÀDñ Ur   c                ó"  € VP                  R4      pVf   R# \        4       ;'       g    / p\        V4      pVP                  R4      pWAR&   WE8X  d   R#  \        W#4       R#   \         d"   p\
        P                  RY4        Rp?R# Rp?ii ; i)a,  Adopt compression.* / model.context_length edits at turn start (messaging gateways rebuild the
agent on these keys; Desktop/TUI keeps the live compressor, so it must be updated in place).

Desktop/TUI only synced the model; the live compressor kept the threshold captured at agent creation
(#95151).
r;   NÚconfig_compression_seenz2Could not apply live compression config for %s: %s)r   Ú	_load_cfgr"   rŒ   r2   rk   rl   )r�   r�   r;   r   r,   ÚseenÚes   &&     r   Ú#_sync_agent_compression_with_configr–   ®   s†   € ð �K‰K˜Ó €EØ‚}ÙÜ
‹+×
Ð
˜€CÜ1°#Ó6€IØ�;‰;Ð0Ó1€DØ)2Ð%Ñ&ØÔÙðUÜ& uÖ2øÜô UÜ�‰ÐKÈS×TÒTûðUús   ÁA" Á"BÁ-B	Â	Bc               ó$   € V ^8„  d   QhRRRRRR/# rŽ   r   )r   s   "r   r   r   Ä   s!   € ÷ %ñ % Sð %°4ð %¸Dñ %r   c                ó  € VP                  RR4      pV'       d   VP                  R4      f   R# VP                  R4      ;'       g
    VR,          p \        WVR,          \        VP                  R4      4      R7      pVP                  R4      '       g   R# VP                  R	4      ;'       g    VP                  R
4      ;'       g    Rp\        P                  RW0VP                  R^4      ^ ,          4       \        VR,          RR4      ;'       g    RpRV RV R2p\        RV RVP                  4       RRRRRRRRRR/4       \        W4       R#   \         d'   p\        P                  RY0T4       RT 2p Rp?L`Rp?ii ; i) u!  Apply a model switch queued (``session["pending_model_switch"]``) while a turn was running. Runs on
the TURN thread at turn start â€” nothing in flight â€” so the in-place swap (client rebuild) is safe. A
failed switch keeps the current model and never blocks the turn.

A dropped pick is a warning notice, not an ``error``: clients paint ``error`` as a failed turn
(Desktop's red retry card under the user's message) while this turn runs normally on the old model.
The session.info re-sync moves the pill off the pick the session never adopted.Úpending_model_switchNr;   Údisplay_modelr‡   Úconfirm_expensive_model)r›   Úconfirm_requiredÚconfirm_messagerl   rD   z4Queued model switch to %s dropped for session %s: %sÚ
rC   zthe current modelz
Stayed on z: switching to z. needs confirmation. Pick it again to confirm.z3Queued model switch to %s failed for session %s: %szCould not switch model: znotification.showÚtextÚlevelÚwarnÚkindÚttlÚttl_msià.  r…   zmodel_switch.droppedÚid)Úpopr   Ú_apply_model_switchrg   rk   rl   ÚsplitrP   r2   Ú_emitÚrstripÚ_emit_session_info)	r�   r�   ÚpendingrC   ÚresultÚdetailÚcurrentrŸ   r•   s	   &&       r   Ú_apply_pending_model_switchr°   Ä   s…  € ð �k‰kÐ0°$Ó7€Gß�g—k‘k 'Ó*Ò2ÙØ�K‰K˜Ó(×:Ð:¨G°E­N€Eð.Ü$ S°7¸5µ>Ô[_Ð`g×`kÑ`kð  mFó  aGó  \Hô  Iˆð �z‰zÐ,×-Ò-ÙØ—‘Ð-Ó.×MÐM°&·*±*¸YÓ2G×MÐMÈ2ˆÜ�‰ÐMÈuÐ[a×[gÑ[gÐhlÐnoÓ[pÐqrÕ[sÔtÜ˜' 'Õ*¨G°RÓ8×OÐOÐ<Oˆð ˜G˜9 O°E°7Ð:hÐiˆô 
Ð
˜sØ�—‘“˜w¨°¸¸xÈØÐ% tÐ-Cð%Eô Fô �sÖ$øô ô .Ü�‰ÐLÈeÐZ[Ô\Ø)¨!¨Ð-�ûð.ús2   ÁAE ÂE Â1E Ã
AE ÄE ÅFÅ!FÆFc                  ó6   a € ] tR t^åtRtRR V 3R llltRtV ;t# )ÚCompressionLockHeldz`Raised by _compress_session_history when a concurrent compression_locks row skipped compression.c               ó   € V ^8„  d   QhRR/# )r   Úholderú
str | Noner   )r   s   "r   r   Ú CompressionLockHeld.__annotate__è   s   € ÷ Jñ J˜zñ Jr   c                	óL   <€ Wn         \        ST `	  R T;'       g    R 24       R# )zCompression lock held: ÚunknownN)r´   Úsuperr-   )Úselfr´   Ú	__class__s   &&€r   r-   ÚCompressionLockHeld.__init__è   s&   ø€ ØŒÜ‰ÑÐ2°6×3FÐ3F¸YÐ2GÐHÖIr   )r´   ©N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r-   Ú__static_attributes__Ú__classcell__)r»   s   @r   r²   r²   å   s   ø† Ùj÷J÷ Jð Jr   r²   c                  ó   € ] tR t^ítRtRtR# )ÚCompressionBusyzjRaised by _manual_compress_turn when a turn already holds the session; callers map it to their busy reply.r   N)r¾   r¿   rÀ   rÁ   rÂ   rÃ   r   r   r   rÆ   rÆ   í   s   † Ýtr   rÆ   c               ó    € V ^8„  d   QhRRRR/# )r   r�   r%   r�   r   r   )r   s   "r   r   r   ò   s   € ÷ ;ñ ;˜sð ;¨Tñ ;r   c              #  ó†  "  € VR,          ;_uu_ 4        VP                  R4      '       d.   \        \        R\        VP                  R4      4      4      4      hR;VR&   VR&   RRR4        Rx € VR,          ;_uu_ 4        VP	                  RR4       RVR&   RRR4       \        W4       \        RW4       R#   + '       g   i     L_; i  + '       g   i     L<; i  TR,          ;_uu_ 4        TP	                  RR4       RTR&   RRR4       M  + '       g   i     M; i\        Y4       \        RY4       i ; i5i)	a…  Hold the session busy (``running``) for a whole manual compaction: snapshot, LLM summary, commit
and session-key re-anchor. A prompt.submit arriving meanwhile takes the busy path (demoted to queue
by ``_session_compression_in_flight``) instead of snapshotting a history version the compaction is
about to bump, which dropped the turn's reply (#133504). The queued prompt drains on release.Úhistory_lockÚrunningÚcompressÚ_manual_compress_activeTNFÚ__compress__)r   rÆ   Úbusy_messagerg   r¦   Ú_emit_session_info_for_sessionÚ_drain_queued_prompt)r�   r�   s   &&r   Ú_manual_compress_turnrÑ   ñ   sù   é € ð 
�×	 ×	 Ø�;‰;�y×!Ò!Ü!¤,¨z¼4ÀÇÁÐLeÓ@fÓ;gÓ"hÓiÐiØBFÐFˆ�	Ñ˜WÐ%>Ñ?÷ 
!ð;Ûà�^×$×$Ø�K‰KÐ1°4Ô8Ø!&ˆG�IÑ÷ %ô 	' sÔ4Ü˜^¨SÖ:÷ 
!×	 ú÷ %×$ûˆW�^×$×$Ø�K‰KÐ1°4Ô8Ø!&ˆG�IÑ÷ %×$×$Ð$úô 	' sÔ4Ü˜^¨SÕ:üse   ‚E”AB:Á#EÁ,C  Á0EÂCÂ!EÂ:C
	ÃEÃC	ÃEÃ D>Ã2D	Ä
	D>ÄD#Ä D>Ä>Ec               ó0   € V ^8„  d   QhRRRRRRRRR	RR
R/# )r   r�   r   Úfocus_topicrµ   Úapprox_tokensz
int | NoneÚbefore_messageszlist | NoneÚhistory_versionr	   ztuple[int, dict]r   )r   s   "r   r   r     s>   € ÷ 0-ñ 0-Øð0-Ø *ð0-ØBLð0-à ð0-à:Dð0-ð ñ0-r   c           	     ó   a a€ ^ RI Hp ^ RIHpHpHpHp	 S R,          p
Ve   SfR   S R,          ;_uu_ 4        \        S P                  R. 4      4      \        S P                  R^ 4      4      upoRRR4       \        V4      V8  d   ^ \        V
4      3# T	! T;'       g    R4      pVP                  '       d   \        V4      h\        S P                  R	4      ;'       g    R\        S 4      R
7      pVV 3R lp T! Y£TS P                  R	4      ;'       g    RVR7      p\!        V4       VP"                  R8X  d   ^ \        V
4      3# VP"                  R8X  d   \%        VP&                  4      hVP"                  R8w  d   ^ \        V
4      3# S R,          ;_uu_ 4        \        S P                  R^ 4      4      S8w  d"   V! V
RR7       ^ \        V
4      3uuRRR4       # VP(                  S R&   S^,           S R&   RRR4       VP*                  \        V
4      3#   + '       g   i     EL³; i  \!        T4       i ; i  + '       g   i     LK; i)a‡  Single choke point for all manual-compress routes. ``focus_topic`` is the RAW argument string after
``/compress``; the shared core (``agent.conversation_compression_manual``) parses boundary forms
(``here [N]``, ``up to here``, ``--keep N``) so a partial compress triggers on EVERY route instead of a
FULL compress focused on the literal text. ``--preview`` returns without touching history.)Ú0finalize_context_engine_compression_notification)ÚAGGRESSIVE_UNSUPPORTEDÚMIN_MESSAGESÚcompress_nowÚparse_compress_argsr;   NrÉ   ÚhistoryrÖ   rD   Úsession_key)Úcwdc                 ó    <€ SR ,          ;_uu_ 4        \        SP                  R^ 4      4      S 8H  uuRRR4       #   + '       g   i     R# ; i)rÉ   rÖ   N)rj   r   )rÖ   r�   s   €€r   Úsnapshot_is_currentÚ6_compress_session_history.<locals>.snapshot_is_current  s6   ø€ Ø�^×$×$Ü�w—{‘{Ð#4°aÓ8Ó9¸_ÑL÷ %×$×$Ó$ús	   “<¼A	r/   )Útask_idrá   ÚpreviewÚlock_skippedÚ
compressedF)Ú	committed)Úagent.conversation_compressionrØ   Ú%agent.conversation_compression_manualrÙ   rÚ   rÛ   rÜ   Úlistr   rj   ÚlenÚ
_get_usageÚ
aggressiverM   Ú_set_session_contextÚ_session_cwdÚ_clear_session_contextÚstatusr²   Úlock_holderÚafter_messagesÚremoved)r�   rÓ   rÔ   rÕ   rÖ   rØ   rÙ   rÚ   rÛ   rÜ   r;   ÚrequestÚtokensrá   r­   s   f&&&f          r   Ú_compress_session_historyr÷     s  ù€ õ `÷Qó Qà�GÕ€Eð Ò /Ò"9Ø�^×$×$Ü/3°G·K±KÀ	È2Ó4NÓ/OÔQTÐU\×U`ÑU`ÐarÐtuÓUvÓQwÐ,ˆO˜_÷ %ä
ˆ?Ó˜lÔ*Ø”*˜UÓ#Ð#Ð#Ù! +×"3Ð"3°Ó4€GØ××ÐÜÐ/Ó0Ð0ô " '§+¡+¨mÓ"<×"BÐ"BÀÌÐU\ÓH]Ô^€FöMð'Ù˜e°gÀwÇ{Á{ÐS`ÓGa×GnÐGnÐenØ2EôGˆô 	˜vÔ&Ø‡}�}˜	Ô!Ø”*˜UÓ#Ð#Ð#à‡}�}˜Ô&Ü! &×"4Ñ"4Ó5Ð5Ø‡}�}˜Ô$Ø”*˜UÓ#Ð#Ð#Ø	�×	 ×	 Üˆw�{‰{Ð,¨aÓ0Ó1°_ÔDá<¸UÈeÕTØ”j Ó'Ð'÷	 
!Ò	 ð
 $×2Ñ2ˆ�	ÑØ%4°qÕ%8ˆÐ!Ñ"÷ 
!ð �>‰>œ: eÓ,Ð,Ð,÷C %×$Ð$ûô$ 	˜vÕ&ú÷ 
!×	 ús/   ·8HÃ:H- Ä	H- Æ7H=ÇH=ÈH*	È-H:È=I	Úclear_pending_titleTÚrestart_slash_workerc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   r�   r%   r�   r   rø   rg   rù   r	   rW   r   )r   s   "r   r   r   9  s4   € ÷ "0ñ "0Ø	ð"0Øð"0Ø59ð"0ØX\ð"0à	ñ"0r   c          	     ó  a € VP                  R4      p\        VRR4      ;'       g    RpVP                  RR4      ;'       g    RpV'       d   WV8X  d   R# \        S WR7      '       g   \        P	                  RS We4       YQR&   \
        P                  ! \        4      ;_uu_ 4        ^ RIH	p \
        P                  ! \        4      ;_uu_ 4        VP                  V4       RRR4       ^ R	IHp V! We4       \
        P                  ! \        4      ;_uu_ 4        VP                  VV 3R
 l4       RRR4       RRR4       \        VP                  R^ 4      4      ^,           VR&   V'       d   RVR&   V'       d:   \
        P                  ! \        4      ;_uu_ 4        \        S V4       RRR4       R# R#   + '       g   i     LÜ; i  + '       g   i     L ; i  + '       g   i     L«; i  + '       g   i     R# ; i)aŠ  Re-anchor the gateway-side ``session_key`` when _compress_context rotates ``agent.session_id``;
otherwise approval routing, slash worker, DB lookups and yolo state keep targeting the ended parent.
``clear_pending_title``: True for manual /compress (title belongs to the old session), False for
post-turn auto-compression. ``restart_slash_worker``: False only when the caller manages the worker.r;   Ú
session_idNrD   rÞ   )Únew_session_idzWCompression session lease did not re-anchor: sid=%s old_session_id=%s new_session_id=%s)Úapproval)Útransfer_session_yoloc                ó   <€ \        SV 4      # r½   )Ú_emit_approval_request)Údatar�   s   &€r   Ú<lambda>Ú2_sync_session_key_after_compress.<locals>.<lambda>S  s   ø€ ÔJ`ÐadÐfjÔJkr   Ú_queued_prompt_generationÚpending_title)r   rP   Ú_transfer_active_session_slotrk   rl   rm   rn   r2   Útoolsrþ   Úunregister_gateway_notifyÚtools.approval_yolorÿ   Úregister_gateway_notifyrj   Ú_restart_slash_worker)	r�   r�   rø   rù   r;   rý   Úold_keyrþ   rÿ   s	   f&$$     r   Ú _sync_session_key_after_compressr  9  sj  ø€ ð �K‰K˜Ó €EÜ˜U L°$Ó7×=Ð=¸2€NØ�k‰k˜-¨Ó,×2Ð2°€Gß˜^Ô6ÙÜ(¨¨g×UÓUÜ�‰ØeØ�ô	
ð
 ,ˆMÑÜ	×	Ò	œY×	'Õ	'Ý"Ü× Ò ¤×+Õ+Ø×.Ñ.¨wÔ7÷ ,å=Ù˜gÔ6Ü× Ò ¤×+Õ+Ø×,Ñ,¨^Ô=kÔl÷ ,÷ 
(ô ,/¨w¯{©{Ð;VÐXYÓ/ZÓ+[Ð^_Õ+_€GÐ'Ñ(ßØ#'ˆ�Ñ ßÜ× Ò ¤×+Õ+Ü! # wÔ/÷ ,Ñ+ñ ÷ ,×+ú÷ ,×+ú÷ 
(×	'ú÷ ,×+Ð+úsH   Â&)GÃF5	Ã!8GÄG	Ä0GÆG.Æ5GÇ GÇGÇGÇG+	Ç.G?	c               ó   € V ^8„  d   QhRR/# )r   r	   rW   r   )r   s   "r   r   r   ^  s   € ÷ 0ñ 0˜ñ 0r   c                ó2   € \        \        4       V RR7       R# )zQPublish this module's helpers + handlers onto ``server``, rebound to its globals.)ÚskipN)Ú_)r   Úglobals)Úservers   &r   Úregisterr  ^  s   € ä”“	˜6¨×/r   ))Úproactive_prune_tokensé    r  )Ú proactive_prune_min_result_charsi@  r  )Ú"proactive_prune_min_reclaim_tokensi   r  )Úprotect_last_né   r  )Úmin_tail_user_messagesé   r  )NNNN)rÂ   Ú
__future__r   rm   Úutilsr   Ú
method_ctxr   r"   r3   r9   rU   rr   rŒ   r–   r°   r2   r²   rÆ   ÚcontextmanagerrÑ   r÷   r  r  r   r   r   Ú<module>r"     s    ðñNõ #ã å !å #õ)õò"	Mõð.Ð õU8õpUõ,%ôBJ˜)ô Jôu�iô uð ×Ñô;ó ð;÷(0-ðf"0Ø<@ð"0Ø_c÷"0÷J0r   