
    PL
j                      d Z ddlmZ ddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlmZ ddlmZ ddlmZ ddlmZmZmZmZmZ ddlmZmZmZ dd	lm Z m!Z! dd
l"m#Z#m$Z$ ddl%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z>m?Z?  ej@        eA          ZBd ZCd+dZDd,dZEd-dZFd.d/d ZGd0d$ZHd1d'ZIdd(d+d)ZJg d*ZKdS )2uu  Helper functions for the chat-completions code path.

Extracted from :class:`AIAgent` for cleanliness — bodies of the
non-streaming API call, request kwargs builder, assistant-message
materializer, provider-fallback activator, max-iterations handler,
and per-turn resource cleanup.

Each function takes the parent ``AIAgent`` as its first argument
(``agent``).  :class:`AIAgent` keeps thin forwarder methods so call
sites unchanged.  Symbols that tests patch on ``run_agent`` (e.g.
``cleanup_vm`` / ``cleanup_browser`` in
``test_zombie_process_cleanup.py``) are resolved through
:func:`_ra` so the patch contract is preserved.
    )annotationsN)datetime)Path)SimpleNamespace)AnyDictListOptionalTuple)urlparseparse_qs
urlunparse)get_provider_request_timeoutget_provider_stale_timeout)classify_api_errorFailoverReason)is_local_endpoint)
_sanitize_surrogates_sanitize_messages_surrogates_sanitize_structure_surrogates_sanitize_messages_non_ascii_sanitize_tools_non_ascii_sanitize_structure_non_ascii_strip_images_from_messages_strip_non_ascii_repair_tool_call_arguments%_escape_invalid_chars_in_json_strings)_is_multimodal_tool_result_multimodal_text_summary)jittered_backoff)ToolGuardrailDecisionappend_toolguard_guidancetoolguard_synthetic_result)is_persistent_env)base_url_host_matchesbase_url_hostnamec                     ddl } | S )zLazy ``run_agent`` reference.

    Used to honor test patches like
    ``patch("run_agent.cleanup_vm")`` / ``patch("run_agent.cleanup_browser")``
    that target symbols imported into ``run_agent``'s namespace.
    r   N	run_agentr(   s    A/home/kuhnn/.hermes/hermes-agent/agent/chat_completion_helpers.py_rar+   C   s         
api_kwargsdictc           	         dddddi fd}                                          dg                     }t          j                    }                     d           t	          j        |d          }|                                 d	}|                                r|                    d
           |dz  }|dz  d	k    r<t          j                    |z
  }                     dt          |           d           t          j                    |z
  }||k    rt          d                     dg           D                       dz  }t                              d||                    dd          |d                                dt          |           d                    dd           d           	  j        dk    r. j                                                                           n.                    d          }	|	                     |	d           n# t&          $ r Y nw xY w                     dt          |           d           |                    d           d         ;d          3t)          d!t          |           d"t          |           d#          d<   n j        r	  j        dk    r. j                                                                           n.                    d          }
|
                     |
d$           n# t&          $ r Y nw xY wt-          d%          |                                d         d         d          S )&a=  
    Run the API call in a background thread so the main conversation loop
    can detect interrupts without waiting for the full HTTP round-trip.

    Each worker thread gets its own OpenAI client instance. Interrupts only
    close that worker-local client, so retries and other requests never
    inherit a closed transport.

    Includes a stale-call detector: if no response arrives within the
    configured timeout, the connection is killed and an error raised so
    the main retry loop can try again with backoff / credential rotation /
    provider fallback.
    Nresponseerrorclientc            	        	 
j         dk    rK
                    d          d<   
                    d         t          
dd                     d<   n
j         dk    r
                              d<   nω
j         d	k    rd
dlm} m}m}m	} 
                    dd          }
                    dd             | |          }	  |j        di }n)# t          $ r} ||          r ||            d }~ww xY w ||          d<   n:
                    d          d<    d         j        j        j        di d<   n# t          $ r}|d<   Y d }~nd }~ww xY w                    d          }	|	
                    |	d           d S d S #                     d          }	|	
                    |	d           w w xY w)Ncodex_responsescodex_stream_requestreasonr-   r3   _codex_on_first_delta)r3   on_first_deltar1   anthropic_messagesbedrock_converser   )_get_bedrock_runtime_clientinvalidate_runtime_clientis_stale_connection_errornormalize_converse_response__bedrock_region__	us-east-1__bedrock_converse__chat_completion_requestr2   request_completer8    )api_mode_create_request_openai_client_run_codex_streamgetattr_anthropic_messages_createagent.bedrock_adapterr=   r>   r?   r@   popconverse	Exceptionchatcompletionscreateget_close_request_openai_client)r=   r>   r?   r@   regionr3   raw_response_bedrock_excerequest_clientagentr-   request_client_holderresults             r*   _callz%interruptible_api_call.<locals>._call`   s   /	^~!222272U2U1) 3V 3 3%h/ &+%<%<0:#*52I4#P#P &= & &z""
 #777%*%E%Ej%Q%Qz""#555
            $(<kJJ5t<<<44V<<#26?#@#@Z#@#@LL     10>> :11&999 &A%@%N%Nz""272U2U4) 3V 3 3%h/ &]%:8%D%I%U%\%j%j_i%j%jz" 	  	  	 F7OOOOOO	  366x@@N)22>J\2]]]]] *) 366x@@N)22>J\2]]]] *sU   CE C E 
D $C;;D  AE F 
E&E!F !E&&F 1Gmessagesz&waiting for non-streaming API responseTtargetdaemonr   333333?timeout   d   z$waiting for non-streaming response (z
s elapsed)c              3  N   K   | ] }t          t          |                    V  !d S Nlenstr.0vs     r*   	<genexpr>z)interruptible_api_call.<locals>.<genexpr>   .      OO13s1vv;;OOOOOOr,      zjNon-streaming API call stale for %.0fs (threshold %.0fs). model=%s context=~%s tokens. Killing connection.modelunknown,%   ⚠️ No response from provider for zs (non-streaming, model: z). Aborting call.r;   stale_call_killrF   z&stale non-streaming call killed after sg       @r2   r1   z'Non-streaming API call timed out after zs with no response (threshold: zs)interrupt_abortz!Agent interrupted during API call)!_compute_non_stream_stale_timeoutrT   time_touch_activity	threadingThreadstartis_alivejoinintsumloggerwarning_emit_statusrH   _anthropic_clientclose_rebuild_anthropic_clientrU   rP   TimeoutError_interrupt_requestedInterruptedError)r[   r-   r^   _stale_timeout_call_startt_poll_count_elapsed_est_ctxrcrZ   r\   r]   s   ``         @@r*   interruptible_api_callr   O   s.    ..F%t,0^ 0^ 0^ 0^ 0^ 0^ 0^ 0^p <<z2&& N )++K	BCCCd333AGGIIIK
**,, @H	sq !!y{{[0H!!Ps8}}PPP   9;;,n$$OO
z20N0NOOOOOSTTHNNC.w	22xOO	   "H " "*4..)*L*L" " "  
	>%999+11333335555.228<<B~::2FW:XXX   !!IXIII   FF3Fg&6*+=+E".Lc(mm L L474G4GL L L# #w % 	H	>%999+11333335555%:%>%>x%H%HN%1::>Rc:ddd   "#FGGGA **,, @HB g"Wo*s&   A'H/ /
H<;H<A'L/ /
L<;L<api_messageslistreturnc                   | j         }| j        dk    r|                                 }|                     |          }t	          | dd          }|r|j        nd}t	          | dd          }|d| _        |                    | j        ||||n| j	        | j
        | j        |                                 |t	          | dd          | j        pi                     d          dk    t          t	          | dd	                    
          S | j        dk    r_|                                 }t	          | dd          pd}t	          | dd          }	|                    | j        ||| j	        pd||	          S | j        dk    r9|                                 }
t!          | j        d          pt!          | j        d          }| j        dk    p| j        dk    od| j        v }| j        dv p
| j        dk    }|                     |          }|rX	 ddlm}  ||          \  }}nB# t0          $ r5}t2                              dt	          | dd          |           Y d}~nd}~ww xY w|
                    | j        ||| j
        t	          | dd          | j	        | j        ||||r|                                 nd          S |                                 }
|                                 }|                                 }t!          | j        d          pt!          | j        d          }d | j        v }d!| j        v }t!          | j        d"          p)t!          | j        d#          pt!          | j        d$          }t!          | j        d%          }| j        pd                                                                d&k    }	 dd'l m!}m"}  || j        | j                  }||u }|s|nd}n# t0          $ r d	}d}Y nw xY wi }| j#        r
| j#        |d(<   | j$        r
| j$        |d)<   | j%        r
| j%        |d*<   | j&        r
| j&        |d+<   | j'        rd,|d-<   | j(        r
| j(        |d.<   d} |s|rEd/| j        pd                                v r(	 dd0l)m*}!  |!| j                  } n# t0          $ r Y nw xY wd}"|r*| j+        pd1tY          t[          j.                              d2}"	 dd3l/m0}#  |#| j                  }$n# t0          $ r d}$Y nw xY w|$rt	          | dd          }%|%d| _        |                     |          }|
                    | j        ||| j        | 1                                | j	        |%| j2        | j
        | j        t	          | dd          |$| j3        |pd| j4        | | 5                                |"4          S t	          | dd          }%|%d| _        |                     |          }& |
j        dWi d5| j        d6|&d7|d8| j        d9| 1                                d:| j	        d;|%d<| j2        d=| j
        d>| j        dt	          | dd          d?| j        pd                                d@|dA|dB|dC|dD|dE|dF|dG|dH| j        dIk    dJ| j3        dK|pddL| j4        dM|r| j6        nddN|r| j7        nddO|"dP|dQ|dR| 5                                dS|r|                                 nddT|r| 8                                nddU| dV| j        S )Xz9Build the keyword arguments dict for the active API mode.r;   context_compressorN_ephemeral_max_output_tokens_anthropic_base_urlspeedfast_oauth_1m_beta_disabledF)rs   r_   tools
max_tokensreasoning_configis_oauthpreserve_dotscontext_lengthbase_url	fast_modedrop_context_1m_betar<   _bedrock_regionrB   _bedrock_guardrail_configi   )rs   r_   r   r   rV   guardrail_configr5   zmodels.github.aizapi.githubcopilot.comopenai-codexzchatgpt.comz/backend-api/codex>   	xai-oauthxaizapi.x.air   )strip_pattern_and_formatu4   %s⚠️ Failed to sanitize tool schemas for xAI: %s
log_prefix 
session_id)rs   r_   r   r   r   r   request_overridesis_github_responsesis_codex_backendis_xai_responsesgithub_reasoning_extranousresearchzintegrate.api.nvidia.comzapi.kimi.comzmoonshot.aizmoonshot.cnztokenhub.tencentmaas.comlmstudio_fixed_temperature_for_modelOMIT_TEMPERATUREonlyignoreordersortTrequire_parametersdata_collectionclaude)_get_anthropic_max_outputhermes)	sessionIdpromptId)get_provider_profile)rs   r_   r   r   re   r   ephemeral_max_output_tokensmax_tokens_param_fnr   r   r   provider_profileollama_num_ctxprovider_preferencesopenrouter_min_coding_scoreanthropic_max_outputsupports_reasoningqwen_session_metadatars   r_   r   r   re   r   r   r   r   r   model_loweris_openrouteris_nousis_qwen_portalis_github_modelsis_nvidia_nimis_kimiis_tokenhubis_lmstudiois_custom_providercustomr   r   r   qwen_prepare_fnqwen_prepare_inplace_fnr   fixed_temperatureomit_temperaturer   r   lmstudio_reasoning_optionsr   provider_namerG   )9r   rH   _get_transport#_prepare_anthropic_messages_for_apirK   r   r   build_kwargsrs   r   r   _is_anthropic_oauth_anthropic_preserve_dotsr   rT   boolr%   r   provider_base_url_hostname_base_url_lower&_prepare_messages_for_non_vision_modeltools.schema_sanitizerr   rP   r   r   #_github_models_reasoning_extra_body_is_qwen_portal_is_openrouter_urlstriploweragent.auxiliary_clientr   r   providers_allowedproviders_ignoredproviders_orderprovider_sortprovider_require_parametersprovider_data_collectionagent.anthropic_adapterr   r   rl   uuiduuid4	providersr   _resolved_api_call_timeout_max_tokens_param_ollama_num_ctxr   _supports_reasoning_extra_body_qwen_prepare_chat_messages#_qwen_prepare_chat_messages_inplace"_lmstudio_reasoning_options_cached)'r[   r   tools_for_api
_transportr;   ctx_lenephemeral_out_btrV   	guardrail_ctr   r   r   _msgs_for_codexr   _exc_is_qwen_is_or_is_gh_is_nous
_is_nvidia_is_kimi_is_tokenhub_is_lmstudior   r   _ft
_omit_temp_fixed_temp_prefs_ant_maxr   
_qwen_metar   _profile_ephemeral_out_msgs_for_chats'                                          r*   build_api_kwargsr     s	   KM~---))++
"FF|TT%!5t<<,3='(('EtLL$15E.&&+'(5(A}}uGW"3.88::"U$94@@.4"99'BBfL!%ge5NPU&V&V!W!W ' 
 
 	
  ~+++""$$ 1488GKE#>EE	+!'/4&   
 
 	
 ~***""$$!%.2DEE N$U^5LMM 	
 Nn, (M9 B(E,AA	 	 !>-AAkUE]akEkFF|TT  	KKKKKK#;#;M#J#J qq   JE<44c        +$"3ulD99'#5 3--Re#o5#L#L#N#N#Nko   
 
 	
 


 
 C $$&&H%%''Fe35GHH 	Q !68OPP  !66H+u/DDJenn== 	@ ??	@ ?? 
 ))>@Z[[LN(b//117799ZGLYYYYYYYY**5;GG,,
!+5cc   

  F 10v 3 2x 0/w -,v( ,'+#$% C$)$B ! H ( U[->B,E,E,G,G G G	IIIIII00==HH 	 	 	D	 J 
)5XDJLL))
 

222222''77     
 (FMM%15E.
 CCLQQ+!^4466'(6 % 7"3#5ulD99% 0!'4(-(I!)$CCEE",'   
 
 	
2 U$BDIIN!-1* AA,OON3 # # #kk## m# 	#
 00222# ### %3N# "33# //#  11# 5,555# [&B--///# f# #  x#   !#" !j##$ %#& !L'#( !L)#* !>X55+#, ,,-#. $^t/#0 %*$E$E1#2 >FO9943#4 NV _ I I[_5#6 )j7#8 &+9#: $;#< !??AAA=#> OU^uHHJJJZ^?#@ R^#g5#K#K#M#M#McgA#B &XC#D nnE# #sN   H 
I#+II2(O O,+O,6R 
RRS# #S21S2finish_reasonrl   c                P
   t          |dd          }|                     |          }t          |          }|sO|j        pd}t	          j        d|t          j                  }|r#d                    d |D                       }|pd}|r.| j        r't          j
        dt          |           d	|            |r<| j        r5| j        s.| j        s'	 |                     |           n# t          $ r Y nw xY w|j        pd}	t!          |	          }
|rt!          |          }t#          |
t$                    r)|
r'|                     |
                                          }
d
|
||d}t          |dd          }|Dt+          |d          r4t          |dd          pi }t#          |t,                    rd|v r|d         }|t!          |          |d<   n|r|                                 r|pd|d<   d|vr|r||d<   t+          |d          r|j        r|j        }g }|D ]}t#          |t,                    r|                    |           -t+          |d          r|                    |j                   Xt+          |d          r'|                    |                                           |r||d<   t          |dd          }|r||d<   t          |dd          }|r||d<   |rCg }|D ]8}t          |dd          }t          |dd          }t#          |t$                    r|                                s|                     |          \  }}|}t#          |t$                    r|                                st#          |t$                    r)|                                r|                                }n_t          |dd          }|rt          |dd          nd}|rt          |dd          nd}|                     ||t          |                    }|                                }t          |dd          }t#          |t$                    r|                                s|                     |          \  }}|}|                     |t#          |t$                    r|nd          }||||j        |j         j!        |j         j"        dd}t          |dd          }|)t+          |d          r|                                }||d<   |                    |           :||d<   |S )zBuild a normalized assistant message dict from an API response message.

    Handles reasoning extraction, reasoning_details, and optional tool_calls
    so both the tool-call path and the final-response path share one builder.
    
tool_callsNr   z<think>(.*?)</think>flags

c              3  f   K   | ],}|                                 |                                 V  -d S ri   )r   )rn   bs     r*   rp   z*build_assistant_message.<locals>.<genexpr>  s7      "P"Paggii"P17799"P"P"P"P"P"Pr,   zCaptured reasoning (z	 chars): 	assistant)rolecontent	reasoningr   reasoning_contentmodel_extra reasoning_details__dict__
model_dumpcodex_reasoning_itemscodex_message_itemsidcall_idfunctionname	arguments{}response_item_idr7  r8  )r4  r5  r:  typer6  extra_content)#rK   _extract_reasoningr   r*  refindallDOTALLr   verbose_loggingloggingdebugrk   reasoning_callbackstream_delta_callback_stream_callbackrP   r   
isinstancerl   _strip_think_blocksr   hasattrr.   _needs_thinking_reasoning_padr/  appendr0  r1  _split_responses_tool_id_deterministic_call_id"_derive_responses_function_call_idr<  r6  r7  r8  ) r[   assistant_messager   assistant_tool_callsreasoning_text_from_structuredr*  think_blockscombined_raw_content_san_contentmsgraw_reasoning_contentr-  raw_details	preserveddcodex_itemsr3  r"  	tool_callraw_idr5  embedded_call_idr  _fn_fn_name_fn_argsr:  embedded_response_item_idtc_dictextras                                    r*   build_assistant_messagerg    s/    ##4lDII--.?@@NN++
  .#+1rz"97")TTT 	.{{"P"Pl"P"P"PPPH%-N ]%/ ][S-@-@[[>[[\\\ %2  * 	53I 	((8888   
 %,2L'55L >-n== ,$$ G G00>>DDFF #&	 C $$57JDQQ$1BM)R)R$/EEKk4(( 	E-@K-O-O$/0C$D!(#78M#N#N  	 9%"E"E"G"G 9 $2#8S 0 #%%.%#1  "566 1;L;^ 1
 (9	 	1 	1A!T"" 1  ####J'' 1  ,,,,L)) 1  000 	1'0C#$ +-DdKKK 3'2#$
 ""35JDQQ 9%8!" /'
- ,	' ,	'IYd33FiD99Ggs++ +7==?? +&+&D&DV&L&L# !*gs++ `7==?? `fc** `v||~~ `$llnnGG!)Z>>C;>FwsFB777BHBEOwsK>>>4H#::8XsS]__GmmooG&y2DdKK.44 =<L<R<R<T<T =/4/M/Mf/U/U,,#< $GG$./?$E$EO  4    "$4!%.3!*!3!= 	 	G I==E 5,// /!,,..E+0(g&&&&&LJs   C% %
C21C2r8   'FailoverReason | None'r   c                   |t           j        t           j        hv rt          t	          | dd                    }t	          | dd          pd                                                                }| j        pi                     d          pd                                                                }|r|r!||k    rt          j
                    dz   | _        | j        t          | j                  k    rdS | j        | j                 }| xj        dz  c_        |                    d          pd                                                                }|                    d          pd                                }|r|s|                                 S t	          | dd          pd                                                                }t	          | dd          pd                                }t!          t	          | dd          pd                              d	                                          }	|                    d          pd                                                    d	                                          }
||k    r0||k    r*t%          j        d
||           |                                 S |
r7|	r5|
|	k    r/||k    r)t%          j        d|
           |                                 S 	 ddlm} |                    d          pd                                pd}|                    d          pd                                pd}|si|                    d          p|                    d          pd                                }|r)t-          j        |d                                          pd}|r(t1          |d          r|st-          j        d          pd} |||d||          \  }}|)t%          j        d|           |                                 S 	 ddlm}  |||          }n# t6          $ r Y nw xY wd}t!          |j                  }|                     |          }|dk    rd}n|dk    s:|                    d	                                                              d          rd}nq|rd}nl|                     |          rd}nT|                      ||          rd}n:|dk    s2tC          |          "                    d           rt1          |d!          rd"}| j#        }d| _$        || _#        || _%        || _        || _&        tO          | d#          r| j(        )                                 d| _*        tW          ||          }|dk    rdd$l,m-}m.}m/} |dk    r|j0        p |            pdn|j0        pd}|| _0        || _1        || _2         ||| j2        |%          | _3        |dk    r ||          nd| _4        d| _5        i | _6        n}|j0        | _0        || _5        t	          |d&d          }|st	          |d'd          }|j0        |d(|rd'to          |          ini | _6        | || j6        d)<   | 8                    d*+           | 9                    ||||,          \  | _:        | _;        | <                                 tO          | d-          r| j=        rdd.l>m?}  || j#        | j        | j0        | j%        t	          | d/d          t	          | d0d          1          }| j=        @                    | j#        || j        t	          | dd          | j%        2           | A                    d3| d4|            t%          jB        d5|||           dS # t6          $ r4}t%          jC        d6||           |                                 cY d}~S d}~ww xY w)7u  Switch to the next fallback model/provider in the chain.

    Called when the current model is failing after retries.  Swaps the
    OpenAI client, model slug, and provider in-place so the retry loop
    can continue with the new backend.  Advances through the chain on
    each call; returns False when exhausted.

    Uses the centralized provider router (resolve_provider_client) for
    auth resolution and client construction — no duplicated provider→key
    mappings.
    _fallback_activatedFr   r   <   rf   rs   r   /z?Fallback skip: chain entry %s/%s matches current provider/modelz>Fallback skip: chain entry base_url %s matches current backendr   )resolve_provider_clientNapi_keykey_envapi_key_envz
ollama.comOLLAMA_API_KEYT)rs   	raw_codexexplicit_base_urlexplicit_api_keyz.Fallback to %s failed: provider not configured)normalize_model_for_providerchat_completionsr   r5   	anthropicz
/anthropicr;   )r   bedrockzbedrock-runtime.zamazonaws.comr<   _transport_cache)build_anthropic_clientresolve_anthropic_token_is_oauth_tokenrd   _custom_headersdefault_headers)rn  r   re   fallback_timeout_applyrF   )r   r   rH   rs   r   )get_model_context_length_config_context_length_custom_providers)r   rn  r   config_context_lengthcustom_providers)rs   r   r   rn  r   u5   🔄 Primary model failed — switching to fallback: z via u"   Fallback activated: %s → %s (%s)z"Failed to activate fallback %s: %s)Dr   
rate_limitbillingr   rK   r   r   _primary_runtimerT   r{   	monotonic_rate_limited_until_fallback_indexrk   _fallback_chain_try_activate_fallbackrl   rstriprC  r   r   rm  osgetenvr%   hermes_cli.model_normalizeru  rP   r   _is_azure_openai_urlendswith_is_direct_openai_url&_provider_model_requires_responses_apir&   
startswithrs   r  r   rH   rJ  ry  clearrj  r   r   rz  r{  r|  rn  _anthropic_api_keyr   r   r   r3   _client_kwargsr.   _replace_primary_openai_client_anthropic_prompt_cache_policy_use_prompt_caching_use_native_cache_layout_ensure_lmstudio_runtime_loadedr   agent.model_metadatar  update_modelr   infor2   )r[   r8   fallback_already_activecurrent_providerprimary_providerfbfb_providerfb_modelcurrent_modelcurrent_base_urlfb_base_url_for_deduprm  fb_base_url_hintfb_api_key_hint
fb_key_env	fb_client_resolved_fb_modelru  fb_api_modefb_base_url_fb_is_azure	old_model_fb_timeoutrz  r{  r|  effective_key
fb_headersr  fb_context_lengthrY   s                                  r*   try_activate_fallbackr    ss	    .+^-CDDD #'wu6KU'S'S"T"T#E:r::@bGGIIOOQQ"39r>>zJJPbWWYY__aa' 	>-= 	>BRVfBfBf(,(8(82(=E%E$9 : :::u		u4	5B	Q66*%%+2244::<<Kw%2,,..H .h .++---  z266<"CCEEKKMMUGR006B==??M75*b99?R@@GGLLRRTTVVJ//52<<>>EEcJJPPRR&&&8}+D+DM	
 	
 	
 ++---
.
. "%555%%L!	
 	
 	
 ++---
h.BBBBBB FF:..4";;==E66),,299;;Ct 	L &&++Jrvvm/D/DJQQSSJ L"$)J";";"A"A"C"C"Kt  	B 56F U U 	B^m 	B i(899ATO(?(?x4.,). ). ).%	% O@   //111	OOOOOO33HkJJHH 	 	 	D	 )),--11+>>.((+KKK'';+=+=c+B+B+H+H+J+J+S+ST`+a+a'.KK 	- -KK((55 	-+KK99  : 
 
 	- ,KKI%%k**556HII &%k?CC & -KK	
 (,$$$$5,-- 	+"((***$(!
 3;II...ppppppppppVaepVpVpY.Q2I2I2K2KQr  xA  xI  xO  MOM)EM'4E$(3E%&<&<u8+' ' 'E# KVYdJdJd(F(F(FjoE%EL#%E   &-EM$EL !,=tDDJ I$Y0A4HH
$,'$ $ =GN%tJ'7'788B$E 
 &2=$Y/ 44<T4UUU 00$$$	 1   	B!5#A 	--/// 5.// 	E4L 	EEEEEE 8 8en&-e5Mt&T&T!(0CT!J!J	! ! ! $11k0y"55 2    	,, ,), ,	
 	
 	
 	0x	
 	
 	
 t . . .:HaHHH++--------.sD   3D.^& #P6 5^& 6
Q ^& QM!^& &
_$0)__$_$r_   api_call_countr   c           
     @   t          d| j         d           d}|                    d|d           	 |                                 }g }|D ]s}|                                }|                     ||           dD ]}|                    |d           |r|                     |           |                    |           t| j        pd}	| j	        r|	d	z   | j	        z   
                                }	|	r	d
|	dg|z   }| j        rK|	rdnd}
t          | j                  D ]0\  }}|                    |
|z   |                                           1|                     |          }|                     |          }i }	 ddlm}m} n# t&          $ r d}d}Y nw xY w| || j        | j                  nd}||u }|rdn|}d| j        v }| j        pd
                                                                dk    o|                                 }|r|                                 nd}|s.|                                 r| j        | j        |d<   nddd|d<   |rddlm}  |            |d<   | j        dk    r|                     |          }|                    dd           |                      |          }| !                                }|"                    |          }|j#        pd
                                }n| j        |d}|||d<   | j$        -|%                    | &                    | j$                             |||d<   i }| j'        r
| j'        |d<   | j(        r
| j(        |d<   | j)        r
| j)        |d<   | j*        r
| j*        |d<   |rJ| j        pd
                                                                dk    s| +                                r||d <   | j        d!k    r| j        pd
                                                                dk    s| +                                r\| j,        U| j,        dk    rJ	 t[          | j,                  }n# t\          t^          f$ r d}Y nw xY w|d"|cxk    rd#k    rn n	d$|d%g|d&<   |r||d'<   | j        d(k    r| !                                }|0                    | j        |d| j$        | j        | j1        | 2                                )          } | 3                    |           }|"                    || j1        *          }!|!j#        pd
                                }nm | 4                    d+,          j5        j6        j7        d7i |}| !                                "                    |          }!|!j#        pd
                                }|rXd-|v r4tq          j9        d.d|tp          j:        /          
                                }|r|                    d0|d           n]d1}nY| j        dk    r|                     |          }|                    dd           |                      |          }"| !                                }#|#"                    |"          }$|$j#        pd
                                }nn| j        d(k    r| !                                }%|%0                    | j        |d| j1        | j$        | j        | 2                                2          }&| 3                    |&          }"|%"                    |"| j1        *          }'|'j#        pd
                                }n| j        |d}|||d<   | j$        -|%                    | &                    | j$                             |||d<   |r||d'<    | 4                    d3,          j5        j6        j7        d7i |}| !                                "                    |          }'|'j#        pd
                                }|rVd-|v r4tq          j9        d.d|tp          j:        /          
                                }|r|                    d0|d           nd1}nd1}nH# t&          $ r;}(tw          j<        d4|(            d5| j         d6t{          |(           }Y d}(~(nd}(~(ww xY w|S )8zSRequest a summary when max iterations are reached. Returns the final response text.u$   ⚠️  Reached maximum iterations (z). Requesting summary...zYou've reached the maximum number of tool-calling iterations allowed. Please provide a final response summarizing what you've found and accomplished so far, without calling any more tools.user)r)  r*  )r+  r   _thinking_prefillNr   r%  systemrf   r   r   r   r   r+  Tmedium)enabledeffort)nous_portal_tagstagsr5   r   )rs   r_   temperaturereasoning_effortr   r   r   r   
openrouterr   zopenrouter/pareto-codeg        g      ?zpareto-router)r4  min_coding_scoreplugins
extra_bodyr;   )rs   r_   r   r   r   r   r   )strip_tool_prefixiteration_limit_summaryrF   z<think>z<think>.*?</think>\s*r#  r(  z>I reached the iteration limit and couldn't generate a summary.)rs   r_   r   r   r   r   r   iteration_limit_summary_retryz Failed to get summary response: z"I reached the maximum iterations (z!) but couldn't summarize. Error: rG   )>printmax_iterationsrL  _should_sanitize_tool_callscopy_copy_reasoning_content_for_apirN   #_sanitize_tool_calls_for_strict_api_cached_system_promptephemeral_system_promptr   prefill_messages	enumerateinsert_sanitize_api_messages#_drop_thinking_only_and_merge_usersr   r   r   rP   rs   r   r   r   r   r   *_resolve_lmstudio_summary_reasoning_effortr   agent.portal_tagsr  rH   _build_api_kwargsrJ   r   normalize_responser*  r   updater   r   r   r   r   r   r   float	TypeError
ValueErrorr   r   r   rL   _ensure_primary_openai_clientrQ   rR   rS   r?  subrA  rC  r   rl   ))r[   r_   r  summary_request_needs_sanitizer   rX  api_msginternal_fieldeffective_system
sys_offsetidxpfmsummary_extra_bodyr   
_OMIT_TEMP_raw_summary_temp_omit_summary_temperature_summary_temperaturer  _is_lmstudio_summary_lm_reasoning_effort_portal_tagscodex_kwargssummary_response_ct_sum_cnr_sumfinal_responsesummary_kwargsr   _ps_tsum_ant_kw_summary_resultretry_response	_ct_retry
_cnr_retry_tretry_ant_kw2_retry_resultrY   s)                                            r*   handle_max_iterationsr    s
   	
_1E
_
_
_```	* 
 OOV@@AAAI~  ;;== 	) 	)ChhjjG11#w???"U 2 2ND1111 C99'BBB(((( 6<"( 	c 06 9E<Y Y``bb 	\%-:JKKL|[L! 	B.5AJ%e&<== B BS##J$4chhjjAAAA 33LAA @@NN	kkkkkkkkk 	 	 	+/(JJJ	
 ,7 )(enEEE 	
 %6$C!'@WttFW!U%:: ^!r((**0022j@ 74466 	 $.E<<>>>)- 	 $ 	(L(L(N(N 	%1272H";//  $&3 3";/  	8JJJJJJ)5v&>... 22<@@LWd+++$66|DD**,,G112BCCH&.4";;==NN ( N $/0D}-+%%e&=&=e>N&O&OPPP#/5I12 $& & G/4/F$V,& I161H$X.$ F050E$W-" C/4/B$V,# F%2,,..4466,FF++-- G 2F":. 777^)r002288::lJJ//11 K 5A5;; ABBCC!:.   CCC?sc'8'8'8'8S'8'8'8'8'8.CHH5&y1 " B/A|,~!555,,..,,5;]a*/*:UMc(-(A-2-K-K-M-M - O O $)#C#CG#L#L "'":":;K_d_x":"y"y"1"9"?R!F!F!H!H $A5#F#FNg#F#h#h#m#y  $A  $S  $S  DR  $S  $S "'"6"6"8"8"K"KL\"]"]"1"9"?R!F!F!H!H 3	bN**!#(@"n\^\e!f!f!f!l!l!n!n b P PQQQQ!a ~!222$66|DD  $///!&!8!8!F!F!0022	&99.II
","4":!A!A!C!C#777..00"//ekL`d).)B+0+;eNd.3.L.L.N.N 0 P P "'!A!A(!K!K ' : :>]b]v : w w"/"7"=2!D!D!F!F #[ ," " (34HN=1#/"))%*A*A%BR*S*STTT'39MN#56% F3EN<0 $G5#F#FNm#F#n#n#s#  $G  $Y  $Y  JX  $Y  $Y  % 4 4 6 6 I IJZ [ ["/"7"=2!D!D!F!F b..%'V,Db.`b`i%j%j%j%p%p%r%rN! fOO[^$T$TUUUU%eNN!a ~ ~ ~>1>>???}e>R}}uxyzu{u{}}~ sb   Ea 9F a Fa FJ#a 7Q a Q"a !Q""O3a 
b 1bbtask_idNonec                   	 t          |          r | j        rt          j        d| d           n!t	                                          |           n8# t          $ r+}| j        rt          j        d| d|            Y d}~nd}~ww xY w	 t	                                          |           dS # t          $ r2}| j        r t          j        d| d|            Y d}~dS Y d}~dS d}~ww xY w)a(  Clean up VM and browser resources for a given task.

    Skips ``cleanup_vm`` when the active terminal environment is marked
    persistent (``persistent_filesystem=True``) so that long-lived sandbox
    containers survive between turns. The idle reaper in
    ``terminal_tool._cleanup_inactive_envs`` still tears them down once
    ``terminal.lifetime_seconds`` is exceeded. Non-persistent backends are
    torn down per-turn as before to prevent resource leakage (the original
    intent of this hook for the Morph backend, see commit fbd3a2fd).
    z0Skipping per-turn cleanup_vm for persistent env z; idle reaper will handle it.zFailed to cleanup VM for task z: Nz#Failed to cleanup browser for task )	r$   rB  rC  rD  r+   
cleanup_vmrP   r   cleanup_browser)r[   r  rY   s      r*   cleanup_task_resourcesr  \  sh   MW%% 	&$ 3w 3 3 3  
 EEW%%% M M M  	MOKWKKKKLLLMRg&&&&& R R R  	ROP'PPQPPQQQQQQQQQ	R 	R 	R 	R 	R 	RRs0   AA 
B!BB!B/ /
C+9!C&&C+)r:   c          	     t     j         rt          d           j        dk    r0 _        	                                d _        S # d _        w xY w j        dk    rdddddiddifd	 fd
}t          j        |d          }|                                 |                                r@|	                    d            j         rt          d          |                                @d         d         d         S ddg ddddddiddidt          j
                    ifd fd fd fd}t           j         j                  }||}n"t          t          j        dd                    }|dk    rK j        rDt%           j                  r0t          d          }t&                              d j                   n`t+          d                     dg           D                       dz  }	|	d k    rt/          |d!          }n|	d"k    rt/          |d#          }n|}t          j        |d          }|                                 t          j
                    }
d$}|                                ru|	                    d           t          j
                    }||
z
  |k    r3|}
t1          |d         z
            }                     d%| d&           t          j
                    d         z
  }||k    rIt+          d'                     dg           D                       dz  }t&                              d(||                    d)d*          |d+                                d,t1          |           d-                    d)d*           d.|d+d/           	                     d0          }|                     |d12           n# t:          $ r Y nw xY w	                      d32           n# t:          $ r Y nw xY wt          j
                    d<                        d4t1          |           d5            j         r	  j        d6k    r. j                                           !                                 n.                    d0          }|                     |d72           n# t:          $ r Y nw xY wt          d8          |                                ud         d         rttE           d9d:          pd:#                                pd}tI                              d;          pg           }|rd<	                    |dd=                   }tK          |          d=k    r|d>tK          |          d=z
   d?z  }d@| dA}|pd:|z   }	  &                    |           n# t:          $ r Y nw xY wt&                              dB|tK          |pd:          d                    n1t&                              dCtK          |pd:          d                    tO          dD|ddE          }tO          dFtE           d)d*          tO          dG|dHI          gdJ          S d         d         S )Ku  Streaming variant of _interruptible_api_call for real-time token delivery.

    Handles all three api_modes:
    - chat_completions: stream=True on OpenAI-compatible endpoints
    - anthropic_messages: client.messages.stream() via Anthropic SDK
    - codex_responses: delegates to _run_codex_stream (already streaming)

    Fires stream_delta_callback and _stream_callback for each text token.
    Tool-call turns suppress the callback — only text-only final responses
    stream to the consumer.  Returns a SimpleNamespace that mimics the
    non-streaming response shape so the rest of the agent loop is unchanged.

    Falls back to _interruptible_api_call on provider errors indicating
    streaming is not supported.
    z+Agent interrupted before streaming API callr5   Nr<   r0   doneFyesc                 f     d         s%r%d d<   	               d S # t           $ r Y d S w xY wd S d S Nr
  TrP   first_delta_firedr:   s   r*   _fire_firstz5interruptible_streaming_api_call.<locals>._fire_first  sq    $V,  ,0!&)"N$$$$$    DD	      
 
,,c                    	 ddl m} m}m}m}                     dd          }                    dd             | |          }	  |j        di }n)# t          $ r} ||          r ||            d }~ww xY wfd}fd}	fd}
 ||                                r|nd |	j	        sj
        r|
nd fd	
          d<   d S # t          $ r}|d<   Y d }~d S d }~ww xY w)Nr   )r=   r>   r?   stream_converse_with_callbacksrA   rB   rC   c                P                                       |            dd<   d S )NTr  )_fire_stream_delta)textr  r[   deltas_were_sents    r*   _on_textzIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_text  s3    KMMM,,T222.2$U+++r,   c                F                                       |            d S ri   )_fire_tool_gen_started)r7  r  r[   s    r*   _on_toolzIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_tool  s(    KMMM0066666r,   c                F                                       |            d S ri   )_fire_reasoning_delta)r  r  r[   s    r*   _on_reasoningzNinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_reasoning  s(    KMMM//55555r,   c                      j         S ri   )r   )r[   s   r*   <lambda>zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>  s
    u/I r,   )on_text_deltaon_tool_starton_reasoning_deltaon_interrupt_checkr1   r2   rG   )rM   r=   r>   r?   r  rN   converse_streamrP   _has_stream_consumersrE  rF  )r=   r>   r?   r  rV   r3   rW   rX   r  r  r  rY   r  r[   r-   r  r]   s               r*   _bedrock_callz7interruptible_streaming_api_call.<locals>._bedrock_call  s   ($            $(<kJJ5t<<<44V<<#96#9#G#GJ#G#GLL     10>> :11&9993 3 3 3 3 3 3
7 7 7 7 7 76 6 6 6 6 6 &D%C .3.I.I.K.K"U((QU"*8=8P'yTYTo'y}}uy'I'I'I'I& & &z"""  $ $ $"#w$s=   AC A C 
A;A66A;;AC 
C)C$$C)Tr`   rc   rd   z)Agent interrupted during Bedrock API callr2   r1   )r1   r2   partial_tool_names)r3   diagr   c                 f     d         s%r%d d<   	               d S # t           $ r Y d S w xY wd S d S r  r  r  s   r*   _fire_first_deltaz;interruptible_streaming_api_call.<locals>._fire_first_delta  sq     ( 	^ 	(,f%        		 	 	 	r  c                    ddl } t          )j        )j                  }||n!t	          t          j        dd                    }||}nft	          t          j        dd                    }|dk    r>)j        r7t          )j                  r#|}t          
                    d)j        |           |t          |d          nd	}i *d
dd
i|                     ||||          d})                    d|          -d<   t          j                    ,d<   )                    d           )                                }|-d<    -d         j        j        j        d8i |})                    t+          |dd                     )                    |t+          |dd                     )                    t+          |dd                     g }i }	t1                      }
i }i }d}d}d}g }d}|D ]X}t          j                    ,d<   )                    d           	 t3          |                    dd                    dz   |d<   |                    d          ,d         |d<   	 t3          |                    dd                    t7          t9          |                    z   |d<   n# t:          $ r Y nw xY wn# t:          $ r Y nw xY w)j        r nr|j        s>tA          |d          r|j        r|j        }tA          |d          r|j!        r|j!        }-|j        d         j"        }tA          |d          r|j        r|j        }t+          |dd          pt+          |dd          }|r4|#                    |            (             )$                    |           |r|j%        r|#                    |j%                   |	s* (             )&                    |j%                   d
+d<   nM)j'        rF	 )'                    |j%                   )(                    |j%                   n# t:          $ r Y nw xY w|r|j)        r|j)        D ]}|j*        |j*        nd}|j+        pd }||vr|||<   |r)||v r%|||         k    rtY          |	d!"          dz   }|||<   |r|||<   ||         }||	vr|j+        pd d#d d d$dd%|	|<   |	|         }|j+        r
|j+        |d&<   |j-        rM|j-        j.        r|j-        j.        |d#         d'<   |j-        j/        r |d#         d(xx         |j-        j/        z  cc<   t+          |d)d          }|,tA          |d*          r|j0        pi                     d)          }|)tA          |d+          r|1                                }||d)<   |d#         d'         }|rS||
vrO|
2                    |            (             )3                    |           .d,         #                    |           |j        d         j4        r|j        d         j4        }tA          |d          r|j!        r|j!        }Zd 5                    |          pd}d}d-}|	rg }tm          |	          D ]}|	|         } | d#         d(         }!| d#         d'         pd.}"|!rZ|!7                                rF	 tq          j9        |!           n0# tp          j:        $ r tw          |!|"          }#|#d/k    r|#}!nd
}Y nw xY w|#                    ty          | d&         | d0         |                     d)          ty          | d#         d'         |!$          1                     |pd2}$|rd3}$d 5                    |          pd}%ty          ||||%4          }&ty          d|&|$5          }'ty          d6t{          t}          j?                              z   ||'g|7          S )9z#Stream a chat completions response.r   NHERMES_API_TIMEOUTg      @HERMES_STREAM_READ_TIMEOUTg      ^@uD   Local provider detected (%s) — stream read timeout raised to %.0fsg      N@      >@Tinclude_usage)connectreadwritepool)streamstream_optionsre   chat_completion_stream_requestr7   r3   r   z)waiting for provider response (streaming)r*  r1   r(  receiving stream responsechunksrf   first_chunk_atbytesrs   usager,  r+  r  r   )defaultr6  r;  )r4  r<  r6  r=  r4  r7  r8  r=  r-  r1  r)  F?r9  r<  )r4  r<  r=  r6  stoplengthr)  r*  r"  r,  indexmessager   zstream-r4  rs   choicesr=  rG   )@httpxr   r   rs   r  r  r  r   r   r   rD  minTimeoutrI   r{   r|   _stream_diag_initrQ   rR   rS   _capture_rate_limitsrK   _stream_diag_capture_response_check_openrouter_cache_statussetr   rT   rk   reprrP   r   rH  rJ  r=  deltarL  r  r*  r  rF  _record_streamed_assistant_textr"  rE  r4  maxr6  r7  r8  r-  r1  addr  r   r   sortedr   jsonloadsJSONDecodeErrorr   r   rl   r   r   )/_httpx_provider_timeout_cfg_base_timeout_stream_read_timeout	_conn_capstream_kwargs_diagr6  content_partstool_calls_acctool_gen_notified_last_id_at_idx_active_slot_by_idxr   
model_namer)  reasoning_parts	usage_objchunkrR  rR  tc_deltaraw_idxdelta_idnew_slotr  entryrf  r7  full_contentmock_tool_callshas_truncated_tool_argstcr8  	tool_namerepairedeffective_finish_reasonfull_reasoningmock_messagemock_choicer,  r[   r-   r  last_chunk_timer\   r]   s/                                           r*   _call_chat_completionsz@interruptible_streaming_api_call.<locals>._call_chat_completions  s	    !=U^U[ Y Y %0 "!ry!5v>>?? 	 !,#8  #(3OQV)W)W#X#X 
 $u,,,DUV[VdDeDe,'4$ZN$8   1F0QCt,,,W[	



.5~~!)#	 &  	

 

 

 +0*M*M3$ +N +
 +
h'  $y{{IJJJ ''))(-f%H&x05AHYY=YY
 	""76:t#D#DEEE 	++E76:t3T3TUUU 	,,WVZ-N-NOOO !!$
 !#$&
 "	 L	( L	(E#'9;;OC !!"=>>>
"%eii!&<&<"="="Ah99-..6.=c.BE*+
%(7A)>)>%?%?#d5kkBRBR%RE'NN    D    ) = 5'** -u{ -!&J5'** ,u{ , %IM!$*Eug&& )5; )"[
 %U,?FFk'RWYdfjJkJkN <&&~666!!###++N;;;   $$U]333% %%''',,U];;;.2$U++ 0 33EMBBB==emLLLL$     ?B) ?B % 0 >B >BH080JhnnPQG'{0bH &9997>+G4 @#66$(@@@#&~r#B#B#BQ#F7?+G4 <3;0-g6C.00"*+"3$.13"(E(E-1	/ /s+ +3/E{ 2&.kd( Z#,1 	O 9A8I8NE*-f5#,6 Z!*-k:::h>O>YY:::#HotDDE}=)I)I}!)!5!; @ @ Q Q("5,77 7$)$4$4$6$6E16o. ,V4D B+< < <)--c222))+++44T::: 34;;DAAA}Q- ? %a 0 > ug&& (5; (!K	 ww}--5"'  	 On--  #C(zN;7	zN629c	 ;!2!2 ;;
9----/ ; ; ; $?y)#T#T#t++(0II 7;3;  &&$xF"$&&"9"9,
^F3"+  	( ( (     #0"96" 	/&.#119T& &,	
 
 
 & 1
 
 

 3tz||,,, M	
 
 
 	
s\   !A	K +AJ/.K /
J<9K ;J<<K  
KK>4P33
Q ?Q 9[*[;:[;c            	     f   d} t          j                     d<                                   }|d<    j        j        j        di 5 }	                     |t          |dd                     n# t          $ r Y nw xY w|D ] }t          j                     d<                       d           	 t          |
                    dd                    d	z   |d<   |
                    d
          d         |d
<   	 t          |
                    dd                    t          t          |                    z   |d<   n# t          $ r Y nw xY wn# t          $ r Y nw xY wj        r nt          |dd          }|dk    r^t          |dd          }|rIt          |dd          dk    r4d} t          |dd          }|r                                  |           ]|dk    rt          |dd          }|rt          |dd          }|dk    r;t          |dd          }	|	r&| s$                                  |	           dd<   |dk    r2t          |dd          }
|
r                                  |
           |                                cddd           S # 1 swxY w Y   dS )a$  Stream an Anthropic Messages API response.

        Fires delta callbacks for real-time token delivery, but returns
        the native Anthropic Message object from get_final_message() so
        the rest of the agent loop (validation, tool extraction, etc.)
        works unchanged.
        Fr   r*  r1   Nr9  r:  r   rf   r;  r<  r<  content_block_startcontent_blocktool_useTr7  content_block_deltarR  
text_deltar  r   r  thinking_deltathinkingrG   )r{   rL  r   r_   r6  rN  rK   rP   r|   r   rT   rk   rQ  r   r  r  r  get_final_message)has_tool_user`  r6  event
event_typeblockrs  rR  
delta_typer  thinking_textr,  r[   r-   r  ry  r\   s              r*   _call_anthropicz9interruptible_streaming_api_call.<locals>._call_anthropic  s      $y{{''))(-f%4U$-4BBzBB @	.f
3376:t<<        2K 2K (,y{{$%%&ABBB	&)%))Ha*@*@&A&AA&EE(Oyy!122:2A#2F./),UYYw-B-B)C)Cc$u++FVFV)Vg$       D - E$UFD99
!666#E?DAAE D!=!=!K!K'+$+E64$@$@	$ D--///!88CCC#888#E7D99E K%,UFD%A%A
%55#*5&"#=#=D# ?L ? 1 1 3 3 3 % 8 8 > > >:> 0 7'+;;;,3E:r,J,JM, K 1 1 3 3 3 % ; ;M J J J ++--A@	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	. @	.s   
J&%A21J&2
A?<J&>A??3J&3A	E=AE E
EEEEJ&
EJ&ED:J&&J*-J*c                    dd l } t          t          j        dd                    }	 t	          |dz             D ]}j        rt          d          	 j        dk    r"                                              d<   n             d<    	                    d          }|
                    |d	
           d S d S # t          $ rV}t          || j        | j        | j        f          }t          || j        | j        t$          f          }                    |          }d         rt)          	                    d                    }d}	|sg|seddlm}
 t          ||
          rOt/          |dd           s>t1          |                                          d}t5          fd|D                       }	|p|p|	p|}|o|o||k     }|sWt6                              d|           |d<   Y d }~ 	                    d          }|
                    |d	
           d S d S 	                     d           n# t          $ r Y nw xY w	                                  n# t          $ r Y nw xY wg d<   dd<   dd<                       ||dz   |dz   d	                    d                     	                    d          }|
                    |d
           d d<   	                      d
           n# t          $ r Y nw xY wY d }~d}|sg|seddlm}
 t          ||
          rOt/          |dd           s>t1          |                                          d}t5          fd|D                       }|s|s|s|r||k     r                    ||dz   |dz   d	                    d                     	                    d          }|
                    |d
           d d<   	                      d
           n# t          $ r Y nw xY wY d }~!                    d||dz   |dz   d	                    d                     "                    |r	d |dz    d!nd"|dz    d!           nbt1          |                                          }d#|v od$|v }|rd_#        $                    d%           t6          %                    d&|           |d<   Y d }~ 	                    d          }|
                    |d	
           d S d S d }~ww xY wnM# t          $ r@}|d<   Y d }~	                    d          }|
                    |d	
           d S d S d }~ww xY w	 	                    d          }|
                    |d	
           d S d S # 	                    d          }|
                    |d	
           w w xY w)'Nr   HERMES_STREAM_RETRIES   rf   z%Agent interrupted before stream retryr;   r1   r3   stream_request_completerF   r  r)  F)APIErrorstatus_code)
zconnection lostzconnection resetzconnection closedzconnection terminatedznetwork errorznetwork connection
terminatedzpeer closedzbroken pipezupstream connect errorc              3      K   | ]}|v V  	d S ri   rG   )rn   phrase_err_lower_previews     r*   rp   zBinterruptible_streaming_api_call.<locals>._call.<locals>.<genexpr>  s=       ?" ?"(. %+.@$@?" ?" ?" ?" ?" ?"r,   z9Streaming failed after partial delivery, not retrying: %sr2   u9   

⚠ Connection dropped mid tool-call; reconnecting…

r
  Tr*  )r2   attemptmax_attemptsmid_tool_callr*  stream_mid_tool_retry_cleanup"stream_mid_tool_retry_pool_cleanupc              3      K   | ]}|v V  	d S ri   rG   )rn   r  _err_lower_sses     r*   rp   zBinterruptible_streaming_api_call.<locals>._call.<locals>.<genexpr>  s<       3 3$* !'. 83 3 3 3 3 3r,   stream_retry_cleanupstream_retry_pool_cleanup	exhausted)kindr2   r  r  r  r*  u5   ❌ Provider returned malformed streaming data after uM    attempts. The provider may be experiencing issues — try again in a moment.u(   ❌ Connection to provider failed after r6  znot supportedu   
⚠  Streaming is not supported for this model/provider. Switching to non-streaming.
   To avoid this delay, set display.streaming: false in config.yaml
z$Streaming failed before delivery: %s)&rI  r   r  r  ranger   r   rH   )_try_refresh_anthropic_client_credentialsrT   rU   rP   rH  ReadTimeoutConnectTimeoutPoolTimeoutConnectErrorRemoteProtocolErrorConnectionError_is_provider_stream_parse_errorr   openair  rK   rl   r   anyr   r   r  _reset_stream_delivery_tracking_emit_stream_dropr  _log_stream_retryr   _disable_streaming_safe_printr  )rZ  _max_stream_retries_stream_attemptrZ   rY   _is_timeout_is_conn_err_is_stream_parse_err_partial_tool_in_flight_is_sse_conn_err_preview	_APIError_SSE_PREVIEW_PHRASES_is_transient_can_silent_retrystale_is_sse_conn_err_SSE_CONN_PHRASES
_err_lower_is_stream_unsupportedr  r  r  rz  r[   r  r  r\   r]   s                      @@r*   r^   z/interruptible_streaming_api_call.<locals>._call^  s   !"),CQ"G"GHH|	e#()<q)@#A#A q q - T*+RSSSh~)===GGIII-<_->->z**-C-C-E-Ez*T 366x@@N)22>Jc2ddddd *)U ! a a a",F.0EvGYZ# #K $.F/1K_]$ $L ,1+P+PQR+S+S( (. _!26"JJ';<<3 3/ 490* "< "DDDDDD)!Y77 "=Z^@_@_ "58VV\\^^ 28" 4 <? ?" ?" ?" ?"2F?" ?" ?" <" <" 8
 ( 4+474  4	 & 4 F -F /2E E *
  1 # #NN []^   /0F7O"FFFFJ 366x@@N)22>Jc2ddddd *)}!!44!6     ) ! ! ! D!!!AACCCC( ! ! ! D!
 8:3427(/49)&1//"#$3a$7)<q)@*.!6!:!:6!B!B 0    !6 9 9( C C ,!>> %.M ?    ?C1(;!!@@'K A      ) ! ! ! D!  (-$& | @@@@@@%a33 GA}VZ<[<[ -0VV\\^^N1- 03 3 3 3 3.?3 3 3 0 0,
 # El E6F EJ^ E +-@@@!33&'(7!(;-@1-D.3%:%>%>v%F%F 4    %:$=$=h$G$GE$0 % B B$)2H !C !" !" !" CG 5h ?% % D D+F !E !" !" !" !" $- % % % $%$HHHH //!,"#$7!$;)<q)@*/!6!:!:6!B!B 0    **
  4	5 52Q65 5 5 5
52Q65 5 5
 
 
 
 &)VV\\^^
$
2 > /: = / 2 7;E4!--!3   B   '(F7OFFFF 366x@@N)22>Jc2ddddd *)Ua!qd   	 	 	  F7OFFF266x@@N)22>Jc2ddddd *)	eqr 366x@@N)22>Jc2ddddd *) 366x@@N)22>Jc2dddd *s  +T) :CT) T%D#T 2T) *I ?T  
I
T IT I&%T &
I30T 2I33A8T ,LT 
LT LT T) CT 9PT 
PT PT  T) &CT )T)  T%%T) (V) )
U33U.8V) .U33V) )1WHERMES_STREAM_STALE_TIMEOUTg     f@infu>   Local provider detected (%s) — stale stream timeout disabledc              3  N   K   | ] }t          t          |                    V  !d S ri   rj   rm   s     r*   rp   z3interruptible_streaming_api_call.<locals>.<genexpr>s  s.      NN!#c!ff++NNNNNNr,   r_   rr   i g     r@iP  g      n@r0  zwaiting for stream response (zs, no chunks yet)c              3  N   K   | ] }t          t          |                    V  !d S ri   rj   rm   s     r*   rp   z3interruptible_streaming_api_call.<locals>.<genexpr>  rq   r,   uq   Stream stale for %.0fs (threshold %.0fs) — no chunks received. model=%s context=~%s tokens. Killing connection.rs   rt   ru   rv   z
s (model: z, context: ~z tokens). Reconnecting...r3   stale_stream_killrF   stale_stream_pool_cleanupzstale stream detected after zs, reconnectingr;   stream_interrupt_abortz+Agent interrupted during streaming API call _current_streamed_assistant_textr   r)  z,    z, +z moreu$   

⚠ Stream stalled mid tool-call (zH); the action was not executed. Ask me to retry if you want to continue.z[Partial stream dropped tool call(s) %s after %s chars of text; surfaced warning to user: %szPartial stream delivered before error; returning stub response with %s chars of recovered content to prevent duplicate messages: %sr(  rC  zpartial-stream-stubr   rA  rD  rG  )(r   r   rH   r9   _interruptible_api_callr}   r~   r   r   r   r{   r   r   rs   r  r  r  r   r   r   rD  r   rT   rT  r   r|   r   r   rU   rP   r  r   r   r   rK   r   r   rk   r  r   ) r[   r-   r:   r(  r   r^   
_cfg_stale_stream_stale_timeout_base_stream_stale_timeout_est_tokens_last_heartbeat_HEARTBEAT_INTERVAL_hb_now_waiting_secs_stale_elapsedr   r   rZ   _partial_text_partial_names	_name_str_warn	_stub_msgr  rz  r  r,  r  r  ry  r\   r]   s    ```                    @@@@@@@@@r*    interruptible_streaming_api_callr  |  s#	     ! NLMMM~***
 '5#	/00<<*.E''$E'.... ~+++"T22#UO!5>	 	 	 	 	 	)	$ )	$ )	$ )	$ )	$ )	$ )	$ )	$ )	$V M$???				jjll 	TFF3F) T&'RSSS jjll 	T '?&/!j!!RHHF'+T::u~ DIKK(O     [
 [
 [
 [
 [
 [
 [
 [
 [
 [
 [
zP. P. P. P. P. P. P. P. P. P.dAe Ae Ae Ae Ae Ae Ae Ae Ae Ae AeH ,ENEKHHJ%/""%*295RTY+Z+Z%[%[" "U**u~*BSTYTbBcBc* %eUW\Weffff NNz~~j"/M/MNNNNNRSS  $'(BE$J$J!!6!!$'(BE$J$J!!$>!d333AGGIIIikkO
**,, CR	s )++_$(;;;%O/#*> >??M!!PPPP   s';;111OO
z20N0NOOOOOSTTHNNC 5w	22xOO	   #N8K8K # #%>>'9==# #%3# # #  *..x88>66rBU6VVV   44<W4XXXX    $(9;;OC !!Ss>/B/BSSS   % 	R	>%999+11333335555%:%>%>x%H%HN%1::>Rj:kkk   "#PQQQG **,, CRH g"E" >	 A2FFL"egg  "&**-A"B"B"HbIIN  IInRaR&899	~&&**!Es>':':Q'>!E!E!EEI@!@ @ @ 
 "/!4" =,,U3333    D<"C(;$<$<fWo    - +,,7O   ( -D"&  I #(eWi88(Yf        Wo*sT   A 	A.P 
PPP4 4
Q QA'S0 0
S=<S=W0 0
W=<W=)r   r  rg  r  r  r  r  )r-   r.   )r   r   r   r.   )r   rl   r   r.   ri   )r8   rh  r   r   )r_   r   r  r   r   rl   )r  rl   r   r  )L__doc__
__future__r   concurrent.futures
concurrentcontextvarsr  rW  rC  r  randomr?  sysr}   r{   r   r   pathlibr   typesr   typingr   r   r	   r
   r   urllib.parser   r   r   hermes_cli.timeoutsr   r   agent.error_classifierr   r   r  r   agent.message_sanitizationr   r   r   r   r   r   r   r   r   r   agent.tool_dispatch_helpersr   r   agent.retry_utilsr    agent.tool_guardrailsr!   r"   r#   tools.terminal_toolr$   utilsr%   r&   	getLogger__name__r   r+   r   r  rg  r  r  r  r  __all__rG   r,   r*   <module>r     sh    # " " " " "            				  				 



                   ! ! ! ! ! ! 3 3 3 3 3 3 3 3 3 3 3 3 3 3 7 7 7 7 7 7 7 7 7 7 X X X X X X X X E E E E E E E E 2 2 2 2 2 2                               / . . . . .         
 2 1 1 1 1 1 : : : : : : : :		8	$	$  V V V Vtj j j j\   Fd. d. d. d. d.PV V V VtR R R R@ QU H H H H H H\  r,   