
    `gj                   f   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j`                  e1      Z2h dZ3dZ4d Z5d3dZ6d4dZ7d5dZ8d6dZ9d7dZ:d8dZ;	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d9dZ<d:dZ=d;dZ>d;dZ?d;dZ@d<d ZAd=d!ZBd>d"ZCd4d#ZDd>d$ZEd>d%ZFd?d&ZGd@d'ZHdAd(ZIdBd)ZJdCd*ZKdDdEd+ZLdFd,ZMdGd-ZNdd.d/ZOdd0d>d1ZPg d2ZQy)Huu  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    P/root/.hermes/venv/lib/python3.12/site-packages/agent/chat_completion_helpers.py_rar"   <   s         c                   d	dd
fd}t        | t              r ||       dz  S t        | t              r| j                  d      }t        |t              r+ ||      }d| v r| | j                  d            z  }|dz  S d| v rL | j                  d             | j                  d            z    | j                  d            z   }|dz  S t	        fd| j                         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
    c                f    | yt        | t              rt        |       S t        t        |             S Nr   )
isinstancestrlen)values    r!   _charsz/estimate_request_context_tokens.<locals>._charsX   s,    =eS!u:3u:r#   messagesc                \    t        | t              s |       S t        fd| D              S )Nc              3  .   K   | ]  } |        y wN ).0itemr+   s     r!   	<genexpr>zJestimate_request_context_tokens.<locals>._message_chars.<locals>.<genexpr>b   s     5D6$<5   )r'   listsum)r,   r+   s    r!   _message_charsz7estimate_request_context_tokens.<locals>._message_chars_   s)    (D)(##5H555r#      toolsinputinstructionsc              3  .   K   | ]  } |        y wr/   r0   )r1   r*   r+   s     r!   r3   z2estimate_request_context_tokens.<locals>.<genexpr>w   s     CU6%=Cr4   )r*   r   returnint)r,   r   r=   r>   )r'   r5   dictgetr6   values)api_payloadr7   r,   total_charsr+   s       @r!   estimate_request_context_tokensrD   G   s   "6
 +t$k*a//+t$??:.h%(2K+%vkoog&>??!##k!{w/089:123 
 !##Ck.@.@.BCCqHH+!##r#   c                    t        t        | dd      xs d      }t        t        | dd      xs d      }t        | dd       dk(  xs |dk(  xr 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   |   se    (92>D"ENGE+?DJKz4(N: 	
. 7$6	r#   c                (    | dkD  ry| dkD  ry| dkD  ryy)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     @        r0   )
est_tokenss    r!    openai_codex_stale_timeout_floorrX      s(     GFFr#   c           	         t        | t              sy| j                         j                         }|sy|t        v r|S t
        j                  d| dj                  t        t                           y)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)raw_sort
sort_values     r!   #_validated_openrouter_provider_sortrd      sb    h$!'')J55
NNJ		&9:;
 r#   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_orderrd   provider_sortprovider_require_parametersprovider_data_collection)rN   preferencesro   s      r!   _provider_preferences_for_agentrs      s    "$K#55F % 7 7H$44G78K8KLM+F((,0()%%).)G)G%&r#   c                    	 t        t        j                  | t        |                  S # t        t
        f$ r |cY S w xY wr/   )floatosgetenvr(   	TypeError
ValueError)namedefaults     r!   
_env_floatr|      s:    RYYtS\233z" s   '* >>c                j   g }t        j                  |       r|j                  |        |)|r_t        j                  |      rJ|j                  |       n8|r6t        j                  |      r!|j                  t        d||z
        |z          |rt	        |      |k  rydt        t	        |             dS )zBDescribe the earliest enabled Codex watchdog on the call timeline.rV   rG   ; auto-reconnect at s)mathisfiniteappendmaxminr>   )	stale_timeoutttfb_enabledttfb_timeoutlast_event_ts
call_startidle_enabledidle_timeoutelapsed	deadliness	            r!   _codex_wait_notice_recoveryr      s      I}}]#'DMM,7\*	$--5S-*"<=LMI'1!#c)n"5!6a88r#   c                V    	 t        t        | dd      xs d      S # t        $ r Y yw xY w)N_consecutive_stale_streamsr   )r>   rM   	ExceptionrN   s    r!   _stale_streakr      s3    75">BGaHH s    	((c                J    	 t        |       dz   | _        y # t        $ r Y y w xY w)N   )r   r   r   r   s    r!   _bump_stale_streakr      s+    +8+?!+C( s    	""c                2    	 d| _         y # t        $ r Y y w xY wr&   )r   r   r   s    r!   _reset_stale_streakr      s!    +,( s   
 	c                f    t        dd      }t        |       }|dkD  r||k\  rt        d| d      yy)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      sO     2A6GE"G{w')Hi ##
 	
 *{r#   c                   t        | j                  | j                        }||}nt        dd      }t	        |      }|dkD  rt        |d      }n|dkD  rt        |d      }n|}ddlm} |j                  d	      xs |j                  d
      xs d} ||      }||j                  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.
    HERMES_STREAM_STALE_TIMEOUT     f@rR        r@rS         n@r   !get_reasoning_stale_timeout_floormodelmodelIdrG   )
r	   rI   r   r   rD   r   agent.reasoning_timeoutsr   r@   _bedrock_reasoning_stale_floor)	rN   
api_kwargs
_cfg_stale_base_est_tokens_timeoutr   	_model_id_reasoning_floors	            r!   _derive_stream_stale_timeoutr     s     ,ENNEKKHJ7?1*=KWue$	v	ue$J w'J:>>)+DJI8CJNN9$=9*Y:OP#x!12Or#   c                4   ddl m} | rt        | t              sy| j	                         j                         }dD ]#  }|j                  |      s|t        |      d } n |g}d|v rF|j                  |j                  dd      d          |j                  |j                  ddd             g }|D ]P  }t        j                  dd|      }t        j                  d	d|      }|||fD ]  }	|	|vs|j                  |	        R |D ]  } ||      }
|
|
c S  y)
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)model_idr   rz   prefixbase_candidates
candidatescanddashed_to_dotteddotted_to_dashedformfloors              r!   r   r   3  s?   @ K:h4>>!!#D  ??6"F%D fO
d{t{{32156t||Ca89J ( 66"3S$?66"4c4@+-=> 	(D:%!!$'	((  1$7L r#   c          	        | j                   dk(  r' |d      }| j                  ||t        | dd            S | j                   dk(  r |dd      }| j                  ||	      S | j                   d
k(  rSddlm}m}m}m} |j                  dd      }|j                  dd        ||      }		  |	j                  di |}
 ||
      S | j                  dk(  r0 | j                  j                  j                  j                   di |S  |d      } |j                  j                  j                   di |S # t        $ r} ||      r ||        d}~ww xY w)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_requestr0   )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  sp     ~~**$%;<&&!"5*A4H ' 
 	

 ~~-- %(/C
 //
>/RR~~++
	
 	
  4kB-t4,V4	*6??8Z8L +<88~~ 4u||  ,,33AjAA !:;N1>**11?J??  	 )6)&1	s   +D2 2	E;EEc                j    t        | dd      dk(  xr" t        | dd      dk(  xr t        | dd      dk7  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     sG     	z4(F2 	6E:t,0BB	6E:t,5r#   c                    t                 j                  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        j                  |d       S S # 1 sw Y    xY w# 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 Y   nxY w j                  |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   Nc                j    5  d   }ddd       j                  ||        yy# 1 sw Y    xY w)z?Abort the inline request from cron's watchdog/interrupt thread.r   Nreason)_abort_request_openai_client)r   r   rN   request_client_holderrequest_client_locks     r!   _abort_active_requestz.direct_api_call.<locals>._abort_active_request  sC      	=28<N	=%..~f.M &	= 	=s   )2c                t    j                  |       }5  |d<   d d d        _        |S # 1 sw Y   xY w)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  sJ    
 44Fz4Z  	5.4!(+	5&;#	5 	5s   .7r   _interrupt_requestedF!Agent interrupted during API callr   request_completer   r   r(   r=   Noneopenai)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%t,#..*N	 	Z5:<
 50%8"#FGGE"5148<QQ*.E'  	328<N.2!(+	3 %..~FX.Y &	3 	3  50%8"#FGTQ 5148<QQ*.E'  	328<N.2!(+	3 	3 	3 %..~FX.Y &sB   C $C5 CC	$C22C5 5ED"	E"D+'Ec           
         !" t               rt               S ddd"t                dddddi t        j                         !ddidddZ !fdd[  !fd	 "fd
} j                        } j                  dk(  }t               }t              }|r|rt        |      }|rt        ||      }t        dd      }|r|r|dkD  rt        ||      }|dkD  rd}	n|dkD  rd}	n
|dkD  rd}	nd}	|}
t        dd      }|dk  rd}
n|rt        dd      }t        j                  j                  dd      j!                         j#                         dv }|s.|dkD  r)||k\  r$|	}||k  rt$        j'                  d|||d|       |}t        dd      }|dkD  r!||kD  rt$        j'                  d|||d       |}|}t        d |	      }|dk  rd}|rd _        d _        t-        j,                         } j/                  d!       t        j0                  |d"#      }|j3                          d}|j5                         r|j7                  d$%       |d&z  }|d'z  dk(  rjt-        j,                         |z
  }	 t9        ||
|t;         d(d      ||||)      } j=                  d*j                  d+d,       d-t?        |       d.| d/       t-        j,                         |z
  }|
r||kD  rt;         d(d      xd}t;         d2d      }tE        |      r	  |j                  d+      3      }t$        jG                  d4||j                  d+d5             |r4 jI                  d6t?        |       d7j                  d+d5       d8|        n1 jI                  d6t?        |       d7j                  d+d5       d9       	  d:        j=                  d;t?        |       d<        j/                  d=t?        |       d>       |j7                  d?%       "d@   X"dA   S|r*tK        dBt?        |       dCt?        |       dD|       "d@<   n'tK        dBt?        |       dCt?        |       dE      "d@<   nt;         d(d      }|r|t-        j,                         |z
  |kD  rt-        j,                         |z
  }t$        jG                  dF||j                  d+d5      |d        jI                  dGt?        |       dHj                  d+d5       d9       	  dI        j/                  d=t?        |       dJ       |j7                  d?%       "d@   ,"dA   'tK        dKt?        |       dLt?        |       dE      "d@<   n||kD  rrt              }d}t;         d2d      }tE        |      r	  |j                  d+      3      }t$        jG                  dM||j                  d+d5      |d       |r4 jI                  dNt?        |       dOj                  d+d5       dP|        n1 jI                  dNt?        |       dOj                  d+d5       dQ       	  dR       tM                 j/                  dSt?        |       dT       |j7                  d?%       "d@   X"dA   S|r*tK        dUt?        |       dVt?        |       dD|       "d@<   n'tK        dUt?        |       dVt?        |       dE      "d@<   nL jN                  r.d"d<   t$        jC                  dW       	  dX       tQ        dY      |j5                         r"d@   "d@   "dA   tS                "dA   S # t@        $ r t$        jC                  d0d"1       Y w xY w# t@        $ r d}Y gw xY w# t@        $ r Y w xY w# t@        $ r Y w xY w# t@        $ r d}Y w xY w# t@        $ r Y {w xY w# t@        $ r Y tQ        dY      w xY w)\a=  
    Run the API call in a background thread so the main conversation loop
    can detect interrupts without waiting for the full HTTP round-trip.

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

    Includes a stale-call detector: if no response arrives within the
    configured timeout, the connection is killed and an error raised so
    the main retry loop can try again with backoff / credential rotation /
    provider fallback.
    Nr  error)r   	owner_tidr*   r  Fr   c               z    5  | d<   |d<   t        j                         d<   d d d        | S # 1 sw Y   | S xY wNr   r*   r  r  	get_identr   r   r   request_client_kindr   s     r!   _set_request_clientz3interruptible_api_call.<locals>._set_request_client&  sS      	G.4!(++/( 2;1D1D1F!+.	G 	G    "0:c                   5  j                  d      }j                  d      }|d uxr |d uxr |t        j                         k7  }|s
d d<   d d<   d d d        y j                  dd      }|dk(  r*rj                  ||        y j	                  ||        y rj                  ||        y j                  ||        y # 1 sw Y   wxY w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!4!66 
 #26%h/59%k2	: !"&&w9''55nV5T55nV5T..~f.M..~f.M/	: 	:   ACCc                    	 t        dfd	      d<    d       y # t        $ rJ} d   r6t        j                  dt	        |       j
                         Y d } ~  d       y | d<   Y d } ~ Wd } ~ ww xY w#  d       w xY w)	Nc                t     |dk(  rj                  |       |      S j                  |       |      S )Nr   r   r   r   ) _create_request_anthropic_clientr   )r   r   r  rN   r   s     r!   <lambda>z7interruptible_api_call.<locals>._call.<locals>.<lambda>`  sT    :M33 ::&: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   r^   debugtype__name__)er  _request_cancelledr  rN   r   results    r!   _callz%interruptible_api_call.<locals>._callV  s     	; "D"F:4 ''9:  	 
 "'*AG$$
  ''9:  F7O	  ''9:s2   # 	A6.A1A9 'A1,A9 1A66A9 9
Br   !HERMES_CODEX_HARD_TIMEOUT_SECONDSg     p@r   rR   r   rS         ^@rU         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   rD   rX   r   r|   r   rv   environr@   r[   r\   r^   infor=  _codex_stream_last_progress_tstimer  Threadstartis_aliver`   r   rM   _emit_wait_noticer>   r   r"  callabler_   _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_callrr    s	   " "%(uj11.F '+$? #H-#..* "5)3;  $N $NL!; !;R <<ZHN$ $nn0AA4U;%DZ%P"#878VW >N" %%H&Q!!#^-@A%/&+#	'&	0&+#	'&	0&*#&*# ,MBEJM	()QS[\zz~~&@"EKKMSSU Z
 
 #a'.2EE*E'::Q "/5a8' !<>F	q=]Y6KKS1!4 &M1$2# a# -1)/3,))+K	BCd3AGGIK
**,	sq !yy{[0HO7"0!.!.")<d#  +!4!4$	 ''%jnnWn&M%Ne8}o &$$-;a1 99;, =(<dCK*.Lu&?FH!(#+*..2I#JL NN& -)K $$<S]O L--7^^GY-O,P Q%%1N4 $$<S]O L--7^^GY-O,P Q$%
*+<= ##3CM? C" # !!,S]O;OP FF3Fg&6*+=+E&2@X P,,/,>+?tL>S'F7O
 '3@X P,,/,>+?rC'F7O 
  'u.KTR$0337JJ#'99;1E#E NN> %#w	21!4   9#>R:S9T U,,6NN7I,N+O P !
*+CD !!,S1E-F,GG[\ FF3Fg&6*+=+E".>sCW?X>Y Z4478K4L3MRQ#w  n$6zBH*.Lu&?FH!(#+*..2I#JL NNC.w	2xl	 $$;CM? K..8nnWi.P-QQT#n& $$;CM? K..8nnWi.P-Q R%&
 ++<=
 u%!!8XqI FF3Fg&6*+=+E&2A#h- Q88;N8K7LD'.*'F7O '3A#h- Q88;N8K7LBP'F7O %%
 +/w'LLT*+<= ##FGGi **,j g"Wo j%E"*}  O>NO( ! (#'L(.  d  , ! (#'L(2  R  "#FGGs   =A]" ^	  ^ ^+ +^; _ _ " ^^	^^	^('^(+	^87^8;_
	_
	__	_32_3c                  * | j                   }| j                  dk(  r| j                         }| j                  |      }t	        | dd      }|r|j
                  nd}t	        | dd      }|d| _        |j                  | j                  ||||n| j                  | j                  | j                  | j                         |t	        | dd      | j                  xs i j                  d      dk(  t        t	        | dd	            
      S | j                  dk(  r]| j                         }t	        | dd      xs d}t	        | dd      }	|j                  | j                  ||| j                  xs d||	      S | j                  dk(  rY| j                         }
t!        | j"                  d      xs t!        | j"                  d      }| j$                  dk(  xs | j&                  dk(  xr d| j(                  v }| j$                  dv xs | j&                  dk(  }| j+                  |      }|r4	 ddl}ddlm}m} |j5                  |      } ||      \  }} ||      \  }}|
j                  | j                  ||| j                  t	        | dd      | j                  | j=                         | j                  ||||r| j?                         ndt        t	        | dd             !      S | j                         }
| jA                         }| jC                         }t!        | j(                  d      xs t!        | j(                  d      }d"| j(                  v }d#| j(                  v }t!        | j"                  d$      xs. t!        | j"                  d%      xs t!        | j"                  d&      }t!        | j(                  d'      }| j$                  xs djE                         jG                         d(k(  }	 dd)l$m%}m&}  || j                  | j"                        }||u }|s|nd} tO        |       }!d}"	 dd*l(m)}#m*}$ | j                  xs djG                         jW                  d+d,      *tY        *fd-|$D              r |#| j                        }"d}%|r.| jZ                  xs d.t]        t_        j`                               d/}%	 dd0l1m2}&  |&| j$                        }'|'rt	        | dd      }(|(d| _        | j+                  |      }|
j                  | j                  ||| j"                  | j=                         | j                  |(| jf                  | j                  | j                  t	        | dd      |'| jh                  |!xs d| jj                  |"| jm                         |%1      S t	        | dd      }(|(d| _        | j+                  |      }) |
j                  dTi d2| j                  d3|)d4|d5| j"                  d6| j=                         d7| j                  d8|(d9| jf                  d:| j                  d;| j                  dt	        | dd      d<| j                  xs djG                         d=|d>|d?|d@|dA|dB|dC|dD|dE| j$                  dFk(  dG| jh                  dH|!xs ddI| jj                  dJ|r| jn                  nddK|r| jp                  nddL|%dM| dN|dO| jm                         dP|r| j?                         nddQ|r| js                         nddR|"dS| j$                  S # t6        $ r-}t8        j;                  dt	        | dd      |       Y d}~d}~ww xY w# t6        $ r d	}d} Y Pw xY w# t6        $ r Y w xY w# t6        $ r d}'Y w xY w)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,   r9   
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,   r9   rz  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,   r9   r{  r  rz  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  
 y wr/   r0   )r1   key_model_norms     r!   r3   z#build_api_kwargs.<locals>.<genexpr>u  s     Fcsk!F   hermes)	sessionIdpromptIdget_provider_profile)r   r,   r9   r  r;  rz  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,   r9   r  r;  rz  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_namer0   ):r9   r   _get_transport#_prepare_anthropic_messages_for_apirM   r~  ru  build_kwargsr   rz  r{  _is_anthropic_oauth_anthropic_preserve_dotsr  r@   boolr   r  rI   rH   rF   &_prepare_messages_for_non_vision_modelcopytools.schema_sanitizerr  r  deepcopyr   r^   r_   _resolved_api_call_timeout#_github_models_reasoning_extra_body_is_qwen_portal_is_openrouter_urlr[   r\   agent.auxiliary_clientr  r  rs   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   api_messages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    sI   KKM~~--))+
"FF|T%!5t<,3'(('EtL$15E.&&++'(5(A}uGWGW"33..88:"U$94@..4"99'BfL!%ge5NPU&V!W ' 
 	
  ~~++""$ 148GKE#>E	++!''/4&   
 	
 ~~**""$!%..2DE J$U^^5HI 	
 NNn, ((M9 B(E,A,AA	 	 !>>-AAkUE]E]akEkFF|T$ $ !&} =#;M#J q#3M#B q ++$"33ulD9''446#55 3--Re5#L#L#Nko'+@$G(   
 	
& 


 C $$&H%%'Fe335GH 	M !6!68KL  !6!66H+u/D/DDJennn= 	@ ?	@ ? 
 ))>)>@Z[LNN(b//1779ZGLY*5;;G,,
!+c -U3F H		
 {{(b//199#sCF-EFF0=H
 J))5XDJJL)

2'7  (FM%15E.
 CCLQ++!^^446''(6 % 7 7"33#55ulD9% 00!'4(-(I(I!)$CCE",'   
 	
2 U$BDIN!-1* AA,ON3 #kk## # 	#
 002# ### %3# "33# //#  11# 5,5# [[&B--/# # #  #   !#" !##$ %#& !'#( !)#* !>>X5+#, ,,-#. $^t/#0 %*$E$E1#2 >F9943#4 NV I I[_5#6 )7#8 &9#: $;#< !??A=#> OUuHHJZ^?#@ R^5#K#K#McgA#B &C#D nnE# #U  JE<4c f  
2  "  sO   #3\ !/] A]$ -]4 	] "]]]! ]!$	]10]14^^c                	   t        |dd      }| j                  |      }t        |      }|s\t        t        |dd            }t	        j
                  d|t        j                        }|rdj                  d |D              }|xs d}|r0| j                  r$t        j                  dt        |       d	|        |r6| j                  r*| j                  s| j                  s	 | j                  |       t        t        |dd            }	t!        |	      }
|rt!        |      }t#        |
t$              r!|
r| j'                  |
      j)                         }
t#        |
t$              r|
rd
dlm}  ||
      }
d|
||d}t        |dd      }|6t/        |d      r*t        |dd      xs i }t#        |t0              r	d|v r|d   }|t!        |      |d<   n|r| j3                         r	|xs d|d<   d|vr|r||d<   t/        |d      r|j4                  r|j4                  }g }|D ]x  }t#        |t0              r|j7                  |       %t/        |d      r|j7                  |j8                         Mt/        |d      sZ|j7                  |j;                                z |r||d<   t        |dd      }|r||d<   t        |dd      }|r||d<   t        |dd      }|r||d<   |rg }|D ]  }t        |dd      }t        |dd      }t#        |t$              r|j)                         s| j=                  |      \  }}|}t#        |t$              r|j)                         s|t#        |t$              r!|j)                         r|j)                         }nKt        |dd      }|rt        |dd      nd}|rt        |dd      nd}| j?                  ||t        |            }|j)                         }t        |dd      }t#        |t$              r|j)                         s| j=                  |      \  }}|}| jA                  |t#        |t$              r|nd      }||||jB                  |jD                  jF                  |jD                  jH                  dd } t        |d!d      }!|!!t/        |!d      r|!j;                         }!|!| d!<   |j7                  |         ||d<   |S # t        $ r Y w xY w)"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  ^   K   | ]%  }|j                         s|j                          ' y wr/   )r[   )r1   bs     r!   r3   z*build_assistant_message.<locals>.<genexpr>  s     "Paggi1779"Ps   --zCaptured reasoning (z	 chars): r   )redact_sensitive_text	assistant)roler  	reasoningfinish_reasonreasoning_contentmodel_extra reasoning_details__dict__
model_dumpanthropic_content_blockscodex_reasoning_itemscodex_message_itemsidcall_idfunctionrz   rG   	arguments{}response_item_idrz   r  )r
  r  r  r#  r  extra_content)%rM   _extract_reasoningr  r   r   findallDOTALLr`   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  rz   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--.?@NN+
 &w/@)T'RSzz"97"))T{{"Pl"PPH%-N%//,S-@,A>JZ[\%22 **53I3I((8 (0A9d(STL'5L-n= ,$00>DDF ,$6,\: #&	C $$57JDQ$1BM)R/EKk4(-@K-O$/0C$D!(#78M#N 	%"E"E"G $2#8S 0 #%.#1  "56;L;^;^
 (99	 	1A!T"  #J'  ,L)  0	1 '0C#$ .0JDQN*8&' +-DdKK'2#$
 ""35JDQ%8!"
- =	'IYd3FiD9Ggs+7==?&+&D&DV&L# !*gs+7==?fc*v||~$llnG!)Z>C;>wsFB7BHBEwsK>4H#::8XsS]_GmmoG&y2DdK.4<L<R<R<T/4/M/Mf/U,,#< $GG$./?$E 4  "$4!%..33!*!3!3!=!=	G< I=E 5,/!,,.E+0(g&{=	'| 'LJI  s   !S 	SSc                (   t        | dd      }t        |t              r|syd|fd|ffD ]`  \  }}|s	t        t	        j
                  d| d|            }|s/|d   }|d|j                           | d| ||j                         d  }b || _        y)	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(   r5   r   finditerrS  endr;  )rN   r   rI   splabelr*   matcheslasts           r!   rewrite_prompt_model_identityrF    s      
/	6Bb#b!5)J+AB Iur{{eE7%#8"=>2;D}

%&ugRwr$((*+6GHBI #%Er#   c                B   t        | j                  d      xs d      j                         j                         t        | j                  d      xs d      j                         t        | j                  d      xs d      j                         j	                  d      fS )NrI   rG   r   r  /)r(   r@   r[   r\   rstrip)fbs    r!   _fallback_entry_keyrK    s|    BFF:$"%++-335BFF7O!r"((*BFF:$"%++-44S9 r#   c                   |j                  d      xs dj                         j                         }|dk7  ry	 ddlm}  |d      xs i }|j                  d      }|j                  d	      }t        |t              xr t        |j                               }t        |t              xr t        |j                               }	|s|	sy
y# t
        $ r"}dt        |      j                   cY d}~S d}~ww xY w)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.authrN  r   r#  r$  r'   r(   r  )
rN   rJ  fb_providerrN  stater  access_valuerefresh_value
has_accesshas_refreshs
             r!   +_fallback_entry_unavailable_without_networkrY    s    66*%+224::<Kf<;'/52 99^,LIIo.ML#.M48J8J8L3MJ]C0PT-:M:M:O5PK+#  <&tCy'9'9&:;;<s   C	 		C4C/)C4/C4c                   |t         j                  t         j                  t         j                  hv rt	        t        | dd            }t        | dd      xs dj                         j                         }| j                  xs i j                  d      xs dj                         j                         }|r|r!||k(  rt        j                         dz   | _        | j                  t        | j                        k\  rt        | j                        dkD  rl|t         j                  t         j                  t         j                  hvr;t        | dd      xs d}t!        |t        j                         t"        z         | _        y| j                  | j                     }| xj                  dz  c_        t%        |      }t        | d	d
      }|t'               }|| _        ||v r't*        j-                  d|       | j/                  |      S |j                  d      xs dj                         j                         }	|j                  d      xs dj                         }
|	r|
s| j/                  |      S t1        | |      }|r:|j3                  |       t*        j5                  d|	|
|       | j/                  |      S t        | dd      xs dj                         j                         }t        | dd      xs dj                         }t7        t        | dd      xs d      j9                  d      j                         }|j                  d      xs dj                         j9                  d      j                         }|	|k(  r-|
|k(  r(t*        j5                  d|	|
       | j/                  |      S |r3|r1||k(  r,|
|k(  r't*        j5                  d|       | j/                  |      S 	 ddlm} |j                  d      xs dj                         xs d
}|j                  d      xs dj                         xs d
}|s`|j                  d      xs |j                  d      xs dj                         }|r(t?        j@                  |d      j                         xs d
}|r'tC        |d      r|st?        j@                  d      xs d
} ||	|
d||      \  }}|8t*        j5                  d|	       |j3                  |       | j/                  |      S 	 ddl"m#}  ||
|	      }
d}t7        |jJ                        }| jM                  |      }|	dk(  rd}n|	d k(  s<|j9                  d      j                         jO                  d!      stQ        |      d"k(  rd#}n\|rd}nW| jS                  |      rd}nC| jU                  |
|	$      rd}n-|	d%k(  s&tQ        |      jW                  d&      rtC        |d'      rd(}| jX                  }| jZ                  }d
| _.        |
| _,        |	| _-        || _%        || _/        ta        | d)      r| jb                  je                          d| _3        t        | d*d
      }|St        |dd      xs dj                         j                         }|r$||	k7  rt*        ji                  d+|	|
|       d
| _5        t        | d*d
      ?	 dd,l6m7}  ||	      }|r.|jq                         r|| _5        t*        ji                  d-|	|
       ts        |	|
      }!|d#k(  rdd/l:m;}"m<}#m=}$ |	d k(  r|j|                  xs  |#       xs dn|j|                  xs d}%|%| _>        |%| _?        || _@         |"|%| j                  |!0      | _A        |	d k(  r |$|%      nd| _B        d
| _C        i | _D        n||j|                  | _>        || _C        t        |d1d
      }&|&st        |d2d
      }&|j|                  |d3|&rd2t        |&      ini | _D        |!!|!| j                  d4<   | j                  d56       | j                  |	|||
7      \  | _H        | _I        | j                          ta        | d8      r| j                  rdd9lLmM}' t        | j|                  t6              r| j|                  nd}( |'| jX                  | jJ                  |(| jZ                  t        | d:d
      t        | d;d
      <      })| j                  j                  | jX                  |)| jJ                  t        | dd      | jZ                  | j^                  =       	 dd>lPmQ}* dd?lRmS}+  |+ |*       xs i | jX                        | _T        t*        ji                  d@| jX                  | j                         t        | |
|	       | j                  dB|
 dC|	        dD| dC| dE|
 dC|	 | _W        t*        ji                  dF||
|	       t        |        y# tH        $ r#}t*        j5                  d|
|	|       Y d
}~d
}~ww xY w# tH        $ r#} t*        j-                  d.|	|
|        Y d
} ~ /d
} ~ ww xY w# tH        $ r+},t*        j-                  dA| jX                  |,       Y d
},~,d
},~,ww xY w# tH        $ rH}-|	dGk(  r|j3                  |       t*        j                  dH|
|-       | j/                  |      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  rH  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)r`  r  r;  fallback_timeout_applyr   )rI   r  r   r   rt  )get_model_context_length_config_context_length_custom_providers)r  r`  rI   config_context_lengthcustom_providers)r   r~  r  r`  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)rM  z"Failed to activate fallback %s: %s)Zr   
rate_limitbillingupstream_rate_limitr  rM   r[   r\   _primary_runtimer@   rQ  	monotonicr]  _fallback_indexr)   _fallback_chainr   _FALLBACK_EXHAUSTED_COOLDOWN_SrK  setr^  r^   r"  _try_activate_fallbackrY  addr_   r(   rI  r  r_  rv   rw   r   hermes_cli.model_normalizerg  r   r  _is_azure_openai_urlendswithr   _is_direct_openai_url&_provider_model_requires_responses_apir   r   rI   rt  r   r  rj  clearr[  rO  rk  agent.credential_poolrl  has_credentialsr   r  rm  rn  ro  r`  _anthropic_api_keyrv  _anthropic_clientr  r   _client_kwargsr?   _replace_primary_openai_client_anthropic_prompt_cache_policy_use_prompt_caching_use_native_cache_layout_ensure_lmstudio_runtime_loadedrt  agent.model_metadatars  r'   update_modelhermes_cli.configry  hermes_constantsrz  r{  rF  rW  _pending_fallback_noticer   r  ).rN   r   fallback_already_activecurrent_providerprimary_provider_existing_cooldownrJ  fb_keyunavailablerS  fb_modellocal_skip_reasoncurrent_modelcurrent_base_urlfb_base_url_for_dedupr_  fb_base_url_hintfb_api_key_hint
fb_key_env	fb_client_resolved_fb_modelrg  	_norm_errfb_api_modefb_base_url_fb_is_azure	old_modelold_provider_existing_pool_pool_providerrl  fallback_poolr  _fb_timeoutrm  rn  ro  effective_key
fb_headersrs  _fb_ctx_api_keyfb_context_lengthry  rz  _reasoning_errr%  s.                                                 r!   try_activate_fallbackr    sm
    .++^-C-C^EgEghh #'wu6KU'S"T#E:r:@bGGIOOQ"339r>>zJPbWWY__a'-=BRVfBf(,(82(=E%E$9$9 :: %%&*~88.:P:PR`RtRtuu!(0Eq!I!NQ(+" #AA)E% 			u44	5B	Q $F%!=tDKe+6(FO++F3366*%+224::<Kw%2,,.Hh++F33CE2N[		
 ++F33  z26<"CCEKKMUGR06B==?M75*b9?R@GGLRRTVVJ/52<<>EEcJPPR&&8}+DM	
 ++F33!%55%L!	
 ++F33
M4B FF:.4";;=E66),299;Ct &&+Jrvvm/DJQQSJ"$))J";"A"A"C"Kt  56F U^m ii(89ATO(?x4.,).%	% NN@ OOF#//77	O3HkJH )),,-11+>.(+K;&!!#&,,.77E -1DD /K -K((5+K99  : 
 ,KI%k*556HI%k?C,KKK	~~
 (,$$$$5,-""((*$(! !(:DA%%nj"EKRRTZZ\N.K"?Q>
 *.&5,d3;; )+ 6 ]%B%B%D-:E*KKN#X 3;I..ppVaepVpY..Q2I2KQr  xA  xI  xI  xO  MOM)EM'4E$(3E%&<u88+'E# KVYdJd(FjoE%EL#%E  &--EM$EL !,=tDJ$Y0A4H
$,,'$ =G%tJ'78B$E 
 &2=$$Y/ 44<T4U 00$$$	 1  	B!5#A 	--/ 5./E4L4LE
 0:%--/MemmSUO 8enn'%..&-e5Mt&T!(0CT!J	! $$11kk0y"5 2 	5A%=#U[[&E" KK<U33 	&eX{CCjk],	
 0	{%~ N*E+0 	& 	0x	
 	E"Q  	NNK+y 	t  M3 X  	LLY^ 	F  4& OOF#98QG++F33	4s    D(i- 
g F'i- >h ?H%i- %Ah6 =Ai- 	h!g?9i- ?hi- 	h3h.(i- .h33i- 6	i*?!i% i- %i**i- -	j>6=j93j>9j>c           
        t        d| j                   d       d}|j                  d|d       	 | j                         }g }|D ]  }|j	                         }| j                  ||       dD ]  }|j                  |d        dD ]  }	|j                  |	d        t        |       |D 
cg c]'  }
t        |
t              s|
j                  d	      s&|
) c}
D ]  }|j                  |d        |r| j                  || j                  
       |j                  |        | j                  xs d}| j                  r |dz   | j                  z   j                         }|r	d|dg|z   }| j                   rF|rdnd}t#        | j                         D ](  \  }}|j%                  ||z   |j	                                * | j'                  |      }| j)                  |      }i }	 ddlm}m} | || j                  | j2                        nd}||u }|rdn|}d| j4                  v }| j6                  xs dj                         j9                         dk(  xr | j;                         }|r| j=                         nd}|s4| j;                         r$| j>                  | j>                  |d<   nddd|d<   |rddl m!}  |       |d<   | jD                  dk(  ru| jG                  |      }|j                  dd       | jI                  |      }| jK                         }|jM                  |      }|jN                  xs dj                         }n| j                  |d}|||d<   | jP                  *|jS                  | jU                  | jP                               |||d<   tW        |       } i }!	 ddl,m-}"  |"| j6                        }#|#C|#j]                  t_        | dd      | xs d| j                  | j2                  | j>                         }!|!r|jS                  |!       | rHd!|!vrD| j6                  xs dj                         j9                         d"k(  s| ja                         r| |d!<   | j                  d#k(  r| j6                  xs dj                         j9                         d"k(  s| ja                         rJ| jb                  >| jb                  dk7  r/	 te        | jb                        }$|$d$|$cxk  rd%k  rn n	d&|$d'g|d(<   |r||d)<   | jD                  d*k(  r| jK                         }%|%jk                  | j                  |d| jP                  | j>                  | jl                  | jo                         +      }&| jq                  |&      }|%jM                  || jl                  ,      }'|'jN                  xs dj                         }ns | js                  d-.      jt                  jv                  jx                  d9i |}| jK                         jM                  |      }'|'jN                  xs dj                         }|rVd/|v r5t{        j|                  d0d|tz        j~                  1      j                         }|r|j                  d2|d       |S d3}	 |S | jD                  dk(  ru| jG                  |      }|j                  dd       | jI                  |      }(| jK                         })|)jM                  |(      }*|*jN                  xs dj                         }n| jD                  d*k(  r| jK                         }+|+jk                  | j                  |d| jl                  | jP                  | j>                  | jo                         4      },| jq                  |,      }(|+jM                  |(| jl                  ,      }-|-jN                  xs dj                         }n| j                  |d}|||d<   | jP                  *|jS                  | jU                  | jP                               |||d<   |r||d)<    | js                  d5.      jt                  jv                  jx                  d9i |}| jK                         jM                  |      }-|-jN                  xs dj                         }|rVd/|v r5t{        j|                  d0d|tz        j~                  1      j                         }|r|j                  d2|d       |S d3}	 |S d3}	 |S c c}
w # t0        $ r d}d}Y w xY w# t0        $ r Y w xY w# tf        th        f$ r d}$Y Jw xY w# t0        $ r>}.t        j                  d6|.        d7| j                   d8t        |.       }Y d}.~.|S d}.~.ww xY w):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	  	timestampr  rD  rG   r  systemr   r   r  r  r  r  Tmedium)enabledeffort)nous_portal_tagstagsr   r9   )r   r,   temperaturereasoning_effortr  r  )r  r  r   r  r{  rI   
openrouterzopenrouter/pareto-coderV   g      ?zpareto-router)r
  min_coding_scoreplugins
extra_bodyr   )r   r,   r9   rz  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,   r9   r|  rz  r{  r}  iteration_limit_summary_retryz Failed to get summary response: z"I reached the maximum iterations (z!) but couldn't summarize. Error: r0   )Bprintmax_iterationsr   _should_sanitize_tool_callsr  _copy_reasoning_content_for_apir   r   r'   r(   r   #_sanitize_tool_calls_for_strict_apir   r;  ephemeral_system_promptr[   prefill_messages	enumerateinsert_sanitize_api_messages#_drop_thinking_only_and_merge_usersr  r  r  r   r  rF   rI   r\   r  *_resolve_lmstudio_summary_reasoning_effortr{  agent.portal_tagsr  r   _build_api_kwargsr   r  normalize_responser  rz  updater  rs   r  r  build_extra_bodyrM   r  r  ru   rx   ry   r  r  r  r   _ensure_primary_openai_clientr   r   r   r   r   r  r^   r_   )/rN   r,   api_call_countsummary_request_needs_sanitizer  r)  api_msginternal_fieldschema_foreignkinternal_key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%  s/                                                  r!   handle_max_iterationsr  o  s	   	01E1E0FF^
_`	* 
 OOV@Ak~  ;;= 	)ChhjG11#w?"U 2ND12 #m 2ND12 #7+,3 `qz!S7Iall[^N_ ` 0L$/099'9U(=	)@ !66<"(( 06 9E<Y<Y Y``b%-:JKL|[L!!.AJ%e&<&<= BS##J$4chhjAB 33LA @@N	k ,7 )ennE 	
 %6$C!'@tFW!U%:%:: ^^!r((*002j@ 7446 	 $ <<>)- 	 $(L(L(N%%1272H2H";/  $&3";/ J)5v&>>.. 22<@LWd+$66|D**,G112BCH&..4";;=N (N $/0D}-+%%e&=&=e>N>N&OP#/5I12 $C5#I !#:#7#G #/)9)J)J#*5,#E-A-IT#kk!&).)?)? *K *& ""))*<=#
:L(L%2,,.446,F++-1E":. 77^^)r00288:lJ//155A55; A ABC ?sc'8S'8.CH5&y1 "/A|,~~!55,,.,,5;;]a*/*:*:UMcMc(-(A(A-2-K-K-M - O $)#C#CG#L "'":":;K_d_x_x":"y"1"9"9"?R!F!F!H $A5#F#FNg#F#h#m#m#y#y  $A  $A  $S  DR  $S "'"6"6"8"K"KL\"]"1"9"9"?R!F!F!HN*!#(@"n\^\e\e!f!l!l!n PQj g "bf a ~~!22$66|D  $/!&!8!8!F!002	&99.I
","4"4":!A!A!C#77..0"//ekkL`d).)B)B+0+;+;eNdNd.3.L.L.N 0 P "'!A!A(!K ' : :>]b]v]v : w"/"7"7"=2!D!D!F #[[ ," (34HN=1##/"))%*A*A%BRBR*ST'39MN#56%3EN<0 $G5#F#FNm#F#n#s#s##  $G  $G  $Y  JX  $Y  % 4 4 6 I IJZ ["/"7"7"=2!D!D!F.%'VV,Db.`b`i`i%j%p%p%rN!OO[^$TU  &fN  "b ] !a<  	+/(J	L  2 ":. CZ  ~9!=>=e>R>R=SStuxyzu{t|}	~s   A:d+ +c*c*c*D	d+ !c/ )F:d+ $Ad Cd+ d Fd+ =d+ Id+  d+ %d+ *d+ /d <d+ ?d  d+ 	dd+ dd+ d($d+ 'd((d+ +	e243e--e2c                   	 t        |      r&| j                  r3t        j                  d| d       nt	               j                  |       	 d}	 ddl	m
}  |       }|r&| j                  r4t        j                  d
| d       yt	               j                  |       yy# t        $ r1}| j                  rt        j                  d| d|        Y d}~d}~ww xY w# t        $ r+ t        t        j                  j                  d	            }Y w xY w# t        $ r6}| j                  r t        j                  d| d|        Y d}~yY d}~y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   r^   r_   tools.browser_toolr  r  rv   rN  r@   cleanup_browser)rN   task_idr%  headedr  s        r!   cleanup_task_resourcesr  k  sH    LW%$$Fwi P2 3
 EW%Q	B:$&F $$KG9 U2 3
 E!!'* %  L  NN;G9BqcJKL  	B"**..)?@AF	B  Q  NN@	A3OPP !QsZ   A
B  D C 'D D  	C)'CC1DD DD 	E'EEdropped_tool_namesc               v    t        | |d|      }t        d|t              }t        t        ||g||xs 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!    sT     #(	L "*K
 !.6$ r#   )r   c               0   &'()*+,-./0123456789:;<  j                   rt        d      t               r j                        S  j                  dk(  r  _        	  j                        d _        S  j                  dk(  rddd:ddi5ddi4d	t        j                         i&j                  d
d      }t               }t                5fd,&, 4:fd}t        j                  |d      }|j                          |j                         r|j                  d        j                   rt        d      t        j                         &d	   z
  }||kD  rt        j!                  d|||j                  dd              j#                  dt%        |       dj                  dd       d       t'                	 ddlm}  ||       t        j                         &d	<   t                t1        dt%        |       dt%        |       d      :d<   n|j                         r j                   rt        d       :d   :d   :d!   t3                :d!   S ddg d":t                dddd#7d$d%i8t        j4                         9d$di.d%d&do789fd'/dp 789fd(*ddi5ddi4d	t        j                         i6d3t        j4                         ;dt7               ddd)<dq;<fd*0dp;<fd+)dr;<fd,1dr;<fd-2ds;<fd.+5fd/-dt+-/123 467:fd0(- 467fd1''()*./0 457:fd2}
t9         j:                   j<                        }||}nt?        d3d4      }|d4k(  rĉ j@                  rtC         j@                        rd5}	 dd6l"m#}  |       }tI        |tJ              r|j                  d7      nd}tI        |tJ              r2|j                  d8      }tI        |t$        tL        f      rtM        |      }t?        d9|      3t        j/                  d: j@                  3       n\tO              }|d;kD  rtQ        |d<      3n|d=kD  rtQ        |d>      3n|3dd?l)m*}  |j                  d@            }|tQ        3|      3t        j                  |
d      }|j                          t        j                         }dA}|j                         r|j                  d       t        j                         }||z
  |k\  r{|}t%        |6d	   z
        }||k\  rN33tM        dB      k7  rdCt%        3       dD}ndE} jW                  dFj                  d@dG       dH| dI| dJ       n jY                  dK| dL       t        j                         6d	   z
  }|3kD  rtO              }t        j!                  dM|3j                  d@d      |dN        j#                  dOt%        |       dj                  d@d       dP|dNdQ       	  )dR        *dR       t'                 j                  dSk(  rn	  j[                  dTU       t        j                         6d	<    jW                  dVt%        |       dW        jY                  dXt%        |       dY        j                   r6d.d$<   t        j/                  dZ       	  )d[        *d[       t        d\      |j                         r j                   rt        d]      :d   4d   rt]         d^dE      xs dEj_                         xs d}ta        :j                  d_      xs g       }|rd`j                  |dda       }tc        |      dakD  r|dbtc        |      daz
   dcz  }dd| de}|xs dE|z   }	  je                  |       t        j!                  df|tc        |xs dE      :d          tf        }n-t        j!                  dgtc        |xs dE      :d          tf        }ti        dh|ddi      } d}!	 ddjl5m6}"m7}#  |":d   tq        t]         dkdE      xs dE      tq        t]         d@dE      xs dE      l      }$|$jr                  |#jt                  k(  }!ti        tv        t]         d@d      ti        d| |m      gd|xs dn      }%|!rd|%_<        t3                |%S :d   :d!   t3                :d!   S # d _        w xY w# t,        $ r!}	t        j/                  d|	       Y d}	~	Id}	~	ww xY w# t,        $ r Y !w xY w# t,        $ r Y w xY w# t,        $ r Y w xY w# t,        $ r Y t        d\      w xY w# t,        $ r Y w xY w# t,        $ r d}!Y w xY w)uu  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
  doneFr1  ri  r   r   c                 P     d   srd d<   	          y y y # t         $ r Y y w xY wNr#  Tr   first_delta_firedr   s   r!   _fire_firstz5interruptible_streaming_api_call.<locals>._fire_first  s@    $V,,0!&)"$ 2@, !     	%%c            	        	 ddl m} m}m}m}m}m} j                  dd      }j                  dd         | |      }	  |j                  di }t#               fd
}
fd}fd} ||j%                         r|
nd |j&                  sj(                  r|nd fdfd      d	<   y # t        $ r}	 ||	      rad_
        j                  d       t        j                  dt        |	      j                          | |j                   di       d	<   Y d }	~	y  ||	      r ||        d }	~	ww xY w# t        $ r}|d<   Y d }~y 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                @             j                  |        dd<   y )NTr1  )_fire_stream_delta)textr)  rN   deltas_were_sents    r!   _on_textzIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_text4	  s!    M,,T2.2$U+r#   c                6             j                  |        y r/   )_fire_tool_gen_started)rz   r)  rN   s    r!   _on_toolzIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_tool9	  s    M006r#   c                6             j                  |        y r/   )_fire_reasoning_delta)r0  r)  rN   s    r!   _on_reasoningzNinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_reasoning=	  s    M//5r#   c                      j                   S r/   )r   r   s   r!   r!  zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>F	  s    u/I/I r#   c                 L     j                  dt        j                               S )Nri  )__setitem__rQ  )_bedrock_last_events   r!   r!  zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>G	  s    %8%D%DS$))+%V r#   )on_text_deltaon_tool_starton_reasoning_deltaon_interrupt_checkon_eventr  r0   )r   r   r   r   r,  r   r-  r   converse_streamr   _disable_streaming_safe_printr^   rO  r#  r$  r   r   _has_stream_consumersr  r  )r   r   r   r,  r   r-  r   r   r   r   r2  r5  r8  r%  r<  r)  rN   r   r1  r'  s                 r!   _bedrock_callz7interruptible_streaming_api_call.<locals>._bedrock_call	  sl   F$  $(<kJ5t<4V<#96#9#9#GJ#GLB $E*3
76 &D .3.I.I.K(QU"*8=8P8PTYToTo}uy'IV&z"_ !  8E370))R
 O .77
 .I+FOO9j9.z*  1>1&99n  $"#w$sI   <D?  B4 A!D? 4	D<=A$D7!D? &D77D<<D? ?	EEETr6  r9  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   rE  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   c               z    5  | d<   |d<   t        j                         d<   d d d        | S # 1 sw Y   | S xY wr  r  r  s     r!   r  z=interruptible_streaming_api_call.<locals>._set_request_client	  sQ      	G.4!(++/(1:1D1D1F!+.		G
 	G
 r  c                   5  j                  d      }j                  d      }|d uxr |d uxr |t        j                         k7  }|s
d d<   d d<   d d d        y j                  dd      }|dk(  r*rj                  ||        y j	                  ||        y rj                  ||        y j                  ||        y # 1 sw Y   wxY wr  r  r  s	        r!   r  zDinterruptible_streaming_api_call.<locals>._close_request_client_once	  s    
 ! 
	:266x@N-11+>Id* 7T)7!4!4!66 
 #26%h/59%k2
	: !"&&w9''55nV5T55nV5T..~f.M..~f.M-
	: 
	:r  )current	cancelleddiscarded_chunksdiscarded_bytesc                 j     5  dxx   dz  cc<   t        d         cd d d        S # 1 sw Y   y xY w)NrK  r   )r>   )stream_attempt_lockstream_attempt_states   r!   _start_stream_attemptz?interruptible_streaming_api_call.<locals>._start_stream_attempt	  s9      	8 +q0++I67	8 	8 	8s   )2c                    5  t        j                  d      xs d      }|rd   j                  |       d d d        rt        j	                  d||        y y # 1 sw Y   $xY w)NrK  r   rL  z&Marked stream attempt %s cancelled: %s)r>   r@   r  r^   r"  )r   rK  rP  rQ  s     r!   _cancel_current_stream_attemptzHinterruptible_streaming_api_call.<locals>._cancel_current_stream_attempt	  sk      	?.229=BCG$[155g>	? LL8 		? 	?s   5AA%c                    5  | t        j                  d      xs d      k(  xr | d   v	 cd d d        S # 1 sw Y   y xY w)NrK  r   rL  )r>   r@   stream_attempt_idrP  rQ  s    r!   _stream_attempt_is_activezCinterruptible_streaming_api_call.<locals>._stream_attempt_is_active	  sS      	!S)=)A)A))L)QPQ%RR O%-A+-NN	 	 	s	   +9Ac                B    5  | d   v cd d d        S # 1 sw Y   y xY w)NrL  r0   rV  s    r!   _stream_attempt_was_cancelledzGinterruptible_streaming_api_call.<locals>._stream_attempt_was_cancelled 
  s-      	J$(<[(II	J 	J 	Js   c                4   	 t        t        |            }5  dxx   dz  cc<   dxx   |z  cc<   d   }d   }d d d        dk(  rt        j	                  d| |       y t        j                  d| |       y # t        $ r d}Y sw xY w# 1 sw Y   QxY w)Nr   rM  r   rN  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   r^   r_   r"  )rW  chunkchunk_bytesrM  rN  rP  rQ  s        r!   _discard_stale_stream_chunkzEinterruptible_streaming_api_call.<locals>._discard_stale_stream_chunk
  s    	d5k*K ! 	F !3494 !23{B334FG23DEO		F
 q NN;!  LL;! !  	K		F 	Fs   A= %B=B
BBc                 P     d   srd d<   	          y y y # t         $ r Y y w xY wr%  r&  r'  s   r!   _fire_first_deltaz;interruptible_streaming_api_call.<locals>._fire_first_delta
  s?     (^(,f%  .<(  r*  c                   ddl }t        :j                  :j                        }||nt	        dd      }||}nt	        dd      }|dk(  rE:j
                  r9t        :j
                        r$|}t        j                  d:j
                  |       n2|dk(  r-9+9t        d      k7  r9|kD  r9}t        j                  d	|       |t        |d
      nd}i ;d|j                  ||||      d}t        :j
                        sddi|d<    6:j                  d|            }t        j                         =d<   :j                  d       :j!                         }|>d<    |j"                  j$                  j&                  dFi |}	t)        :      }
t+        |	d      rt        j-                  d:j                  xs d:j                  xs d       d:_        |	j0                  }t3        |t4        t6        f      r|r|d   nd}t9        |dd      }|}t9        |dd      xs t9        |dd      }t3        |t:              r|r 5        :j=                  |       t9        |dd      }t3        |t:              r|r 5        :j?                  |       |	S :jA                  t9        |	dd             :jC                  t9        |	dd             :jE                  |t9        |	dd             :jG                  t9        |	dd             g }i }tI               }i }i }d}d}d}g }d}|	D ]  }tK        :|
      s)t        jM                  d;jO                  d d              nt        j                         =d<   :j                  d!       	 tQ        |jO                  d"d            d#z   |d"<   |jO                  d$      =d   |d$<   	 tQ        |jO                  d%d            tS        tU        |            z   |d%<   :jX                  r n 7|       s
 4| |       |j0                  sJt+        |d       r|j                  r|j                  }t+        |d&      r|jZ                  r|jZ                  }G|j0                  d   j\                  }t+        |d       r|j                  r|j                  }t9        |dd      xs t9        |dd      }|r)|j_                  |        5        :j=                  |       |r|j`                  r|j_                  |j`                         |s( 5        :j?                  |j`                         d<d'<   nC:jb                  r7	 :jc                  |j`                         :je                  |j`                         |r9|jf                  r,|jf                  D ]  }|jh                  |jh                  nd}|jj                  xs d(}||vr|||<   |r!||v r|||   k7  rtm        |d)*      d#z   }|||<   |r|||<   ||   } | |vr8|jj                  }!t3        |!tP              rt;        |!      }!|!xs d(d+d(d(d,dd-|| <   ||    }"|jj                  .|jj                  }#t3        |#tP              rt;        |#      }#|#r|#|"d.<   |jn                  rl|jn                  jp                  r|jn                  jp                  |"d+   d/<   |jn                  jr                  r$|"d+   d0xx   |jn                  jr                  z  cc<   t9        |d1d      }$|$Ct+        |d2      r7t3        |jt                  tv              r|jt                  ni jO                  d1      }$|$!t+        |$d3      r|$jy                         }$|$|"d1<   |"d+   d/   }%|%s| |vs|j{                  |         5        :j}                  |%       ?d4   j_                  |%        |j0                  d   j~                  r|j0                  d   j~                  }t+        |d&      s|jZ                  s|jZ                  }  8|       r|j                  d5|  d6      d(j                  |      xs d}&d}'d7}(|rg }'t        |      D ]  } ||    })|)d+   d0   }*|)d+   d/   xs d8}+|*r&|*j                         r	 t        j                  |*       |'j_                  t        |)d.   |)d:   |)jO                  d1      t        |)d+   d/   |*,      ;              ||s|s|st        d<      |(xr |du }-|-rct        |      D  cg c]  } ||    d+   d/   xs d8 }.} t        jM                  d=|.       t        ||&d(j                  |      xs d|||.xs d>      S |du xr |xr | }/|/r7t        jM                  d?       t        ||&d(j                  |      xs d||      S |xs d@}0|(rdA}0d(j                  |      xs d}1t        ||&|'|1B      }2t        d|2|0C      }3t        dDt;        t        j                               z   ||3g|E      S # tV        $ r Y 5w xY w# tV        $ r Y Ew xY w# tV        $ r Y w xY w# t        j                  $ r t        |*|+      },|,d9k7  r|,}*nd}(Y w xY wc c} w )Gz#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)streamr;  include_usagestream_optionschat_completion_stream_requestr   ri  z)waiting for provider response (streaming)rH  r  z}Streaming request returned a final response object instead of an iterator; switching %s/%s to non-streaming for this session.rE  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  r1  rG   r>  )r{   r  r  )r
  r#  r  r  r
  rz   r  r  r  r  rG  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).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  r0   )Mhttpxr   rI   r   r   r  r   r^   r"  ru   r   Timeoutr   r   rQ  r  _stream_diag_initr   r   r   r   r  rO  rC  r  r'   r5   tuplerM   r(   r7  r/  _capture_rate_limits_capture_credits_stream_diag_capture_response_check_openrouter_cache_statusr  r   r_   r@   r>   r)   r\  r   r   r  deltar   r  r  _record_streamed_assistant_textr  r  r
  r   r  rz   r  r  r?   r  r  r4  r   RemoteProtocolErrorr`   ra   r[   jsonloadsJSONDecodeErrorr   r   r   r!  r  r  )@rW  _httpx_provider_timeout_cfg_base_timeout_stream_read_timeout	_conn_capstream_kwargsr   _diagrk  _writer_tokenr  first_choicer  r#  r  content_partstool_calls_acctool_gen_notified_last_id_at_idx_active_slot_by_idxr   r  r  reasoning_partsr  r]  r~  tc_deltaraw_idxdelta_idnew_slotr  _tc_identry_new_idr8  rz   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_  ra  r  rX  rZ  _stream_stale_timeoutrN   r   r1  last_chunk_timer   r'  s@                                                       r!   _call_chat_completionsz@interruptible_streaming_api_call.<locals>._call_chat_completions'
  s'    !=U^^U[[ Y %0 "/8 	 !,#8 #,-I5#Q 
 $u,DUV[VdVdDe'4$ZNN$8
 %-)5)U5\9),@@ (=$23G 1F0QCt,W[		
	
~~!)#	 & 	
  )8/>.EM*+,//7( 0 
  $yy{IJ '')(-f%7$$0077H-H
 ,E2  69%KKR+)(y	 (,E$
 nnG)3GdE])KPW71:]aLlIt<G"G%8$? ;wT:  nc2~%'//?!'9d;gs+%',,W5M
 	""76:t#DEwvz4@A 	++E76:t3TU 	,,WVZ-NO !!$
 !#$&
 "	 d	(E
 ,E=A" NN7I6	 #'99;OC !!"=>
"%eii!&<"="Ah99-.6.=c.BE*+
%(7A)>%?#d5kBR%RE'N )),->?+,=uE==5'*u{{!&J5'*u{{ %IMM!$**Eug&5;;"[[
 %U,?Fk'RWYdfjJkN&&~6!#++N; $$U]]3%%',,U]];.2$U+ 0033EMMB==emmL
 )) % 0 0 FBH080JhnnPQG'{{0bH &997>+G4 #6$(@@#&~r#BQ#F7?+G43;0-g6C.0!)%fc2%([F"(,B$.13"(E-1	/s+ +3/E{{."*++%gs3&)'lG"*1E$K((#,,11 9A8I8I8N8NE*-f5#,,66!*-k:h>O>O>Y>YY:#HotDE}=)I9CHDXDXZ^9_!5!5eg l lm| }("5,7$)$4$4$6E16o. ,V4D+< <)--c2)+44T: 34;;DAMFBP }}Q-- %a 0 > > ug&5;;!KK	Id	(L )):;,,!"3!4OD 
 ww}-5"' On- #C(zN;7	zN629c	!2;

9-   &&$xF"$&&"9,
^F3"+	( -H !!#""G 2 (?'X=TXCX$' ".1  $Z08?C?N  NNN 	 .l(0DI#1#9T	  T! ##"" 	%
 (NNE .l(0DI  #0"96"&.#19T& &,	
 & 1

 3tzz|,, M	
 	
] !  f % L  // ; $?y)#T#t+(0I 7;3;zsZ   :h)=3h6h9i	i9	h&"h)%h&&h))	h65h69	ii	)i65i6c           	     6   d}d}t        j                          d<   j                         }|d<   ddlm}  |t	        dd              | j
                  j                  d$i 5 }	 j                  |t	        |d	d
             t              }|D ]  }t        |      s)t        j                  dj                  dd              nd}t        j                          d<   j                  d       	 t        |j                  dd            dz   |d<   |j                  d      d   |d<   	 t        |j                  dd            t!        t#        |            z   |d<   j$                  r nt	        |dd
      }|dk(  rPt	        |dd
      }	|	st	        |	dd
      dk(  sd}t	        |	dd
      }
|
s(         j'                  |
       B|dk(  sIt	        |dd
      }|sZt	        |dd
      }|dk(  r4t	        |dd      }|s}|r         j)                  |       dd<   |dk(  st	        |dd      }|s         j+                  |        j$                  r
	 d
d
d
       y
	 |j-                         }|s'|t	        |d!d
      st	        |d"d
      t1        d#      |cd
d
d
       S # t        $ r Y Gw xY w# t        $ r Y xw xY w# t        $ r Y w xY w# t.        $ r |st1        d       d
 w xY w# 1 sw Y   y
xY w)%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).
        Fri  rH  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   rE  Tro  rp  r   rq  rr  r#  content_block_startcontent_blocktool_userz   content_block_deltar~  
text_deltar0  r1  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).r0   )rQ  rx  r  r  rM   r,   rk  r|  r   r   r   r^   r_   r@   r  r>   r)   r\  r   r4  r/  r7  get_final_messageAssertionErrorr   )r   has_tool_usesaw_stream_eventr  r  rk  r  event
event_typeblockr  r~  
delta_typer0  thinking_text_final_messagera  rN   r   r1  r  r   s                   r!   _call_anthropicz9interruptible_streaming_api_call.<locals>._call_anthropic  sx     !  $yy{'')(-f%
 	F!75,#C	
 ,^$$++9j9 u	"V
3376:t< 06M =K 0}ENN> #w	:	 #'  (,yy{$%%&AB	&)%))Ha*@&AA&EE(Oyy!12:2A#2F./),UYYw-B)Cc$u+FV)Vg --$UFD9
!66#E?DAE!=!K'+$+E64$@	$-/!88C#88#E7D9E%,UFD%A
%5#*5&"#=D#L 1 3 % 8 8 >:> 0 7'+;;,3E:r,JM, 1 3 % ; ;M J{=KL ))ku	" u	"x!'!9!9!; $&	4@tDL 'K  "ku	" u	"  B %   d " '*O    }u	" u	"s   )L+KA0L9:K#43K'/LL*L=LL/!LL$L<L(L?K3*L	KLKL	K K#K  K##	K0,L/K00L3LLLc                 	   dd l } t        dd      }	 t        |dz         D ]r  }        } j                  r d       t	        d      	  j
                  dk(  r&  j                  d	      d
      } |      $d<   n |      $d<     d       y  	  d       y # t        $ r}d   r7t        j                  dt        |      j                         Y d }~  d       y t        || j                  | j                  | j                  f      }t        || j                   | j"                  t$        f      } j'                  |      }t        |t(              }	!d   ryt+        $j-                  d            }
d}|sP|sNddlm} t        ||      r<t3        |dd       s/t5        |      j7                         d}t9        fd|D              }|xs
 |xs |xs |}|
xr	 |xr ||k  }|s)t        j;                  d|       |$d<   Y d }~  d       y 	  j=                  d       n# t        $ r Y nw xY w	  j?                          n# t        $ r Y nw xY wg $d<   d!d<   d"d<    jA                  ||dz   |dz   d#j-                  d              d        d        j
                  dk7  r#	  jC                  d	       n# t        $ r Y nw xY wY d }~d}|sP|sNddlm} t        ||      r<t3        |dd       s/t5        |      j7                         d}t9        fd|D              }|s|s|s|s|	r||k  rs jA                  ||dz   |dz   d#j-                  d              d         d         j
                  dk7  r#	  jC                  d!	       n# t        $ r Y nw xY wY d }~ jE                  d"||dz   |dz   d#j-                  d      #       |r
d$|dz    d%}n|	r
d&|dz    d%}n	d'|dz    d%} jG                  |       not5        |      j7                         }d(|v xr d)|v }d}|sd*|v rdd+l$m%}  ||      }|s|rd _&         jO                  |rd,nd-       t        jQ                  d.|       |$d<   Y d }~  d       y d }~ww xY w# t        $ r}|$d<   Y d }~ d       y d }~ww xY w#  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.r1  rG  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  
 y wr/   r0   )r1   phrase_err_lower_previews     r!   r3   zBinterruptible_streaming_api_call.<locals>._call.<locals>.<genexpr>  s      ?"(. %+.@$@?"r  z9Streaming failed after partial delivery, not retrying: %sr  u9   

⚠ Connection dropped mid tool-call; reconnecting…

r#  TrH  )r  attemptmax_attemptsmid_tool_callrH  stream_mid_tool_retry_cleanup"stream_mid_tool_retry_pool_cleanupc              3  &   K   | ]  }|v  
 y wr/   r0   )r1   r  _err_lower_sses     r!   r3   zBinterruptible_streaming_api_call.<locals>._call.<locals>.<genexpr>X  s      3$* !'. 83r  stream_retry_cleanupstream_retry_pool_cleanup	exhausted)r   r  r  r  r  rH  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 rk  znot supportedinvokemodelwithresponsestream)r,  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))rv  r   ranger   r  r   r   r   r^   r"  r#  r$  r'   ReadTimeoutConnectTimeoutPoolTimeoutConnectErrorr  ConnectionError_is_provider_stream_parse_errorr   r  r@   r  r  rM   r(   r\   r  r_   r/  _reset_stream_delivery_tracking_emit_stream_dropr  _log_stream_retryrW  r   r,  rC  rD  rO  )%r  _max_stream_retries_stream_attemptrW  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_deniedr,  r  r  r  r  rT  r  r&  r  rR  rN   r1  r(  r   r'  s%                          @@r!   r(  z/interruptible_streaming_api_call.<locals>._call  s    %&=qAD	B#()<q)@#A {$9$;! --23RS*+RSSp~~)== *=!BB'A C  "6	* .=^-Lz*-CDU-Vz*T	 ''@AG
{F
 ''@AS	 ! a *'2F G,,
 t ''@As #-F..0E0EvGYGYZ#K $.F//1K1K_]$L ,1+P+PQR+S('1!5E'F$ (.26"JJ';<3/ 490*<D)!Y7=Z^@_58V\\^ 28" 4 <? ?"2F?" <" 8
 ( 4+474  4	 & 4 F -F /2E E *
  1 #NN []^ /0F7O"j ''@A[!!44!6  ) ! !!!AAC( ! !
 8:3427(/49)&1//"#$3a$7)<q)@*.!6!:!:6!B 0  77VW23RS
 !>>-AA% % D D+O !E !" $- % $%  (-$&|@%a3GA}VZ<[-0V\\^N1- 03 3.?3 0, $'+/+ +-@@!33&'(7!(;-@1-D.3%:%>%>v%F 4  ;;QR67MN  %~~1EE!)$)$H$H/J %I %& (1 !)$(!)$ //!,"#$7!$;)<q)@*/!6!:!:6!B 0  0 W#6#:"; <9!9 + .!))<q)@(A B9!9 + !K#6#:"; <9!9 + ,,^<%(V\\^
$
2 > /: = / 5:1 6 ?: M !A C 6 25N7;E4!-- $=!V!3	 B '(F7O ''@AS	aD	   	  F7O&'@A	 ''@As  7R A B"R R "
R,.RR (D!R	R H*)R*	H63R5H66R:I
R	IRIAR4KR	KRKRR B-R
NR	N)&R(N))R,R 2CRR RR 	R;$R6)R> 6R;;R> >
Sr   r   rT   rx  rN   local_stream_stale_timeout!HERMES_LOCAL_STREAM_STALE_TIMEOUTuB   Local provider detected (%s) — stale stream timeout set to %.0fsrR   r   rS   r   r   r   rf  re  r~   r   rG   r>  r?  r@  zRs with no output yet (provider may be slow or overloaded, or the model is thinkingrA  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.r3  rI  z, context: ~z tokens). Reconnecting...stale_stream_killr   stale_stream_pool_cleanupr   u    ⚠ no output from provider for rG  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_textrG  rZ      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  rL  r   r=   r>   )rW  r>   r=   r  )rW  r>   r=   r   )rW  r>   )=r   r  r   _interruptible_api_callr   r   rQ  r@   r   r   r  rR  rS  rT  r`   r^   r_   rW  r>   r   r   r   r   r"  rX  r   r  r  r	   rI   r   r   r  r   r  ry  r'   r?   ru   rD   r   r   r   rU  r  r  rM   r[   r5   r)   r/  r   r   agent.error_classifierr  r   r(   r   content_policy_blockedr
   _content_filter_terminated)=rN   r   r   r  _bedrock_stale_timeoutrF  ri  _stale_elapsedr   
_inval_excr(  r   _stream_stale_timeout_base_local_defaultry  _cfg
_agent_cfg_vr   r   r   _last_heartbeat_HEARTBEAT_INTERVAL_hb_now_waiting_secsrl  rq  _partial_text_partial_names	_name_str_warn_stub_finish_reason	_stub_msgr  r  r   _cls_stubr<  r  r  rT  r  r_  r)  ra  r&  r  rR  rX  rZ  r  r1  r(  r  r   r  r   r'  rP  rQ  s=   ```                                   @@@@@@@@@@@@@@@@@@@@@@@r!    interruptible_streaming_api_callr    sx
     !!LMM "%(,,Z88~~**
 '5#	/00<*.E' ~~++"T2#UO!5>  #DIIK0 %..)={K!=eZ!P
 	E"	G	$ G	$R M$?		jjlFF3F))&'RSS
 "YY[+>s+CCN 66C"$:#Z^^Iy%I	 $$8^9L8M N)~~iCDNT #5)O-o> ,099;#C( $E*
 #/<S=P<Q R""%&<"=!> ?EF#w
 k jjl| %%"#\]]'?&/! *)&j!!RHF
 '+TM #H-#..* "5)3;  N N:  u~ DIIK(O !#..*U	8

J6P
 P
 P
d]" ]"~IB IBX
 ,ENNEKKHJ%/"%./Le%T" "U*u~~BSTYTbTbBc 
	5=D.8t.D'*$J*d+^^$@Ab3,/%*2YN !**M~ ^PNN1	
 6jA $'(BE$J!6!$'(BE$J!$>! 	O<Z^^G=TU'$'(=?O$P!d3AGGIiikO
**,	s ))+_$(;;%O/#*> >?M 33 *5-u="6s;P7Q6RRS TI "I''%jnnWn&M%Ne$o &CCL+QP %%3M?BST s';;116zBHNNC 5w	2xl	   7N8K7L M%>>'9=> ?%aL )"#./BC*+>?
 u% ~~!55 88@[8\
 $(99;OC ##23~3F2G H" # !!.s>/B.C?S %%
 +/w'LL)./GH ++CD ##PQQ] **,h !!Z[[g"E" A2FL"eg  "&**-A"B"HbIN IInRa&89	~&*3s>':Q'>&?u!EEI!{ #?@ 
 "/!4" =,,U3 <"C(;$<fWo
 ';#& +,7O ';#' -D"&I */&3U)7O 
B!?!E2FgeWb9?R@ KK>#H#HH +
 $)eWi8(Y>Q  $2$:dE *370  &LWo j%E"*m0 +/E'^ ! LLCZ `$  		@  & ! :  "#PQQJ ! V  3-2*3s   %c5 d 'A2d. %d> e e 7e7 6Af 5	c>	d+
d&&d+.	d;:d;>	e
e	ee	e43e47	ffff)rr  r  r9  r  r  r  r  )rB   r   r=   r>   )r=   r  )rW   r>   r=   ru   )rb   r   r=   Optional[str])r=   zDict[str, Any])rz   r(   r{   ru   r=   ru   )r   ru   r   r  r   ru   r   zOptional[float]r   ru   r   r  r   ru   r   ru   r=   r(   r  )r=   r   )r   r?   r=   ru   )r   objectr=   z'float | None')r   r?   )r  r5   r=   r?   )r   r(   r=   r?   )r   r(   rI   r(   r=   r   )rJ  r?   r=   ztuple[str, str, str])rJ  r?   r=   r  r/   )r   z'FailoverReason | None'r=   r  )r,   r5   r  r>   r=   r(   )r  r(   r=   r   )R__doc__
__future__r   r  r  r   rv   r   r  rQ  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$  r^   r]   r  r"   rD   rP   rX   rd   rs   r|   r   r   r   r   r   r   r   r   r   r  rr  r  r9  rF  rK  rY  r  r  r  r!  r  __all__r0   r#   r!   <module>r      s   #    	 	    ! & & X I 1 ) 5 A 2 6 U 1 N N			8	$#E   "% 2$j	&"&99 9 	9
 #9 9 9 9 9 	9H
#L>B<@~5ZpZ|@HgV%:*j4\xx-Qd @ QU {B2r#   