+
    iHàjƒ¬  ã                  óÂ  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	H
t
HtHtHt ^ RIHt ^ RIHt ^ RIHt ^ RIHtHt ^ R	IHt ^ R
IHt ^ RIHtHt ^ RIHt ^ RI H!t! R5t"0 R6mt#R7t$R8t%R R lt&R R lt'R R lt(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t0R# R$ lt1R% R& lt2R' t3R( t4R) R* lt5R+ R, lt6R-RR.R/R/ R0 llt7R1RR2R3/R4 lt8R# )9a.  Post-loop turn finalization for ``run_conversation``.

Budget summary, trajectory save, persist, diagnostics, response transforms, result
assembly, steer drain, memory/skill review. Synchronous, single return. ``logger`` is
imported lazily from ``agent.conversation_loop`` (no cycle, same logger name).)ÚannotationsN)Úsuppress)ÚAnyÚCallableÚListÚOptionalÚTuple)Ú_summarize_user_message_for_log)Ú"is_dispatcher_owned_worker_context)Ú"interrupted_during_api_call_reason)Úexit_reason_failureÚstamp_failure)Ú_DB_PERSISTED_MARKER)Úflatten_message_text)Úappend_messageÚstamp_message_timestamp)Ú_sanitize_surrogates)Úresult_model_fieldsc               ó    € V ^8„  d   QhRRRR/# )é   ÚmsgÚdictÚreturnÚbool© )Úformats   "Ú9/home/ubuntu/.hermes/hermes-agent/agent/turn_finalizer.pyÚ__annotate__r   (   s   € ÷ @ñ @¨Tð @°dñ @ó    c                ó¸   € \        V \        4      '       d   V P                  R4      R8w  d   R# \        V P                  R4      4      P	                  4       '       * # )zJTrue when an assistant row has no visible text (blank final or tool-only).ÚroleÚ	assistantFÚcontent)Ú
isinstancer   Úgetr   Ústrip)r   s   &r   Ú#_assistant_row_missing_visible_textr&   (   sA   € ä�cœ4× Ò  C§G¡G¨F£O°{Ô$BÙÜ# C§G¡G¨IÓ$6Ó7×=Ñ=Ó?Ô?Ð?r   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   Úkanban_taskÚstrÚapi_call_countÚintÚmax_iterationsÚloggerúlogging.Loggerr   ÚNoner   )r   s   "r   r   r   /   s4   € ÷ %
ñ %
Øð%
Ø&)ð%
Ø;>ð%
ØHVð%
à	ñ%
r   c                óø  €  ^ RI Hp ^ RI Hp ^ RI Hp VP	                  4       p VP                  VV RV RV R2RRRR	VR
V/R7       \        \        4      ;_uu_ 4        VP                  4        RRR4       R#   + '       g   i     R# ; i  \        \        4      ;_uu_ 4        TP                  4        RRR4       i   + '       g   i     i ; i; i  \         d    TP                  RT RR7        R# i ; i)u  Record a terminal ``timed_out`` outcome for a kanban worker out of budget.

Routed via ``_record_task_failure`` (not ``kanban_block``) so it counts toward the
consecutive-failure circuit breaker. Idempotent via the ``_end_run`` CAS
(``WHERE ended_at IS NULL``), so safe from multiple exit paths.

This is a bounded fallback (#87096): the CAS invariant in ``_end_run`` (``WHERE ended_at IS NULL``)
guarantees idempotence â€” if another path already closed the run this is a no-op â€” so it is safe to call
from multiple exit paths.
)Ú	kanban_db)Úkanban_db_connect)Úkanban_db_dispatchzIteration budget exhausted (Ú/u;   ) â€” task could not complete within the allowed iterationsÚ	timed_outTÚbudget_usedÚ
budget_max)ÚerrorÚoutcomeÚrelease_claimÚend_runÚevent_payload_extraNz5Failed to record budget-exhausted failure for task %s©Úexc_info)
Ú
hermes_clir1   r2   r3   ÚconnectÚ_record_task_failurer   Ú	ExceptionÚcloseÚwarning)r(   r*   r,   r-   Ú_kbÚ_kbcÚ_kbdÚ_conns   &&&&    r   Ú_record_kanban_budget_exhaustedrI   /   sÛ   € ð
Ý/Ý8Ý9Ø—‘“ˆð	Ø×%Ñ%ØØà2°>Ð2BÀ!ÀNÐCSð TLð Lð $Ø"ØØ%2°NÀLÐR`Ð$að &ô ô œ)×$Õ$Ø—‘”÷ %×$×$Ò$û”œ)×$Õ$Ø—‘”÷ %×$×$Ð$þäô 
Ø�‰ØCÀ[Ð[_ð 	÷ 	
ð
ús^   ‚"C ¥#B ÁC ÁA:Á0C Á:B	ÂC ÂC ÂCÂ&C 	Â7	CÃ CÃCÃC ÃC9Ã8C9c               ó   € V ^8„  d   QhRR/# ©r   r   r/   r   )r   s   "r   r   r   W   s   € ÷ ñ ¸Tñ r   c                óþ   a€ V  Uau. uFe  o\        S\        4      '       dK   \        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       d   Kc  SNKg  	  upV R&   R# u upi )z¡Remove verification-continuation nudges in place; only the synthetic nudges carry
these flags, so the real attempted final answer persisted to state.db survives.c              3  óF   <"  € T F  pSP                  V4      x € K  	  R # 5i©N)r$   )Ú.0ÚfÚms   & €r   Ú	<genexpr>Ú>_drop_verification_continuation_scaffolding.<locals>.<genexpr>\   s   øé € Ð+_Ñ>^¸¨A¯E©E°!¯H¨HÓ>^ùs   ƒ!TFºNNNN)r#   r   ÚanyÚ _VERIFICATION_CONTINUATION_FLAGS)ÚmessagesrQ   s   &`r   Ú+_drop_verification_continuation_scaffoldingrX   W   sX   ø€ ñ ôÙˆaÜ˜1œd×#Ò#¯«Ô+_Õ>^Ó+_¯¯ªÔ+_Õ>^Ó+_×(_÷ 	
ˆ‘8ñ€HˆQƒKùò s   ‡%A:­A:ÁA:Á,A:c                óF   € ^ RI Hp V  Uu. uF
  q!! V4      NK  	  up# u upi )z;Copy the review input without aliasing the live transcript.)Ú_clone_message_for_send)Úagent.conversation_looprZ   )rW   rZ   Úmessages   &  r   Ú!_clone_background_review_messagesr]   `   s&   € õ @á<DÓE¹H°Ð# GÖ,¹HÑEÐEùÒEs   ‹c               ó$   € V ^8„  d   QhRRRRRR/# )r   Únamer)   r-   r.   r   Úlistr   )r   s   "r   r   r   h   s!   € ÷ ñ ˜cð ¨>ð Èñ r   c                óz   €  ^ RI Hp V! V 3/ VB #   \         d   pTP                  RY4       . u Rp?# Rp?ii ; i)zDFire a lifecycle plugin hook; a failing hook is logged, never fatal.)Úinvoke_hookz%s hook failed: %sN)Úhermes_cli.lifecyclerb   rB   rD   )r_   r-   Úkwargsrb   Úexcs   &&,  r   Ú_invoke_hook_safelyrf   h   s>   € ðÝ4Ù˜4Ñ* 6Ñ*Ð*øÜô Ø�‰Ð+¨TÔ7Ø�	ûðús   ‚ ‘:œ5¯:µ:c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úlabelr)   ÚfnzCallable[[], Any]Úerrorsz	list[str]r   r/   r   )r   s   "r   r   r   r   s0   € ÷ Qñ Q˜Cð QÐ%6ð QÀ	ð QÐVZñ Qr   c                óœ   €  V! 4        R#   \          d6   pTP                  T  RT 24       TP                  RYRR7        Rp?R# Rp?ii ; i)z…Post-loop cleanup must never lose the response: each step is guarded
independently and errors surface via ``cleanup_errors`` (#8049).z: zfinalize_turn: _%s failed: %sTr=   N)rB   Úappendr8   )rh   ri   rj   r-   Úerrs   &&&& r   Ú_guarded_cleanuprn   r   sL   € ðQÙ
ŽøÜô QØ�‰˜˜˜r # Ð'Ô(Ø�‰Ð4°eÈ4ˆ×PÒPûðQús   ‚ ‹A–*AÁAc               ó   € V ^8„  d   QhRR/# )r   r   ztuple[Any, Any, bool, Any]r   )r   s   "r   r   r   |   s   € ÷ G[ñ G[ð  ñG[r   c       	        óh  € W P                   8¬  ;'       g    V P                  P                  ^ 8*  p
RpVfÝ   V
'       dÕ   V'       gÍ   V'       gÅ   \        V4      R9   dµ   RV RV P                    R2pV'       d   TpV'       d   RV n        Wn        RpMV P                  RV RV P                    R24       V P                  '       g%   V P                  R	V RV P                    R
2RR7       \        P                  ! 4       p V P                  WR4      pV
'       d0   \        4       '       d    \         P"                  P%                  R4      MRpV'       d   \'        WâV P                   V	4       WW³3#   \         d9    ^ RIHp Rp\        T 4      pT \        P                  ! 4       T,
          R R2p Lži ; i)z{Iteration-budget exhaustion. Returns ``(final_response, _turn_exit_reason,
preserved_verification_fallback, interrupted)``.FNzmax_iterations_reached(r4   Ú)Tu#   âš ï¸� Iteration budget exhausted (u   ) â€” asking model to summariseu%   
âš ï¸�  Iteration budget exhausted (u   ) â€” requesting summary...)Ú
diagnostic)Ú"INTERRUPT_WAITING_FOR_MODEL_PREFIXz.1fzs elapsed).ÚHERMES_KANBAN_TASK>   ÚunknownÚbudget_exhausted)r,   Úiteration_budgetÚ	remainingr)   Ú_response_was_previewedÚ_reused_response_textÚ_emit_diagnostic_statusÚ
quiet_modeÚ_safe_printÚtimeÚ_handle_max_iterationsÚInterruptedErrorr[   rs   r   r
   ÚosÚenvironr$   rI   )ÚagentÚfinal_responser*   ÚinterruptedÚfailedrW   Ú_turn_exit_reasonÚ_pending_verification_responseÚ(_pending_verification_response_previewedr-   rv   Úpreserved_verification_fallbackÚ_summary_startrs   Ú_kanban_tasks   &$$$$$$$$$     r   Ú_resolve_budget_fallbackr�   |   sÂ  € ð 	×.Ñ.Ñ.×WÐW°%×2HÑ2H×2RÑ2RÐVWÑ2Wð ð ',Ð#àÒ×#3¿K×PVÜÐ!Ó"Ð&EÔEà5°nÐ5EÀQÀu×G[ÑG[ÐF\Ð\]Ð^Ðß)ð
 <ˆNß7Ø04�Ô-à.<Ô+Ø.2Ñ+ð ×)Ñ)Ø5°nÐ5EÀQÀu×G[ÑG[ÐF\ð ]0ð 0ôð ×#×#Ð#Ø×!Ñ!Ø<¸^Ð<LÈAÈe×NbÑNbÐMcð d0ð 0Ø<@ð "ô ô "ŸYšY›[ˆNð	vØ!&×!=Ñ!=¸hÓ!W�÷" Ô B× DÒ Dô 	�
‰
�‰Ð+Ô,ØJNð ÷ Ü'¨Àe×FZÑFZÐ\bÔcØÐ.MÐZÐZøô? $ô võ WØ"�Ü$FÀuÓ$MÐ!Ø$FÐ#GÌÏ	Ê	ËÐVdÕHdÐehÐGiÐitÐ!u’ðvús   ÄE. Å.A F1Æ0F1c               ó   € V ^8„  d   QhRR/# rK   r   )r   s   "r   r   r   Æ   s   € ÷ .ñ .À4ñ .r   c                ó<  € \        V RR4      pVRJ d‰   \        V\        4      '       dq   \        V\        4      '       gY   \        V RR4      RJdF   \        V RR4      e5   \        V P                  RR4      p\        V4      '       d   V! V4       R# R# R# R# R# R# R# )zçRoll back the preflight-seeded display count only when an interrupt wins before
any provider response; compaction state (incl. ``-1``) stays with the real-usage
path. Type-pinned guards keep MagicMock/SimpleNamespace doubles inert.Ú _turn_preflight_display_snapshotNTÚ _turn_received_provider_responseFÚcontext_compressorÚ-rollback_interrupted_preflight_display_tokens)Úgetattrr#   r+   r   r’   Úcallable)rƒ   r…   Ú_preflight_snapshotÚ_rollback_fns   &&  r   Ú'_rollback_interrupted_preflight_displayr˜   Æ   s©   € ô " %Ð)KÈTÓRÐà�tÓÜÐ*¬C×0Ò0ÜÐ.´×5Ò5Ü�EÐ=¸uÓEÈTÓQÜ�EÐ/°Ó6ÒBäØ×$Ñ$Ð&UÐW[ó
ˆô �L×!Ò!ÙÐ,Ö-ñ "ñ Cñ Rñ 6ñ 1ñ 	r   c               ó   € V ^8„  d   QhRR/# rK   r   )r   s   "r   r   r   Ù   s   € ÷ :ñ :°Tñ :r   c                ó>   € V P                  V4       \        V4       R# )zäStrip private retry scaffolding first, or a later "continue" replays
assistant("(empty)") / recovery nudges into the same empty-response loop. Only
the synthetic verification nudges go; the assistant candidate persists (#65919).N)Ú)_drop_trailing_empty_response_scaffoldingrX   )rƒ   rW   s   &&r   Ú_drop_transcript_scaffoldingrœ   Ù   s   € ð 
×3Ñ3°HÔ=Ü/°Ö9r   c               ó   € V ^8„  d   QhRR/# )r   r   ztuple[Any, bool]r   )r   s   "r   r   r   á   s   € ÷ !ñ !ÐN^ñ !r   c                ó  € V'       g	   V'       d   VR3# \        V RR4      ;'       g    Rp\        V\        4      '       d   VP                  4       MRpV'       d    \	        V4      P                  4       '       g   T'       d   TR3# VR3# )u‘  An empty terminal completion is not authoritative when the stream already
delivered text; recover before persist so a blank tail isn't frozen (#95514).
Returns ``(final_response, recovered_from_stream)``. Called by the finalizer BEFORE
the fallible tail-shaping/persist steps so the recovered text is already bound when
one of them raises â€” a persist failure must not lose text the user already saw.FÚ _current_streamed_assistant_textÚ T)r”   r#   r)   r%   r   )rƒ   r„   r…   r†   Ú	_streameds   &&&& r   Ú_recover_final_from_streamr¢   á   st   € ÷ —fØ˜uÐ$Ð$Ü˜ÐAÀ2ÓF×LÐLÈ"€IÜ%/°	¼3×%?Ò%?�	—‘Ô!ÀR€Iß<JÔ  Ó0×6Ñ6×8Ò8×XaØ˜$ˆÐØ˜5Ð Ð r   c               ó   € V ^8„  d   QhRR/# rK   r   )r   s   "r   r   r   ð   s   € ÷ ,"ñ ,"Ðdhñ ,"r   c                ó&  € V'       d   ^ RI Hp V! W4       V'       dË   V'       gÃ   V'       d
   VR,          MRp\        V\        4      '       d   VP	                  R4      R8w  d   \        VRRRV/4       MrVP	                  R4      V8w  d]   \        V4      '       dL   VP	                  R4      '       g	   V'       d-   W&R&   \        V4       VP                  \        R4       RV n
        \        V RR4      p\        V4      '       d   V! V4       R# R# )	z’Shape the transcript tail before the durable snapshot (scaffolding already dropped
and ``final_response`` already stream-recovered by the caller).)Úclose_interrupted_tool_sequenceNr    r!   r"   Ú
tool_callsÚ$_apply_persist_user_message_overrideéÿÿÿÿ)Úagent.message_sanitizationr¥   r#   r   r$   r   r&   r   Úpopr   Ú_db_flush_scan_prefixr”   r•   )rƒ   rW   r„   r…   Ú_recovered_from_streamr¥   Ú_tailÚ_apply_overrides   &&&&&   r   Ú_close_transcript_tailr¯   ð   sØ   € ÷
 ÝNÙ'¨ÔA÷
 Ÿk÷ !)�˜–¨dˆÜ˜%¤×&Ò&¨%¯)©)°FÓ*;¸{Ô*JÜ˜8 f¨k¸9ÀnÐ%UÕVà�I‰I�iÓ  NÔ2Ü3°E×:Ò:Ø—‘˜<×(Ò(×,Bð  .�)ÑÜ# EÔ*Ø�I‰IÔ*¨DÔ1Ø*.ˆEÔ'ô ˜eÐ%KÈTÓR€OÜ�× Ò Ù˜Ö!ñ !r   c               ó   € V ^8„  d   QhRR/# rK   r   )r   s   "r   r   r     s   € ÷ )<ñ )<ÐSWñ )<r   c                óæ  €  \        V RR4      pV'       Ed/   \        VRR4      RJ Ed   \        \        VRR4      4      '       dý   V'       dó   \        V RR4      RJdà   \        V RR4      '       gË   \        V4      pVP                  V\        V R	R4      R
7      p\        VRR4      '       d   RVn        RV n        \        V\        4      '       d;   V'       d3   WqJpWqR&   V'       d$   ^ RIH	p	 T	! Y@P                  ;'       g    RR7       V\        V4      8w  d   VP                  RV\        V4      4       R# R# R# R# R# R# R# R#   \         d   p
TP                  RT
4        Rp
?
R# Rp
?
ii ; i)z�Post-turn micro-compaction: absorb the oldest uncompacted exchange into the
rolling summary before persist, amortizing compression across turns.r’   NÚ_micro_compact_enabledFTÚ_micro_compactÚcompression_checkpoint_requiredÚ_persist_disabledÚ_inflight_turn_session_id)Úturn_session_idÚ_flush_scan_cursor_invalidatedrT   )Ú_reset_read_dedup_cachesr    )Ú
session_idz#Micro-compaction: %d -> %d messageszMicro-compaction failed: %s)r”   r•   Úlenr³   r¸   r«   r#   r`   Úagent.conversation_compressionr¹   rº   ÚinforB   )rƒ   rW   r„   r-   Útask_idÚ_compressorÚ_beforeÚ
_compactedÚ_splicedr¹   Ú_mc_errs   &&&&&      r   Ú_micro_compact_after_turnrÄ     sd  € ð&<Ü˜eÐ%9¸4Ó@ˆ÷ ˆKÜ˜Ð%=¸uÓEÈÔMÜœ Ð.>ÀÓE×FÒFßÜ˜Ð@À%ÓHÐPTÓTÜ˜EÐ#6¸×>Ò>ä˜(“mˆGà$×3Ñ3Ø¬'°%Ð9TÐVZÓ*[ð 4ó ˆJô �{Ð$DÀe×LÒLØ=B�Ô:Ø.2�Ô+Ü˜*¤d×+Ò+·
Ø%Ð5�Ø(˜‘ßõ Xá,¨W×AQÑAQ×AWÐAWÐUWÕXØœ#˜h›-Ô'Ø—‘ÐAÀ7ÌCÐPXËMÖZñ (ñ- ?ñ Uñ ñ Gñ Nñ øô: ô <Ø�‰Ð1°7×;Ò;ûð<ús+   ‚AE ÁBE Ã)E Ä4E ÅE0ÅE+Å+E0c               ó   € V ^8„  d   QhRR/# rK   r   )r   s   "r   r   r   K  s   € ÷ 5,ñ 5,Ðosñ 5,r   c                ó`  € \        V RR4      p\        V4      '       d
    V! R4       V'       d   VR,          P	                  R4      MRpRp	VR8X  dš   \        V4       FŠ  p
V
P	                  R4      R	8X  g   K  V
P	                  R
4      '       g   K4  V
R
,          pV'       dF   \        V^ ,          \        4      '       d)   VR,          P	                  R/ 4      P	                  R4      p	 M	  \        R V 4       4      p\        V RR4      pRV'       d   RMR,           pY@P                  Y0P                  V P                  '       d   V P                  P                  M^ V P                  '       d   V P                  P                  M^ YÈV'       d   \        V4      M^ V P                  ;'       g    R.
V'       d   V3MRO5pVR8X  d/   V'       g'   VP                   ! RV,           R,           .VOV	N5!   R# VP"                  ! V.VO5!   R#   \         d    TP                  RRR7        ELi ; i)zƒAlways INFO so agent.log captures WHY every turn ended; WARNING when the last
message is a tool result (the "just stops" scenario).Ú_touch_activityNzturn end loggedzturn-end activity stamp failedTr=   r    Útoolr!   r¦   Úfunctionr_   c              3  ó¸   "  € T FP  p\        V\        4      '       g   K  VP                  R 4      R8X  g   K3  VP                  R4      '       g   KL  ^x € KR  	  R# 5i)r    r!   r¦   N)r#   r   r$   )rO   rQ   s   & r   rR   Ú!_log_turn_exit.<locals>.<genexpr>d  sH   é € ð ÙˆaÜ�aœ×ô 	
Ø#$§5¡5¨£=°KÑ#?ô 	
ØDEÇEÁEÈ,×DW÷ 	
Š“8ùs   ‚AŸA·AÁ
AÚ_turn_originzuTurn ended: reason=%s model=%s api_calls=%d/%d budget=%d/%d tool_turns=%d last_msg_role=%s response_len=%d session=%sz
 origin=%sr    Únonez>Turn ended with pending tool result (agent may appear stuck). z last_tool=%sr¨   r   )r”   r•   rB   Údebugr$   Úreversedr#   r   ÚsumÚmodelr,   rw   ÚusedÚ	max_totalr»   rº   rD   r½   )rƒ   rW   r„   r*   r‡   r…   r-   Ú_touchÚ_last_msg_roleÚ_last_tool_nameÚ_mÚ_tcsÚ_turn_tool_countrÌ   Ú	_diag_msgÚ
_diag_argss   &&&&&&&         r   Ú_log_turn_exitrÜ   K  sø  € ô �UÐ-¨tÓ4€FÜ�×Òð	JÙÐ$Ô%÷ 2:�X˜b•\×%Ñ% fÔ-¸t€NØ€OØ˜Ôä˜8Ö$ˆBØ�v‰v�f‹~ Ö,°·±¸×1EÔ1EØ˜,Õ'�ßœJ t¨A¥w´×5Ò5Ø&*¨2¥h§l¡l°:¸rÓ&B×&FÑ&FÀvÓ&N�OÙñ %ô ñ Ùóó Ðô ˜5 .°$Ó7€Lð	Dç'‰<¨Rõ	1ð ð 	Ÿ;™;¨×8LÑ8LØ',×'=×'=Ð'=ˆ×Ñ×#Ò#À1Ø,1×,B×,BÐ,Bˆ×Ñ×(Ò(ÈØÇ¬#¨nÔ*=ÐUVØ×Ñ×"Ð"˜Fð÷ *ˆ<‰/¨rñ€Jð ˜Ô¯Ø�ŠØLØõØ)õ*ð	
ð ð	
ð )ö	
ð 	�Š�IÐ+ 
Ö+øôS ô 	JØ�L‰LÐ9ÀDˆL×Ið	Jús    H ÈH-È,H-c                óX  €  \        V RR4      ;'       g    / pV'       d_   V P                  4       '       dI   V P                  V4      pV P                  V4      pV'       d   VP	                  4       R,           V,           pV#   \
         d   pTP                  RT4        Rp?T# Rp?ii ; i)z¤Append the verifier advisory when ``write_file`` / ``patch`` calls failed and were
never superseded by a successful write to the same path (surfaces over-claiming).Ú_turn_failed_file_mutationsNú

z(file-mutation verifier footer failed: %s)r”   Ú_file_mutation_verifier_enabledÚ_file_mutations_still_failedÚ$_format_file_mutation_failure_footerÚrstriprB   rÎ   )rƒ   r„   r-   Ú_failedÚfooterÚ_ver_errs   &&&   r   Ú_append_file_mutation_footerrç   ƒ  s¡   € ðKô ˜%Ð!>ÀÓE×KÐKÈˆß�u×<Ñ<×>Ò>Ø×8Ñ8¸ÓAˆGØ×?Ñ?ÀÓHˆFßØ!/×!6Ñ!6Ó!8¸6Õ!AÀFÕ!J�ð Ðøô ô KØ�‰Ð?À×JÐJØÐûðKús,   ‚B –
B ¡B ·)B Á!B ÂB)ÂB$Â$B)c                óÆ  €  V P                  4       '       g   V# T;'       g    RP                  4       pVR9   pV'       * ;'       dY    V'       * ;'       dJ    \        V4      P                  R4      '       * ;'       d#    \	        V4      ^8*  ;'       d    VRR \
        9  pV'       g   V'       g   \        V4      R8X  dw   T P                  T\        V RR4      \        \        V RR4      RR4      \        \        V RR4      ;'       g    R4      R	7      pV'       d   V'       d   TMVR
,           V,           pV#   \         d   p	TP                  RT	4        Rp	?	T# Rp	?	ii ; i)zçTurn-completion explainer: on abnormal exits, surface one explanation from
``_turn_exit_reason``. Only acts when no usable reply exists (empty, "(empty)",
or a short unpunctuated fragment); ``text_response(...)`` exits stay silent.r    Útext_responseNÚpartial_stream_recoveryÚ_last_persistence_error_causeÚ_session_dbÚdb_pathrÑ   )rí   rÑ   rß   z$turn-completion explainer failed: %s)r    z(empty)r¨   )
Ú"_turn_completion_explainer_enabledr%   r)   Ú
startswithr»   Ú_SENTENCE_ENDÚ#_format_turn_completion_explanationr”   rB   rÎ   )
rƒ   r„   r‡   rŠ   r-   Ú	_strippedÚ_is_empty_terminalÚ_is_partial_fragmentÚ_explanationÚ_exp_errs
   &&&&&     r   Ú_explain_abnormal_exitr÷   ™  sg  € ðGØ×7Ñ7×9Ò9Ø!Ð!Ø#×)Ð) r×0Ñ0Ó2ˆ	Ø&¨/Ñ9Ðð #Ô"÷ 4ð 4Ø3Ô3÷4ð 4äÐ)Ó*×5Ñ5°oÓFÔF÷4ð 4ô �I“ "Ñ$÷4ð 4ð ˜"˜#�¤mÑ3ð 	÷ ×!5¼Ð=NÓ9OÐSlÔ9lØ ×DÑDØ!¤7¨5Ð2QÐSWÓ#XÜ¤¨¨}¸dÓ CÀYÐPTÓUÜœ' %¨°"Ó5×;Ð;¸Ó<ð Eó ˆL÷
 ç1C¡ÈÐU[ÕI[Ð^jÕIj�ð Ðøô ô GØ�‰Ð;¸X×FÐFØÐûðGúsW   ‚D8 ˜D8 šD8 £#D8 ÁD8 Á&D8 Á=D8 ÂD8 Â(D8 Â0A+D8 ÄD8 Ä$D8 Ä8E ÅEÅE c               ó   € V ^8„  d   QhRR/# )r   r   zOptional[Any]r   )r   s   "r   r   r   ¹  s   € ÷ 	ñ 	 mñ 	r   c                óÐ   € \        V 4       FV  pVP                  R4      R8X  d    R# VP                  R4      R8X  g   K4  VP                  R4      '       g   KM  VR,          u # 	  R# )zÞReasoning from the CURRENT turn only: stop at this turn's user message (#17055),
but take the most recent non-empty reasoning since many providers emit it on the
tool-call step and leave the final step with reasoning=None.r    ÚuserNr!   Ú	reasoning)rÏ   r$   )rW   r   s   & r   Ú_last_turn_reasoningrü   ¹  sT   € ô ˜Ö!ˆØ�7‰7�6‹?˜fÔ$ÚØ�7‰7�6‹?˜kÖ)¨c¯g©g°k×.BÔ.BØ�{Õ#Ò#ñ	 "ñ
 r   c               ó   € V ^8„  d   QhRR/# ©r   r   ztuple[Any, bool, Optional[Any]]r   )r   s   "r   r   r   Å  s   € ÷ 6ñ 6ð %ñ6r   c               ó¶   € \        WWSVR7      w  rp	\        V RR4      '       g3   \        RVV P                  VVVV\	        V4      V P
                  VR7
       WV	3# )a  Resolve the turn's ``transform_llm_output`` outcome, then fire ``post_llm_call`` once per
turn after the tool loop. Returns ``(final_response, transformed, pre_transform_response)``.

The transform itself normally already ran before the assistant row was first persisted
(``apply_llm_output_transform`` from ``finish_text_response`` / ``_persist_step``); this
call returns that recorded outcome, and only fires the hook here when no earlier seam saw a
response (e.g. text that only appeared through ``_explain_abnormal_exit``).)Úturn_idÚplatformr-   rµ   FÚpost_llm_call)rº   r¾   r   Úuser_messageÚassistant_responseÚconversation_historyrÑ   r  )Úapply_llm_output_transformr”   rf   rº   r`   rÑ   )
rƒ   r„   r-   r  Úeffective_task_idr   Úoriginal_user_messagerW   ÚtransformedÚpre_transforms
   &&&$$$$$  r   Ú_apply_output_hooksr  Å  sm   € ô 2LØ wÈ&ô2Ñ.€N ô �5Ð-¨u×5Ò5ÜØ˜VØ×'Ñ'Ø%ØØ.Ø-Ü!% h£Ø—+‘+Øõ
	
ð ¨Ð5Ð5r   r  r-   c               ó   € V ^8„  d   QhRR/# rþ   r   )r   s   "r   r   r   ã  s   € ÷ '6ñ '6à$ñ'6r   c          
     óÔ  € Vf   ^ RI Hp \        V RR4      p\        V\        4      '       d(   \        V4      ^8X  d   V^ ,          V8X  d
   Vw  rgpWV3# V'       g   VRR3# Vf   \        V RR4      ;'       g    RpRRr‡\        RTTV P                  ;'       g    RV P                  VVR7       F)  p	\        V	\        4      '       g   K  V	'       g   K%  YR	rqp M	  W'V3V n
        WV3# )
u\  Fire ``transform_llm_output`` once per turn and return
``(final_response, transformed, pre_transform_response)``.

Called BEFORE the final assistant row is first persisted â€” from ``finish_text_response``
ahead of its durable flush, and from ``finalize_turn._persist_step`` ahead of the
recovery-path tail close â€” so the text the user sees is the text stored in SQLite/JSON and
replayed next turn (#44239). SQLite treats a non-blank assistant row as settled (a re-flush
adopts the stored content rather than overwriting it), so transforming after that first
write can never reach the durable store. Idempotent per ``turn_id``: later callers in the
same turn get the recorded outcome instead of a second hook firing. Only the current
turn's not-yet-written text is touched â€” earlier turns and the system prompt are never
rewritten (prompt-cache invariant).N©r-   Ú_llm_output_transformFr  r    Útransform_llm_output)Úresponse_textrº   rÑ   r  r   T)r[   r-   r”   r#   Útupler»   rf   rº   rÑ   r)   r  )
rƒ   r„   r   r  r-   ÚrecordedÚ_r	  r
  Ú_hook_results
   &&$$$     r   r  r  ã  sõ   € ð ‚~Ý2Ü�uÐ5°tÓ<€HÜ�(œE×"Ò"¤s¨8£}¸Ô'9¸hÀq½kÈWÔ>TØ(0Ñ%ˆ˜Ø¨MÐ9Ð9ßØ˜u dÐ*Ð*ØÒÜ˜5 *¨dÓ3×9Ð9°rˆØ!&¨�ä+Ø Ø$Ø×#Ñ#×)Ð) rØ�k‰kØØ÷ˆô �l¤C×(Ô(¯\©\Ø9GÐW[¨;ˆMÙñð $+¸Ð"G€EÔØ¨Ð5Ð5r   rˆ   r‰   Fc               óÄ  a aaaaaaaa	a a!a"€ ^ RI Ho! \        S SVSSSVVVS!R7
      w  orÏoS'       g¹   S'       g±   S'       d©   \        SRM,          \        4      '       dŒ   SRM,          P                  R4      R8X  do   \        S RR4      ;'       g    RP                  4       '       gD   RpRoRo S P                  4       '       d   S P                  RR	4      ;'       g    RoS'       g   R
oS'       d   R	M
\        V4      pVe   VP                  '       d   RoSR	J;'       dP    S'       * ;'       dA    S'       * ;'       d2    VS P                  8  ;'       g    \        V4      P                  R4      o \!        S S4       ^ RIHp V! S VSSSR7       . p^ RIHo" \+        RV V"3R lVS!4       \+        RV V VV	3R lVS!4       \+        RV V3R lVS!4       V VVVVVV!VV3	R lp\+        RVVS!4       \-        \        4      ;_uu_ 4        SS n        R	R	R	4       \1        S SSW,SS!4       S'       d   S'       g   \3        S SS!4      oS'       g   \5        S SWÏS!4      o\        S RR	4      ;'       g    RpRpR	pS'       d    S'       g   \7        S SS!VSSV
SR7      w  opp ^ RI Hp V! S S\        S RR	4      S!SSVSSVR7
       \        S\        4      '       d   \=        S4      oRSR\?        S4      R SR!TR"S R#TR$SR%RR&SR'TR(TR)\        S R*R4      R+\A        S4      ;'       d    S\        S R,R	4      8H  R-S PB                  /\E        S 4      CR.S PF                  R/S PH                  /C\J         Uu/ uF  pV\        S R0V 24      bK  	  upCR1\        S PL                  R1^ 4      ^ 8”  d,   \        S PL                  R2S PL                  PN                  4      M\        S PL                  R1^ 4      ;'       g    ^ /C\P         Uu/ uF  pV\        S R0V 24      bK  	  upCR3\        S R4/ 4      ;'       g    / P                  R54      ;'       g    / P                  R34      R6S PR                  /CpS PT                  e   S PT                  PW                  4       VR7&   S'       dS   \        V4      R88X  dC   ^ R9I,H-p S;'       g    R:V! 4        R;2VR<&   \        S R=R	4      pR>T;'       g    R?,           VR@&   MEVeB   S'       d   S;'       g    \        V4      VR<&   \]        VVP^                  VP`                  4       V'       d   VVRA&   \        S RBR	4      ;'       g    S Pb                  ! 4       pV'       d   VVRC&   RS n2        R	S n3        S'       d"   S Ph                  '       d   S Ph                  VRD&   S Pk                  4        R	S n6        ^ REI7H8p V! S 4       S Pr                  ^ 8„  ;'       d1    S Pt                  S Pr                  8¬  ;'       d    RFS Pv                  9   pV'       d   ^ S n:        S Py                  V
SSSRG7       S'       di   S'       ga   \        S RHR4      '       gN   V'       g	   V'       d>   \-        \        4      ;_uu_ 4        S P{                  \}        S4      VVRI7       R	R	R	4       \        S RJR4      '       g+   \        RKS!S PR                  SSS SSVS PB                  VRL7       R	S n@        RS nA        V#   \         d    Ro EL i ; i  + '       g   i     ELþ; i  \         d   pS!P;                  RT4        R	p?EL{R	p?ii ; iu upi u upi   + '       g   i     Lº; i)NzCRun the post-loop finalization and return the turn ``result`` dict.r  )	r„   r*   r…   r†   rW   r‡   rˆ   r‰   r-   r    rÈ   rŸ   r    Úpending_tool_resultTNzmNo reply: the turn stopped while a tool result was still pending. Send `continue` to let the model summarize.ztext_response()Úfinish_turn)r…   r†   )Ústart_deferred_title_upgrader  c                 ó   <€ S! S 4      # rN   r   )rƒ   r  s   €€r   Ú<lambda>Úfinalize_turn.<locals>.<lambda>\  s   ø€ Ñ=YÐZ_Ô=`r   Úsave_trajectoryc                 ó<   <€ S P                  S\        S4      S4      # rN   )Ú_save_trajectoryr	   )rƒ   Ú	completedrW   r  s   €€€€r   r  r  `  s   ø€ �×&Ñ& xÔ1PÐQ]Ó1^Ð`iÔjr   Úcleanup_task_resourcesc                 ó&   <€ S P                  S4      # rN   )Ú_cleanup_task_resources)rƒ   r  s   €€r   r  r  d  s   ø€ ¨%×*GÑ*GÐHYÔ*Zr   c                 ó  <	€ \        SS	4       \        SSSS4      w  op S'       d   S'       g   \        SSS
SR 7      w  o p\        SS	SSV 4       S'       g   S'       g   \	        SS	SSS4       SP                  S	S4       R# ))r   r-   N)rœ   r¢   r  r¯   rÄ   Ú_persist_session)r¬   r  rƒ   r  r  r†   r„   r…   r-   rW   r   s     €€€€€€€€€r   Ú_persist_stepÚ$finalize_turn.<locals>._persist_stepl  s~   ø€ ä$ U¨HÔ5Ü1KØ�> ;°ó2
Ñ.ˆÐ.÷ §+Ü#=¸eÀ^Ð]dÐmsÔ#tÑ ˆN˜A˜qÜ˜u h°ÀÐMcÔdß§6Ü% e¨X°~ÀvÐO`ÔaØ×Ñ˜xÐ)=Ö>r   Úpersist_sessionr  F)r  r  r   r  rW   )Ú$_notify_context_engine_turn_completeÚ_last_turn_usage)Úusager-   r   r¾   r*   r…   r†   Úturn_exit_reasonz(on_turn_complete notification failed: %sr„   Úlast_reasoningrW   Ú	api_callsr   r,  r†   Úpartialr…   Úresponse_transformedÚpre_transform_responseÚresponse_previewedry   Úresponse_reusedrz   rÑ   ÚproviderÚbase_urlÚsession_Úlast_prompt_tokensÚlast_real_prompt_tokensÚservice_tierÚrequest_overridesÚ
extra_bodyrº   Ú	guardrailÚsession_persistence_failed)Úprofile_cli_selectoruR   session storage could not be written â€” check the state database health (`hermes z&doctor`), then send your message againr8   rë   zsession_persistence_failed:ru   Úfailure_reasonÚcleanup_errorsÚ_drain_leftover_steerÚpending_steerÚinterrupt_message)Úend_voice_turn_routeÚskill_manage)r  r„   r…   rW   Úskip_background_review)Úmessages_snapshotÚreview_memoryÚreview_skillsrµ   Úon_session_end)	rº   r¾   r   r   r†   r…   r,  rÑ   r  r¨   )Br[   r-   r�   r#   r   r$   r”   r%   rî   rñ   rB   r   Ú
fails_turnr,   r)   rï   r˜   Ú/hermes_cli.observability.shared_metrics_harnessr  Úagent.turn_contextr  rn   r   Ú_session_messagesrÜ   rç   r÷   r  r)  rD   r   rü   r   rÑ   r   r4  r5  Ú_SESSION_TOKEN_KEYSr’   r7  Ú_SESSION_COST_KEYSrº   Ú_tool_guardrail_halt_decisionÚto_metadataÚhermes_constantsr>  r   ÚreasonÚ	retryableÚ_drain_pending_steerry   rz   Ú_interrupt_messageÚclear_interruptÚ_stream_callbackÚagent.voice_turn_routerD  Ú_skill_nudge_intervalÚ_iters_since_skillÚvalid_tool_namesÚ_sync_external_memory_for_turnÚ_spawn_background_reviewr`   rf   r�   r‘   )#rƒ   r„   r*   r…   r†   rW   r  r  r   r  r  Ú_should_review_memoryr‡   rˆ   r‰   rŠ   Ú_exit_failurer  Ú_cleanup_errorsr&  Ú	_platformÚ_response_transformedÚ_pre_transform_responser)  re   ÚkeyÚresultr>  Ú_causeÚ_leftover_steerrD  Ú_should_review_skillsr   r-   r  s#   fd$ddddddd$$$$$                 @@@r   Úfinalize_turnrk    s�  ÿû€ õ /äVnØ˜n¸^Ø¨¸Ø+Ø'EØ1YØôWÑS€NÐ%È÷& ßßÜ�x •|¤T×*Ò*Ø�R�L×Ñ˜VÓ$¨Ô.Ü˜Ð BÀBÓG×MÐMÈ2×TÑT×VÒVà1ÐØˆØˆð	 Ø×7Ñ7×9Ò9à×=Ñ=Ð>SÐUYÓZ×`Ð`Ð^`ð ÷
 ð>ð ÷ (‘DÔ-@ÐARÓ-S€MØÒ  ]×%=×%=Ð%=Øˆð
 	˜dÐ"÷ 	kð 	kØŒJ÷	kð 	kàŒO÷	kð 	kð ˜e×2Ñ2Ñ2×iÐi´cÐ:KÓ6L×6WÑ6WÐXhÓ6ið	 ô ,¨E°;Ô?åKÙ�Ð(¨.ÀkÐZ`Õaà!#€Oõ @ÜÐ3Õ5`ÐbqÐsyÔzäØßjØ˜ôô
 Ø Õ"ZØ˜ô÷?õ ?ô" Ð&¨°ÈÔOô 
”)×	Õ	Ø"*ˆÔ÷ 
ô �5˜( N°NÐWbÐdjÔk÷ ŸkÜ5°e¸^ÈVÓTˆßÜ/Ø�>Ð#4ÐW]ó
ˆô ˜˜z¨4Ó0×6Ð6°B€IØ!ÐØ"ÐßŸkÜI\Ø�> 6°IÐQbØÐ3HÐS[ôJ
ÑFˆÐ-Ð/FðHÝPÙ,Ø�8¤7¨5Ð2DÀdÓ#KÐTZØÐ%6À~Ø#¨FÐEVõ	
ô  �.¤#×&Ò&Ü-¨nÓ=ˆð 	˜.ØÔ.¨xÓ8Ø�HØ�^Ø�YØÐ-Ø�&Ø�5Ø�{ØÐ 5Ø Ð"9Øœg eÐ-FÈÓNð 	œ4 Ó/×sÐs°NÄgÈeÐUlÐnrÓFsÑ4sØ�—‘ð!"ô$ ˜eÓ
$ð%"ð& 	�E—N‘NØ�E—N‘Nñ)"õ* =PÓ
PÑ<O°Sˆ3”˜ ¨#¨Ð/Ó0Ò0Ñ<OÑ
Pð+"ð. 	ä�u×/Ñ/Ð1EÀqÓIÈAÔMô �E×,Ñ,Ð.GÈ×IaÑIa×ItÑItÔuä˜×1Ñ1Ð3GÈÓK÷ð ð ñ7"õ8 =OÓ
OÑ<N°Sˆ3”˜ ¨#¨Ð/Ó0Ò0Ñ<NÑ
Oð9"ð< 	Ü�UÐ/°Ó4×:Ð:¸×?Ñ?ÀÓM×SÐSÐQSß
‰#ˆnÓ
Ø�e×&Ñ&ñC"€FðF ×*Ñ*Ò6Ø#×AÑA×MÑMÓOˆˆ{Ñ÷ ”#Ð'Ó(Ð,HÔHÝ9ð )÷ 
ð 
ðÙ3Ó5Ð6Ð6\ð^ð 	ˆw‰ô ˜Ð ?ÀÓFˆØ#@ÀF×DWÐDWÈiÕ#XˆÐÒ Ø	Ò	"ßØ,×FÐF´Ð4EÓ0FˆF�7‰OÜ�f˜m×2Ñ2°M×4KÑ4KÔLçØ#2ˆÐÑ ô ˜uÐ&=¸tÓD×bÐbÈ×HbÑHbÐbÓe€OßØ"1ˆˆÑØ$)€EÔ!Ø"&€EÔß�u×/×/Ð/Ø&+×&>Ñ&>ˆÐ"Ñ#Ø	×ÑÔØ!€EÔõ <Ù˜Ôð 	×#Ñ# aÑ'÷ 	5ð 	5Ø×$Ñ$¨×(CÑ(CÑC÷	5ð 	5à˜e×4Ñ4Ñ4ð ÷
 Ø#$ˆÔ ð 
×(Ñ(Ø3ÀNØ¨(ð )ô ÷ 	ßÜ˜Ð7¸×?Ò?ß"×&;ä”i× Õ Ø×*Ñ*Ü"& x£.Ð@UØ3ð +ô ÷ !ô �5Ð-¨u×5Ò5ÜØ˜fØ×'Ñ'Ø%ØØØØ#Ø.Ø—+‘+Øõ	
ð .2€EÔ*Ø-2€EÔ*Ø€Møôi ô 	 Ø‹Nð	 ú÷R 
×	Ð	ûô@ ô HØ�‰ÐAÀ3×GÒGûðHüòF Qùò P÷R !× úsZ   Â0[2 Ã[2 Ã[2 È	\Ê#\ Í,]Ï:]
Ù?]Û2\Ü\Ü\	Ü]Ü%\=Ü=]Ý]	)Ú_verification_stop_syntheticÚ_pre_verify_synthetic>   Ú!rq   Ú.Ú?Ú`õ   ã€‚õ   ï¼�õ   ï¼Ÿ)Úinput_tokensÚoutput_tokensÚcache_read_tokensÚcache_write_tokensÚreasoning_tokensÚprompt_tokensÚcompletion_tokensÚtotal_tokens)Úestimated_cost_usdÚcost_statusÚcost_source)9Ú__doc__Ú
__future__r   Úloggingr�   r~   Ú
contextlibr   Útypingr   r   r   r   r   Úagent.codex_responses_adapterr	   Úagent.delegation_contextr
   Úagent.interrupt_controlr   Úagent.turn_failure_copyr   r   Úagent.context_compressorr   Úagent.message_contentr   Úagent.message_metadatar   r   r©   r   Úagent.served_modelr   rV   rð   rO  rP  r&   rI   rX   r]   rf   rn   r�   r˜   rœ   r¢   r¯   rÄ   rÜ   rç   r÷   rü   r  r  rk  r   r   r   Ú<module>r�     sî   ðñRõ #ã Û 	Û Ý ß 7Õ 7å IÝ GÝ Fß FÝ 9Ý 6ß JÝ ;Ý 2ð
 $]Ð  â>€ðÐ ð JÐ õ@õ%
õPòFõõQõG[õT.õ&:õ!õ,"õ^)<õX5,òpò,õ@	õ6ð<'6Ø04ð'6Ø=A÷'6ðT_ð 7;ð_ð .3ö	_r   