+
    iHàjbG  ã                  ó"  € R t ^ RIHt ^ RIHt ^ RIt^ RIt^ RIHtH	t	H
t
 ^ RIHt ^ RIHt ^ RIHtHtHtHt ^ RIHtHt ^ R	IHt ]P2                  ! R
4      t] ! R R4      4       tR R ltR R ltR R lt] ! R R4      4       tR R lt R# )u  Post-call response verification for the conversation turn's retry loop: stop the thinking
spinner, validate the response shape (retry / eager fallback / terminal invalid-response
result), derive ``finish_reason`` per api_mode, route content-policy refusals and
``length`` truncation, fold usage into the compressor, and mark the logical relay call
complete. Nothing here imports ``agent.conversation_loop`` at module level (cycle) â€”
loop-internal helpers resolve lazily so ``patch("agent.conversation_loop.X")`` keeps intercepting.
)Úannotations)Ú	dataclassN)ÚAnyÚDictÚOptional)ÚFailoverReason)Ústop_thinking_spinner)Úinvalid_response_failure_reasonÚprovider_label_forÚ	site_copyÚstamp_failure)Úhandle_content_policy_refusalÚrecover_from_truncation)Úrecord_response_usagez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tR]R&   RtR# )ÚResponseCheckVerdictuþ   ``action``: ``"break"`` (leave the retry loop â€” success, or a fallback/refusal restart
armed on ``_retry``), ``"continue"`` (retry the API call) or ``"return"`` (``result`` is
the turn's result dict). The other fields are the retry-loop locals rebound.ÚstrÚactionr   Úthinking_spinnerÚmessagesÚactive_system_promptÚfinish_reasonÚretry_countÚcompression_attemptsÚlength_continue_retriesÚtruncated_response_partsÚtruncated_tool_call_retriesÚ_preflight_compression_blockedÚ_last_preflight_pressureÚapi_durationNúOptional[dict[str, Any]]Úresult© ©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r!   Ú__static_attributes__r"   ó    Ú>/home/ubuntu/.hermes/hermes-agent/agent/turn_response_check.pyr   r      sa   ‡ ñTð ƒKØÓØƒMØÓØÓØÓØÓØ Ó Ø!Ó!Ø!$Ó$Ø$'Ó'Ø!Ó!ØÓØ'+€FÐ$×+r+   r   c               ó    € V ^8„  d   QhRRRR/# )é   Úresponser   Úreturnr   r"   )Úformats   "r,   Ú__annotate__r2   /   s   € ÷ ñ  3ð ¨3ñ r+   c                ó¢  € \        V RR4      p\        V\        4      '       d   VP                  4       P	                  4       p\        V RR4      p\        V\
        4      '       d   VP                  R4      pM\        VRR4      pVe(   \        V4      P                  4       P	                  4       pVR8X  d
   VR9   d   R# VR8X  d
   VR8X  d   R# R# )	z›Responses API max-output exhaustion is a normal Codex incomplete turn: route it to
the Codex continuation path (``"incomplete"``), not the length rollback.ÚstatusNÚincomplete_detailsÚreasonÚ
incompleteÚcontent_filterÚstop>   ÚlengthÚmax_output_tokens)ÚgetattrÚ
isinstancer   ÚstripÚlowerÚdictÚget)r/   r4   r5   Úincomplete_reasons   &   r,   Ú_codex_finish_reasonrC   /   sÁ   € ô �X˜x¨Ó.€FÜ�&œ#×ÒØ—‘“×%Ñ%Ó'ˆÜ  Ð+?ÀÓFÐÜÐ$¤d×+Ò+Ø.×2Ñ2°8Ó<Ñä#Ð$6¸À$ÓGÐØÒ$ÜÐ 1Ó2×8Ñ8Ó:×@Ñ@ÓBÐØ�ÔÐ"3Ð7VÔ"VÙØ�ÔÐ"3Ð7GÔ"GÙÙr+   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r.   Úagentr   r/   r   r0   r   r"   )r1   s   "r,   r2   r2   C   s(   € ÷ ñ  ð °ð ¸sð Àsñ r+   c                óè  € V P                   R 8X  dF   \        V4      pVR8X  d2   V P                  4       P                  V4      P                  '       d   R# V# V P                  4       pV P                   R8X  d   VP                  V4      # VP                  V4      pVP                  pV P                   R8w  d<   V P                  W5V4      '       d$   V P                  V P                   R2RRR7       R# V# )Úcodex_responsesr7   r:   Úanthropic_messagesÚbedrock_converseuA   âš ï¸�  Treating suspicious Ollama/GLM stop response as truncatedT)ÚforceÚ
diagnostic)
Úapi_moderC   Ú_get_transportÚnormalize_responseÚ
tool_callsÚresponse_finish_reasonr   Ú_should_treat_stop_as_truncatedÚ_vprintÚ
log_prefix)rE   r/   r   r   Ú	transportÚ
normalizeds   &&&   r,   Ú_derive_finish_reasonrV   C   sì   € Ø‡~�~Ð*Ô*Ü,¨XÓ6ˆð ˜LÔ(¨U×-AÑ-AÓ-C×-VÑ-VÐW_Ó-`×-k×-kÐ-kÙØÐØ×$Ñ$Ó&€IØ‡~�~Ð-Ô-Ø×/Ñ/°Ó9Ð9Ø×-Ñ-¨hÓ7€JØ×,Ñ,€MØ‡~�~Ð+Ô+°×0UÑ0UØ 8÷1ò 1ð 	�‰Ø×ÑÐ Ð aÐbØ 4ð 	ô 	
ñ ØÐr+   c          4     ó€   € 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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.   rE   r   r/   Ú_retryr   r   Úapi_messagesÚ
api_kwargsr   Úconversation_historyr   r   Úmax_retriesr   Úmax_compression_attemptsr   r   r   Úcurrent_turn_user_idxÚapi_call_countÚapi_request_idÚapi_start_timeÚeffective_task_idÚturn_idr   r   r0   r   r"   )r1   s   "r,   r2   r2   \   s(  € ÷ ~ñ ~Øð~Ø ð~Ø*-ð~ØADð~ØPSð~àð~à#&ð~à>Að~àY\ð~ð ð~ð &)ð~ð 8;ð~ð SVð~ð "ð	~ð =@ð	~ð \_ð	~ð
 "%ð~ð
 >Að~ð
 SVð~ð ð~ð *-ð~ð BEð~ð PSð~ð %(ð~ð DGð~ð ñ~r+   c               ó¸  aaaa	a
aaaaaaa&€ ^ RI Hp R3R VVVV&VV	VVV
VVV3R lllp\        P                  ! 4       V,
          o&\        V S4      oV P                  '       g#   V P                  V P                   RS&R R24       V P                  '       dR   V'       d   \        VRR	4      MR	p\        P                  ! R
T R\        VR4      '       d   VP                  MR	 24       V! W4      w  ppV'       dŸ   \        V 3/ RVbRVbRVbRSbRSbRVbRVbRSbRVbRS
bRVbRSbRVbRVbRVbRS&bRVbRVb pVP                  oVP                  oVP                   o
VP"                  oVP$                  R8w  d   V! VP$                  VP&                  4      # R V n        \+        WS4      o	^ R!IHp V! WS	4       S	R"8X  dX   \1        WVSSWVSVVVVVVS
VR#7      p RoV P                  oV P$                  R$8X  d   V! R$V P&                  4      # ^ o
^ oV! R%4      # S	R&8X  d�   \3        WS	VSW†VVVSSSS
SR'7      p!V!P4                  oV!P6                  oV!P8                  oV!P:                  oV!P                   o
V!P"                  oV!P$                  R49   d   V! V!P$                  V!P&                  4      # \=        WSVS&SVR(7      p"V"P"                  oV"P>                  '       d   R)oRoR)Vn         V PB                  R*8X  d    ^ R+I"H#p# ^ R,I$H%p$ V#! V$! V 4      R-7       ^ R.I'H(p% V%PS                  VR/R07       V PU                  R1V R224       V! R%4      #   \L         d     LCi ; i)5zôVerify ``response`` in the original order. The retry buffer is NOT cleared on success
(bytes back != usable content); ``_preflight_compression_blocked``/``_last_preflight_pressure``
reset only when the usage fold re-arms the compression budget.)Úvalidate_response_shapeNc               ó$   € V ^8„  d   QhRRRRRR/# )r.   r   r   r!   r    r0   r   r"   )r1   s   "r,   r2   Ú(check_api_response.<locals>.__annotate__j   s#   € ÷ 
ñ 
˜ð 
Ð&>ð 
ÐJ^ñ 
r+   c                ó6   <€ \        V SS	SSS
SSSSSSSVR 7      # ))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   s   &&€€€€€€€€€€€€r,   Ú_verdictÚ$check_api_response.<locals>._verdictj   s7   ø€ Ü#ØÐ,<ÀxØ!5À]Ø#Ð:NØ$;Ø%=Ø(CØ+IØ%=ÈLØô

ð 
	
r+   u   â�±ï¸�  API call completed in z.2fÚsÚmodelzN/AzAPI Response received - Model: z	, Usage: Úusager/   Úerror_detailsrX   r   r   rY   rZ   r   r[   r   r\   r   r_   r`   ra   r   rb   rc   ÚfallthroughT)Úrecord_reply_finishr8   )r   r   rY   rZ   r   r[   r_   rb   rc   r`   ra   r   r\   r0   Úbreakr:   )r   r[   rZ   r_   rb   r^   r   r   r   r   r   )r   r_   r   r   r]   FÚnous)Úclear_nous_rate_limit)Úis_anonymous_agent)Ú	anonymous)Ú	relay_llmÚsuccess)Úoutcomez
API call #z
 completed©N)r0   rq   Úcontinue)+Úagent.turn_recoveryre   Útimer   Ú
quiet_moderR   rS   Úverbose_loggingr<   ÚloggingÚdebugÚhasattrrm   Úretry_invalid_responser   r   r   r   r   r!   Ú _turn_received_provider_responserV   Ú/hermes_cli.observability.shared_metrics_harnessrp   r   r   r   r   r   r   r   ÚrearmedÚhas_retried_429ÚproviderÚagent.nous_rate_guardrs   Úhermes_cli.anon_authrt   Ú	ExceptionrE   rv   Úcomplete_logical_callÚ_touch_activity)'rE   r/   rX   r   r   rY   rZ   r   r[   r   r   r\   r   r]   r   r   r   r^   r_   r`   ra   rb   rc   r   r   re   ri   Ú
resp_modelÚresponse_invalidrn   Ú_ivrp   Ú_rvÚ_tvÚ_usage_outcomers   rt   rv   r   s'   &$$dd$$d$dd$d$ddd$$$$$$dd             @r,   Úcheck_api_responser“   \   sç  ÿû€ õ <÷
÷ 
õ 
ô —9’9“; Õ/€Lô -¨UÐ4DÓEÐà××ÐØ�‰˜×)Ñ)Ð*Ð*HÈÐVYÐHZÐZ[Ð\Ô]à××Ðß:B”W˜X w°Ô6Èˆ
Ü�ŠÐ7¸
°|À9Ô_fÐgoÐqx×_yÒ_yÈXÏ^Ê^ð  @Eð  MFð  Gô  	Há&=¸eÓ&NÑ#Ð�mßÜ$Øò	
Ù$ð	
Ù4Að	
ÙJPð	
á-ð	
á8@ð	
áO[ð	
ñ "ð	
ñ 9Mð	
ñ "6ð		
ñ DOð		
ñ
 $ð	
ñ
 ;Oð	
ñ *ð	
ñ ;Ið	
ñ *ð	
ñ 9Eð	
ñ 0ð	
ñ :Að	
ˆð ×/Ñ/ÐØ"×7Ñ7ÐØ—o‘oˆØ"×7Ñ7ÐØ�:‰:˜Ô&Ù˜CŸJ™J¨¯
©
Ó3Ð3à-1€EÔ*Ü)¨%¸8ÓD€MÝSÙ˜¨Ô7ð Ð(Ô(Ü+Ø˜VÐ6FÐQYØ%Ø!5ÐL`Ø)Ð=NÐX_Ø)¸.ÐVaØ#ô
ˆð  ÐØ"×7Ñ7ÐØ�:‰:˜Ô!Ù˜H c§j¡jÓ1Ð1ØˆØ ÐÙ˜Ó Ð à˜Ô Ü%Ø˜]¨F¸XØ!5Ø)Ð=NØ"7Ø$;Ø%=Ø(CÐQ\Ø!5ô	
ˆð —<‘<ˆØ"%×"=Ñ"=ÐØ#&×#?Ñ#?Ð Ø&)×&EÑ&EÐ#Ø—o‘oˆØ"×7Ñ7ÐØ�:‰:Ð8Ô8Ù˜CŸJ™J¨¯
©
Ó3Ð3ô +Ø (¸>Ø!Ð8LØ!9ô€Nð
 *×>Ñ>ÐØ××ÐØ).Ð&Ø#'Ð à"€FÔà‡~�~˜Ôð	ÝCÝ?Ù!Ñ,>¸uÓ,EÕFõ  à×#Ñ# N¸IÐ#ÔFØ	×Ñ˜J ~Ð&6°jÐAÔBÙ�GÓÐøô ô 	Ùð	ús   Ë:M ÍMÍMc                  ó\   € ] tR t^Ýt$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R	tR
]R&   RtR	# )ÚInvalidResponseVerdicta+  ``action``: ``"continue"`` (retry the API call after backoff), ``"break"`` (fallback
armed / redirect pending) or ``"return"`` (``result``: terminal invalid-response result or
interrupt during backoff). Rebinds ``thinking_spinner``/``active_system_prompt``/
``retry_count``/``compression_attempts``.r   r   r   r   r   r   r   Nr    r!   r"   r#   r"   r+   r,   r•   r•   Ý   s1   ‡ ñ1ð
 ƒKØÓØÓØÓØÓØ'+€FÐ$×+r+   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RRRRRRRRRRRRRRRR/# )r.   rE   r   r/   rn   rX   r   r   rY   rZ   r   r[   r   r\   r   r_   r`   ra   r   rb   rc   r0   r•   r"   )r1   s   "r,   r2   r2   ì   sÞ   € ÷ t ñ t Øðt Ø ðt Ø14ðt Ø>Aðt ØUXðt àðt à!$ðt à25ðt àMPðt ð ðt ð -0ðt ð ?Bðt ð Z]ðt ð ð	t ð *-ð	t ð ?Bð	t ð RUð	t ð
 ðt ð
 &)ðt ð ñt r+   c               óì  aaa
a€ ^ RI Hp ^ RIHp ^ RIHpHpHp R:R VVV
V3R lllpT P                  TTTYßTRRP                  V4      ;'       g    R	\        \        VR
R4      RR4      S
VRRR7       \        V S4      oV! W4      w  ppVe·   VP                  \        P                  \        P                  39   g   VP                   '       dv   V P#                  RVP$                  VP                  VVP&                  R7      w  pVn        V'       d2   V P)                  RVP                  P*                   R24       V! R4      # S
^,          o
V P,                  \/        V P0                  4      8  d   V P)                  R4       V P3                  4       '       d   V! WSV4      o^ o
^ oV! R4      # V! WV4      w  pppV P5                  RS
 RV RRP                  V4       24       V P5                  RV 24       V P5                  RV P7                  V4       24       V P5                  RV 24       S
V8¼  Ed"   V P9                  4       '       d   V P)                  RV R24       V P3                  4       '       d   V! WSV4      o^ o
^ oV! R4      # V P;                  4        V P=                  RV R24       \>        PA                  RV PB                  V4       V PE                  WY4       VR;9   g   VPG                  R 4      '       d   \I        V PJ                  4      MTp\M        RVVVR!7      p V! R"\O        R#V R$VR%R&R'VR
R(V R)V 2R*R/\Q        V4      R4      4      # V! S
R+R,R-7      p!V P5                  R.V!R/ R0V R124       \>        PS                  R2S
VRP                  V4      V4       V! V V!W5V	VR3R4V R5S
 RV R62R7S
 RV R82R97	      p"V"e
   V! R"V"4      # VPT                  '       d	   V! R4      # V! R4      # )<zÝMalformed/empty provider response: fire the error hook, stop the spinner, eager
fallback (empty responses often mean rate limiting), terminal result at max retries,
else jittered backoff that preserves a pending redirect.)Ú_arm_fallback_restart)Újittered_backoff)Úclassify_codex_soft_failureÚdescribe_invalid_responseÚinterruptible_backoff_sleepNc               ó$   € V ^8„  d   QhRRRRRR/# )r.   r   r   r!   r    r0   r•   r"   )r1   s   "r,   r2   Ú,retry_invalid_response.<locals>.__annotate__ü   s#   € ÷ 
ñ 
˜ð 
Ð&>ð 
ÐJ`ñ 
r+   c           	     ó&   <€ \        V SSSSVR 7      # ))r   r   r   r   r   r!   )r•   )r   r!   r   r   r   r   s   &&€€€€r,   ri   Ú(retry_invalid_response.<locals>._verdictü   s    ø€ Ü%ØÐ,<Ø!5À;Ø!5¸fô
ð 	
r+   ÚInvalidAPIResponsez, zInvalid API responseÚerrorÚcodeTÚinvalid_response)Útask_idrc   r`   r_   ra   rZ   Ú
error_typeÚerror_messageÚstatus_coder   r\   Ú	retryabler6   )r¨   r†   Úclassified_reasonÚerror_contextÚbilling_unverifiedu   ðŸ”„ Codex soft failure (u7   ) â€” switched to the next pool credential, retrying...rz   u<   âš ï¸� Empty/malformed response â€” switching to fallback...rq   u&   âš ï¸�  Invalid API response (attempt Ú/z): u      ðŸ�¢ Provider: u      ðŸ“� Provider message: u      â�±ï¸�  u   âš ï¸� Max retries (u.   ) for invalid responses â€” trying fallback...u   â�Œ Max retries (z,) exceeded for invalid responses. Giving up.z(%sInvalid API response after %d retries.zmodel=)ÚlabelÚattemptsÚdetailr0   Úfinal_responser   Ú	completedFÚ	api_callszInvalid API response after z
 retries: Úfailedg      @g      ^@)Ú
base_delayÚ	max_delayu   â�³ Retrying in z.1fzs (z)...z5Invalid API response (retry %d/%d): %s | Provider: %sz/Interrupt detected during retry wait, aborting.z$Operation interrupted during retry (z
, attempt z).zretry backoff (Ú))r   r[   r_   Úabort_messageÚinterrupt_textÚactivity_labelry   )ÚUnknownÚ )+Úagent.conversation_loopr˜   Úagent.retry_utilsr™   r{   rš   r›   rœ   Ú_invoke_api_request_error_hookÚjoinr<   r   r6   r   Ú
rate_limitÚbillingÚis_authÚ_recover_with_credential_poolr†   r¬   Ú_buffer_diagnostic_statusÚvalueÚ_fallback_indexÚlenÚ_fallback_chainÚ_try_activate_fallbackÚ_buffer_vprintÚ_clean_error_messageÚ_has_pending_fallbackÚ_flush_status_bufferÚ_emit_diagnostic_statusÚloggerr¢   rS   Ú_persist_sessionÚ
startswithr
   r‡   r   r   r	   ÚwarningÚ restart_with_redirected_messages)#rE   r/   rn   rX   r   r   rY   rZ   r   r[   r   r\   r   r_   r`   ra   r   rb   rc   r˜   r™   rš   r›   rœ   ri   Ú_softÚ	_soft_ctxÚ
_recoveredÚ	error_msgÚprovider_nameÚ_failure_hintÚ_labelÚ_final_responseÚ	wait_timeÚ_interrupteds#   &$$$d$$$d$d$d$$$$$$                r,   r‚   r‚   ì   sr  û€ õ >Ý2÷ñ ÷
õ 
ð 
×(Ñ(Ø!¨7À>Ø%ÐQ[Ø'Ø—i‘i Ó.×HÐHÐ2HÜœG H¨g°tÓ<¸fÀdÓKØ¨[ÀDÐQcð )ô ô -¨UÐ4DÓEÐñ 3°5ÓCÑ€Eˆ9ØÒ˜eŸl™l¬~×/HÑ/HÌ.×J`ÑJ`Ð.aÔaÐej×er×erÐerØ-2×-PÑ-PØ¨f×.DÑ.DÐX]×XdÑXdØ#¸×8PÑ8Pð .Qó .
Ñ*ˆ
�FÔ*÷ Ø×+Ñ+Ð.GÈÏÉ×HZÑHZÐG[ð  \Sð  -Tô  UÙ˜JÓ'Ð'Ø�1Õ€Kð ×Ñœs 5×#8Ñ#8Ó9Ô9Ø×'Ñ'Ð(fÔgØ×#Ñ#×%Ò%Ù4ØÐ!5°vó ?ÐàˆØ ÐÙ˜Ó Ð á.GØ˜ó/Ñ+€Iˆ}˜mð 
×ÑÐAÀ+ÀÈaÐP[È}Ð\_Ð`d×`iÑ`iÐjwÓ`xÐ_yÐzÔ{Ø	×ÑÐ-¨m¨_Ð=Ô>Ø	×ÑÐ5°e×6PÑ6PÐQZÓ6[Ð5\Ð]Ô^Ø	×Ñ˜; } oÐ6Ô7à�kÕ!Ø×&Ñ&×(Ò(Ø×+Ñ+Ð.BÀ;À-ÐO}Ð,~ÔØ×'Ñ'×)Ò)Ù#8ØÐ%9¸6ó$CÐ àˆKØ#$Ð Ù˜GÓ$Ð$à×"Ñ"Ô$Ø×%Ñ%Ð(9¸+¸ÐFrÐ&sÔtÜ�‰Ð?À×AQÑAQÐS^Ô_Ø×Ñ˜xÔ>ð  Ô/°=×3KÑ3KÈH×3UÒ3Uô ˜uŸ~™~Ô.àð 	ô
 $Ø f°{È=ô
ˆñ ˜¤-Ø˜oØ˜Ø˜Ø˜ØÐ2°;°-¸zÈ-ÈÐYØ�dð1
ô +¨8Ó4°dó#<ó =ð 	=ñ ! ¸ÈÔN€IØ	×ÑÐ+¨I°c¨?¸#¸m¸_ÈDÐQÔRÜ
‡N�NÐJÈKÐYdÐfj×foÑfoÐp}Óf~ð  ANô  Oñ /Øˆy˜&ÐJ^Ø%ØGØ=¸m¸_ÈJÐWbÐVcÐcdÐepÐdqÐqsÐtØ(¨¨°Q°{°mÀ1ÐEô€Lð ÒÙ˜ ,Ó/Ð/Ø×.×.Ð.Ù˜Ó Ð Ù�JÓÐr+   )!r(   Ú
__future__r   Údataclassesr   r   r|   Útypingr   r   r   Úagent.error_classifierr   Úagent.turn_api_callr   Úagent.turn_failure_copyr	   r
   r   r   Úagent.turn_truncationr   r   Úagent.turn_usager   Ú	getLoggerrÐ   r   rC   rV   r“   r•   r‚   r"   r+   r,   Ú<module>rè      sŠ   ðñõ #å !Û Û ß &Ñ &å 1Ý 5ß qÓ qß XÝ 2à	×	Ò	Ð4Ó	5€ð ÷,ð ,ó ð,õ*õ(õ2~ðB ÷,ð ,ó ð,÷t r+   