+
    iHàj�U  ã                  ó  € R t ^ RIHt ^ RIt^ RIHt ^ RIHtHtH	t	H
t
 ^ RIHt ^ RIHtHtHtHtHtHtHt ^ RIHt ^ RIHtHtHtHtHtHt ]P<                  ! R	4      t] ! R
 R4      4       t R R lt!] ! R R4      4       t"R R lt#R# )a/  Pre-API preflight compression gate and post-tool compression for the turn loop.

Runs once per API call after the request pressure is measured: grow a managed llama.cpp
window (last resort), or compress when over threshold (deferring on noisy estimates, in
failure cooldown, or while the review fork's first request is pending), handle the
provider-proven overflow re-check fail-closed, and emit the deduped blocked/uncompressed
overflow warnings. Nothing here imports ``agent.conversation_loop`` at module level
(cycle); loop-internal helpers resolve lazily.)ÚannotationsN)Ú	dataclass)ÚAnyÚDictÚListÚOptional)Ú#automatic_compaction_status_message)Ú#PRE_API_COMPRESSION_STATUS_TEMPLATEÚ_reset_read_dedup_cachesÚcompression_blocked_transientlyÚcompression_skipped_due_to_lockÚcontext_compression_timed_outÚ&conversation_history_after_compressionÚ&ensure_compression_feasibility_checked)Ú"_review_fork_first_request_pending)Ú_apply_grown_windowÚ_blocked_compress_reasonÚ_clear_overflow_warnÚ_refund_api_callÚ	_reanchorÚ#_reset_retry_state_after_compactionzagent.conversation_loopc                  ó¶   € ] tR t^t$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R]R	&   R]R
&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   RtR]R&   RtR# )ÚPreflightGateVerdictuð  ``action``: ``"fallthrough"`` (make the API call), ``"continue"`` (window grown or
history compacted â€” the call/budget was refunded, re-enter the turn loop and
re-measure), ``"break"`` (turn ends: compression timeout or non-actionable compaction
handoff â€” ``final_response``/``failed``/``_turn_exit_reason`` set) or ``"return"``
(``result`` is the turn's result dict). The other fields are the loop locals the gate
rebinds; ``_last_preflight_pressure`` is re-armed only by a compression pass.ÚstrÚactionr   Úpending_moa_prepared_requestÚmessagesÚactive_system_promptÚconversation_historyÚapi_call_countÚcompression_attemptsÚfinal_responseÚfailedÚ_turn_exit_reasonÚ_compression_timeout_exhaustedÚ_preflight_compression_blockedÚ#_provider_overflow_recovery_pendingÚ_last_preflight_pressureNúOptional[dict[str, Any]]Úresult© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r)   Ú__static_attributes__r*   ó    Ú9/home/ubuntu/.hermes/hermes-agent/agent/turn_preflight.pyr   r      sf   ‡ ñUð ƒKØ"%Ó%ØƒMØÓØÓØÓØÓØÓØƒKØÓØ$'Ó'Ø$'Ó'Ø),Ó,Ø!Ó!Ø'+€FÐ$×+r2   r   c               óH   € V ^8„  d   QhRRRRRRRRRR	R
RRRRRRRRRRRRR/# )é   Úagentr   Úvr   Ú
compressorÚrequest_pressure_tokensÚintÚprovider_overflow_preflightÚboolÚdefer_preflightÚmoa_prepared_requestÚsystem_messageÚuser_messageÚmax_compression_attemptsÚeffective_task_idÚreturnr*   )Úformats   "r3   Ú__annotate__rE   9   sˆ   € ÷ h ñ h Øðh Ø'ðh Ø8;ðh ØVYðh à!%ðh à8;ðh àSVðh ð ðh ð (+ðh ð GJðh ð _bðh ð ñ	h r2   c       	        ó  a aaa	a€ ^ RI HpHpHpHpHoHp RR V3R lllpR VV V	VV3R llp\        VRR 4      ! 4       pS P                  ;'       d0    \        SP                  4      ^8„  ;'       d    SP                  S	8  pV'       d   \        S S4       V'       EdQ   \        S 4      '       Eg?   SP                  '       d
   V'       Ed$   V! S4      '       d
   V'       Ed   V'       Eg   VP                  S4      '       Edì   V! S VS4      pV'       d1   \!        S VV4       \#        S SP$                  4      Sn        V! R	4      # Ve   VSn        S;P                  ^,          un        \)        S 4       \+        \        VR
^ 4      ;'       g    ^ 4      p\+        \        VR^ 4      ;'       g    ^ 4      p\,        P/                  RSR VR \        VR^ 4      '       d   VR MRSP                  S	4       \1        VR\2        P4                  ! SR7      SVVS P6                  SP                  S	R7	      pV'       d   S P9                  V4       SSn        SP                  pS P=                  SP                  VSV
RR7      w  Sn
        Sn        \A        S 4      '       d@   \#        S SP$                  4      Sn        VSn!        RSn"        RSn#        RSn$        V! R4      # SP                  VJ d\   \K        S 4      '       g   \M        S 4      '       d:   S;P                  ^,          un        RSn        SP&                  VJ d   RSn        EM!\O        S 4       \Q        S SP                  SPR                  4      Sn)        \#        S SP$                  4      Sn        V! SP                  V4      '       d>   \,        P/                  R4       SPB                  '       g   VSn!        RSn$        V! R4      # V! R	4      # V'       dV   V'       dN   S PU                  SP                  SPR                  4       V! RV! S SP                  SP$                  RR7      4      # V'       d    SP                  S	8¼  d   V! RV! 4       4      # V'       d]   V! S4      '       gO   V'       dG   \W        VS4      pV'       d2   S PY                  TS\+        \        VR
^ 4      ;'       g    ^ 4      4       M�S P                  '       g~   \        SP                  4      ^8”  dd   \        \        S RR4      RR4      p\[        V\*        4      '       d6   V^ 8”  d/   SV8”  d(   \        S RR4      p\]        V4      '       d
   V! SV4       V'       d   V! RV! 4       4      # V! R4      # )u  Mirror of the turn-prologue guard chain (defer on noisy estimate â†’ skip in failure
cooldown â†’ ``should_compress``), rebinding the loop locals on ``v`` and setting
``v.action``. A compression pass that never reaches the provider refunds the
call/budget in every branch (skip, re-run, timeout) so ``api_call_count`` never
over-reports; a lock/transient skip refunds the attempt and leaves the progress
blocker unarmed. A forced provider-overflow preflight that any gate blocks fails
closed (llama.cpp may silently truncate).)Ú#_COMPRESSION_TIMEOUT_FINAL_RESPONSEÚ_HANDOFF_SKIP_FINAL_RESPONSEÚ_compression_deferred_resultÚ_maybe_grow_local_windowÚ#_provider_overflow_exhausted_resultÚ-_should_skip_model_call_for_reference_handoffNc               ó$   € V ^8„  d   QhRRRRRR/# )r5   r   r   r)   r(   rC   r   r*   )rD   s   "r3   rE   Ú/run_preflight_compression.<locals>.__annotate__K   s#   € ÷ ñ �cð Ð#;ð ÐG[ñ r2   c                ó$   <€ WuSn         Sn        S# ©N)r   r)   )r   r)   r7   s   &&€r3   Ú_doneÚ(run_preflight_compression.<locals>._doneK   s   ø€ Ø#ÐˆŒ�!”(Øˆr2   c               ó   € V ^8„  d   QhRR/# )r5   rC   zdict[str, Any]r*   )rD   s   "r3   rE   rN   O   s   € ÷ 
ñ 
˜~ñ 
r2   c                 óZ   <€ S ! SSP                   SP                  SP                  SS4      # rP   )r   r   r   )rK   r6   rA   r9   r7   s   €€€€€r3   Ú_exhausted_resultÚ4run_preflight_compression.<locals>._exhausted_resultO   s/   ø€ Ù2Ø�1—:‘:˜q×5Ñ5°q×7GÑ7GÐI`Ø$ó
ð 	
r2   Ú'get_active_compression_failure_cooldownc                 ó   € R # rP   r*   r*   r2   r3   Ú<lambda>Ú+run_preflight_compression.<locals>.<lambda>V   s   € Átr2   ÚcontinueÚthreshold_tokensÚcontext_lengthzSPre-API compression: ~%s request tokens >= %s threshold (context=%s, attempt=%s/%s)Ú,ÚunknownÚpre_api)Útokens)ÚphaseÚdefault_messageÚapprox_tokensr\   r]   ÚmodelÚattemptÚmax_attempts©rd   Útask_idÚtriggerTÚcontext_compression_timeoutÚbreakzgSkipping post-compaction model call: reference-only handoff would be the sole active user turn (#80622)Ú!compaction_handoff_not_actionablerC   Útransient_block)ÚreasonÚcontext_compressorÚ#_warn_uncompressed_context_overflowÚfallthroughrP   )/Úagent.conversation_looprG   rH   rI   rJ   rK   rL   ÚgetattrÚcompression_enabledÚlenr   r    r   r   r%   Úshould_compressr   r   r   r   r   r:   ÚloggerÚinfor   r	   rD   re   Ú_emit_statusr'   Ú_compress_contextr   r   r!   r"   r$   r#   r   r   r   r   r   Ú_persist_sessionr   Ú_warn_context_overflow_blockedÚ
isinstanceÚcallable)r6   r7   r8   r9   r;   r=   r>   r?   r@   rA   rB   rG   rH   rI   rJ   rL   rQ   rU   Ú_compression_cooldownÚ	_eligibleÚ_grown_windowÚ
_thresholdÚ_context_lengthÚ_pre_api_statusÚ_pre_api_inputÚ_block_reasonÚ_ctx_lenÚ_warn_fnrK   s   ff$d$$$$$d$                 @r3   Úrun_preflight_compressionrŠ   9   sô  ü€ ÷÷ ÷ò ÷
ô 
ô $ØÐ=¹|ôó Ðð 	×!Ñ!÷ 	>ð 	>Ü�—
‘
‹O˜aÑ÷	>ð 	>à×"Ñ"Ð%=Ñ=ð ÷
 ä.¨uÐ6MÔNçˆ	Ü2°5×9Ó9Ø×1×1Ð1×5PÐ5PÙ Ð!8×9Ò9×=XÐ=Xß%Ð%Ø×&Ñ&Ð'>×?Ó?ñ 1°¸
ÐD[Ó\ˆßô    z°=ÔAÜ/°°q×7GÑ7GÓHˆAÔÙ˜Ó$Ð$ØÒ+Ø-AˆAÔ*Ø	×Ò !Õ#Õô 	˜UÔ#Üœ Ð-?ÀÓC×HÐHÀqÓIˆ
Üœg jÐ2BÀAÓF×KÐKÈ!ÓLˆÜ�‰ð*à& qÐ)Ø˜!ˆnÜ&-¨jÐ:JÈA×&NÒ&Nˆ˜qÑ!ÐT]Ø×"Ñ"Ø$ô	
ô >ØØÜ?×FÒFØ.ôð 2Ø'Ø*Ø—+‘+Ø×*Ñ*Ø1ô
ˆ÷ Ø×Ñ˜Ô/Ø%<ˆÔ"ØŸ™ˆØ-2×-DÑ-DØ�J‰J˜Ð6MØ%¨yð .Eó .
Ñ*ˆŒ
�AÔ*ô )¨×/Ò/ô  0°°q×7GÑ7GÓHˆAÔØBˆAÔØˆAŒHØ/3ˆAÔ,Ø"?ˆAÔÙ˜“>Ð!Ø�:‰:˜Ó'Ü+¨E×2Ò2Ô6UÐV[×6\Ò6\ð ×"Ò" aÕ'Õ"Ø)-ˆAÔ&Ø×-Ñ-Ð1EÓEØ15�Ô.ùä/°Ô6ô &LØ�q—z‘z 1×#9Ñ#9ó&ˆAÔ"ô
  0°°q×7GÑ7GÓHˆAÔÙ<¸Q¿Z¹ZÈ×VÒVô —‘ðJôð ×'×'Ð'Ø'C�AÔ$Ø&I�Ô#Ù˜W“~Ð%Ù˜Ó$Ð$ß	$×)>ð 	×Ñ˜qŸz™z¨1×+AÑ+AÔBÙ�XÑ;Ø�1—:‘:˜q×/Ñ/Ð8Iô 
ó ð 	÷ 
%¨×)?Ñ)?ÐC[Ô)[ñ �XÑ0Ó2Ó3Ð3ß	™?Ð+B×CÒC×H]ô 1°Ð=TÓUˆßØ×0Ñ0ØÐ6Ü”G˜JÐ(:¸AÓ>×CÐCÀ!ÓDôøð ×&×&Ð&¬3¨q¯z©z«?¸QÔ+>ô œ7 5Ð*>ÀÓEÐGWÐY]Ó^ˆÜ�h¤×$Ò$¨°A¬Ð:QÐT\Ô:\Ü˜uÐ&KÈTÓRˆHÜ˜×!Ò!ÙÐ0°(Ô;ç"ñ �XÑ0Ó2Ó3Ð3Ù�ÓÐr2   c                  ól   € ] tR t^ät$ RtR]R&   R]R&   R]R&   R]R&   R	]R
&   R]R&   R]R&   R	]R&   RtR# )ÚPostToolCompressionVerdictu®   ``end_turn`` True â†’ a reference-only compaction handoff would be the sole active
user turn: stop without another model call (``final_response`` /
``turn_exit_reason`` set).r<   Úend_turnúlist[dict[str, Any]]r   r   r   r   r:   r    r!   Úturn_exit_reasonÚcurrent_turn_user_idxr*   N)r+   r,   r-   r.   r/   r0   r1   r*   r2   r3   rŒ   rŒ   ä   s8   ‡ ñ"ð ƒNØ"Ó"ØÓØÓØÓØÓØÓØ×r2   rŒ   c               óL   € V ^8„  d   QhRRRRRRRRRRRRR	R
RR
RRRRRRRR
RR/# )r5   r6   r   r   rŽ   r?   r@   r   r   r    r:   rA   rB   r!   r�   r�   rC   rŒ   r*   )rD   s   "r3   rE   rE   ô   s‘   € ÷ Xñ XØðXØ1ðXØCFðXØVYðXàðXà58ðXàPSðXð "ðXð 7:ðXð LOðXð ð	Xð 36ð	Xð
  ñXr2   c               óö  aaaaa	a
a€ ^ RI HpHpHp ^ RIHp R VVVVV	VV
3R llpV P                  p\        \        VRR4      4      '       d	   V! R4      # ^ RI	H
p V! S\        V RR	4      4      pVe   TpMcVP                  ^ 8”  d   VP                  pMEVP                  R8X  d   ^ pM1T! T SS;'       g    R
T! SV P                  ;'       g    R	R7      4      pV P                  '       d   SV8  d   \        V V4       V P                  '       dð   SV8  dé   \        \        VRR4      4      '       gÍ   VP                  V4      '       d¶   S^,          o\!        V 4       V P#                  R4       SpV P%                  SVVVRR7      w  ooSVJ d   \'        V 4      '       d   S^,          oEM\)        V SS4      oV! SV4      '       d*   \*        P-                  R4       S	'       g   Vo	Ro
V! R4      # \/        V SV4      oMÆV P                  '       dµ   \1        VVSR7      pV'       d2   T P3                  TT\5        \        VR^ 4      ;'       g    ^ 4      4       \        VRR	4      p\7        V4      '       dP    V! SVR7      w  ppV'       d:   VSJd4   ^ RIHp V! V SVV4       Vo\A        Y€PB                  ;'       g    R
R7       V! R4      #   \8         d    \*        P;                  RRR7       S^ pp Lqi ; i)u¿  Post-tool-call compression decision. Pressure comes from API-reported
``prompt_tokens`` (a tight lower bound; thinking models inflate completion tokens),
``0`` right after compression (no real count yet), else the route-aware
overhead-inclusive estimate. Over threshold but blocked â†’ deduped warning plus the
deterministic tool-result-only prune, committed only when the engine returns a NEW
list (never rebuild ``conversation_history`` for it).)rH   Ú _midturn_request_pressure_tokensrL   )Úestimate_request_tokens_roughc               ó    € V ^8„  d   QhRRRR/# )r5   r�   r<   rC   rŒ   r*   )rD   s   "r3   rE   Ú1compress_after_tool_results.<locals>.__annotate__  s   € ÷ 
ñ 
˜4ð 
Ð$>ñ 
r2   c                ó*   <€ \        V SSSSSSSR 7      # ))r�   r   r   r   r    r!   r�   r�   )rŒ   )r�   r   r    r   r�   r!   r   r�   s   &€€€€€€€r3   Ú_verdictÚ-compress_after_tool_results.<locals>._verdict  s'   ø€ Ü)Ø¨ÐG[Ø!5ÐL`Ø)Ð<LØ"7ô	
ð 	
r2   Ú%awaiting_real_usage_after_compressionF)Úanchored_context_tokensÚ_usage_anchorNÚ )Útoolsu     âŸ³ compacting contextâ€¦Ú	post_toolrh   zlSkipping post-tool compaction model call: reference-only handoff would be the sole active user turn (#80622)rm   T)Úattempts_spentr\   Úprune_tool_results_only)Úcurrent_tokensz,proactive tool-result prune failed; skipping)Úexc_info)Úpublish_prune)Ú
session_idéÿÿÿÿ)"rs   rH   r“   rL   Úagent.model_metadatar”   rp   r<   rt   Úagent.usage_anchorr›   Úlast_prompt_tokensrž   ru   r   rw   r   Ú_safe_printr{   r   r   rx   ry   r   r   r}   r:   r   Ú	ExceptionÚdebugÚagent.compaction_eventsr¤   r
   r¥   )r6   r   r?   r@   r   r   r    rA   rB   r!   r�   r�   rH   r“   rL   r”   r˜   Ú_compressorr›   Ú	_anchoredÚ_real_tokensÚ_post_tool_inputr‡   Ú_pruneÚ_pruned_msgsÚ	_pruned_nr¤   s   &d$$ddd$$ddd               r3   Úcompress_after_tool_resultsrµ   ô   sÿ  þ€ ÷ñ õ C÷
ö 
ð ×*Ñ*€Kô ŒG�KÐ!HÈ%ÓP×QÒQÙ˜‹Ðõ ;á'¨´'¸%ÀÐRVÓ2WÓX€IØÒØ ‰Ø	×	'Ñ	'¨!Ô	+ð #×5Ñ5‰Ø	×	'Ñ	'¨2Ô	-Ø‰á7Ø�8Ð1×7Ð7°RÙ)¨(¸%¿+¹+×:MÐ:MÈÔNó
ˆð
 × × Ð Ð%9Ð<TÔ%TÜ.¨u°lÔCà×!×!Ð!Ø Ð#;Ô;ÜÜ�KÐ!HÈ%ÓP÷
ò 
ð ×'Ñ'¨×5Ò5à Õ!Ðô 	˜UÔ#Ø×ÑÐ7Ô8Ø#Ðð */×)@Ñ)@Ø�n°LÐJ[Ðepð *Aó *
Ñ&ˆÐ&ð Ð'Ó'Ô,KÈE×,RÒ,Rð6 ! AÕ%Ò ä#IØ�xÐ!5ó$Ð ñ =¸XÀ|×TÒTÜ—‘ð0ô÷
 &Ø%A�NØ#FÐ Ù “~Ð%Ü$-¨e°X¸|Ó$LÑ!Ø	×	"×	"Ð	"ô
 1Ø˜Ð6Jô
ˆ÷ Ø×0Ñ0Ø˜|¬S´¸ÐFXÐZ[Ó1\×1aÐ1aÐ`aÓ-bôô ˜Ð&?ÀÓFˆÜ�F×Òð6Ù*0°È,Ô*WÑ'�˜i÷ ˜\°Ó9ÝAá˜e X¨|¸YÔGØ'�ô )Ð):×GWÑGW×G]ÐG]Ð[]Õ^Ù�E‹?Ðøô! ô 6Ü—‘ÐKÐVZ�Ô[Ø*2°A˜i�™ið6ús   É9K Ë&K8Ë7K8)$r/   Ú
__future__r   ÚloggingÚdataclassesr   Útypingr   r   r   r   Úagent.context_enginer   Úagent.conversation_compressionr	   r
   r   r   r   r   r   Úagent.turn_contextr   Úagent.turn_context_compactionr   r   r   r   r   r   Ú	getLoggerrx   r   rŠ   rŒ   rµ   r*   r2   r3   Ú<module>r¿      s�   ðñ2õ #ã Ý !ß ,Ó ,å D÷÷ ñ õ
 B÷÷ ð
 
×	Ò	Ð4Ó	5€ð ÷,ð ,ó ð,õ2h ðV ÷ð ó ð÷Xr2   