
    .cjF                   @   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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 dd
lmZ ddlmZ ddlm Z  ddl!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/  ej0        e1          Z2h dZ3dZ4d Z5d[dZ6d\dZ7d]dZ8d^d!Z9d_d#Z:d`d'Z;dad1Z<dbd2Z=dcd4Z>dcd5Z?dcd6Z@ddd9ZAded=ZBdfd>ZCd\d?ZDdfd@ZEdfdAZFdgdDZGdhdFZHdidIZIdjdLZJdkdMZKdldmdPZLdndSZMdodUZNddVdWZOddXdfdYZPg dZZQdS )puu  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)SimpleNamespace)AnyDictOptional)get_provider_request_timeoutget_provider_stale_timeout)PARTIAL_STREAM_STUB_IDFINISH_REASON_LENGTH)FailoverReason)EmptyStreamError)substitute_api_content)is_native_gemini_base_url)is_local_endpoint)flatten_message_text)_sanitize_surrogates_repair_tool_call_arguments)claim_stream_writerstream_writer_is_current)is_persistent_env)base_url_host_matchesbase_url_hostname	env_floatenv_int>   pricelatency
throughputg      @c                     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    ?/home/ice/.hermes/hermes-agent/agent/chat_completion_helpers.py_rar"   <   s         api_payloadr   returnintc                   dddfd}t          | t                    r ||           dz  S t          | t                    r|                     d          }t          |t                    r5 ||          }d	| v r!| |                     d	                    z  }|dz  S d
| v ra |                     d
                     |                     d                    z    |                     d	                    z   }|dz  S t	          fd|                                 D                       dz  S  |           dz  S )a   Estimate context/load tokens from an API payload, dict or messages list.

    The stale-call detectors historically assumed a Chat Completions request:
    they pulled ``api_kwargs["messages"]`` and ran a cheap char/4 estimate.
    Codex / Responses API requests carry the conversational payload in
    ``input`` (with additional load in ``instructions`` and ``tools``), so the
    legacy estimator reported ~0 tokens for every Codex turn and the
    context-tier scaling never fired.

    This helper handles both shapes:
      - bare list -> treat as Chat Completions ``messages``
      - dict with ``messages`` -> Chat Completions (+ ``tools`` if present)
      - dict with ``input`` -> Responses API (+ ``instructions``/``tools``)
      - any other dict -> fall back to summing string values
    valuer   r%   r&   c                    | dS t          | t                    rt          |           S t          t          |                     S Nr   )
isinstancestrlen)r(   s    r!   _charsz/estimate_request_context_tokens.<locals>._charsX   s<    =1eS!! 	u::3u::r#   messagesc                z    t          | t                    s |           S t          fd| D                       S )Nc              3  .   K   | ]} |          V  d S N ).0itemr.   s     r!   	<genexpr>zJestimate_request_context_tokens.<locals>._message_chars.<locals>.<genexpr>b   s+      55D66$<<555555r#   )r+   listsum)r/   r.   s    r!   _message_charsz7estimate_request_context_tokens.<locals>._message_chars_   sH    (D)) 	$6(###5555H555555r#      toolsinputinstructionsc              3  .   K   | ]} |          V  d S r2   r3   )r4   r(   r.   s     r!   r6   z2estimate_request_context_tokens.<locals>.<genexpr>w   s+      CCU66%==CCCCCCr#   )r(   r   r%   r&   )r/   r   r%   r&   )r+   r7   dictgetr8   values)r$   r9   r/   total_charsr.   s       @r!   estimate_request_context_tokensrC   G   s   "   6 6 6 6 6 6
 +t$$ 0~k**a//+t$$ I??:..h%% 	$(.22K+%%vvkoog&>&>???!##k!!{w//00&8899:&11223 
 !##CCCCk.@.@.B.BCCCCCqHH6+!##r#   boolc                    t          t          | dd          pd          }t          t          | dd          pd          }t          | dd           dk    p	|dk    od|v S )N_base_url_lower _base_url_hostnameprovideropenai-codexchatgpt.com/backend-api/codex)r,   getattr)agentbase_url_lowerr   s      r!   _is_openai_codex_backendrP   |   st    (92>>D"EENGE+?DDJKKz4((N: 	
. 7$6	r#   
est_tokensfloatc                6    | dk    rdS | dk    rdS | dk    rdS dS )u  Minimum wall-clock stale timeout for openai-codex by estimated context.

    Gateway/Telegram sessions routinely ship ~15–25k tokens of tools +
    instructions before the first user message. Subscription-backed Codex can
    legitimately spend several minutes in backend admission/prefill at that
    size; the generic 90s non-stream stale default aborts healthy calls. The
    floor engages above 10k estimated tokens so those gateway-scale payloads
    are covered; smaller requests keep the generic default.
    順 g     @P        @'  g     @        r3   )rQ   s    r!    openai_codex_stale_timeout_floorrY      s9     GvFuFu3r#   raw_sortOptional[str]c           	         t          | t                    sdS |                                                                 }|sdS |t          v r|S t
                              d| d                    t          t                                         dS )z;Return a normalized OpenRouter provider.sort value or None.Nz@Ignoring invalid OpenRouter provider.sort value %r (allowed: %s), )	r+   r,   striplower _OPENROUTER_PROVIDER_SORT_VALUESloggerwarningjoinsorted)rZ   
sort_values     r!   #_validated_openrouter_provider_sortrf      s    h$$ t!!''))J t555
NNJ		&9::;;  
 4r#   Dict[str, Any]c                    i }| j         r
| j         |d<   | j        r
| j        |d<   | j        r
| j        |d<   t          | j                  }|r||d<   | j        rd|d<   | j        r
| j        |d<   |S )zDBuild the validated provider-routing object shared by request paths.onlyignoreordersortTrequire_parametersdata_collection)providers_allowedproviders_ignoredproviders_orderrf   provider_sortprovider_require_parametersprovider_data_collection)rN   preferencesrr   s      r!   _provider_preferences_for_agentrv      s    "$K 6#5F 8 % 7H 5$4G78KLLM ,+F( 1,0()% H).)G%&r#   namer,   defaultc                    	 t          t          j        | t          |                              S # t          t
          f$ r |cY S w xY wr2   )rR   osgetenvr,   	TypeError
ValueError)rw   rx   s     r!   
_env_floatr~      sP    RYtS\\22333z"   s   .1 AAstale_timeoutttfb_enabledttfb_timeoutlast_event_tsOptional[float]
call_startidle_enabledidle_timeoutelapsedc                   g }t          j        |           r|                    |            |,|r)t          j        |          r|                    |           n?|r=t          j        |          r)|                    t          d||z
            |z              |rt	          |          |k    rdS dt          t	          |                     dS )zBDescribe the earliest enabled Codex watchdog on the call timeline.NrX   rG   ; auto-reconnect at s)mathisfiniteappendmaxminr&   )	r   r   r   r   r   r   r   r   	deadliness	            r!   _codex_wait_notice_recoveryr      s      I}]## (''' 	+DM,77 	+\***	 N$-55 NS-*"<==LMMM I'11r8#c)nn"5"58888r#   c                f    	 t          t          | dd          pd          S # t          $ r Y dS w xY w)N_consecutive_stale_streamsr   )r&   rM   	ExceptionrN   s    r!   _stale_streakr      sI    75">BBGaHHH   qqs   " 
00Nonec                X    	 t          |           dz   | _        d S # t          $ r Y d S w xY w)N   )r   r   r   r   s    r!   _bump_stale_streakr      sD    +8+?+?!+C(((   s    
))c                8    	 d| _         d S # t          $ r Y d S w xY wr*   )r   r   r   s    r!   _reset_stale_streakr      s7    +,(((   s    
c                    t          dd          }t          |           }|dk    r||k    rt          d| d          dS dS )u   Raise immediately when the consecutive-stale streak is past the
    give-up threshold — no network attempt, no stale-timeout wait.HERMES_STREAM_STALE_GIVEUP   r   z:Provider has been unresponsive (no response received) for u    consecutive stale attempts — aborting this call to avoid an indefinite stall. Switch models or start a new session, then retry.N)r   r   RuntimeError)rN   _giveup_streaks      r!   _check_stale_giveupr      sj     2A66GE""G{{w'))## # #
 
 	
 {))r#   
api_kwargsr?   c                   t          | j        | j                  }||}nt          dd          }t	          |          }|dk    rt          |d          }n|dk    rt          |d          }n|}dd	lm} |                    d
          p|                    d          pd} ||          }|*|                    d          rt          |d                   }|t          ||          }|S )u  Stale-stream patience for a provider that is never a local endpoint.

    Mirrors the main streaming path's derivation — provider config → env base
    → context-size scaling → reasoning-model floor — minus the local-endpoint
    ``float('inf')``/900s disable branch, which cannot apply to Bedrock (its
    endpoint is always the AWS cloud). Factored so the Bedrock streaming
    watchdog shares the exact same patience budget as the OpenAI/Anthropic
    stale-stream detector below.
    NHERMES_STREAM_STALE_TIMEOUT     f@rT        r@rU         n@r   !get_reasoning_stale_timeout_floormodelmodelIdrG   )
r	   rI   r   r   rC   r   agent.reasoning_timeoutsr   r@   _bedrock_reasoning_stale_floor)	rN   r   
_cfg_stale_base_est_tokens_timeoutr   	_model_id_reasoning_floors	            r!   _derive_stream_stale_timeoutr     s    ,ENEKHHJ7??1*==KWue$$	v		ue$$JJJJJJ w''J:>>)+D+DJI88CCJNN9$=$=9*Y:OPP#x!122Or#   model_idobject'float | None'c                   ddl m} | rt          | t                    sdS |                                                                 }dD ]0}|                    |          r|t          |          d         } n1|g}d|v rY|                    |	                    dd          d                    |                    |
                    ddd                     g }|D ]O}t          j        dd|          }t          j        d	d|          }|||fD ]}	|	|vr|                    |	           P|D ]} ||          }
|
|
c S dS )
u  Map a Bedrock inference-profile id to its reasoning stale-timeout floor.

    Bedrock carries the model as a dotted, region-prefixed id such as
    ``us.anthropic.claude-opus-4-6-v1:0``, whereas
    :func:`get_reasoning_stale_timeout_floor` anchors its slug patterns at the
    start of a bare slug (``claude-opus-4``). Strip the region prefix
    (``us.``/``eu.``/``apac.``/...) and try two candidate slugs against the
    floor:

    * the segment after the provider namespace (``claude-opus-4-6-v1:0``) —
      matches Anthropic-style slugs whose floor key excludes the provider
      (``claude-opus-4``); and
    * the region-stripped id with the provider dot rewritten to a dash
      (``deepseek-r1-v1:0``) — matches provider-qualified floor keys
      (``deepseek-r1``).

    The floor's right-anchor (``$`` or ``-``/``.``/``_``) tolerates the
    trailing date-stamp / ``-v1:0`` version suffix, so no suffix stripping is
    needed. First non-None wins; returns None for unknown models.

    The floor table mixes version-separator conventions: some keys are
    keyed with a dashed version (``claude-opus-4``) while others embed a
    dotted version (``claude-sonnet-4.5``, ``claude-sonnet-4.6``). Bedrock
    always dashes the version (``claude-sonnet-4-5-v1:0``), so for every
    candidate slug we also try the alternate version-separator form —
    digit-dash-digit rewritten to digit-dot-digit and vice-versa — so a
    dashed Bedrock id matches a dotted floor key (and the reverse). The
    rewrite only touches version-number separators (a dash/dot flanked by
    digits), never other dashes in the slug, so ``claude-sonnet`` is left
    intact while ``4-5`` becomes ``4.5``.
    r   r   N)zglobal.zus.zeu.zapac.zap.zau.zjp.zca.zsa.zme.zaf..r   -z(?<=\d)-(?=\d)z(?<=\d)\.(?=\d))r   r   r+   r,   r^   r_   
startswithr-   r   rsplitreplaceresub)r   r   rw   prefixbase_candidates
candidatescanddashed_to_dotteddotted_to_dashedformfloors              r!   r   r   3  s   @ KJJJJJ :h44 t>>!!##D   ??6"" 	F%DE	 fO
d{{t{{32215666t||Ca88999J ( ( 6"3S$??6"4c4@@+-=> 	( 	(D:%%!!$'''	(   11$77LLL 4r#   c          	        | j         dk    r2 |d          }|                     ||t          | dd                    S | j         dk    r$ |dd          }|                     ||	          S | 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 ||
          S | j        dk    r | j        j        j        j        di |S  |d          } |j        j        j        di |S )um  Run one non-streaming LLM request for the active api_mode and return it.

    Shared by the interrupt-worker path (``interruptible_api_call``) and the
    inline path (``direct_api_call``) so the per-api_mode dispatch — codex /
    anthropic / bedrock / MoA / OpenAI-compatible — lives in exactly one place.

    ``make_client(reason, kind=...)`` builds the per-request client for the
    codex / OpenAI-compatible (``kind="openai"``) and anthropic
    (``kind="anthropic_messages"``) branches; the worker path uses it to
    register the client with its stranger-thread abort machinery, the inline
    path uses it to capture the client for its own ``finally`` close. The
    bedrock / MoA branches manage their own clients and never call it. All
    interrupt, abort, cancellation, and close semantics stay in the callers —
    this helper only issues the request.
    codex_responsescodex_stream_request_codex_on_first_deltaN)clienton_first_deltaanthropic_messagesanthropic_messages_requestkind)r   bedrock_converser   )_get_bedrock_runtime_clientinvalidate_runtime_clientis_stale_connection_errornormalize_converse_response__bedrock_region__	us-east-1__bedrock_converse__moachat_completion_requestr3   )api_mode_run_codex_streamrM   _anthropic_messages_createagent.bedrock_adapterr   r   r   r   popconverser   rI   r   chatcompletionscreate)rN   r   make_clientrequest_clientr   r   r   r   regionr   raw_response_bedrock_excs               r!   "_dispatch_nonstreaming_api_requestr   t  s     ~***$%;<<&&!"5*A4HH ' 
 
 	

 ~--- %(/C
 
 
 //
>/RRR~+++
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
  4kBB-t444,,V44	*6?88Z88LL 	 	 	 )(66 2))&111	 +*<888~ 4u| ,3AAjAAA [!:;;N1>*1??J???s   <C
 

C0C++C0c                    t          | dd          dk    o)t          | dd          dk    ot          | dd          dk    S )a  Whether a cron OpenAI-wire request should skip the interrupt worker.

    Issue #62151 is specific to OpenRouter's chat-completions path inside the
    gateway cron thread stack. Keep native/Codex/Bedrock/MoA transports on their
    established workers: their cancellation and client ownership differ, and
    the report provides no evidence that those paths share the pre-HTTP wedge.
    platformNcronr   chat_completionsrI   r   )rM   r   s    r!   should_use_direct_api_callr     sP     	z4((F2 	6E:t,,0BB	6E:t,,5r#   c                    t                                           d           ddit          j                    d fddd fd}	 t	           |          }t           dd          rt          d          t                      |t           dd          u rd _        5  d         }dd<   ddd           n# 1 swxY w Y   | 	                    |d           S S # t          $ r# t           dd          rt          d          d w xY w# t           dd          u rd _        5  d         }dd<   ddd           n# 1 swxY w Y   | 	                    |d           w w xY w)u.  Run a non-streaming LLM call inline on the conversation thread.

    Used when ``should_use_direct_api_call`` is True. Skips the interrupt worker
    (whose only job is interactive-interrupt responsiveness, which this context
    does not have) so the nested-pool deadlock (#62151) cannot occur. Because the
    request runs in-flight normally, the per-request OpenAI client's own httpx
    timeout (provider ``request_timeout_seconds`` / ``HERMES_API_TIMEOUT``) bounds
    a genuinely hung provider — the same bound interactive calls already rely on.
    &waiting for non-streaming API responser   Nreasonr,   r%   r   c                    5  d         }ddd           n# 1 swxY w Y   |                     ||            dS dS )z?Abort the inline request from cron's watchdog/interrupt thread.r   Nr   )_abort_request_openai_client)r   r   rN   request_client_holderrequest_client_locks     r!   _abort_active_requestz.direct_api_call.<locals>._abort_active_request  s      	= 	=28<N	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	=%..~f.MMMMM &%s   	openair   c                                         |           }5  |d<   d d d            n# 1 swxY w Y   _        |S )Nr   r   r   )_create_request_openai_client_active_request_abort)r   r   r   r   rN   r   r   r   s      r!   _make_clientz%direct_api_call.<locals>._make_client  s    
 44Fz4ZZ  	5 	5.4!(+	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5&;#s   -11r   _interrupt_requestedF!Agent interrupted during API callr   request_completer   r   r,   r%   r   r   )r   r,   r   r,   )r   _touch_activity	threadingLockr   rM   InterruptedErrorr   r   _close_request_openai_clientr   )rN   r   r   responser   r   r   r   s   ``   @@@r!   direct_api_callr    s    	BCCC%t,#.**N N N N N N N N	 	 	 	 	 	 	 	 	 	 	Z5:<
 
 
 50%88 	H"#FGGGE"""51488<QQQ*.E'  	3 	328<N.2!(+	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 %..~FX.YYYY &    50%88 	R"#FGGTQ 51488<QQQ*.E'  	3 	328<N.2!(+	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 %..~FX.YYYY &sT   C3 '0D# 3CC	C	3-D  D# #F  EF EF !E"F c           
          !" t                     rt                     S ddd"t                      dddddi t          j                    !ddiddd_ !fd
d`  !fd "fd}                               } j        dk    }t                     }t                    }|r#|r!t          |          }|rt          ||          }t          dd          }|r|r|dk    rt          ||          }|dk    rd}	n|dk    rd}	n|dk    rd}	nd}	|}
t          dd          }|dk    rd}
n|rt          dd          }t          j                            dd                                                                          d v }|s6|dk    r0||k    r*|	}||k     r"t$                              d!|||d"|           |}t          d#d          }|dk    r'||k    r!t$                              d$|||d"           |}|}t          d%|	          }|dk    rd}|rd _        d _        t-          j                    }                     d&           t          j        |d'(          }|                                 d}|                                r|                    d)*           |d+z  }|d,z  dk    rt-          j                    |z
  }	 t9          ||
|t;           d-d          ||||.          }                     d/                    d0d1           d2t?          |           d3| d4           n,# t@          $ r t$          !                    d5d'6           Y nw xY wt-          j                    |z
  }|
r||k    rt;           d-d          d}t;           d7d          }tE          |          r3	  |                    d0          8          }n# t@          $ r d}Y nw xY wt$          #                    d9||                    d0d:                     |r@ $                    d;t?          |           d<                    d0d:           d=|            n= $                    d;t?          |           d<                    d0d:           d>           	  d?           n# t@          $ r Y nw xY w                     d@t?          |           dA                                dBt?          |           dC           |                    dD*           "dE         s"dF         k|r6tK          dGt?          |           dHt?          |           dI|           "dE<   n3tK          dGt?          |           dHt?          |           dJ          "dE<   nt;           d-d          }|rC|@t-          j                    |z
  |k    r%t-          j                    |z
  }t$          #                    dK||                    d0d:          |d"            $                    dLt?          |           dM                    d0d:           d>           	  dN           n# t@          $ r Y nw xY w                     dBt?          |           dO           |                    dD*           "dE         ;"dF         3tK          dPt?          |           dQt?          |           dJ          "dE<   ni||k    rt                    }d}t;           d7d          }tE          |          r3	  |                    d0          8          }n# t@          $ r d}Y nw xY wt$          #                    dR||                    d0d:          |d"           |r@ $                    dSt?          |           dT                    d0d:           dU|            n= $                    dSt?          |           dT                    d0d:           dV           	  dW           n# t@          $ r Y nw xY wtM                                           dXt?          |           dY           |                    dD*           "dE         s"dF         k|r6tK          dZt?          |           d[t?          |           dI|           "dE<   n3tK          dZt?          |           d[t?          |           dJ          "dE<   ng j'        rKd'd<   t$          !                    d\           	  d]           n# t@          $ r Y nw xY wtQ          d^          |                                "dE         "dE         "dF         tS                      "dF         S )aa=  
    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r  error)r   	owner_tidr(   r   Fr   r   r,   c               |    5  | d<   |d<   t          j                    d<   d d d            n# 1 swxY w Y   | S Nr   r(   r  r  	get_identr   r   r   request_client_kindr   s     r!   _set_request_clientz3interruptible_api_call.<locals>._set_request_client&  s      	G 	G.4!(++/( 2;1D1F1F!+.	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G    !155r   r%   r   c                   5                       d          }                     d          }|d uo|d uo|t          j                    k    }|s
d d<   d d<   d d d            n# 1 swxY w Y   |d S                      dd          }|dk    r4|r                    ||            d S                     ||            d S |r                    ||            d S                     ||            d S )Nr   r  r(   r   r   r   r@   r  r  _abort_request_anthropic_client_close_request_anthropic_clientr   r  )	r   r   r  stranger_threadr   rN   r   r  r   s	        r!   _close_request_client_oncez:interruptible_api_call.<locals>._close_request_client_once0  s    ! 	: 	:266x@@N-11+>>Id* 7T)7!4!6!66 
 # :26%h/59%k2	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: !F"&&w99''' U55nV5TTTTT55nV5TTTTT 	N..~f.MMMMM..~f.MMMMMs   AA&&A*-A*c                 <   	 t          d	fd	          d<   nb# t          $ rU} d         r>t                              dt	          |           j                   Y d } ~  d           d S | d<   Y d } ~ nd } ~ ww xY w d           d S #  d           w xY w)
Nr   c                     |dk    r                     |           n                    |           |          S )Nr   r   r   r   ) _create_request_anthropic_clientr   )r   r   r  rN   r   s     r!   <lambda>z7interruptible_api_call.<locals>._call.<locals>.<lambda>`  sa    :M:M333 ::&:III<<%* =   ; ; ; r#   r  r  r(   uh   Non-streaming worker caught %s after request cancellation — exiting without surfacing a network error.r  r  r  )r   r   ra   debugtype__name__)er  _request_cancelledr  rN   r   results    r!   _callz%interruptible_api_call.<locals>._callV  s    	; "D      " " "F:  	  	  	 
 "'* AGG$  
  '&'9:::::  F7OOOOOO	  '&'9:::::&&'9::::s7    B 
A>5A9B /A94B 9A>>B Br   !HERMES_CODEX_HARD_TIMEOUT_SECONDSg     p@r   rT   r   rU         ^@rW         N@g      (@!HERMES_CODEX_TTFB_TIMEOUT_SECONDS&HERMES_CODEX_TTFB_DISABLE_ABOVE_TOKENSg     @HERMES_CODEX_TTFB_STRICTrG   >   1onyestruezScaling openai-codex no-byte TTFB watchdog from %.0fs to %.0fs for large request (context=~%s tokens >= %.0f). Set HERMES_CODEX_TTFB_STRICT=1 to keep the smaller cutoff.,HERMES_CODEX_TTFB_MAX_SECONDSz~Capping openai-codex no-byte TTFB timeout from %.0fs to %.0fs (context=~%s tokens). Set HERMES_CODEX_TTFB_MAX_SECONDS to tune.(HERMES_CODEX_EVENT_STALE_TIMEOUT_SECONDSr   Ttargetdaemon333333?timeoutr   d   _codex_stream_last_event_ts)r   r   r   r   r   r   r   r      ⏳ waiting on r   the provider    — z:s with no response yet (provider may be slow or overloaded)zwait-notice construction failed)exc_info_codex_silent_hang_hintr   zCodex stream produced no bytes within TTFB cutoff (%.0fs > %.0fs, model=%s). Backend accepted the connection but sent no stream events. Killing connection so the retry loop can reconnect.unknownu&   ⚠️ No first byte from provider in zs (codex stream, model: z). Reconnecting. z). Reconnecting.codex_ttfb_killu!   ⚠ no response from provider in    s — reconnecting...zcodex stream killed after zs with no first byteg       @r  r  z&Codex stream produced no bytes within zs (TTFB threshold: zs). zs)zCodex stream produced no SSE events for %.0fs after first byte (threshold %.0fs, model=%s, context=~%s tokens). Killing connection so the retry loop can reconnect.u'   ⚠️ Codex stream sent no events for zs after first byte (model: codex_stream_idle_killzs with no SSE eventsz(Codex stream produced no SSE events for zs after first byte (threshold: zjNon-streaming API call stale for %.0fs (threshold %.0fs). model=%s context=~%s tokens. Killing connection.%   ⚠️ No response from provider for zs (non-streaming, model: z). z). Aborting call.stale_call_killz&stale non-streaming call killed after r   z'Non-streaming API call timed out after zs with no response (threshold: zBForce-closing httpx client due to interrupt (not a network error).interrupt_abortr  r   r,   r  )*r   r  r   r  r	  !_compute_non_stream_stale_timeoutr   rP   rC   rY   r   r~   r   rz   environr@   r^   r_   ra   infor?  _codex_stream_last_progress_tstimer  Threadstartis_aliverc   r   rM   _emit_wait_noticer&   r   r$  callablerb   _buffer_statusTimeoutErrorr   r  r
  r   )#rN   r   r*  _stale_timeout_codex_watchdog_enabled_openai_codex_backend_est_tokens_for_codex_watchdog_codex_floor_codex_hard_timeout_codex_idle_timeout_default_ttfb_enabled_ttfb_timeout_ttfb_disable_above_ttfb_strict_large_request_ttfb_timeout	_ttfb_cap_codex_idle_enabled_codex_idle_timeout_call_startt_poll_count_elapsed	_recovery_silent_hint_hint_fn_last_codex_event_ts_event_stale_elapsed_est_ctxr  r(  r  r   r  r   r)  s#   ``                          @@@@@@@r!   interruptible_api_callrt    sw   " "%(( 2uj111..F '+$?? #H-#.** "5)3;          $N $N $N $N $N $N $N $N $NL!; !; !; !; !; !; !; !; !; !;R <<ZHHN$ $n0AA4U;;%DZ%P%P" ?#8 ?78VWW 	? >>N" %%H&QQB!B  !##^-@AA%//&+##	'&	0	0&+##	'&	0	0&*##&*# ,MBEJJM	 &()QS[\\z~~&@"EEKKMMSSUU Z
 
 	<#a''.2EEE*E':::Q "/599'   !<>FF	q==]Y66KKS155   &M1$2#  a# 4 -1)/3,)++K	BCCCd333AGGIIIK
**,, TH	sq !!y{{[0HO7"0!.!.")<d# #  +!4!4$  	 ''1jnnWn&M&M 1 18}}1 1$-1 1 1   
  O O O>NNNNNO 9;;, 7	=((<dCCK*.Lu&?FFH!! ((#+8*..2I2I#J#J#JLL  ( ( (#'LLL(NN& -)K)K    $$4S]] 4 4-7^^GY-O-O4 4%14 4    $$%S]] % %-7^^GY-O-O% % %  
**+<====   ###CMM # # #   !!PS]]PPP   FF3Fg&6*+=+E 	&2SX S S,/,>,>S SDPS S' 'F7OO
 '3CX C C,/,>,>C C C' 'F7O 
  'u.KTRR!	$0337JJJ#'9;;1E#E NN> %#w	22155     !#>R:S:S ! !,6NN7I,N,N! ! !  
**+CDDDD   !!\S1E-F-F\\\   FF3Fg&6*+=+E".QsCW?X?X Q Q478K4L4LQ Q Q# #w  n$$6zBBH*.Lu&?FFH!! ((#+8*..2I2I#J#J#JLL  ( ( (#'LLL(NNC.w	22xOO	    $$&CMM & &.8nnWi.P.P& &#& &    $$&CMM & &.8nnWi.P.P& & &  
 +*+<====    u%%%!!IXIII   FF3Fg&6*+=+E 
&2*#h-- * *8;N8K8K* *'* *' 'F7OO '3P#h-- P P8;N8K8KP P P' 'F7O % 	H
 +/w'LLT  **+<====   "#FGGGi **,, THj g"Wo j%E"""*s   A&M &M+*M+O# #O21O2&R2 2
R?>R?Y' '
Y43Y41] ] ] `# #
`0/`0!d- -
d:9d:api_messagesr7   c                z  * | 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    r|                                 }
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    }|                     |          }|r	 ddl}ddlm}m} |                    |          } ||          \  }} ||          \  }}nB# t6          $ r5}t8                              dt	          | dd          |           Y d}~nd}~ww xY w|
                    | j        ||| j
        t	          | dd          | j	        |                                 | j        ||||r|                                 ndt          t	          | d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# t6          $ r d	}d} Y nw xY wtO          |           }!d}"	 dd*l(m)}#m*}$ | j        pd#                                +                    d+d,          *tY          *fd-|$D                       r |#| j                  }"n# t6          $ r Y nw xY wd}%|r*| j-        pd.t]          t_          j0                              d/}%	 dd0l1m2}&  |&| j                  }'n# t6          $ r d}'Y nw xY w|'rt	          | dd          }(|(d| _        |                     |          }|
                    | j        ||| j        |                                 | j	        |(| j3        | j
        | j        t	          | dd          |'| j4        |!pd| j5        |"| 6                                |%1          S t	          | dd          }(|(d| _        |                     |          }) |
j        dTi d2| j        d3|)d4|d5| j        d6|                                 d7| j	        d8|(d9| j3        d:| j
        d;| j        dt	          | dd          d<| j        pd#                                d=|d>|d?|d@|dA|dB|dC|dD|dE| j        dFk    dG| j4        dH|!pddI| j5        dJ|r| j7        nddK|r| j8        nddL|%dM| dN|dO| 6                                dP|r|                                 nddQ|r| 9                                nddR|"dS| j        S )Uz9Build 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)r   r/   r;   
max_tokensreasoning_configis_oauthpreserve_dotscontext_lengthbase_url	fast_modedrop_context_1m_betar   _bedrock_regionr   _bedrock_guardrail_configi   )r   r/   r;   r}  r   guardrail_configr   zmodels.github.aizgithubcopilot.comrJ   rK   rL   >   	xai-oauthxaizapi.x.air   )strip_pattern_and_formatstrip_slash_enumu4   %s⚠️ Failed to sanitize tool schemas for xAI: %s
log_prefixrG   
session_id_codex_reasoning_replay_enabledT)r   r/   r;   r~  r  r}  r=  request_overridesis_github_responsesis_codex_backendis_xai_responsesgithub_reasoning_extrareplay_encrypted_reasoningnousresearchzintegrate.api.nvidia.comzapi.kimi.comzmoonshot.aizmoonshot.cnztokenhub.tencentmaas.comlmstudio_fixed_temperature_for_modelOMIT_TEMPERATURE)_get_anthropic_max_output_ANTHROPIC_OUTPUT_LIMITSr   r   c              3      K   | ]}|v V  	d S r2   r3   )r4   key_model_norms     r!   r6   z#build_api_kwargs.<locals>.<genexpr>u  s(      FFcsk!FFFFFFr#   hermes)	sessionIdpromptIdget_provider_profile)r   r/   r;   r  r=  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_metadatar   r/   r;   r  r=  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_namer3   ):r;   r   _get_transport#_prepare_anthropic_messages_for_apirM   r  rx  build_kwargsr   r}  r~  _is_anthropic_oauth_anthropic_preserve_dotsr  r@   rD   r   r  rI   rH   rF   &_prepare_messages_for_non_vision_modelcopytools.schema_sanitizerr  r  deepcopyr   ra   rb   _resolved_api_call_timeout#_github_models_reasoning_extra_body_is_qwen_portal_is_openrouter_urlr^   r_   agent.auxiliary_clientr  r  rv   agent.anthropic_adapterr  r  r   anyr  r,   uuiduuid4	providersr  _max_tokens_param_ollama_num_ctxr  _supports_reasoning_extra_body_qwen_prepare_chat_messages#_qwen_prepare_chat_messages_inplace"_lmstudio_reasoning_options_cached)+rN   ru  tools_for_api
_transportr   ctx_lenephemeral_out_btr   	guardrail_ctr  r  r  _msgs_for_codex_copyr  r  _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  r  
_qwen_metar  _profile_ephemeral_out_msgs_for_chatr  s+                                             @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 J$U^5HII 	
 Nn, (M9 B(E,AA	 	 !>-AAkUE]akEkFF|TT$  	$$$$        !&} = =#;#;M#J#J q#3#3M#B#B qq   JE<44c        +$"3ulD99'4466#5 3--Re#o5#L#L#N#N#Nko'+@$GG( (   
 
 	
& 


 
 C $$&&H%%''Fe35GHH 	M !68KLL  !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   

 -U33F H		
 	
 	
 	
 	
 	
 	
 	
 {(b//1199#sCCFFFF-EFFFFF 	>00==H    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# #sO   =I 
J+I==J(P5 5QQA"R> >
S
S=T T#"T#finish_reasonc                $   t          |dd          }|                     |          }t          |          }|sdt          t          |d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t          t          |dd                    }	t!          |	          }
|rt!          |          }t#          |
t$                    r)|
r'|                     |
                                          }
t#          |
t$                    r|
rd
dlm}  ||
          }
d|
||d}t          |dd          }|Dt/          |d          r4t          |dd          pi }t#          |t0                    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#          |t0                    r|                    |           -t/          |d          r|                    |j                   Xt/          |d          r'|                    |                                           |r||d<   t          |dd          }|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_callsNcontentz<think>(.*?)</think>flags

c              3  f   K   | ],}|                                 |                                 V  -d S r2   )r^   )r4   bs     r!   r6   z*build_assistant_message.<locals>.<genexpr>  s7      "P"Paggii"P17799"P"P"P"P"P"Pr#   zCaptured reasoning (z	 chars): r   )redact_sensitive_text	assistant)roler  	reasoningr  reasoning_contentmodel_extra reasoning_details__dict__
model_dumpanthropic_content_blockscodex_reasoning_itemscodex_message_itemsidcall_idfunctionrw   rG   	arguments{}response_item_idrw   r  )r
  r  r  r%  r  extra_content)%rM   _extract_reasoningrD   r   r   findallDOTALLrc   verbose_loggingloggingr$  r-   reasoning_callbackstream_delta_callback_stream_callbackr   r   r+   r,   _strip_think_blocksr^   agent.redactr  hasattrr?   _needs_thinking_reasoning_padr  r   r  r  _split_responses_tool_id_deterministic_call_id"_derive_responses_function_call_idr%  r  rw   r  )"rN   assistant_messager  assistant_tool_callsreasoning_text_from_structuredr  think_blockscombined_raw_content_san_contentr  msgraw_reasoning_contentr  raw_details	preserveddordered_blockscodex_itemsr	  r  	tool_callraw_idr  embedded_call_idr  _fn_fn_name_fn_argsr  embedded_response_item_idtc_dictextras"                                     r!   build_assistant_messager9    s    ##4lDII--.?@@NN++
  .&w/@)T'R'RSSz"97")TTT 	.{{"P"Pl"P"P"PPPH%-N ]%/ ][S-@-@[[>[[\\\ %2  * 	53I 	((8888   
 (0A9d(S(STTL'55L >-n== ,$$ G G00>>DDFF ,$$ ; ;666666,,\:: #&	 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#$ .0JDQQN 9*8&' +-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: :
DDr   rI   c                h   t          | dd          }t          |t                    r|sdS d|fd|ffD ]w\  }}|st          t	          j        d| d|                    }|rG|d         }|d|                                          | d| ||                                d          }x|| _        dS )	u-  Point the cached system prompt's ``Model:``/``Provider:`` lines at
    the active runtime after a provider switch.

    The system prompt is session-stable and replayed verbatim for prefix-cache
    warmth, but after a failover the new backend's cache is cold anyway —
    while a stale identity line makes the agent misreport which model it is
    when asked.  Rewrite the lines in place WITHOUT persisting to the session
    DB: the stored row keeps the primary's labels, so when the primary is
    restored the prompt is byte-identical to the stored copy again and its
    prefix cache still matches.

    Only the LAST occurrence of each line is touched — the identity lines
    live in the volatile tail of the prompt, and earlier matches could be
    user content (memory snapshots, context files).
    _cached_system_promptNModelProviderz(?m)^z: .*$: )	rM   r+   r,   r7   r   finditerrU  endr;  )rN   r   rI   splabelr(   matcheslasts           r!   rewrite_prompt_model_identityrF    s      
/	6	6Bb# b !5)J+AB I Iu 	r{#8E#8#8#8"==>> 	I2;D}

}%HuHHHr$((**++HHB"$Er#   fbtuple[str, str, str]c                   t          |                     d          pd                                                                          t          |                     d          pd                                          t          |                     d          pd                                                              d          fS )NrI   rG   r   r  /)r,   r@   r^   r_   rstrip)rG  s    r!   _fallback_entry_keyrL    s    BFF:$"%%++--3355BFF7OO!r""((**BFF:$"%%++--44S99 r#   c                J   |                     d          pd                                                                }|dk    rdS 	 ddlm}  |d          pi }n.# t
          $ r!}dt          |          j         cY d}~S d}~ww xY w|                     d          }|                     d	          }t          |t                    o t          |                                          }t          |t                    o t          |                                          }	|s|	sd
S dS )zGReturn a skip reason for fallback entries known to be unusable locally.rI   rG   nousNr   )get_provider_auth_stateznous_auth_unreadable:access_tokenrefresh_tokennous_token_missing)r@   r^   r_   hermes_cli.authrO  r   r%  r&  r+   r,   rD   )
rN   rG  fb_providerrO  stater  access_valuerefresh_value
has_accesshas_refreshs
             r!   +_fallback_entry_unavailable_without_networkrZ    s?   66*%%+2244::<<Kft<;;;;;;''//52 < < <;tCyy'9;;;;;;;;<99^,,LIIo..ML#..M48J8J8L8L3M3MJ]C00PT-:M:M:O:O5P5PK $+ $##4s   A 
B#A?9B?Br   'FailoverReason | None'c                l   |t           j        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    rt          | j                  dk    rf|t           j        t           j        t           j        hvrAt          | dd          pd}t!          |t          j                    t"          z             | _        dS | j        | j                 }| xj        dz  c_        t%          |          }t          | d	d
          }|t'                      }|| _        ||v r0t*                              d|           |                     |          S |	                    d          pd                                                                }	|	                    d          pd                                }
|	r|
s|                     |          S t1          | |          }|rG|                    |           t*                              d|	|
|           |                     |          S t          | dd          pd                                                                }t          | dd          pd                                }t7          t          | dd          pd                              d                                          }|	                    d          pd                                                    d                                          }|	|k    r7|
|k    r1t*                              d|	|
           |                     |          S |r>|r<||k    r6|
|k    r0t*                              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(tC          |d          r|st?          j         d          pd
} ||	|
d||          \  }}|Et*                              d|	           |                    |           |                     |          S 	 ddl"m#}  ||
|	          }
n4# tH          $ r'}t*                              d|
|	|           Y d
}~nd
}~ww xY wd}t7          |j%                  }| &                    |          }|	dk    rd}n|	d k    sM|                    d                                          '                    d!          stQ          |          d"k    rd#}nq|rd}nl| )                    |          rd}nT| *                    |
|	$          rd}n:|	d%k    s2tQ          |          +                    d&          rtC          |d'          rd(}| j,        }| j-        }d
| _.        |
| _,        |	| _-        |	| _/        || _%        || _0        tc          | d)          r| j2        3                                 d| _4        t          | d*d
          }|ct          |dd          pd                                                                }|r*||	k    r$t*          5                    d+|	|
|           d
| _6        t          | d*d
          	 dd,l7m8}  ||	          }|r7|9                                r#|| _6        t*          5                    d-|	|
           n4# tH          $ r'} t*                              d.|	|
|            Y d
} ~ nd
} ~ ww xY wtu          |	|
          }!|d#k    rdd/l;m<}"m=}#m>}$ |	d k    r|j?        p |#            pdn|j?        pd}%|%| _?        |%| _@        || _A         |"|%| jA        |!0          | _B        |	d k    r |$|%          nd| _C        d
| _D        i | _E        n}|j?        | _?        || _D        t          |d1d
          }&|&st          |d2d
          }&|j?        |d3|&rd2t          |&          ini | _E        |! |!| jE        d4<   | G                    d56           | H                    |	|||
7          \  | _I        | _J        | K                                 tc          | d8          r| jL        rdd9lMmN}' t          | j?        t6                    r| j?        nd}( |'| j,        | j%        |(| j-        t          | d:d
          t          | d;d
          <          })| jL        P                    | j,        |)| j%        t          | dd          | j-        | j0        =           	 dd>lQmR}* dd?lSmT}+  |+ |*            pi | j,                  | _U        t*          5                    d@| j,        | jU                   n8# tH          $ r+},t*                              dA| j,        |,           Y d
},~,nd
},~,ww xY wt          | |
|	           | W                    dB|
 dC|	            dD| dC| dE|
 dC|	 | _X        t*          5                    dF||
|	           t          |            dS # tH          $ rV}-|	dGk    r|                    |           t*          Z                    dH|
|-           |                     |          cY d
}-~-S d
}-~-ww xY w)Iu  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_activatedFrI   rG   <   r   _rate_limited_untilr   _unavailable_fallback_keysNz/Fallback skip: %s previously marked unavailabler   zMFallback skip: %s/%s is not locally usable (%s); suppressing for this sessionr  rJ  z?Fallback skip: chain entry %s/%s matches current provider/modelz>Fallback skip: chain entry base_url %s matches current backend)resolve_provider_clientapi_keykey_envapi_key_envz
ollama.comOLLAMA_API_KEYT)r   	raw_codexexplicit_base_urlexplicit_api_keyz.Fallback to %s failed: provider not configured)normalize_model_for_providerz9Could not normalize fallback model %r for provider %r: %sr   rJ   r   	anthropicz
/anthropiczapi.anthropic.comr   )rI   bedrockzbedrock-runtime.zamazonaws.comr   _transport_cache_credential_poolznFallback to %s/%s: clearing primary credential pool (pool_provider=%s) to prevent cross-provider contamination)	load_poolz4Fallback to %s/%s: attached fallback credential poolz7Fallback to %s/%s: could not attach credential pool: %s)build_anthropic_clientresolve_anthropic_token_is_oauth_tokenr<  _custom_headersdefault_headers)rb  r  r=  fallback_timeout_applyr   )rI   r  r   r   rw  )get_model_context_length_config_context_length_custom_providers)r  rb  rI   config_context_lengthcustom_providers)r   r  r  rb  rI   r   load_config)resolve_reasoning_configz*Fallback %s: reasoning_config resolved: %szGFailed to resolve reasoning_config for fallback %s; keeping current: %su5   🔄 Primary model failed — switching to fallback: z via u!   🔄 Switched to fallback model: u    → u"   Fallback activated: %s → %s (%s)rN  z"Failed to activate fallback %s: %s)[r   
rate_limitbillingupstream_rate_limitrD   rM   r^   r_   _primary_runtimer@   rS  	monotonicr_  _fallback_indexr-   _fallback_chainr   _FALLBACK_EXHAUSTED_COOLDOWN_SrL  setr`  ra   r$  _try_activate_fallbackrZ  addrb   r,   rK  r  ra  rz   r{   r   hermes_cli.model_normalizeri  r   r  _is_azure_openai_urlendswithr   _is_direct_openai_url&_provider_model_requires_responses_apir   r   rI   rv  requested_providerr   r  rl  clearr]  rQ  rm  agent.credential_poolrn  has_credentialsr   r  ro  rp  rq  rb  _anthropic_api_keyry  _anthropic_clientr  r   _client_kwargsr?   _replace_primary_openai_client_anthropic_prompt_cache_policy_use_prompt_caching_use_native_cache_layout_ensure_lmstudio_runtime_loadedrw  agent.model_metadataru  r+   update_modelhermes_cli.configr{  hermes_constantsr|  r~  rF  rY  _pending_fallback_noticer   r  ).rN   r   fallback_already_activecurrent_providerprimary_provider_existing_cooldownrG  fb_keyunavailablerT  fb_modellocal_skip_reasoncurrent_modelcurrent_base_urlfb_base_url_for_dedupra  fb_base_url_hintfb_api_key_hint
fb_key_env	fb_client_resolved_fb_modelri  	_norm_errfb_api_modefb_base_url_fb_is_azure	old_modelold_provider_existing_pool_pool_providerrn  fallback_poolr  _fb_timeoutro  rp  rq  effective_key
fb_headersru  _fb_ctx_api_keyfb_context_lengthr{  r|  _reasoning_errr'  s.                                                 r!   try_activate_fallbackr    s    .+^-C^Eghhh #'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 : ::: %&&**~8.:PR`Rtuuu!(0Eq!I!I!NQ(+"  #AA) )E% u		u4	5B	Q $$F%!=tDDKee+6(FOOO++F33366*%%+2244::<<Kw%2,,..H 4h 4++F333CE2NN 4[		
 	
 	
 ++F333  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	
 	
 	
 ++F333
4
4 "%555%%L!	
 	
 	
 ++F333
N4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.,). ). ).%	% NN@   OOF###//777	OOOOOO33HkJJHH 	 	 	NNK+y       	 )),--11+>>.((+KK;&&!!#&&,,..77EE ' --1DDD /KK 	- -KK((55 	-+KK99  : 
 
 	- ,KKI%%k**556HII &%k?CC & -KK	~
 (,$$#. $$5,-- 	+"((***$(! !(:DAA%%nj"EEKRRTTZZ\\N ..K"?"?Q>  
 *.&5,d33;;;;;;; )	+ 6 6  ]%B%B%D%D -:E*KKN#X      M3        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
 0:%-/M/MUemmSUO 8 8en'%.&-e5Mt&T&T!(0CT!J!J	! ! ! $11k0y"55 2   	555555AAAAAA%=%=#U[& &E" KK<U3     	 	 	LLY^       	 	&eX{CCC,, ,), ,	
 	
 	
0	 0 0 0 00 0"-0 0 	& 	0x	
 	
 	
 	E"""t 4 4 4&  OOF###98QGGG++F33333333	4s   E
m V. -m .
W8Wm WG-m A
` m 
a	"a?m a		Hm Aj. -m .
k#8!km k##A.m 
n3An.(n3.n3r/   api_call_countc           
     0   t          d| j         d           d}|                    d|d           	 |                                 }g }|D ]}|                                }|                     ||           dD ]}|                    |d           dD ]}	|                    |	d           t          |           d	 |D             D ]}
|                    |
d           |rl| j        }| j	        d
k    rCt          | dd          }|0t          |dd          }|r|                    d          r|d         }|                     ||           |                    |           | 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# t0          $ 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!<   tU          |           }"i }#	 dd"l+m,}$  |$| j	                  }%|%:|%-                    t          | d#d          |"pd| j        | j        | j        $          }#n# t0          $ r Y nw xY w|#r|(                    |#           |"rNd%|#v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	 ta          | j/                  }&n# tb          td          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| $                                }'|'3                    | j        |d| j'        | j        | j4        | 5                                /          }(| 6                    |(          }|'%                    || j4        0          })|)j&        pd                                } nm | 7                    d12          j8        j9        j:        d=i |!}| $                                %                    |          })|)j&        pd                                } | rXd3| v r4tw          j<        d4d| tv          j=        5                                          } | r|                    d6| d           n]d7} nY| j!        dk    r| "                    |          }|                    dd           | #                    |          }*| $                                }+|+%                    |*          },|,j&        pd                                } nn| j!        d.k    r| $                                }-|-3                    | j        |d| j4        | j'        | j        | 5                                8          }.| 6                    |.          }*|-%                    |*| j4        0          }/|/j&        pd                                } n| j        |d}!|||!d <   | j'        -|!(                    | )                    | j'                             |||!d!<   |r||!d-<    | 7                    d92          j8        j9        j:        d=i |!}| $                                %                    |          }/|/j&        pd                                } | rVd3| v r4tw          j<        d4d| tv          j=        5                                          } | r|                    d6| d           nd7} nd7} nN# t0          $ rA}0t|          ?                    d:|0            d;| j         d<t          |0           } Y d}0~0nd}0~0ww xY w| S )>zSRequest 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_prefillN)	tool_namer  r	  	timestampc                f    g | ].}t          |t                    |                    d           ,|/S )r  )r+   r,   r   )r4   ks     r!   
<listcomp>z)handle_max_iterations.<locals>.<listcomp>  s9     ` ` `qz!S7I7I `all[^N_N_ ` ` ` `r#   r   r   last_aggregator_slotr   rF  rG   r  systemr   r   r  r  r  r   Tmedium)enabledeffort)nous_portal_tagstagsr   r;   )r   r/   temperaturereasoning_effortr  r  )r  r  r   r  r~  rI   
openrouterzopenrouter/pareto-coderX   g      ?zpareto-router)r
  min_coding_scoreplugins
extra_bodyr   )r   r/   r;   r}  r~  r  r  )strip_tool_prefixiteration_limit_summaryr   z<think>z<think>.*?</think>\s*r  r  z>I reached the iteration limit and couldn't generate a summary.)r   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: r3   )Aprintmax_iterationsr   _should_sanitize_tool_callsr  _copy_reasoning_content_for_apir   r   r   rI   rM   r@   #_sanitize_tool_calls_for_strict_apir;  ephemeral_system_promptr^   prefill_messages	enumerateinsert_sanitize_api_messages#_drop_thinking_only_and_merge_usersr  r  r  r   r  rF   r_   r  *_resolve_lmstudio_summary_reasoning_effortr~  agent.portal_tagsr  r   _build_api_kwargsr   r  normalize_responser  r}  updater  rv   r  r  build_extra_bodyr  r  rR   r|   r}   r  r  r  r   _ensure_primary_openai_clientr   r   r   r   r   r  ra   rb   r,   )1rN   r/   r  summary_request_needs_sanitizeru  r)  api_msginternal_fieldschema_foreigninternal_key_sanitize_model_moa_client	_agg_slot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  profile_extra_bodyr  r  _ps_tsum_ant_kw_summary_resultretry_response	_ct_retry
_cnr_retry_tretry_ant_kw2_retry_resultr'  s1                                                    r!   handle_max_iterationsr  p  s    	
_1E
_
_
_```	* 
 OOV@@AAAu~  ;;== (	) (	)ChhjjG11#w???"U 2 2ND1111 #m 2 2ND1111 #7+++ ` `G ` ` ` 0 0L$//// Z #(+>U**")%4"@"@K".$+K9OQU$V$V	$ Aw)?)? A.7.@O99'9YYY(((( 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 $C5#I#I !#::::::#7#7#G#G #/)9)J)J#*5,#E#E-A-IT#k!&).)? *K * *&     " >"))*<===# F
:L(L(L%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 ~ ~ ~=!==>>>}e>R}}uxyzu{u{}}~ s   G,e !H* )e *H;8e :H;;G e <AQ e 
Qe QCe )T> =e >Ue UO3e 
f7fftask_idc                   	 t          |          r | j        rt          j        d| d           n!t	                                          |           n># t          $ r1}| j        r t                              d| d|            Y d}~nd}~ww xY w	 d}	 ddl	m
}  |            }n<# t          $ r/ t          t          j                            d	                    }Y nw xY w|r#| j        rt          j        d
| d           dS dS t	                                          |           dS # t          $ r8}| j        r&t                              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).

    Skips ``cleanup_browser`` in headed mode so the browser window stays
    visible between turns. The inactivity reaper in
    ``browser_tool._cleanup_inactive_browser_sessions`` still handles
    idle sessions.
    z0Skipping per-turn cleanup_vm for persistent env z; idle reaper will handle it.zFailed to cleanup VM for task r?  NFr   )_is_headed_modeAGENT_BROWSER_HEADEDz5Skipping per-turn cleanup_browser for headed session z#Failed to cleanup browser for task )r   r  r  r$  r"   
cleanup_vmr   ra   rb   tools.browser_toolr  rD   rz   rP  r@   cleanup_browser)rN   r  r'  headedr  s        r!   cleanup_task_resourcesr  v  s*    LW%% 	&$ 3w 3 3 3  
 EEW%%% L L L  	LNNJGJJqJJKKKLQ	B::::::$_&&FF 	B 	B 	B"*..)?@@AAFFF	B 	+$ 3G 3 3 3      EE!!'***** Q Q Q  	QNNOOOAOOPPPPPPPPP	Q 	Q 	Q 	Q 	Q 	QQsZ   AA 
B'B		BD* B& %D* &6CD* C$D* !D* *
E,4'E''E,dropped_tool_namesc                   t          | |d|          }t          d|t                    }t          t          ||g||pd          S )a  Build a partial-stream-stub response for mid-stream drop scenarios.

    Used when the SSE stream ends without a ``finish_reason`` after
    delivering content (text-only drops, tool-call-arg drops).  The stub
    is tagged ``PARTIAL_STREAM_STUB_ID`` with ``FINISH_REASON_LENGTH`` so
    the conversation loop enters its continuation/retry path instead of
    silently accepting truncated output as a complete turn (#32086).
    Nr  r  r  r  r   indexmessager  r
  r   choicesusage_dropped_tool_names)r   r   r
   )r  full_contentfull_reasoning
model_name	usage_objr  mock_messagemock_choices           r!   _build_partial_stream_stubr*    sr     #(	  L "*  K
 !.6$   r#   )r   c               "   &'()*+,-./0123456789:;<=>?  j         rt          d          t                     r                               S  j        dk    r0 _        	                                d _        S # d _        w xY w j        dk    rkddd=ddi8ddi7d	t          j                    i&                    d
d          }t                     }t                      8fd-&- 7=fd}t          j        |d          }|                                 |                                r|                    d            j         rt          d          t          j                    &d	         z
  }||k    rt                              d|||                    dd                                          dt%          |           d                    dd           d           t'                      	 ddlm}  ||           n2# t,          $ r%}	t                              d|	           Y d}	~	nd}	~	ww xY wt          j                    &d	<   t                      t1          dt%          |           dt%          |           d          =d<   n|                                 j         rt          d           =d         =d         =d!         t3                      =d!         S ddg d"=t                      dddd#:d$d%i;t          j                    <d$di/d%d&dz:;<fd)0d* 55:;<fd+1d{5fd/+d{+ :;<fd0*ddi8ddi7d	t          j                    i9d6t          j                    >dt7                      ddd1?d|>?fd32d{>?fd4)d}>?fd73d}>?fd84d~>?fd9,8fd:.d,.01346 79:=fd;(. 79:fd<''()*/02 78:=fd=}
t9           j         j                  }||}nt?          d>d?          }|d?k    r j         rtC           j                   rd@}	 ddAl"m#}  |            }tI          |tJ                    r|                    dB          nd}tI          |tJ                    r@|                    dC          }tI          |t$          tL          f          rtM          |          }n# t,          $ r Y nw xY wt?          dD|          6t                              dE j         6           nutO                    }|dFk    rtQ          |dG          6n|dHk    rtQ          |dI          6n|6ddJl)m*}  |                    dK                    }|tQ          6|          6t          j        |
d          }|                                 t          j                    }dL}|                                r|                    d           t          j                    }||z
  |k    r|}t%          |9d	         z
            }||k    r_6'6tM          dM          k    rdNt%          6           dO}ndP} +                    dQ                    dKdR           dS| dT| dU           n ,                    dV| dW           t          j                    9d	         z
  }|6k    rQtO                    }t                              dX|6                    dKd          |dY                                dZt%          |           d                    dKd           d[|dYd\           	  )d]            *d]           n# t,          $ r Y nw xY wt'                       j        d^k    rn(	  -                    d_`           n# t,          $ r Y nw xY wt          j                    9d	<    +                    dat%          |           db            ,                    dct%          |           dd            j         rVd/d$<   t                              de           	  )df            *df           n# t,          $ r Y nw xY wt          dg          |                                 j         rt          dh          =d         37d         r"t]           didP          pdP/                                pd}ta          =                    dj          pg           }|rdk                    |ddl                   }tc          |          dlk    r|dmtc          |          dlz
   dnz  }do| dp}|pdP|z   }	  2                    |           n# t,          $ r Y nw xY wt                              dq|tc          |pdP          =d                    tf          }n8t                              drtc          |pdP          =d                    tf          }ti          ds|ddt          } d}!	 ddul5m6}"m7}#  |"=d         tq          t]           dvdP          pdP          tq          t]           dKdP          pdP          w          }$|$j9        |#j:        k    }!n# t,          $ r d}!Y nw xY wti          tv          t]           dKd          ti          d| |x          gd|pdy          }%|!rd|%_<        t3                      |%S =d         =d!         t3                      =d!         S )u  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 callr   Nr   r  doneFr3  rk  r   r   c                 f     d         s%r%d d<   	               d S # t           $ r Y d S w xY wd S d S Nr,  Tr   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}m}m}                     dd          }                    dd             | |          }	  |j        di }n# t          $ r}	 ||	          rhd_
                            d           t                              dt          |	          j                    | |j        di           d	<   Y d }	~	d S  ||	          r ||            d }	~	ww xY wt#                     fd
}
fd}fd} ||                                r|
nd |j        sj        r|nd fdfd          d	<   d S # t          $ r}|d<   Y d }~d S d }~ww xY w)Nr   )r   r   r    is_streaming_access_denied_errorr   stream_converse_with_callbacksr   r   r   Tu   
⚠  AWS IAM denied bedrock:InvokeModelWithResponseStream — falling back to non-streaming InvokeModel.
   Grant that action to restore streaming output.
u`   bedrock: converse_stream denied by IAM (%s) — using non-streaming converse() for this session.r  c                P                                       |            dd<   d S )NTr3  )_fire_stream_delta)textr2  rN   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 r2   )_fire_tool_gen_started)rw   r2  rN   s    r!   _on_toolzIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_toolD	  s(    KMMM0066666r#   c                F                                       |            d S r2   )_fire_reasoning_delta)r9  r2  rN   s    r!   _on_reasoningzNinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_reasoningH	  s(    KMMM//55555r#   c                      j         S r2   )r  r   s   r!   r#  zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>Q	  s
    u/I r#   c                 R                          dt          j                              S )Nrk  )__setitem__rS  )_bedrock_last_events   r!   r#  zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>R	  s    %8%D%DS$)++%V%V r#   )on_text_deltaon_tool_starton_reasoning_deltaon_interrupt_checkon_eventr  r3   )r   r   r   r   r5  r   r6  r   converse_streamr   _disable_streaming_safe_printra   rQ  r%  r&  r   r   _has_stream_consumersr  r  )r   r   r   r5  r   r6  r   r   r   r   r;  r>  rA  r'  rE  r2  rN   r   r:  r)  s                 r!   _bedrock_callz7interruptible_streaming_api_call.<locals>._bedrock_call	  s   F$                $(<kJJ5t<<<44V<<#96#9#G#GJ#G#GLL     87EE 370))R  
 O ..7  
 .I-H+FO99j99. .z*  10>> :11&9999@ $E***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VVVV& & &z"""  $ $ $"#w$sJ   AE A E 
C2#A-C-E C--C22A%E 
E3#E..E3Tr8  r;  r<  z)Agent interrupted during Bedrock API calluk   Bedrock stream stale for %.0fs (threshold %.0fs) — no events received. region=%s model=%s. Aborting call.r   rG  u"   ⚠️ No events from Bedrock for z
s (model: z). Aborting...r   )r   z)bedrock: stale client eviction failed: %sz&Bedrock stream produced no events for zs (threshold uF   s) — aborting stalled stream so the retry/fallback path can recover.r  z7Agent interrupted during Bedrock API call (post-worker)r  )r  r  partial_tool_names)r   diagr  r(   r   r   r   r,   c               |    5  | d<   |d<   t          j                    d<   d d d            n# 1 swxY w Y   | S r  r  r  s     r!   r  z=interruptible_streaming_api_call.<locals>._set_request_client	  s      	G 	G.4!(++/(1:1D1F1F!+.		G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G
 r  c                    t          | dd           }t          |          r|S t          | dd           }t          |dd           }t          |          r|S d S )Ncloser  )rM   rX  )streamrT  r  s      r!   _stream_close_callablez@interruptible_streaming_api_call.<locals>._stream_close_callable	  s`    ..E?? 	L6:t44'400E?? 	Ltr#   c                     |           | S 5  | d<   dd<   t          j                    d<   d d d            n# 1 swxY w Y   | S )Nr   rU  r(   r  r  )rU  rV  r   r  r   s    r!   _set_request_stream_handlezDinterruptible_streaming_api_call.<locals>._set_request_stream_handle	  s     "!&))1M  	G 	G.4!(++3(1:1D1F1F!+.	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G s   !>AAr   r%   r   c                     |           }|d S 	  |             t                               d|           d S # t          $ r'}t                               d||           Y d }~d S d }~ww xY w)Nz%Streaming response handle closed (%s)z/Streaming response handle close failed (%s): %s)ra   rQ  r   r$  )rU  r   rT  r  rV  s       r!   _close_request_stream_handlezFinterruptible_streaming_api_call.<locals>._close_request_stream_handle	  s    &&v..=F	EGGGKK?HHHHH 	 	 	LLA        	s   %9 
A*A%%A*c                &   	5                       d          }                     dd          }                     d          }|dk    o|d uo|d uo|t          j                    k    }|s
d d<   d d<   d d d            n# 1 swxY w Y   |d S |dk    r ||            d S |dk    r4|r                    ||            d S                     ||            d S |r                    ||            d S                     ||            d S )Nr   r(   r   r  rU  r   r   r  )
r   r   request_kindr  r  rZ  rN   r   r  r   s
        r!   r  zDinterruptible_streaming_api_call.<locals>._close_request_client_once	  s   
 ! 	: 	:266x@@N.227HEEL-11+>>I ( 7"$.7T)7 !4!6!66	  # :26%h/59%k2!	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	:" !F8##((@@@@@111 U55nV5TTTTT55nV5TTTTT 	N..~f.MMMMM..~f.MMMMMs   A2BB	B)current	cancelleddiscarded_chunksdiscarded_bytesr&   c                      5  dxx         dz  cc<   t          d                   cd d d            S # 1 swxY w Y   d S )Nr]  r   )r&   )stream_attempt_lockstream_attempt_states   r!   _start_stream_attemptz?interruptible_streaming_api_call.<locals>._start_stream_attempt$
  s      	8 	8 +++q0++++I677	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8s   %6::c                    5  t                              d          pd          }|rd                             |           d d d            n# 1 swxY w Y   |rt                              d||            d S d S )Nr]  r   r^  z&Marked stream attempt %s cancelled: %s)r&   r@   r  ra   r$  )r   r]  rb  rc  s     r!   _cancel_current_stream_attemptzHinterruptible_streaming_api_call.<locals>._cancel_current_stream_attempt)
  s      	? 	?.229==BCCG ?$[155g>>>	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	?  	LL8    	 	s   AAAAstream_attempt_idrD   c                    5  | t                              d          pd          k    o	| d         v	 cd d d            S # 1 swxY w Y   d S )Nr]  r   r^  )r&   r@   rg  rb  rc  s    r!   _stream_attempt_is_activezCinterruptible_streaming_api_call.<locals>._stream_attempt_is_active5
  s      	 	!S)=)A)A))L)L)QPQ%R%RR O%-A+-NN	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   3AAAc                P    5  | d         v cd d d            S # 1 swxY w Y   d S )Nr^  r3   ri  s    r!   _stream_attempt_was_cancelledzGinterruptible_streaming_api_call.<locals>._stream_attempt_was_cancelled<
  s      	J 	J$(<[(II	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	Js   
c                   	 t          t          |                    }n# t          $ r d}Y nw xY w5  dxx         dz  cc<   dxx         |z  cc<   d         }d         }d d d            n# 1 swxY w Y   |dk    rt                              d| ||           d S t                              d| ||           d S )Nr   r_  r   r`  z[Discarding chunk from superseded stream attempt %s (discarded_chunks=%s discarded_bytes=%s)zUDiscarded stale stream chunk from attempt %s (discarded_chunks=%s discarded_bytes=%s))r-   reprr   ra   rb   r$  )rg  chunkchunk_bytesr_  r`  rb  rc  s        r!   _discard_stale_stream_chunkzEinterruptible_streaming_api_call.<locals>._discard_stale_stream_chunk@
  si   	d5kk**KK 	 	 	KKK	  	F 	F !34449444 !2333{B33334FG23DEO		F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F
 q  NN;!      LL;!     s     //1A11A58A5c                 f     d         s%r%d d<   	               d S # t           $ r Y d S w xY wd S d S r.  r/  r0  s   r!   _fire_first_deltaz;interruptible_streaming_api_call.<locals>._fire_first_delta[
  sq     ( 	^ 	(,f%        		 	 	 	r3  c                ^  3 ddl }t          ;j        ;j                  }||nt	          dd          }||}nt	          dd          }|dk    r?;j        r8t          ;j                  r$|}t                              d;j        |           n>|dk    r8:6:t          d          k    r#:|k    r:}t                              d	|           |t          |d
          nd}i <d|                    ||||          d}t          ;j                  sddi|d<    6;                    d|                    }t          j                    >d<   ;                    d           ;                                }|?d<    |j        j        j        dHi |}	;j        dk    r 7|	          }	t)          ;          }
t+          |	d          rt                              d;j        pd;j        pd           d;_        |	j        }t3          |t4          t6          f          r
|r|d         nd}t9          |dd          }|t9          |dd          pt9          |dd          }t3          |t:                    r!|r 5             ;                    |           t9          |dd          }t3          |t:                    r!|r 5             ;                    |           |	S ;                     t9          |	dd                     ;!                    t9          |	dd                     ;"                    |t9          |	dd                     ;#                    t9          |	dd                     g }i 3tI                      }i }i }d}d}d}g }d}|	D ]}tK          ;|
          s2t          &                    d <'                    d!d                      nt          j                    >d<   ;                    d"           	 tQ          |'                    d#d                    d$z   |d#<   |'                    d%          >d         |d%<   	 tQ          |'                    d&d                    tS          tU          |                    z   |d&<   n# tV          $ r Y nw xY wn# tV          $ r Y nw xY w;j,        r n 8|           s 4| |           C|j        s>t+          |d!          r|j        r|j        }t+          |d'          r|j-        r|j-        }|j        d         j.        }t+          |d!          r|j        r|j        }t9          |dd          pt9          |dd          }|r4|/                    |            5             ;                    |           |r|j0        r|/                    |j0                   3s* 5             ;                    |j0                   d=d(<   nM;j1        rF	 ;1                    |j0                   ;2                    |j0                   n# tV          $ r Y nw xY w|r*|j3        r"|j3        D ]}|j4        |j4        nd}|j5        pd)}||vr|||<   |r)||v r%|||         k    rtm          3d*+          d$z   }|||<   |r|||<   ||         }|3vr:|j5        } t3          | tP                    rt;          |           } | pd)d,d)d)d-dd.3|<   3|         }!|j5        2|j5        }"t3          |"tP                    rt;          |"          }"|"r|"|!d/<   |j7        rM|j7        j8        r|j7        j8        |!d,         d0<   |j7        j9        r |!d,         d1xx         |j7        j9        z  cc<   t9          |d2d          }#|#Ft+          |d3          r6t3          |j:        tv                    r|j:        ni '                    d2          }#|#)t+          |#d4          r|#<                                }#|#|!d2<   |!d,         d0         }$|$rS||vrO|=                    |            5             ;>                    |$           @d5         /                    |$           |j        d         j?        r|j        d         j?        }t+          |d'          r|j-        r|j-        } 9|           r|@                    d6|  d7          d)A                    |          pd}%d}&d8}'3rg }&t          3          D ]}3|         }(|(d,         d1         })|(d,         d0         pd9}*|)rZ|)C                                rF	 t          jE        |)           n0# t          jF        $ r t          |)|*          }+|+d:k    r|+})nd}'Y nw xY w|&/                    t          |(d/         |(d;         |('                    d2          t          |(d,         d0         |)-          <                     ||s|s3st          d=          |'o|du },|,rb3fd>t          3          D             }-t          &                    d?|-           t          ||%d)A                    |          pd|||-pd@          S |du o|o3 }.|.rBt          &                    dA           t          ||%d)A                    |          pd||          S |pdB}/|'rdC}/d)A                    |          pd}0t          ||%|&|0D          }1t          d|1|/E          }2t          dFt;          t          jL                              z   ||2g|G          S )Iz#Stream a chat completions response.r   NHERMES_API_TIMEOUTg      @HERMES_STREAM_READ_TIMEOUTr,  uD   Local provider detected (%s) — stream read timeout raised to %.0fsinfuV   Cloud reasoning stream — read timeout raised to %.0fs to match stale-stream detectorr-        >@T)connectreadwritepool)rU  r=  include_usagestream_optionschat_completion_stream_requestr   rk  z)waiting for provider response (streaming)rQ  r   r!  z}Streaming request returned a final response object instead of an iterator; switching %s/%s to non-streaming for this session.rG  r  r  r   r  r  r  zxStreaming attempt superseded by a newer stream; stopping consumption to preserve the single-writer invariant (model=%s).r   receiving stream responsechunksr   first_chunk_atbytesr"  r3  rG   r>  )rx   r  r  )r
  r%  r  r  r
  rw   r  r  r  r  rP  zstream attempt z was supersededF?r  r%  )r
  r%  r  r  zlProvider returned an empty stream with no finish_reason (possible upstream error or malformed SSE response).c                <    g | ]}|         d          d         pdS )r  rw   r  r3   )r4   r  tool_calls_accs     r!   r  zTinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>.<listcomp>  s=         $Z08?C  r#   zStream ended with no finish_reason while a tool call's arguments were still incomplete (tools=%s); treating as a mid-tool-call stream drop, not an output-length truncation.r  zkStream ended with no finish_reason after delivering text with no tool calls; treating as a mid-stream drop.stoplengthr  r  zstream-)r
  r   r!  r"  r3   )Mhttpxr   rI   r   r   r  r   ra   r$  rR   r   Timeoutr   r   rS  r  _stream_diag_initr   r   r   r   r  rQ  rL  r!  r+   r7   tuplerM   r,   r@  r8  _capture_rate_limits_capture_credits_stream_diag_capture_response_check_openrouter_cache_statusr  r   rb   r@   r&   r-   rn  r   r  r"  deltar   r  r  _record_streamed_assistant_textr  r  r
  r   r  rw   r  r  r?   r  r  r=  r  RemoteProtocolErrorrc   rd   r^   jsonloadsJSONDecodeErrorr   r   r   r*  r  r  )Arg  _httpx_provider_timeout_cfg_base_timeout_stream_read_timeout	_conn_capstream_kwargsr   _diagrU  _writer_tokenr!  first_choicer  r#  r  content_partstool_gen_notified_last_id_at_idx_active_slot_by_idxr  r&  r  reasoning_partsr'  ro  r  tc_deltaraw_idxdelta_idnew_slotr  _tc_identry_new_idr8  rw   r$  mock_tool_callshas_truncated_tool_argstcr  r  repaired_tool_args_dropped_no_finish_dropped_names_text_only_dropped_no_finisheffective_finish_reasonr%  r(  r)  r  rq  rs  r  rX  rj  rl  _stream_stale_timeoutrN   r   r:  last_chunk_timer   r)  sA                                                      @r!   _call_chat_completionsz@interruptible_streaming_api_call.<locals>._call_chat_completionsc
  sU    !=U^U[ Y Y %0 "!/88 	 !,#8  #,-I5#Q#Q 
 $u,,,DUV[VdDeDe,'4$ZN$8   
 %--)5)U5\\99),@@@ (=$23G   1F0QCt,,,W[		
	
~~!)#	 &  	
 	
 	
  )88 	F/>.EM*+,,//7( 0  
 
  $y{{IJJJ ''))(-f%7$07HH-HH>U"" 0/77F
 ,E22  69%% 	KKR+)(y	   (,E$
 nG)3GdE])K)KaPWa71::]aLlIt<<G"G%8$?? ;wT::  nc22 @~ @%%'''//???!'9d;;gs++ 6 6%%''',,W555M
 	""76:t#D#DEEEwvz4@@AAA 	++E76:t3T3TUUU 	,,WVZ-N-NOOO !!$
 !#$&
 "	 d	( d	(E
 ,E=AA " NN7I66	   #'9;;OC !!"=>>>
"%eii!&<&<"="="Ah99-..6.=c.BE*+
%(7A)>)>%?%?#d5kkBRBR%RE'NN    D    ) ,,->?? ++,=uEEE= 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$     GB) GB % 0 FB F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!)%fc22 1%([[F"(,B$.13"(E(E-1	/ /s+ +3/E{."*+%gs33 3&)'llG" 2*1E$K( Z#,1 	O 9A8I8NE*-f5#,6 Z!*-k:::h>O>YY:::#HotDDE}=)I)I}9CHDXZ^9_9_!g!5!5eg l lm| } }("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	(():;; 	,,D"3DDD  
 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"+  	( ( (     !! "# " # "
 #G  2 (?'X=TXCX$' 	   !.11  N NNN 	   .l((0DI#1#9T	    T! ##"" 	%
 ( 		NNE   .l((0DI   #0"96" 	/&.#119T& &,	
 
 
 & 1
 
 

 3tz||,,, M	
 
 
 	
s\   A	R$ARR$
R R$R  R$$
R10R1;4X00
X=<X=e*ffc           	     (   d}d}t          j                     d<                                   }|d<   ddlm}  |t	          dd                      | j        j        d$i 5 }	                     |t	          |d	d
                     n# t          $ r Y nw xY wt                    }|D ]D}t          |          s2t                              d                    dd                      n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                                  |           Fj        r	 d
d
d
           d
S 	 |                                }n!# t.          $ r |st1          d           d
 w xY w|s3|"t	          |d!d
          s t	          |d"d
          t1          d#          |cd
d
d
           S # 1 swxY w Y   d
S )%aV  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.

        Uses ``request_client`` (a per-request Anthropic client registered with
        the stranger-thread abort machinery) rather than the shared
        ``_anthropic_client``, so the stale/interrupt watchdog can abort this
        stream's socket without closing the shared client mid-flight (#67142).
        Frk  rQ  r   )sanitize_anthropic_kwargsr  rG   )r  r  NzAnthropic streaming attempt superseded by a newer stream; stopping consumption to preserve the single-writer invariant (model=%s).r   rG  Tr  r  r   r  r  r%  content_block_startcontent_blocktool_userw   content_block_deltar  
text_deltar9  r3  thinking_deltathinkingzeProvider returned an empty stream with no events (possible upstream error or malformed event stream).r  stop_reasonzjProvider returned an empty stream with no stop_reason (possible upstream error or malformed event stream).r3   )rS  r  r  r  rM   r/   rU  r  r   r   r   ra   rb   r@   r  r&   r-   rn  r  r=  r8  r@  get_final_messageAssertionErrorr   )r   has_tool_usesaw_stream_eventr  r  rU  r  event
event_typeblockr  r  
delta_typer9  thinking_text_final_messagers  rN   r   r:  r  r   s                   r!   _call_anthropicz9interruptible_streaming_api_call.<locals>._call_anthropic:  s7     !  $y{{''))(-f%
 	FEEEEE!!75,#C#C	
 	
 	
 	
 ,^$+99j99 u	"V
3376:t<<        066M =K =K 0}EE NN> #w	::	   E#'  (,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 ) ku	" u	" u	" u	" u	" u	" u	" u	"x!'!9!9!;!;!   '  *O      $ 
&	4@@ '  tDDL 'K   "ku	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	" u	"s   )N+%BN
BNBBN%A	G/AF32G3
G =G?G  GN
GNGD/NL#"N#M9NNNc                 
   dd l } t          dd          }	 t          |dz             D ]}             } j        r d           t	          d          	  j        dk    r0                      d	          d
          } |          $d<   n |          $d<     d           d S # t          $ rt}d         r?t          	                    dt          |          j                   Y d }~  d           d S t          || j        | j        | j        f          }t          || j        | j        t$          f          }                     |          }t          |t(                    }	!d         rt+          $                    d                    }
d}|sg|seddlm} t          ||          rOt3          |dd           s>t5          |                                          d}t9          fd|D                       }|p|p|p|}|
o|o||k     }|s2t                              d|           |$d<   Y d }~  d           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            j        dk    r(	  !                    d	           n# t          $ r Y nw xY wY d }~ d}|sg|seddlm} t          ||          rOt3          |dd           s>t5          |                                          d}t9          fd|D                       }|s|s|s|s|	r||k     r                      ||dz   |dz   d#                    d                      d             d             j        dk    r(	  !                    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|	r
d&|dz    d%}n	d'|dz    d%} #                    |           nt5          |                                          }d(|v od)|v }d}|sd*|v rdd+l$m%}  ||          }|s|r d _&         '                    |rd,nd-           t          (                    d.|           |$d<   Y d }~  d           d S d }~ww xY wn(# t          $ r}|$d<   Y d }~ d           d S d }~ww xY w	  d           d S #  d           w xY w)/Nr   HERMES_STREAM_RETRIES   r   interrupt_before_stream_retryz%Agent interrupted before stream retryr   anthropic_stream_requestr   r   r  stream_request_completer(   uP   Streaming worker caught %s after request cancellation — exiting without retry.r3  rP  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 r2   r3   )r4   phrase_err_lower_previews     r!   r6   zBinterruptible_streaming_api_call.<locals>._call.<locals>.<genexpr>3  s=       ?" ?"(. %+.@$@?" ?" ?" ?" ?" ?"r#   z9Streaming failed after partial delivery, not retrying: %sr  u9   

⚠ Connection dropped mid tool-call; reconnecting…

r,  TrQ  )r  attemptmax_attemptsmid_tool_callrQ  stream_mid_tool_retry_cleanup"stream_mid_tool_retry_pool_cleanupc              3      K   | ]}|v V  	d S r2   r3   )r4   r  _err_lower_sses     r!   r6   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)r   r  r  r  r  rQ  u5   ❌ Provider returned malformed streaming data after uM    attempts. The provider may be experiencing issues — try again in a moment.u5   ❌ Provider returned an empty response stream after u(   ❌ Connection to provider failed after rU  znot supportedinvokemodelwithresponsestream)r5  u   
⚠  AWS IAM denied bedrock:InvokeModelWithResponseStream. Switching to non-streaming.
   Grant that action to restore streaming output.
u   
⚠  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))r  r   ranger  r
  r   r"  r   ra   r$  r%  r&  r+   ReadTimeoutConnectTimeoutPoolTimeoutConnectErrorr  ConnectionError_is_provider_stream_parse_errorr   rD   r@   r   r  rM   r,   r_   r  rb   r8  _reset_stream_delivery_tracking_emit_stream_dropr  _log_stream_retryrY  r   r5  rL  rM  rQ  )%r  _max_stream_retries_stream_attemptrg  r   r'  _is_timeout_is_conn_err_is_stream_parse_err_is_empty_stream_partial_tool_in_flight_is_sse_conn_err_preview	_APIError_SSE_PREVIEW_PHRASES_is_transient_can_silent_retry_is_sse_conn_err_SSE_CONN_PHRASES_exhausted_msg
_err_lower_is_stream_unsupported_is_bedrock_stream_deniedr5  r  r  r  r  rf  r  r(  r  rd  rN   r:  r1  r   r)  s%                          @@r!   r*  z/interruptible_streaming_api_call.<locals>._call  s>	   %&=qAAD	B#()<q)@#A#A { {$9$9$;$;! - T223RSSS*+RSSSp~)=== *=)<!BB'A C   "6	* * * .=_^-L-Lz**-C-CDU-V-Vz*T	 '&'@AAAAAS	 ! a a a *'2 F GG,  
 t '&'@AAAAAs #-F.0EvGYZ# #K $.F/1K_]$ $L ,1+P+PQR+S+S('1!5E'F'F$ (. `!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 '&'@AAAAA[!!44!6     ) ! ! ! D!!!AACCCC( ! ! ! D!
 8:3427(/49)&1//"#$3a$7)<q)@*.!6!:!:6!B!B 0    767VWWW223RSSS
 !>-AAA% % D D+O !E !" !" !" !" $- % % % $%  (-$& | @@@@@@%a33 GA}VZ<[<[ -0VV\\^^N1- 03 3 3 3 3.?3 3 3 0 0, $t't ,t 0	t
 ,t +-@@@!33&'(7!(;-@1-D.3%:%>%>v%F%F 4    ;:;QRRR667MNNN  %~1EEE!)$)$H$H/J %I %& %& %& %& (1 !) !) !)$(D!)$HHHH //!,"#$7!$;)<q)@*/!6!:!:6!B!B 0    0 !9#6#:!9 !9 !9 +N . !9)<q)@!9 !9 !9 +N!9#6#:!9 !9 !9 + ,,^<<<<%(VV\\^^
$
2 > /: = / 5:1 6 ?: M M      !A @ C C 6 2 5N 7;E4!-- $=!3 !V !V!3	 	 	 B   '(F7OFFFF '&'@AAAAAS	a5{x	   	 	 	  F7OFFF&&'@AAAAA	y	{F
 '&'@AAAAA&&'@AAAAs  A T4 A	B1#T4 1T0<5T+1T4 D8T+;T4 I$#T+$
I1.T+0I11T+5J
	T+

JT+JA&T+>LT+
L"T+!L""T+%T4 +CT+;PT+
PT+PT+"T4 (C1T+T4 +T00T4 3U* 4
U>UU* UU* *U7r   r   rV   rz  rN   local_stream_stale_timeout!HERMES_LOCAL_STREAM_STALE_TIMEOUTuB   Local provider detected (%s) — stale stream timeout set to %.0fsrT   r   rU   r   r   r   rx  rw  r   r   rG   r@  rA  rB  zRs with no output yet (provider may be slow or overloaded, or the model is thinkingrC  zwaiting for stream response (zs, no chunks yet)uq   Stream stale for %.0fs (threshold %.0fs) — no chunks received. model=%s context=~%s tokens. Killing connection.r5  rK  z, context: ~z tokens). Reconnecting...stale_stream_killr   stale_stream_pool_cleanupr   u    ⚠ no output from provider for rI  zstale stream detected after zs, reconnectingzLForce-closing streaming httpx client due to interrupt (not a network error).stream_interrupt_abortz+Agent interrupted during streaming API callz9Agent interrupted during streaming API call (post-worker) _current_streamed_assistant_textrP  r]      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 length-truncated stub with %s chars of recovered content so the loop can continue from where the stream died: %sr  r  )classify_api_errorr   rI   )rI   r   r  r   rN  r  r%   r&   )rg  r&   r%   rD   )rg  r&   r%   r   )rg  r&   )=r  r
  r   _interruptible_api_callr   r   rS  r@   r   r   r  rT  rU  rV  rc   ra   rb   rY  r&   r   r   r   r   r$  rZ  r   r	  r  r	   rI   r   r   r  r   r  r{  r+   r?   rR   rC   r   r   r   rW  r  r  rM   r^   r7   r-   r8  r   r   agent.error_classifierr  r   r,   r   content_policy_blockedr
   _content_filter_terminated)@rN   r   r   r  _bedrock_stale_timeoutrO  rk  _stale_elapsedr   
_inval_excr*  r   _stream_stale_timeout_base_local_defaultr{  _cfg
_agent_cfg_vr   r   r   _last_heartbeat_HEARTBEAT_INTERVAL_hb_now_waiting_secsrn  rs  _partial_text_partial_names	_name_str_warn_stub_finish_reason	_stub_msgr  r  r   _cls_stubrE  r  r  rf  r  rZ  rq  r2  rs  r(  r  rX  rd  rj  rl  rV  r  r:  r1  r  r   r  r   r)  rb  rc  s@   ```                                   @@@@@@@@@@@@@@@@@@@@@@@@@@r!    interruptible_streaming_api_callr     s     ! NLMMM "%(( 9,,Z888~***
 '5#	/00<<*.E''$E'.... ~+++"T22#UO!5>  #DIKK0 %..)={KK!=eZ!P!P
 	E"""	 	 	 	 	 	G	$ G	$ G	$ G	$ G	$ G	$ G	$ G	$ G	$ G	$R M$???				jjll 5	FF3F) T&'RSSS
 "Y[[+>s+CCN 666C"$:#Z^^Iy%I%I	   $$T^9L9L T T)~~iCCT T T   #5)))OOOOOO--o>>>>    LLCZ        ,09;;#C( $E***
 #/FS=P=P F F"%&<"="=F F F# #w
 k jjll 5	| % 	^"#\]]]'?&/! *)&&&j!!RHHF
 '+TMM #H-#.** "5)3;                        "N "N "N "N "N "N "N "N "N "NH  u~ DIKK(O !#.**UU	 8 8 8 8 8 8 8

 
 
 
 
 
 
      J J J J J J J      6     U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
 U
n]" ]" ]" ]" ]" ]" ]" ]" ]" ]"~IB IB IB IB IB IB IB IB IB IB IB IB IB IB IB IBX
 ,ENEKHHJ%/""%./Le%T%T" "U**u~*BSTYTbBcBc* 
	555555;==D.8t.D.DN'***$J*d++ /^^$@AAb3,// /%*2YYN 	 	 	D	 )*M~ ^ ^PN1	
 	
 	
 	
 6jAA  $'(BE$J$J!!6!!$'(BE$J$J!!$>! 	ONNNNN<<Z^^G=T=TUU'$'(=?O$P$P!d333AGGIIIikkO
**,, nR	s )++_$(;;;%O/#*> >??M 333 *5-u== Ts;P7Q7Q T T TII "I''PjnnWn&M&M P P$P PCLP P P    %%TMTTT   s';;1116zBBHNNC 5w	22xOO	     #N8K8K # #%>>'9==# #%3# # #  ../BCCC**+>????    u%%% ~!555 88@[8\\\\    D $(9;;OC ###3~3F3F # # #   !!Ss>/B/BSSS   % 	R
 +/w'LL)  ../GHHH +*+CDDDD   "#PQQQ] **,, nRh ! \Z[[[g"E" V	 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 */&3UUUUUUUU))7O 
B!?!?!E2FFgeWb99?R@@   K>#HH +*  3 3 3-2***3#)eWi88(Y>Q    $2$:d  E * 8370  &&&LWo j%E"""*s   +B 	BH% %
I/IIBS% %
S21S2"]9 9
^^%^< <
_	_	a, ,
a98a9,f 
ffA(j jj)rt  r  r9  r  r  r  r   )r$   r   r%   r&   )r%   rD   )rQ   r&   r%   rR   )rZ   r   r%   r[   )r%   rg   )rw   r,   rx   rR   r%   rR   )r   rR   r   rD   r   rR   r   r   r   rR   r   rD   r   rR   r   rR   r%   r,   r  )r%   r   )r   r?   r%   rR   )r   r   r%   r   )r   r?   )ru  r7   r%   r?   )r  r,   r%   r?   )r   r,   rI   r,   r%   r   )rG  r?   r%   rH  )rG  r?   r%   r[   r2   )r   r[  r%   rD   )r/   r7   r  r&   r%   r,   )r  r,   r%   r   )R__doc__
__future__r   r  r  r   rz   r   r  rS  r  typesr   typingr   r   r   hermes_cli.timeoutsr   r	   r  r
   r   r	  r   agent.errorsr   agent.turn_contextr   agent.gemini_native_adapterr   r  r   agent.message_contentr   agent.message_sanitizationr   r   agent.stream_single_writerr   r   tools.terminal_toolr   utilsr   r   r   r   	getLoggerr&  ra   r`   r  r"   rC   rP   rY   rf   rv   r~   r   r   r   r   r   r   r   r   r   r  rt  r  r9  rF  rL  rZ  r  r  r  r*  r   __all__r3   r#   r!   <module>r0     sn    # " " " " "    				 				       ! ! ! ! ! ! & & & & & & & & & & X X X X X X X X I I I I I I I I 1 1 1 1 1 1 ) ) ) ) ) ) 5 5 5 5 5 5 A A A A A A 2 2 2 2 2 2 6 6 6 6 6 6        U T T T T T T T 1 1 1 1 1 1 N N N N N N N N N N N N		8	$	$#E#E#E   "%   2$ 2$ 2$ 2$j	 	 	 	   &   "   &   9 9 9 9H         
 
 
 
# # # #L> > > >B<@ <@ <@ <@~   5Z 5Z 5Z 5ZpZ Z Z Z|@ @ @ @Hg g g gV% % % %:      *k4 k4 k4 k4 k4^B B B BL-Q -Q -Q -Qd     @ QU q q q q q qn3  r#   