
    sj                   Z   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddl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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/ ddl0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6  ej7        e8          Z9h dZ:ddhZ;h dZ<dZ=dZ>d Z?ddZ@d  ZA G d! d"eB          ZCdd&ZDdd(ZEdd+ZFdd-ZGdd0ZHdd1dd4ZIdd1dd5ZJdd7ZKdd8ZLdd1dd<ZMdd?ZNdd@ZOddCZPddEZQddGZRddIZSddKZTddNZUddPZVddZZWdd[ZXdd\ZYdd]ZZd^Z[dd`Z\daddbddfZ]ddgZ^ddhZ_ddiZ`ddmZaddnZbddoZcdpZdddqZeddrZfddsZgddtZhdddyZiddzZjdd}ZkddZlddZmdddZnddZoddZpdddZqddddZrg dZsdS )uu  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#PROVIDER_STREAM_NON_JSON_ERROR_CODE)EmptyStreamError)substitute_api_content)is_native_gemini_base_url)is_local_endpoint)flatten_message_text)append_messagestamp_message_timestamp)_sanitize_surrogates_repair_tool_call_arguments)separate_glued_reasoning_blocks)claim_stream_writerstream_writer_is_current)is_persistent_env)base_url_host_matchesbase_url_hostname	env_floatenv_int>   pricelatency
throughputerrorerror_finish>   iddataeventretry   g      @c                8     t          j                     fdS )z=Bind a no-argument thread target to the caller's ContextVars.c                 .                                    S N)runcallbackcontexts   A/home/agent/.hermes/hermes-agent/agent/chat_completion_helpers.py<lambda>z(_context_thread_target.<locals>.<lambda>H   s    7;;x((     )contextvarscopy_contextr-   s   `@r0   _context_thread_targetr5   E   s$    &((G((((((r2   labelstrreturnNonec               "   	 ddl m} |                    d          }||                                sdS n# t          $ r Y dS w xY w|                     d           |                                 rt                              d|           dS dS )	u.  Bounded worker join before raising InterruptedError (#81521).

    Raising immediately lets turn teardown (finish_logical_calls /
    end_turn / close_session) race a still-open Relay physical LLM scope
    and corrupt the LIFO stack — "scope handle is not at the top of the
    stack" → CLI EIO / redraw storm.  Only joins when Relay managed
    execution is actually live: when no Relay consumers are registered
    there is no scope to unwind, and the join would just delay interrupt
    detection (tests/run_agent/test_interrupt_propagation.py).
    r   )relay_runtimeF)createN       @timeoutz%s worker still alive after interrupt abort (2.0s join timeout); Relay teardown will best-effort drain orphaned scopes (#81521).)	agentr;   get_runtimemanaged_execution_enabled	Exceptionjoinis_aliveloggerwarning)workerr6   r;   runtimes       r0   _join_worker_for_relay_teardownrJ   K   s    ''''''++5+99?'"C"C"E"E?F    
KKK 
 		
 	
 	
 	
 	

 
s   27 
AA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_agentrL   s    r0   _rarN   h   s     r2   c                  2     e Zd ZdZddd fdZddZ xZS )ProviderStreamErrorzKProvider encoded an API error as streaming content instead of an SDK error.Nheadersstatus_codeOptional[int]bodydictraw_textr7   rR   r   c                   || _         || _        || _        t          |pi           | _        t                                          |                                            d S )NrQ   )rS   rU   rW   r   responsesuper__init___format_message)selfrS   rU   rW   rR   	__class__s        r0   r[   zProviderStreamError.__init__v   s[     '	 '2>>>--//00000r2   r8   c                   t          | j        t                    r| j                            di           ni }t          |t                    r|                    d          nd }t          |t                    r|                    d          nd }dg}| j        r|                    d| j                    |r"|                    t          |                     d                    |          }|r|d| z  }|S )Nr"   codemessagez'Provider stream returned an error eventzHTTP z - : )
isinstancerU   rV   getrS   appendr7   rD   )r]   	error_objr`   ra   partstexts         r0   r\   z#ProviderStreamError._format_message   s    2<TY2M2MUDIMM'2...SU	(29d(C(CMy}}V$$$.8D.I.IS)--	***t:; 	5LL3!133444 	$LLT###zz%   	#NNN"Dr2   )rS   rT   rU   rV   rW   r7   rR   r   r8   r7   )__name__
__module____qualname____doc__r[   r\   __classcell__)r^   s   @r0   rP   rP   s   sf        UU 1 1 1 1 1 1 1 1       r2   rP   valuer   rT   c                .   t          | t                    rd| cxk    rdk     rn n| S t          | t                    sd S t          j        d| t          j                  }|sd S 	 t          |                    d                    S # t          $ r Y d S w xY w)Nd   iX  z (?:HTTP_STATUS/)?\b([1-5]\d\d)\b   )rc   intr7   research
IGNORECASEgroup
ValueError)ro   matchs     r0   _status_code_from_valuerz      s    % #"4"4"4"4"4"4"4"4"4eS!! tI95"-PPE t5;;q>>"""   tts   $!B 
BBpayloadc                R   t          | t                    sd S |                     d          |                     d          |                     d          g}|                     d          }t          |t                    re|                    |                    d          |                    d          |                    d          |                    d          g           |                    |                     d                     |D ]}t          |          }||c S d S )NrS   statushttp_statusr"   r`   )rc   rV   rd   extendre   rz   )r{   
candidatesrf   	candidaterS   s        r0   _status_code_from_payloadr      s'   gt$$ t 	M""HM""J
 G$$I)T"" MM-((MM(##MM-((MM&!!	
 	 	 	 gkk&))***  	-i88" #4r2   rh   Optional[dict]c                    | pd                                 }|                    d          sd S 	 t          j        |          }n# t          j        t
          f$ r Y d S w xY wt          |t                    r|nd S )N {)strip
startswithjsonloadsJSONDecodeError	TypeErrorrc   rV   )rh   strippeddecodeds      r0   _json_object_from_textr      s    
!!##Hs## t*X&& ),   tt $//977T9s   A AA
list[dict]c                  	 g 	dg g i ddd	fd}| pd	                                 D ]Q}|                    d
          }|d	k    r |             )|                    d          r6d                             |dd                                                    t|                    d          \  }}}|s0d	d         |                                                                <   |                                                                }|                    d          r
|dd         }|dk    r|                                d<   #|dk    rd                             |           F|d         |<   S |             	S )z7Parse provider text that looks like Server-Sent Events.Nr&   r%   commentsfieldsr&   rV   r8   boolc                    t          |                     d          p>|                     d          p)|                     d          p|                     d                    S )Nr&   r%   r   r   )r   rd   )r&   s    r0   _has_event_dataz3_parse_provider_sse_events.<locals>._has_event_data   sa    IIg #yy  #yy$$# yy""	
 
 	
r2   c                               rd                     d                   } t          d                   }dD ]-}|d         v r!|                    d         |                    .                    d         | t          d                   t          d                   t	          d d |D             D             d           d	           d g g i d
d S )N
r%   r   )r}   rS   r~   r   r&   c              3     K   | ]}||V  	d S r+    ).0r}   s     r0   	<genexpr>zE_parse_provider_sse_events.<locals>._flush_current.<locals>.<genexpr>   s8        " "- 
 .--- r2   c              3  4   K   | ]}t          |          V  d S r+   )rz   )r   ro   s     r0   r   zE_parse_provider_sse_events.<locals>._flush_current.<locals>.<genexpr>   s>       ' ' % 4E::' ' ' ' ' 'r2   )r&   r%   r   r   rS   r   )rD   listre   rV   next)	data_textstatus_candidateskeyr   currenteventss      r0   _flush_currentz2_parse_provider_sse_events.<locals>._flush_current   s&   ?7## 			'&/22I $WZ%8 9 9? E E'(+++%,,WX->s-CDDDMM )! !455wx011# ' '):' ' '   
  
     " !""KKr2   r   :r   rr   r    r%   )r&   rV   r8   r   )
splitlinesrstripr   re   r   	partitionlower)
rh   r   raw_linelinefieldsepro   r   r   r   s
          @@@r0   _parse_provider_sse_eventsr      s   FbbBGGG
 
 
 
L L L L L L L6 ZR++-- - -t$$2::N??3 	J&&tABBx~~'7'7888 NN3//sE 	79GHekkmm11334##%%C   	!""IEG${{}}GGf__FO""5))))',GHe$$NMr2   rV   rS   c                8   t          | t                    r-|                     d          }t          |t                    r| S ni } |                     d          p2|                     d          p|                     d          p|rd| nd}|                     d          p+|                     d          p|                     d          pd	}dt          |          i}|rt          |          |d<   d
D ]"}|                     |          r| |         ||<   #d|iS )zDNormalize common provider error payloads to OpenAI-style body.error.r"   r`   
error_codetypeHTTP_provider_stream_errorra   error_descriptionz(Provider stream returned an error event.)
request_idparamr   )rc   rV   rd   r7   )r{   rS   rf   r`   ra   normalized_errorr   s          r0   _provider_error_bodyr   	  s[   '4   KK((	i&& 	N	  	F 	O;;|$$	O;;v	O &1M!K!!!6M	 	 	I 	6;;*++	6;;w	6 6	  "3w<<0 -#&t99 . 1 1;;s 	1$+CLS!%&&r2   rY   json.JSONDecodeErrorrY   c               H   ddl m} t          t          | dd          pd                                          } |t          |          d          }|dt                   }|pd}|t          |d	d          nd}t          dt          t          |d
d          ||          S )aJ  Preserve plain-text SSE data rejected inside the OpenAI SDK.

    OpenAI-compatible providers occasionally send ``event: error`` with a
    non-JSON ``data:`` field.  The SDK raises from ``sse.json()`` before it can
    yield a completion chunk, but ``JSONDecodeError.doc`` still contains the
    provider's original message.
    r   redact_sensitive_textdocr   T)forceNz+Provider stream returned non-JSON SSE data.rR   r`   ra   rS   rU   rW   rR   )
agent.redactr   r7   getattrr   r   !_PROVIDER_STREAM_ERROR_TEXT_LIMITrP   r   r   )r"   rY   r   rW   	safe_textra   rR   s          r0   -_provider_stream_error_from_json_decode_errorr   '  s     32222275%,,23399;;H%%X&&  I <<<=IHHG4<4Hgh	4000dG!;"  
 
    r2   c             #     K   	 | E d{V  dS # t           j        $ rE}t          |          r
 |            n|}|t          | dd          }t	          ||          |d}~ww xY w)zAYield SDK chunks while translating SDK-level SSE decode failures.NrY   r   )r   r   callabler   r   )streamrY   r"   stream_responses       r0   _iter_provider_stream_chunksr   L  s      	   (0(:(:H((***"%fj$??O;$
 
 
 		s    A"A AA"r   c                6   t          | t                    sdS t          |                     d          t          t          f          rdS |                     d          r;|                     d          s$|                     d          st	          |           dS dS )NFr"   Tra   r`   r   )rc   rV   rd   r7   r   )r{   s    r0   _payload_has_error_shaper   Z  s    gt$$ u'++g&&s44 t{{9 F;;|$$ %W--9t5r2   c                >   | pd                                 }|sdS |                                }|                    d          }d}t          |          D ]\  }}|                    d          }|dk    r!|                    d          rd}9|                    d          \  }}	}
|                                                                |	rt          v rd}|t          |          dz
  k    o| }|r#t          fdt          D                       r dS  dS |S )	zEReturn True while pending text still looks like an SSE control block.r   F)r   r   r   r   Trr   c              3  B   K   | ]}|                               V  d S r+   )r   )r   	sse_field
field_names     r0   r   z3_provider_stream_text_may_be_sse.<locals>.<genexpr>  sE       &
 &
   ,,&
 &
 &
 &
 &
 &
r2   )lstripr   endswith	enumerater   r   r   r   r   _PROVIDER_STREAM_SSE_FIELDSlenany)rh   r   linestrailing_newlinesaw_sse_fieldindexr   r   r   r   _valueis_last_incompleter   s               @r0    _provider_stream_text_may_be_sser   h  sb   
""$$H u!!E((66M$U++  xt$$2::??3 	 M!^^C00sF[[]]((**
 	:!<<< M"c%jj1n4M=M9M 	# &
 &
 &
 &
8&
 &
 &
 #
 #
 	 44uur2   finish_reasonOptional[str]Optional[ProviderStreamError]c                  | sdS t          |pd                                          }|t          v }|sdS t          |           D ] }t          |                    d          pd                                                                          }t          |                    d          pd          pi }|                    d          pt          |          }|dk    }	|duo|dk    }
t          |          }|	o|p|
p|}|	 o|o|}|
s|s|s|t          |dd          nd}t          |t          ||          | |	          c S t          |           }|Ot          |          }|s|<|dk    r6|t          |dd          nd}t          |t          ||          | |	          S |rJ|                                 r6|t          |dd          nd}t          dt          i d          | |	          S dS )
zGConvert provider-streamed error text into an exception for retry logic.Nr   r&   r%   rS   r"   i  rR   r   )r7   r   %_PROVIDER_STREAM_ERROR_FINISH_REASONSr   rd   r   r   r   r   r   rP   r   )rh   r   rY   finish_reason_texthas_error_finishr&   
event_namer{   rS   is_error_eventis_http_erroris_error_payloadis_structured_error_eventis_bare_error_finish_payloadrR   s                  r0    _provider_stream_error_from_textr     s     t]0b117799)-RR t+D11 
 
7++1r2288::@@BB
(6):):)@bAAGRii..T2KG2T2T#w.#4/FK34F3G<<$2 %
AA1A 	" H#3H8H 	%
 	(	 ,	
 8@8L'(It444RV"#%g{;;	
 
 
 	
 	
 	
 %T**G/88 	 7K3<N<N<D<Pgh	4888VZG&')';??	     
DJJLL 
8@8L'(It444RV"%b$//	
 
 
 	
 4r2   api_payloadrs   c                   dddfd}t          | t                    r ||           dz  S t          | t                    r|                     d          }t          |t                    r5 ||          }d	| v r!| |                     d	                    z  }|dz  S d
| v ra |                     d
                     |                     d                    z    |                     d	                    z   }|dz  S t	          fd|                                 D                       dz  S  |           dz  S )a   Estimate context/load tokens from an API payload, dict or messages list.

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

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

    Gateway/Telegram sessions routinely ship ~15–25k tokens of tools +
    instructions before the first user message. Subscription-backed Codex can
    legitimately spend several minutes in backend admission/prefill at that
    size; the generic 90s non-stream stale default aborts healthy calls. The
    floor engages above 10k estimated tokens so those gateway-scale payloads
    are covered; smaller requests keep the generic default.
    順 g     @P        @'  g     @        r   )r  s    r0    openai_codex_stale_timeout_floorr    s9     GvFuFu3r2   raw_sortc           	         t          | t                    sdS |                                                                 }|sdS |t          v r|S t
                              d| d                    t          t                                         dS )z;Return a normalized OpenRouter provider.sort value or None.Nz@Ignoring invalid OpenRouter provider.sort value %r (allowed: %s), )	rc   r7   r   r    _OPENROUTER_PROVIDER_SORT_VALUESrF   rG   rD   sorted)r  
sort_values     r0   #_validated_openrouter_provider_sortr  "  s    h$$ t!!''))J t555
NNJ		&9::;;  
 4r2   Dict[str, Any]c                    i }| j         r
| j         |d<   | j        r
| j        |d<   | j        r
| j        |d<   t          | j                  }|r||d<   | j        rd|d<   | j        r
| j        |d<   |S )zDBuild the validated provider-routing object shared by request paths.onlyignoreordersortTrequire_parametersdata_collection)providers_allowedproviders_ignoredproviders_orderr  provider_sortprovider_require_parametersprovider_data_collection)r@   preferencesr)  s      r0   _provider_preferences_for_agentr-  3  s    "$K 6#5F 8 % 7H 5$4G78KLLM ,+F( 1,0()% H).)G%&r2   'str | None'c                    	 ddl m}  ||           S # t          $ r  t                              dd           Y dS w xY w)uv  Rotation-stable logical cache scope for *agent*, or None.

    Guarded-import wrapper over the never-raising
    ``agent.prompt_cache_scope.resolve_prompt_cache_scope_safe`` — the
    transports treat a None/empty value as "fall back to the physical
    session_id", so any resolution failure degrades to pre-#79017 behavior
    instead of blocking the request build.
    r   )resolve_prompt_cache_scope_safez$prompt-cache scope resolution failedTexc_infoN)agent.prompt_cache_scoper0  rC   rF   debug)r@   r0  s     r0   _prompt_cache_scope_for_agentr5  F  sc    LLLLLL..u555   ;dKKKtts    &==anthropic_kwargsc           	     V   t          | dd          dvr|S 	 ddlm}  |d          }|L|                    di                               |                    t          | dd          	                     n2# t          $ r%}t                              d
|           Y d}~nd}~ww xY w|S )u  Merge Portal ``tags`` / ``session_id`` onto an Anthropic Messages kwargs dict.

    The Nous provider profile is only consulted by the OpenAI-wire transport;
    anthropic_messages callers must merge it themselves. Passes ``session_id``
    only — not ``provider_preferences`` (those become a top-level ``provider``
    routing object on the OpenAI wire). Never blocks a turn on tagging.
    r  N>   nousnousresearchnous-portalr   get_provider_profiler8  
extra_body
session_id)r>  z'Nous Portal extra_body merge failed: %s)	r   	providersr<  
setdefaultupdatebuild_extra_bodyrC   rF   r4  )r@   r6  r<  nous_profileexcs        r0   &_merge_nous_portal_messages_extra_bodyrE  X  s     uj$''/VVVE222222++F33#''b99@@--&ulDAA .    
  E E E>DDDDDDDDEs   AA7 7
B&B!!B&namedefaultc                    	 t          t          j        | t          |                              S # t          t
          f$ r |cY S w xY wr+   )r  osgetenvr7   r   rx   )rF  rG  s     r0   
_env_floatrK  q  sP    RYtS\\22333z"   s   .1 AAchunkc                   d}	 t          | dd          }|rt          |d         dd          }|dD ]:}t          ||d          }t          |t                    r|t          |          z  };t          |dd          }|r|D ]}t          |dd          }|pt          |d	d          }	t          |	t                    r|t          |	          z  }t          |d
d          }
t          |
t                    r|t          |
          z  }nLdD ]I}t          t          | dd          |d          }t          |t                    r|t          |          z  }Jn# t          $ r Y nw xY w|S )u   Cheap per-chunk size estimate for the stream diagnostic counters.

    The previous implementation used ``len(repr(chunk))`` — a full recursive
    repr of a pydantic model on EVERY streaming chunk (5.5-8.8 µs each,
    ~20-30 ms of pure CPU on a 3,000-chunk response, in the hottest loop in
    the agent). The counter only feeds a retry-diagnostic log line, so an
    estimate based on the delta payload lengths is plenty (2.1-2.4 µs, ~3x
    cheaper, and independent of model/pydantic field count). Chat Completions
    chunks are sized from their delta content/reasoning/tool-argument strings
    plus a small framing constant; anything shape-unknown (Anthropic events,
    stub providers) falls back to a flat constant so `bytes` stays monotonic
    and roughly proportional to traffic.
    (   choicesNr   delta)contentreasoning_content	reasoning
tool_callsfunction	argumentsrF  )rh   partial_json)r   rc   r7   r   rC   )rL  sizerO  rP  attrvrT  tcfnargsrF  s              r0   _estimate_chunk_bytesr^  x  s    D%D11 	#GAJ66E I ' 'DtT22A!!S)) 'A$UL$??
 	2( 2 2$RT::>#*2{D#A#AD)$44 2 $D		 1#*2vt#<#<D)$44 2 $D		 1 1 # #GE7D994FFa%% #CFFND   Ks   EE 
E#"E#stale_timeoutttfb_enabledttfb_timeoutlast_event_tsOptional[float]
call_startidle_enabledidle_timeoutelapsedc                   g }t          j        |           r|                    |            |,|r)t          j        |          r|                    |           n?|r=t          j        |          r)|                    t          d||z
            |z              |rt	          |          |k    rdS dt          t	          |                     dS )zBDescribe the earliest enabled Codex watchdog on the call timeline.Nr  r   ; auto-reconnect at s)mathisfinitere   maxminrs   )	r_  r`  ra  rb  rd  re  rf  rg  	deadliness	            r0   _codex_wait_notice_recoveryrp    s      I}]## (''' 	+DM,77 	+\***	 N$-55 NS-*"<==LMMM I'11r8#c)nn"5"58888r2   c                f    	 t          t          | dd          pd          S # t          $ r Y dS w xY w)N_consecutive_stale_streamsr   )rs   r   rC   r@   s    r0   _stale_streakrt    sI    75">BBGaHHH   qqs   " 
00c                X    	 t          |           dz   | _        d S # t          $ r Y d S w xY w)Nrr   )rt  rr  rC   rs  s    r0   _bump_stale_streakrv    sD    +8+?+?!+C(((   s    
))c                8    	 d| _         d S # t          $ r Y d S w xY wr   )rr  rC   rs  s    r0   _reset_stale_streakrx    s7    +,(((   s    
      >@response_startedc                   |s|t           k     rdS t          |            t                              d|t	          |                      dS )au  Count a user-aborted pre-response stall toward the stale breaker.

    Interactive users commonly send a follow-up while a provider is wedged.
    Once the same no-output interval that earns a wait notice has elapsed, that
    interrupt is evidence of an unresponsive attempt rather than a quick user
    cancellation. Mid-response and early interrupts remain neutral.
    FzeInterrupted provider wait counted as stale after %.0fs with no output; consecutive stale attempts=%d.T)_INTERRUPTED_WAIT_STALE_SECONDSrv  rF   rG   rt  )r@   rg  rz  s      r0   !_record_interrupted_provider_waitr}    sZ      7%DDDuu
NN	)e	   4r2   F)inlinehint
api_kwargsr~  r  c          
     L   |                     dd          }t                              d|rdnd|||t          |          d           	 |                     dt          |           d| d	|pd
            dS # t          $ r  t                              dd           Y dS w xY w)u  Emit the user/operator-facing trio for a stale non-streaming kill.

    Shared by the interrupt-worker poll loop and the inline
    ``direct_api_call`` watchdog so the log line, status message, and
    activity token stay identical across both paths. Only reporting lives
    here — the kill/state sequences differ deliberately between the two
    callers (locking models are not the same).
    modelunknownzk%son-streaming API call stale for %.0fs (threshold %.0fs). model=%s context=~%s tokens. Killing connection.zInline nN,%   ⚠️ No response from provider for zs (non-streaming, model: z). zAborting call.zstale status buffering failedTr1  N)rd   rF   rG   r  _buffer_statusrs   rC   r4  )r@   r  rg  r_  r~  r  r  s          r0   _report_stale_nonstream_killr    s    " NN7I..E
NN	;%

#*:66::  EKCLL K K&+K K040H8HK K	
 	
 	
 	
 	
  E E E4tDDDDDDEs   
-A9 9&B#"B#c                    	 |                      dt          |           d           d S # t          $ r  t                              dd           Y d S w xY w)Nz&stale non-streaming call killed after rj  zstale activity touch failedTr1  )_touch_activityrs   rC   rF   r4  )r@   rg  s     r0   _touch_stale_kill_activityr     s    CDS\\DDD	
 	
 	
 	
 	
  C C C2TBBBBBBCs   &* &AAc                    t          dd          }t          |           }|dk    r||k    rt          d| d          dS dS )u   Raise immediately when the consecutive-stale streak is past the
    give-up threshold — no network attempt, no stale-timeout wait.HERMES_STREAM_STALE_GIVEUP   r   z:Provider has been unresponsive (no response received) for u    consecutive stale attempts — aborting this call to avoid an indefinite stall. Switch models or start a new session, then retry.N)r   rt  RuntimeError)r@   _giveup_streaks      r0   _check_stale_giveupr  )  sj     2A66GE""G{{w'))## # #
 
 	
 {))r2   c                   t          | j        | j                  }||}nt          dd          }t	          |          }|dk    rt          |d          }n|dk    rt          |d          }n|}dd	lm} |                    d
          p|                    d          pd} ||          }|*|                    d          rt          |d                   }|t          ||          }|S )u  Stale-stream patience for a provider that is never a local endpoint.

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

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

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

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

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

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

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

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

C0C++C0c                    t          | dd          dk    rdS t          | dd          dk    rdS t          | dd          dk    rd	S 	 d
dlm}  |            rd	S n# t          $ r Y nw xY wt          | dd          dk    S )u
  Whether an OpenAI-wire request should skip the interrupt worker.

    Two nested-pool contexts wedge before the socket opens when the request
    is pushed onto yet another daemon worker thread:

    - Gateway cron turns (#62151): gateway asyncio loop → cron thread →
      interrupt worker. Fixed by running inline.
    - Delegated children (#60203): gateway loop → async-delegation executor
      (module-lifetime daemon pool) → per-child timeout executor → interrupt
      worker. Same fingerprint after multi-day gateway uptime — children hang
      at their FIRST API call with zero stale-detector output (the worker
      never reaches dispatch), all providers, restart cures it. The cron fix
      originally excluded delegation "for lack of evidence"; #60203 is that
      evidence.

    Running inline drops the deepest thread layer (whose only job is
    interactive-interrupt responsiveness). Interrupts still work: the inline
    path registers ``agent._active_request_abort``, which ``interrupt()``
    invokes cross-thread to shut the active sockets — the same mechanism the
    async-delegation stall monitor (#72227) relies on.

    Keep native/Codex/Bedrock/MoA transports on their established workers:
    their cancellation and client ownership differ.
    r  Nchat_completionsFr  r  platformcronTr   )is_delegated_child_contextsubagent)r   agent.delegation_contextr  rC   )r@   r  s     r0   should_use_direct_api_callr    s    2 uj$''+===uuj$''500uuj$''611tGGGGGG%%'' 	4	   5*d++z99s   A 
A'&A'g      .@c                   t          | dd          }t          |          st          d          S  ||          }t          |t                    st          |t
          t          f          st          d          S t          |          S )u+  Stale budget for the inline non-streaming call.

    Same derivation the interrupt-worker path uses for its stale-call
    detector (provider ``stale_timeout_seconds`` →
    ``HERMES_API_CALL_STALE_TIMEOUT`` → reasoning-model floor → context-size
    scaling, ``inf`` for a local endpoint on the implicit default), so cron and
    delegated turns get exactly the patience every other non-streaming request
    already gets.

    A non-numeric result — an agent stub that never implements the resolver —
    leaves the watchdog disarmed rather than arming it on a bogus budget.
    A resolver that *raises* propagates, exactly as it does on the worker
    path's stale detector: swallowing it into ``inf`` would silently disarm
    the watchdog and reinstate the unbounded hang this exists to fix.
    !_compute_non_stream_stale_timeoutNinf)r   r   r  rc   r   rs   )r@   r  resolverro   s       r0   _resolve_direct_stale_timeoutr    s      uA4HHHH U||HZ  E% je&E&E U||<<r2   c                    t          j        |           r| dk    rdS t          | d          }	 ddl}|                    || ||          S # t
          $ r | cY S w xY w)u^  Socket-level backstop for inline non-streaming calls (#85252).

    The keepalive httpx client uses ``read=None`` so SSE streams can idle
    during reasoning. That same client serves cron/subagent non-streaming
    calls. Combined with a stranger-thread abort that must not ``close()``
    the FD (#29507), a hung provider then waits until TCP dies — observed
    5–11× past the stale threshold.

    Returns an ``httpx.Timeout`` whose read budget equals the stale
    watchdog, a float if httpx is unavailable, or ``None`` when the
    watchdog is disarmed (local endpoint / non-finite budget).
    r   N      N@connectreadwritepool)rk  rl  rn  httpxTimeoutrC   )r_  conn_cap_httpxs      r0   _inline_nonstream_hard_timeoutr  7  s     ='' =A+=+=t=$''H
~~	  
 
 	
    s   A AAc           	         t                                           d           dddddt          j                    t          j                    d% fd	d&d' fd}d( fd}t          j        |dd          }t          j                    t                     t                    }|dvrt                    |d<   |
                                 d( fd}d}t          j                  r=dk    r7t          j        |          }d|_        d|_        |
                                 d}	 t!           |          }	t#           dd          rt%          d          5  dd<   ddd           n# 1 swxY w Y   t'                      d}|	||                                 5  dd<   ddd           n# 1 swxY w Y                                    |                    d           t#           dd          u rd _        5  d         }
dd<   ddd           n# 1 swxY w Y   |
                     |
|rdnd            S S # t2          $ r t#           dd          rt%          d          d5  d!         }ddd           n# 1 swxY w Y   |rEt5          d"t7          t          j                    z
             d#t7                     d$          d w xY w# ||                                 5  dd<   ddd           n# 1 swxY w Y                                    |                    d           t#           dd          u rd _        5  d         }
dd<   ddd           n# 1 swxY w Y   |
                     |
|rdn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 (cron turns and
    delegated children). Skips the interrupt worker (whose only job is
    interactive-interrupt responsiveness, which these contexts do not have)
    so the nested-pool deadlock (#62151, #60203) cannot occur.

    While the inline request blocks, a lightweight activity heartbeat keeps
    ``last_activity_ts`` advancing. Subagents use this path (non-streaming),
    and without mid-call ticks the async stall monitor / sync heartbeat treat
    a slow-but-healthy local model wait as "no progress" and interrupt around
    450s — surfacing as ``Operation interrupted: waiting for model response``.

    A stale-call watchdog bounds the request the same way the interrupt
    worker's poll loop does (#80759). The keepalive httpx client uses
    ``read=None`` (SSE), so the socket itself is not a usable bound: a
    provider that accepts the request and then goes silent never trips a
    read timeout, and a stranger-thread abort cannot ``close()`` the FD
    (#29507). The watchdog aborts in-flight sockets through the already-
    registered abort hook; a per-call ``timeout`` matching the stale budget
    is the hard backstop when that abort finds nothing to shut down
    (#85252). Either path surfaces a retryable ``TimeoutError`` so the
    outer retry loop reconnects with backoff / credential rotation /
    provider fallback.
    &waiting for non-streaming API responseNF)r  donestale	cancelledreasonr7   r8   r   c                   5  d         r	 ddd           dS | dk    rd         r	 ddd           dS | dk    rdd<   | dk    od          }|rdd<   t                     d         }|F	                     || 	           n-# t          $ r  t                              d
| d           Y nw xY w|cddd           S # 1 swxY w Y   dS )zAbort the inline request from a watchdog/interrupt thread.

        Returns True when this call owned the stale transition (so the
        timer callback only reports/bumps once, and never after an
        interrupt or a completed request).
        r  NFstale_call_killr  Tr  r  r  z Inline request abort failed (%s)r1  )rv  _abort_request_openai_clientrC   rF   r4  )r  newly_staler  r@   request_client_lockrequest_states      r0   _abort_active_requestz.direct_api_call.<locals>._abort_active_requestz  s    ! 	 	V$ 	 	 	 	 	 	 	 	 ***}[/I*		 	 	 	 	 	 	 	
 ***
 .2k* $55TmG>T:TK *)-g&
 #5)))*84N)66~f6UUUU    LL:FT !      7	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s?   
CC:C2B
	C
'B41C3B44CC	C	openair  c                h                        |           }d}5  |d<   d         rGd}	                     |d           n,# t          $ r t                              dd	           Y nw xY wd d d            n# 1 swxY w Y   |r t          d
t          	           d          _        |S )Nr  r  Fr  r  Tr  r  z2Inline abort after late client registration failedr1  zENon-streaming API call timed out before request dispatch (threshold: s))_create_request_openai_clientr  rC   rF   r4  TimeoutErrorrs   _active_request_abort)
r  r  r  stale_before_dispatchr  r@   r  r  r  r_  s
       r0   _make_clientz%direct_api_call.<locals>._make_client  s\   
 44Fz4ZZ %  	 	&,M(#W%  )-%66'8 7     !   LLL!% !     !	 	 	 	 	 	 	 	 	 	 	 	 	 	 	* ! 	6"=116 6 6   '<#s4   A>AA>&A/,A>.A//A>>BBr9   c                                           t                    sC	                     d           n# t          $ r Y nw xY w                      t                    Ad S d S )Nr  )wait&_DIRECT_API_ACTIVITY_HEARTBEAT_SECONDSr  rC   )activity_hb_stopr@   s   r0   _activity_heartbeatz,direct_api_call.<locals>._activity_heartbeat  s     #''(NOO 	%%&NOOOO    #''(NOO 	 	 	 	 	s   3 
A A zdirect-api-activity-hbT)targetrF  daemonr?   c                      d          sd S t          j                     z
  } t          | d           t          |            d S )Nr  T)r~  )timer  r  )rg  r  r@   r  rd  r_  s    r0   	_on_stalez"direct_api_call.<locals>._on_stale  sh     %$%677 	F)++
*$:wd	
 	
 	
 	
 	#5'22222r2   r   zdirect-api-stale-watchdogr  _interrupt_requested!Agent interrupted during API callr  r=   r>   r  r  request_completerequest_error_cleanupr  r  'Non-streaming API call timed out after s with no response (threshold: r  )r  r7   r8   r   r   )r  r7   r  r7   r8   r9   )r  r  	threadingLockEventThreadr  r  r  rV   startrk  rl  TimerrF  r  r  r   InterruptedErrorrx  cancelsetrD   r  _close_request_openai_clientrC   r  rs   )r@   r  r  r  activity_hbhard_timeoutr  stale_watchdog	succeededrY   r  	was_staler  r  rd  r  r  r_  s   ``          @@@@@@r0   direct_api_callr+  T  s   4 	BCCC  $UUQVWWM#.** ((( ( ( ( ( ( ( (T" " " " " " " " " " " "H       ""%  K J1%DDM
 2-@@LIZ$?$?*%%
 ,
93 3 3 3 3 3 3 3 3 3 N}]## (9(9"	BB9 $
 I35:<
 
 
( 50%88 	H"#FGGG ! 	) 	)$(M&!	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)E"""	%!!###  	) 	)$(M&!	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)%%%51488<QQQ*.E'  	+ 	+*84N&*M(#	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ %..-6S))<S /     &W    50%88 	R"#FGGTQ  	/ 	/%g.I	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 		
 6ty{{Z/006 6"=116 6 6  	
 	@ %!!###  	) 	)$(M&!	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)%%%51488<QQQ*.E'  	+ 	+*84N&*M(#	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ %..-6S))<S /     &s   I. "L  FL FL FL GG	 G	*II	I	.-L	J0$L0J4	4L7J4	8ALL O L2&O2L66O9L6:A	ONON!!O$N!%"Oc           
         ! t                     rt                     S ddd!t                      dddddit          j                     ddiddd\ fd
d]  fd !fd}                               } j        dk    }t                     }t                    }|r#|r!t          |          }|rt          ||          }t          dd          }|r|r|dk    rt          ||          }|dk    rd}	n|dk    rd}	n|dk    rd}	nd}	|}
t          dd          }|dk    rd}
n|rt          dd          }t          j                            dd                                                                          d v }|s6|dk    r0||k    r*|	}||k     r"t$                              d!|||d"|           |}t          d#d          }|dk    r'||k    r!t$                              d$|||d"           |}|}t          d%|	          }|dk    rd}|rd _        d _        t-          j                    }                     d&           t          j        t3          |          d'(          }|                                 d}|                                r3|                    d)*           |d+z  }|d,z  dk    rt-          j                    |z
  }	 t;          ||
|t=           d-d          ||||.          }                     d/                    d0d1           d2tA          |           d3| d4           n,# tB          $ r t$          "                    d5d'6           Y nw xY wt-          j                    |z
  }|
r||k    rt=           d-d          d}t=           d7d          }tG          |          r3	  |                    d0          8          }n# tB          $ r d}Y nw xY wt$          $                    d9||                    d0d:                     |r@ %                    d;tA          |           d<                    d0d:           d=|            n= %                    d;tA          |           d<                    d0d:           d>           	  d?           n# tB          $ r Y nw xY w                     d@tA          |           dA                                dBtA          |           dC           |                    dD*           !dE         s!dF         k|r6tM          dGtA          |           dHtA          |           dI|           !dE<   n3tM          dGtA          |           dHtA          |           dJ          !dE<   n2t=           d-d          }|rC|@t-          j                    |z
  |k    r%t-          j                    |z
  }t$          $                    dK||                    d0d:          |d"            %                    dLtA          |           dM                    d0d:           d>           	  dN           n# tB          $ r Y nw xY w                     dBtA          |           dO           |                    dD*           !dE         ;!dF         3tM          dPtA          |           dQtA          |           dJ          !dE<   n||k    r7d}t=           d7d          }tG          |          r3	  |                    d0          8          }n# tB          $ r d}Y nw xY wtO           |||R           	  dS           n# tB          $ r Y nw xY wtQ                      tS           |           |                    dD*           !dE         s!dF         k|r6tM          dTtA          |           dUtA          |           dI|           !dE<   n3tM          dTtA          |           dUtA          |           dJ          !dE<   n j*        rtW           ||ot=           d-d          duV           d'd<   t$          "                    dW           	  dX           n# tB          $ r Y nw xY wtY          |dYZ           t[          d[          |                                3!dE         !dE         !dF         t]                      !dF         S )^a=  
    Run the API call in a background thread so the main conversation loop
    can detect interrupts without waiting for the full HTTP round-trip.

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

    Includes a stale-call detector: if no response arrives within the
    configured timeout, the connection is killed and an error raised so
    the main retry loop can try again with backoff / credential rotation /
    provider fallback.
    NrY   r"   )r  	owner_tidro   r   Fr  r  r7   c               |    5  | d<   |d<   t          j                    d<   d d d            n# 1 swxY w Y   | S Nr  ro   r.  r  	get_identr  r  request_client_holderrequest_client_kindr  s     r0   _set_request_clientz3interruptible_api_call.<locals>._set_request_clientc  s      	G 	G.4!(++/( 2;1D1F1F!+.	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G    !155r  r8   r9   c                0   5                       d          }                     d          }|d uo|d uo|t          j                    k    }|rW                     dd          dk    r                    ||            n                    ||            	 d d d            d S d d<   d d<   d d d            n# 1 swxY w Y   |d S                      dd          dk    r                    ||            d S                     ||            d S )Nr  r.  ro   r   r  r  rd   r  r2  _abort_request_anthropic_clientr  _close_request_anthropic_clientr%  )r  r  r.  stranger_threadr@   r4  r5  r  s       r0   _close_request_client_oncez:interruptible_api_call.<locals>._close_request_client_oncem  s    ! 	6 	6266x@@N-11+>>Id* 7T)7!4!6!66 
   '**7H==AUUU99&v :     66~f6UUU-	6 	6 	6 	6 	6 	6 	6 	60 /3!(+15!+.3	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	64 !F""7H559MMM11.1PPPPP..~f.MMMMMs   BB='
B==CCc                 x   	 t          d
fd	          d<   nl# t          $ r_} d         rHt                              dt	          |           j                   Y d } ~  d         dnd           d S | d	<   Y d } ~ nd } ~ ww xY w d         dnd           d S #  d         dnd           w xY w)Nr   c                     |dk    r                     |           n                    |           |          S )Nr  r  r  r  ) _create_request_anthropic_clientr  )r  r  r6  r@   r  s     r0   r1   z7interruptible_api_call.<locals>._call.<locals>.<lambda>  sa    :M:M333 ::&:III<<%* =   ; ; ; r2   r  rY   ro   uh   Non-streaming worker caught %s after request cancellation — exiting without surfacing a network error.r  r  r"   r  )r  rC   rF   r4  r   rj   )er=  _request_cancelledr6  r@   r  results    r0   _callz%interruptible_api_call.<locals>._call  sj   (	 "D      " " "F:  	  	  	 
 "'* AGG$  
  '&*%1 #",      F7OOOOOO	 $ '&*%1 #",    &&*%1 #",   s7    B" 
B5BB" 9B>B" BB" "B9r  !HERMES_CODEX_HARD_TIMEOUT_SECONDSg     p@r   r  r  r        ^@r  r  g      (@!HERMES_CODEX_TTFB_TIMEOUT_SECONDS&HERMES_CODEX_TTFB_DISABLE_ABOVE_TOKENSg     @HERMES_CODEX_TTFB_STRICTr   >   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.r  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r  r  333333?r>   rr   rq   _codex_stream_last_event_ts)r_  r`  ra  rb  rd  re  rf  rg     ⏳ waiting on r  the provider    — z:s with no response yet (provider may be slow or overloaded)zwait-notice construction failedr1  _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.r  u&   ⚠️ 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 byter=   r"   rY   z&Codex stream produced no bytes within zs (TTFB threshold: zs). r  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: )r  r  r  r  rz  zBForce-closing httpx client due to interrupt (not a network error).interrupt_abortzNon-streamingr6   r  r  r7   r  r7   r8   r9   )/r  r+  r  r  r  r  r  r  r  r  rm  rK  rn  rI  environrd   r   r   rF   inforR  _codex_stream_last_progress_tsr  r  r  r5   r   rE   rD   rp  r   _emit_wait_noticers   rC   r4  r   rG   r  r  r  rv  r  r  r}  rJ   r"  rx  )"r@   r  rD  _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_elapsedr=  rB  r6  r4  r5  r  rC  s"   ``                         @@@@@@@r0   interruptible_api_callr}  7  s   " "%(( 2uj111..F '+$?? #H-#.** "5)3;          ,N ,N ,N ,N ,N ,N ,N ,N ,N\) ) ) ) ) ) ) ) ) )b <<ZHHN$ $n0AA4U;;%DZ%P%P" ?#8 ?78VWW 	? >>N" %%H&QQB!B  !##^-@AA%//&+##	'&	0	0&+##	'&	0	0&*##&*# ,MBEJJM	 &()QS[\\z~~&@"EEKKMMSSUU Z
 
 	<#a''.2EEE*E':::Q "/599'   !<>FF	q==]Y66KKS155   &M1$2#  a# 4 -1)/3,)++K	BCCC 6u = =dKKKAGGIIIK
**,, PH	sq !!y{{[0HO7"0!.!.")<d# #  +!4!4$  	 ''1jnnWn&M&M 1 18}}1 1$-1 1 1   
  O O O>NNNNNO 9;;, 7	=((<dCCK*.Lu&?FFH!! ((#+8*..2I2I#J#J#JLL  ( ( (#'LLL(NN& -)K)K    $$4S]] 4 4-7^^GY-O-O4 4%14 4    $$%S]] % %-7^^GY-O-O% % %  
**+<====   ###CMM # # #   !!PS]]PPP   FF3Fg&6*+=+E 	&2SX S S,/,>,>S SDPS S' 'F7OO
 '3CX C C,/,>,>C C C' 'F7O 
  'u.KTRR!	$0337JJJ#'9;;1E#E NN> %#w	22155     !#>R:S:S ! !,6NN7I,N,N! ! !  
**+CDDDD   !!\S1E-F-F\\\   FF3Fg&6*+=+E".QsCW?X?X Q Q478K4L4LQ Q Q# #w  n$$*.Lu&?FFH!! ((#+8*..2I2I#J#J#JLL  ( ( (#'LLL((z8^,    +*+<====    u%%%&uh777FF3Fg&6*+=+E 
&2*#h-- * *8;N8K8K* *'* *' 'F7OO '3P#h-- P P8;N8K8KP P P' 'F7O % !	H-+ X'DdKKSWW    +/w'LLT  **+<====    ,A_EEEE"#FGGGa **,, PHb g"Wo j%E"""*s   (A&M &M87M8O0 0O?>O?3R? ?
SS(Y4 4
Z Z/] ]]6^ 
^^b 
b('b(api_messagesr   tools_for_apilist | Nonec                P  . || j         }| j        dk    r|                                 }|                     |          }t	          | dd          }|r|j        nd}t	          | dd          }|d| _        |                    | j        ||||n| j	        | j
        | j        |                                 |t	          | dd          | j        pi                     d          dk    t          t	          | dd	                    
          }t!          | |          S | j        dk    r_|                                 }t	          | dd          pd}	t	          | dd          }
|                    | j        ||| j	        pd|	|
          S t#          |           }| j        dk    r|                                 }t%          | j        d          pt%          | j        d          }| j        dk    p| j        dk    od| j        v }| j        dv p
| j        dk    }|                     |          }ddlm}  || |||          }|r	 ddl}ddlm}m} |                    |          } ||          \  }} ||          \  }}nB# t>          $ r5}t@          !                    dt	          | dd          |           Y d}~nd}~ww xY w|                    | j        ||| j
        t	          | d d          || j        | j	        | "                                | j        t	          | d!d          ||||r| #                                ndt          t	          | d"d#                    |$          S |                                 }| $                                }| %                                }t%          | j        d          pt%          | j        d          }t%          | j        d%          }t%          | j        d&          }t%          | j        d'          p)t%          | j        d(          pt%          | j        d)          }t%          | j        d*          }| j        pd&                                '                                d+k    }	 dd,l(m)} m*}!  | | j        | j                  }"|"|!u }#|#s|"nd}$n# t>          $ r d	}#d}$Y nw xY wtW          |           }%d}&	 dd-l,m-}'m.}( | j        pd'                                /                    d.d/          .ta          .fd0|(D                       r |'| j                  }&n# t>          $ r Y nw xY wd})|r*| j1        pd1te          tg          j4                              d2})	 dd3l5m6}*  |*| j                  }+n# t>          $ r d}+Y nw xY w|+rt	          | dd          },|,d| _        |                     |          }|                    | j        ||| j        | "                                | j	        |,| j7        | j
        | j        t	          | d d          ||+| j8        |%pd| j9        |&| :                                |)4          S t	          | dd          },|,d| _        |                     |          }- |j        dXi d5| j        d6|-d7|d8| j        d9| "                                d:| j	        d;|,d<| j7        d=| j
        d>| j        d t	          | d d          d?|d@| j        pd'                                dA|dB|dC|dD|dE|dF|dG|dH|dI| j        dJk    dK| j8        dL|%pddM| j9        dN|r| j;        nddO|r| j<        nddP|)dQ|$dR|#dS| :                                dT|r| #                                nddU|r| =                                nddV|&dW| j        S )Yz9Build the keyword arguments dict for the active API mode.Nr  context_compressor_ephemeral_max_output_tokens_anthropic_base_urlspeedfast_oauth_1m_beta_disabledF)r  r   r   
max_tokensreasoning_configis_oauthpreserve_dotscontext_lengthbase_url	fast_modedrop_context_1m_betar  _bedrock_regionr  _bedrock_guardrail_configr(   )r  r   r   r  r  guardrail_configr  zmodels.github.aizgithubcopilot.comr	  r
  r  >   	xai-oauthxaizapi.x.air   )$native_compaction_context_management)is_codex_backendis_xai_responsesis_github_responses)strip_pattern_and_formatstrip_slash_enumu4   %s⚠️ Failed to sanitize tool schemas for xAI: %s
log_prefixr   r>  r  _codex_reasoning_replay_enabledT)r  r   r   r  r>  cache_scope_idr  r  r?   request_overridesr  r  r  r  github_reasoning_extrareplay_encrypted_reasoningcontext_managementznousresearch.comzintegrate.api.nvidia.comzapi.kimi.comzmoonshot.aizmoonshot.cnztokenhub.tencentmaas.comlmstudio_fixed_temperature_for_modelOMIT_TEMPERATURE)_get_anthropic_max_output_ANTHROPIC_OUTPUT_LIMITSr  r  c              3      K   | ]}|v V  	d S r+   r   )r   r   _model_norms     r0   r   z#build_api_kwargs.<locals>.<genexpr>  s(      FFcsk!FFFFFFr2   hermes)	sessionIdpromptIdr;  )r  r   r   r  r?   r  ephemeral_max_output_tokensmax_tokens_param_fnr  r  r>  r  provider_profileollama_num_ctxprovider_preferencesopenrouter_min_coding_scoreanthropic_max_outputsupports_reasoningqwen_session_metadatar  r   r   r  r?   r  r  r  r  r  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_namer   )>r   r  _get_transport#_prepare_anthropic_messages_for_apir   r  r  build_kwargsr  r  r  _is_anthropic_oauth_anthropic_preserve_dotsr  rd   r   rE  r5  r   r  r  r  r  &_prepare_messages_for_non_vision_modelagent.native_compactionr  copytools.schema_sanitizerr  r  deepcopyrC   rF   rG   _resolved_api_call_timeout#_github_models_reasoning_extra_body_is_qwen_portal_is_openrouter_urlr   r   agent.auxiliary_clientr  r  r-  agent.anthropic_adapterr  r  r  r   r>  r7   uuiduuid4r?  r<  _max_tokens_param_ollama_num_ctxr  _supports_reasoning_extra_body_qwen_prepare_chat_messages#_qwen_prepare_chat_messages_inplace"_lmstudio_reasoning_options_cached)/r@   r~  r  
_transportr  ctx_lenephemeral_outr6  _btr  	guardrail_cache_scope_id_ctr  r  r  _msgs_for_codexr  _context_management_copyr  r  _rD  _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/                                                 @r0   build_api_kwargsr  !  s
   ~---))++
"FF|TT%!5t<<,3='(('EtLL$15E.%22+'(5(A}}uGW"3.88::"U$94@@.4"99'BBfL!%ge5NPU&V&V!W!W 3 
 
$ 6e=MNNN ~+++""$$ 1488GKE#>EE	+!'/4&   
 
 	
 4E::O~***""$$!%.2DEE J$U^5HII 	
 Nn, (M9 B(E,AA	 	 !>-AAkUE]akEkFF|TT
 	QPPPPPBB-- 3	
 
 
.  	$$$$        !&} = =#;#;M#J#J q#3#3M#B#B qq   JE<44c        +$"3ulD99*^'4466#5UJ55 3--Re#o5#L#L#N#N#Nko'+@$GG( (  3'   
 
 	
. 


 
 C $$&&H%%''Fe35GHH 	M !68KLL  %U%:<NOOH&u'<>XYYJenn== 	@ ??	@ ?? 
 ))>@Z[[LN(b//117799ZGLYYYYYYYY**5;GG,,
!+5cc   

 -U33F H		
 	
 	
 	
 	
 	
 	
 	
 {(b//1199#sCCFFFF-EFFFFF 	>00==H    J 
)5XDJLL))
 

222222''77     
 (FMM%15E.
 CCLQQ+!^4466'(6 % 7"3#5ulD99*% 0!'4(-(I!)$CCEE",)   
 
 	
4 U$BDIIN!-1* AA,OON3 $ $ $kk$$ m$ 	$
 00222$ ##$ %3N$ "33$ //$  11$ 5,555$ '$ [&B--///$ f$ $   x!$"  #$$ !j%$& '$( !L)$* !L+$, !>X55-$. ,,/$0 $^t1$2 %*$E$E3$4 >FO9945$6 NV _ I I[_7$8 )j9$: &+;$< $=$> !??AAA?$@ OU^uHHJJJZ^A$B R^#g5#K#K#M#M#McgC$D &XE$F nnG$ $sO   <=I: :
J9+J44J93(R R-,R-A"T% %
T21T2$U; ;V
	V
c                   t          |dd          }|                     |          }t          |          }|sdt          t          |dd                    }t	          j        d|t          j                  }|r#d                    d |D                       }|pd}|r.| j        r't          j
        dt          |           d	|            |r<| j        r5| j        s.| j        s'	 |                     |           n# t          $ r Y nw xY wt          t          |dd                    }	t!          |	          }
|rt!          |          }t#          |
t$                    r)|
r'|                     |
                                          }
t#          |
t$                    r|
rd
dlm}  ||
          }
t/          d|
||d          }t          |dd          }|Dt1          |d          r4t          |dd          pi }t#          |t2                    rd|v r|d         }|t!          |          |d<   n|r|                                 r|pd|d<   d|vr|r||d<   t1          |d          r|j        r|j        }g }|D ]}t#          |t2                    r|                    |           -t1          |d          r|                    |j                   Xt1          |d          rb	 |                    |                    d                     # t>          $ r* |                    |                                           Y w xY w|r||d<   t          |dd          }|r||d<   t          |dd          }|r||d<   t          |dd          }|r||d<   |rkg }|D ]`}t          |dd          }t          |dd          }t#          |t$                    r|                                s|                      |          \  }}|}t#          |t$                    r|                                st#          |t$                    r)|                                r|                                }n_t          |dd          }|rt          |dd          nd}|rt          |dd          nd}| !                    ||t          |                    }|                                }t          |d d          }t#          |t$                    r|                                s|                      |          \  }}|}| "                    |t#          |t$                    r|nd          }||||j#        |j$        j%        |j$        j&        d!d"} t          |d#d          }!|!Qt1          |!d          r<	 |!                    d          }!n$# t>          $ r |!                                }!Y nw xY w|!| d#<   |                    |            b||d<   |S )$zBuild a normalized assistant message dict from an API response message.

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

c              3  f   K   | ],}|                                 |                                 V  -d S r+   )r   )r   bs     r0   r   z*build_assistant_message.<locals>.<genexpr>T  s7      "P"Paggii"P17799"P"P"P"P"P"Pr2   zCaptured reasoning (z	 chars): r   r   	assistant)rolerQ  rS  r   rR  model_extrar   reasoning_details__dict__
model_dumpFwarningsanthropic_content_blockscodex_reasoning_itemscodex_message_itemsr$   call_idrU  rF  r   rV  {}response_item_idrF  rV  )r$   r  r  r   rU  extra_content)'r   _extract_reasoningr   r   rt   findallDOTALLrD   verbose_loggingloggingr4  r   reasoning_callbackstream_delta_callback_stream_callbackrC   r   rc   r7   _strip_think_blocksr   r   r   r   hasattrrV   _needs_thinking_reasoning_padr  re   r  r  r   _split_responses_tool_id_deterministic_call_id"_derive_responses_function_call_idr   rU  rF  rV  )"r@   assistant_messager   assistant_tool_callsreasoning_text_from_structuredrQ  think_blockscombined_raw_content_san_contentr   msgraw_reasoning_contentr  raw_details	preserveddordered_blockscodex_itemsr  rT  	tool_callraw_idr  embedded_call_idr  _fn_fn_name_fn_argsr  embedded_response_item_idtc_dictextras"                                     r0   build_assistant_messager8  C  sM    ##4lDII--.?@@NN++
  .&w/@)T'R'RSSz"97")TTT 	.{{"P"Pl"P"P"PPPH%-N ]%/ ][S-@-@[[>[[\\\ %2  * 	53I 	((8888   
 (0A9d(S(STTL'55L >-n== ,$$ G G00>>DDFF ,$$ ; ;666666,,\:: "#&	# #  C $$57JDQQ$1BM)R)R$/EEKk4(( 	E-@K-O-O$/0C$D!(#78M#N#N  	 9%"E"E"G"G 9 $2#8S 0 #%%.%#1  "566 1;L;^ 1
 (9	 	5 	5A!T"" 
5  ####J'' 5  ,,,,L)) 55 $$Q\\5\%A%ABBBB  5 5 5$$Q\\^^4444455  	1'0C#$ .0JDQQN 9*8&' +-DdKKK 3'2#$
 ""35JDQQ 9%8!" C'
- @	' @	'IYd33FiD99Ggs++ +7==?? +&+&D&DV&L&L# !*gs++ `7==?? `fc** `v||~~ `$llnnGG!)Z>>C;>FwsFB777BHBEOwsK>>>4H#::8XsS]__GmmooG&y2DdKK.44 =<L<R<R<T<T =/4/M/Mf/U/U,,#< $GG$./?$E$EO  4    "$4!%.3!*!3!= 	 	G< I==E 5,// 33 % 0 0% 0 @ @$ 3 3 3 % 0 0 2 23+0(g&&&&&LJs6   $C: :
DD!)L1L?>L?$V;;WWr  r  c                h   t          | dd          }t          |t                    r|sdS d|fd|ffD ]w\  }}|st          t	          j        d| d|                    }|rG|d         }|d|                                          | d| ||                                d          }x|| _        dS )	u-  Point the cached system prompt's ``Model:``/``Provider:`` lines at
    the active runtime after a provider switch.

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

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

}%HuHHHr$((**++HHB"$Er2   fbtuple[str, str, str]c                   t          |                     d          pd                                                                          t          |                     d          pd                                          t          |                     d          pd                                                              d          fS )Nr  r   r  r  /)r7   rd   r   r   r   )rD  s    r0   _fallback_entry_keyrH  ^	  s    BFF:$"%%++--3355BFF7OO!r""((**BFF:$"%%++--44S99 r2   c                J   |                     d          pd                                                                }|dk    rdS 	 ddlm}  |d          pi }n.# t
          $ r!}dt          |          j         cY d}~S d}~ww xY w|                     d          }|                     d	          }t          |t                    o t          |                                          }t          |t                    o t          |                                          }	|s|	sd
S dS )zGReturn a skip reason for fallback entries known to be unusable locally.r  r   r8  Nr   )get_provider_auth_stateznous_auth_unreadable:access_tokenrefresh_tokennous_token_missing)rd   r   r   hermes_cli.authrJ  rC   r   rj   rc   r7   r   )
r@   rD  fb_providerrJ  staterD  access_valuerefresh_value
has_accesshas_refreshs
             r0   +_fallback_entry_unavailable_without_networkrU  f	  s?   66*%%+2244::<<Kft<;;;;;;''//52 < < <;tCyy'9;;;;;;;;<99^,,LIIo..ML#..M48J8J8L8L3M3MJ]C00PT-:M:M:O:O5P5PK $+ $##4s   A 
B#A?9B?Br  'FailoverReason | None'c                (   |t           j        t           j        t           j        hv rt	          t          | dd                    }t          | dd          pd                                                                }| j        pi 	                    d          pd                                                                }|r|rp||k    rjt          | dd          }|dz   | _
        t          dd	|z  z  d
          }t          j                    |z   | _        t          j        d|||dz  |dz              | j        t%          | j                  k    rt%          | j                  dk    rf|t           j        t           j        t           j        hvrAt          | dd          pd}t)          |t          j                    t*          z             | _        dS | j        | j                 }| xj        dz  c_        t-          |          }	t          | dd          }
|
t/                      }
|
| _        |	|
v r0t2                              d|	           |                     |          S |	                    d          pd                                                                }|	                    d          pd                                }|r|s|                     |          S t9          | |          }|rG|
                    |	           t2                              d|||           |                     |          S ddlm }m!} |"                    t          | dd          t          | dd          tG          t          | dd          pd                    }|"                    |||	                    d          pd          } |||          r>t2                              d|||j$        p|j%                   |                     |          S 	 ddl&m'} ddl(m)} |	                    d          pd                                pd} ||          }t	          tG          |	                    d          pd                                                    }d}|r5tG          |	                    d                                                    }n\|dk    rd}nS|rQ|*                    d                                          }|+                    d          stY          |          dk    rd}|r%t[          |d          r|sdd l.m/}  |d!          pd} |||d"|||#          \  }}|Et2                              d$|           |
                    |	           |                     |          S 	 dd%l0m1}  |||          }n4# td          $ r'}t2                              d&|||           Y d}~nd}~ww xY wtG          |j$                  }| 3                    |          }|s|dk    r|d'k    rd(}n|d)v rdd*l4m5}   | |          }n|*                    d                                          +                    d          stY          |          dk    rd}nq|rd}nl| 6                    |          rd(}nT| 7                    ||+          rd(}n:|d,k    s2tY          |          8                    d-          rt[          |d.          rd/}| j9        }!| j%        }"d| _:        || _9        || _%        || _;        || _$        || _<        t	          |	                    d0d                    | _=        t}          | d1          r| j?        @                                 d"| _A        t          | d2d          }#|#jt          |#dd          pd                                                                }$|$r1|$|k    r+t2                              d3|||$           d| _B        d| _C        t          | d2d          	 dd4lDmE}%  |%|          }&|&r7|&F                                r#|&| _B        t2                              d5||           n4# td          $ r'}'t2                              d6|||'           Y d}'~'nd}'~'ww xY wt          ||          }(|dk    rdd7lHmI})mJ}*mK}+ |dk    r|jL        p |*            pdn|jL        pd},|,| _L        |,| _M        || _N         |)|,| jN        |(8          | _O        |dk    r |+|,          nd| _P        d| _Q        i | _R        n}|jL        | _L        || _Q        t          |d9d          }-|-st          |d:d          }-|jL        |d;|-rd:t          |-          ini | _R        |( |(| jR        d<<   | T                    d=>           dd?lUmV}.  |.|            | W                    ||||@          \  | _X        | _Y        | Z                                 t}          | dA          r| j[        rddBl\m]}/ t          | jL        tF                    r| jL        nd}0 |/| j9        | j$        |0| j%        t          | dCd          t          | dDd          E          }1| j[        _                    | j9        |1| j$        t          | dFd          | j%        | j<        G           	 ddHl`ma}2 ddIlbmc}3  |3 |2            pi | j9                  | _d        t2                              dJ| j9        | jd                   n8# td          $ r+}4t2                              dK| j9        |4           Y d}4~4nd}4~4ww xY wt          | ||           | f                    dL| dM|            dN|! dM|" dO| dM| | _g        t2                              dP|!||           t          |            d"S # td          $ rV}5|dQk    r|
                    |	           t2          i                    dR||5           |                     |          cY d}5~5S d}5~5ww xY w)Su  Switch to the next fallback model/provider in the chain.

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

    Uses the centralized provider router (resolve_provider_client) for
    auth resolution and client construction — no duplicated provider→key
    mappings.
    _fallback_activatedFr  r   _rate_limit_backoff_countr   rr   <      i@8  zARate-limit backoff level %d: cooldown %d s (%.1f min, backoff#%d)_rate_limited_until_unavailable_fallback_keysNz/Fallback skip: %s previously marked unavailabler  zMFallback skip: %s/%s is not locally usable (%s); suppressing for this session)BackendIdentityshould_skip_candidater  )r  r  r  zUFallback skip: chain entry %s/%s resolves to the same backend as the current one (%s))resolve_provider_client)resolve_entry_api_keyr  r  	anthropicr  rG  z
/anthropiczapi.anthropic.comz
ollama.com)
get_secretOLLAMA_API_KEYT)r  	raw_codexexplicit_base_urlexplicit_api_keyr  z.Fallback to %s failed: provider not configured)normalize_model_for_providerz9Could not normalize fallback model %r for provider %r: %sr	  r  >   r8  r9  r:  )nous_api_mode)r  bedrockzbedrock-runtime.zamazonaws.comr  reasoning_echo_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)api_keyr  r?   fallback_timeout_applyr  )sync_credential_pool_entry_id)r  r  r  r  r  )get_model_context_length_config_context_length_custom_providers)r  rt  r  config_context_lengthcustom_providersrt  )r  r  r  rt  r  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)r8  z"Failed to activate fallback %s: %s)jr   
rate_limitbillingupstream_rate_limitr   r   r   r   _primary_runtimerd   rY  rn  r  	monotonicr\  r  rb  _fallback_indexr   _fallback_chainrm  _FALLBACK_EXHAUSTED_COOLDOWN_SrH  r$  r]  rF   r4  _try_activate_fallbackrU  addrG   agent.backend_identityr^  r_  buildr7   r  r  r  r`  hermes_cli.fallback_configra  r   r   r   r   agent.secret_scoperc  hermes_cli.model_normalizerh  rC   _is_azure_openai_urlhermes_cli.providersri  _is_direct_openai_url&_provider_model_requires_responses_apir   r  rx  requested_providerr  _reasoning_echo_flagr  rl  clearrX  rm  _credential_pool_entry_idagent.credential_poolrn  has_credentialsr   r  ro  rp  rq  rt  _anthropic_api_keyr  _anthropic_clientr  r  _client_kwargsrV   _replace_primary_openai_clientagent.agent_runtime_helpersrv  _anthropic_prompt_cache_policy_use_prompt_caching_use_native_cache_layout_ensure_lmstudio_runtime_loadedr  agent.model_metadatarw  rc   update_modelhermes_cli.configr|  hermes_constantsr}  r  rC  r  _pending_fallback_noticerx  r"   )6r@   r  fallback_already_activecurrent_providerprimary_providerbackoff_countbackoff_seconds_existing_cooldownrD  fb_keyunavailablerO  fb_modellocal_skip_reasonr^  r_  current_identfb_identr`  ra  fb_base_url_hintfb_api_key_hintfb_api_mode_explicitfb_api_mode	_orig_urlrc  	fb_client_resolved_fb_modelrh  	_norm_errfb_base_url_fb_is_azureri  	old_modelold_provider_existing_pool_pool_providerrn  fallback_poolrD  _fb_timeoutro  rp  rq  effective_key
fb_headersrv  rw  _fb_ctx_api_keyfb_context_lengthr|  r}  _reasoning_errrA  s6                                                         r0   try_activate_fallbackr  {	  s    .+^-C^Eghhh #'wu6KU'S'S"T"T#E:r::@bGGIIOOQQ"39r>>zJJPbWWYY__aa' 	-= 	BRVfBfBf $E+FJJM.;a.?E+!"](:";UCCO(,(8(8?(JE%LS"0DmVWFW   E$9 : ::: %&&**~8.:PR`Rtuuu!(0Eq!I!I!NQ(+"  #AA) )E% u		u4	5B	Q $$F%!=tDDKee+6(FOOO++F33366*%%+2244::<<Kw%2,,..H 4h 4++F333CE2NN 4[		
 	
 	
 ++F333 NMMMMMMM#))
B//eWb))WUJ339r:: *  M
 $$&&$$* %  H
 X}55 4&=#9#S]=S	
 	
 	

 ++F333
y4BBBBBB 	EDDDDDFF:..4";;==E//33  $Cz(:(:(@b$A$A$G$G$I$IJJ( 	3bffZ00117799KKK''
 /KK 	3(//44::<<I""<003$%566:MMM2
  	C 56F U U 	C^m 	C555555(j)9::BdO(?(?x4., 	)" )" )"%	%
 NN@   OOF###//777	OOOOOO33HkJJHH 	 	 	NNK+y       	 ),--11+>># '	17I(I(In,,/ GGG
 ?>>>>>+mH55""3''--//88FF1$[115HHH 3 1 1,,[99 1/==$ >   1 0	))!+..99:LMM *)+GG * 1K	~
 (,$$#. $$ &*"&&1A5*I*I%J%J"5,-- 	+"((***$(! !(:DAA%%nj"EEKRRTTZZ\\N 7.K"?"?Q>  
 *.&26/5,d33;;;;;;; )	+ 6 6  ]%B%B%D%D -:E*KKN#X      M3        3;II...ppppppppppVaepVpVpY.Q2I2I2K2KQr  xA  xI  xO  MOM)EM'4E$(3E%&<&<u8+' ' 'E# KVYdJdJd(F(F(FjoE%EL#%E   &-EM$EL !,=tDDJ I$Y0A4HH
$,'$ $ =GN%tJ'7'788B$E 
 &2=$Y/ 44<T4UUUMMMMMM%%e,,, 00$$$	 1   	B!5#A 	--/// 5.// 	E4L 	EEEEEE
 0:%-/M/MUemmSUO 8 8en'%.&-e5Mt&T&T!(0CT!J!J	! ! ! $11k0y"55 2   	555555AAAAAA%=%=#U[& &E" KK<U3     	 	 	LLY^       	 	&eX{CCC,, ,), ,	
 	
 	
0	 0 0 0 00 0"-0 0 	& 	0x	
 	
 	
 	E"""t 4 4 4&  OOF###98QGGG++F33333333	4s   Fn1 #V6 5n1 6
W' W"n1 "W''H2n1 A
a% $n1 %
b/bn1 bH"n1 9Al n1 
m!l<7n1 <mA.n1 1
p;Apppr   api_call_countc                   56                       d j         d           dt          j                     5d}dI 5fd}dd	lm} |}t          |d
|d           	                                  }g }|D ]}	|	                                }
 	                    |	|
           dD ]}|

                    |d           dD ]}|

                    |d           t          |
           |rl j        } j        dk    rCt           dd          }|0t          |dd          }|r|                    d          r|d         }                     |
|           |                    |
            j        pd} j        r|dz    j        z                                   }|r	d|dg|z   } j        rK|rdnd}t-           j                  D ]0\  }}|                    ||z   |                                           1                     |          }                     |          }|D ]<}
t5          |
t6                    r%d |
D             D ]}|

                    |d           =i }	 ddlm}m} n# t>          $ r d}d}Y nw xY w| | j         j                   nd}||u }|rdn|}d j!        v } j        pd                                "                                dk    o #                                }|r $                                nd}|s. #                                r j%         j%        |d<   nddd|d<   |rdd l&m'}  |            |d!<    j(        d"k    r )                    |          }|
                    d#d            *                    |          }  +                                }!|!,                    |           }"|"j-        pd                                }#n j        |d$}$|||$d%<    j.        -|$/                     0                     j.                             |||$d&<   tc                     }%i }&	 dd'l2m3}'  |' j                  }(|(:|(4                    t           d(d          |%pd j         j          j%        )          }&n# t>          $ r Y nw xY w|&r|/                    |&           |%rNd*|&vrJ j        pd                                "                                d+k    s 5                                r|%|d*<    j        d,k    r j        pd                                "                                d+k    s 5                                r\ j6        U j6        dk    rJ	 to           j6                  })n# tp          tr          f$ r d})Y nw xY w|)d-|)cxk    rd.k    rn n	d/|)d0g|d1<   |r||$d2<    j(        d3k    r +                                }*|*:                     j        |d j.         j%         j;         <                                t           d4d          5          }+t{           |+          }+ ||+ j>        d6          } |*,                    |  j;        7          },|,j-        pd                                }#ni ?                    d89          6 ||$6fd:d6          }  +                                ,                    |           },|,j-        pd                                }#|#rUd;|#v r4t          jA        d<d|#t          jB        =                                          }#|#rd>}t          |d?|#d           ntd@}#np j(        d"k    r )                    |          }|
                    d#d            *                    |          }- +                                }.|.,                    |-          }/|/j-        pd                                }#n j(        d3k    r +                                }0|0:                     j        |d j;         j.         j%         <                                t           d4d          A          }1t{           |1          }1 ||1 j>        d6          }-|0,                    |- j;        7          }2|2j-        pd                                }#n j        |d$}$|||$d%<    j.        -|$/                     0                     j.                             |||$d&<   |r||$d2<    ?                    dB9          6 ||$6fdCd6          }  +                                ,                    |           }2|2j-        pd                                }#|#rSd;|#v r4t          jA        d<d|#t          jB        =                                          }#|#rd>}t          |d?|#d           nd@}#nd@}#nL# t>          $ r?}3t          D                    dD|3           dE j         dFt          |3           }#Y d}3~3nd}3~3ww xY wddGlFmG}4 |4H                    5|H           n"# ddGlFmG}4 |4H                    5|H           w xY w|#S )JzSRequest a summary when max iterations are reached. Returns the final response text.u$   ⚠️  Reached maximum iterations (z). Requesting summary...ziteration-summary:failedretry_countrs   c                  ddl m} |                    | |t          t	          dd          pd          t          t	          dd          pd          t          t	          dd          pd          d|d	d
          S )Nr   	relay_llmr  r   r  r  r  iteration_summary)r  api_request_id	call_roler  T)rF  
model_namemetadatadefer_logical_completion)r@   r  execute_currentr7   r   )requestr.   r  r  r@   summary_api_request_ids       r0   _managed_summary_callz4handle_max_iterations.<locals>._managed_summary_call*  s    ######((WUJ33AzBB75'266<"==E:r22H6H  #90*  &* ) 
 
 	
r2   r   )MAX_ITERATIONS_SUMMARY_REQUESTuser)r  rQ  )rS  r   N)	tool_namer  r  	timestampr  r  last_aggregator_slotr  rX  r   r  systemrr   c                f    g | ].}t          |t                    |                    d           ,|/S )r  )rc   r7   r   )r   ks     r0   
<listcomp>z)handle_max_iterations.<locals>.<listcomp>  s<    $d$d$d1:a;M;M$dRSR^R^_bRcRc$dQ$d$d$dr2   r  r9  r  rS  Tmedium)enabledeffort)nous_portal_tagstagsr  r   )r  r   temperaturereasoning_effortr;  r>  )r>  r  r  r  r  r  
openrouterzopenrouter/pareto-coder  g      ?zpareto-router)r$   min_coding_scorepluginsr=  r  r  )r  r   r   r  r  r  r  r  )r  )strip_tool_prefixiteration_limit_summaryr  c                2     j         j        j        di | S Nr   r  r  r<   r  summary_clients    r0   r1   z'handle_max_iterations.<locals>.<lambda>  !    $JN$7$C$J$U$UW$U$U r2   z<think>z<think>.*?</think>\s*r  successr  z>I reached the iteration limit and couldn't generate a summary.)r  r   r   r  r  r  r  r  iteration_limit_summary_retryc                2     j         j        j        di | S r  r  r  s    r0   r1   z'handle_max_iterations.<locals>.<lambda>X  r  r2   z"Failed to get summary response: %sz"I reached the maximum iterations (z!) but couldn't summarize. Error: r  )outcome)r  rs   )I_safe_printmax_iterationsr  r  agent.context_compressorr  r   _should_sanitize_tool_callsr  _copy_reasoning_content_for_apir  r   r  r  r   rd   #_sanitize_tool_calls_for_strict_apire   r:  ephemeral_system_promptr   prefill_messagesr   insert_sanitize_api_messages#_drop_thinking_only_and_merge_usersrc   rV   r  r  r  rC   r  r  r   r  *_resolve_lmstudio_summary_reasoning_effortr  agent.portal_tagsr  r  _build_api_kwargsr  r  normalize_responserQ  r  rA  r  r-  r?  r<  rB  r  r  r  r   rx   r  r  r  rE  r  _ensure_primary_openai_clientrt   r  r  rF   rG   r7   r@   r  complete_logical_call)7r@   r   r  summary_call_outcomer  r  summary_request_needs_sanitizer~  r(  api_msginternal_fieldschema_foreign_sanitize_model_moa_client	_agg_sloteffective_system
sys_offsetidxpfminternal_key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_resultrA  r  r  r  s7   `                                                    @@r0   handle_max_iterationsr/  !  s   	]u/C]]]   A$*,,@@#
 
 
 
 
 
 
, HGGGGG4O8fIIJJJp
  ;;== &	) &	)ChhjjG11#w???"@ 2 2ND1111 #m 2 2ND1111 #7+++ Z #(+>U**")%4"@"@K".$+K9OQU$V$V	$ Aw)?)? A.7.@O99'9YYY(((( 6<"( 	c 06 9E<Y Y``bb 	\%-:JKKL|[L! 	B.5AJ%e&<== B BS##J$4chhjjAAAA 33LAA @@NN
 $ 	4 	4G'4(( 4$d$d$d$d$d 4 4LKKd3333	kkkkkkkkk 	 	 	+/(JJJ	
 ,7 )(enEEE 	
 %6$C!'@WttFW!U%:: ^!r((**0022j@ 74466 	 $.E<<>>>)- 	 $ 	(L(L(N(N 	%1272H";//  $&3 3";/  	8JJJJJJ)5v&>... 22<@@LWd+++$66|DD**,,G112BCCH&.4";;==NN ( N $/0D}-+%%e&=&=e>N&O&OPPP#/5I12 $C5#I#I !#::::::#7#7#G#G #/)9)J)J#*5,#E#E-A-IT#k!&).)? *K * *&     " >"))*<===# F
:L(L(L%2,,..4466,FF++-- G 2F":. 777^)r002288::lJJ//11 K 5A5;; ABBCC!:.   CCC?sc'8'8'8'8S'8'8'8'8'8.CHH5&y1 " B/A|,~!555,,..,,+)$/%*%;"6"'"@"@"B"B$U,A4HH - 	 	 APP#8#84 !$ $ $ 
 #(":":;K_d_x":"y"y"1"9"?R!F!F!H!H!&!D!D4 "E " " $9#8"UUUU !$ $ $ 
 #("6"6"8"8"K"KL\"]"]"1"9"?R!F!F!H!H M	bN**!#(@"n\^\e!f!f!f!l!l!n!n b'0$(^DD   
 "b ~!222$66|DD  $///!&!8!8!F!F!0022	&99.II
","4":!A!A!C!C#777..00"//+)"6$/%*%;"'"@"@"B"B$U,A4HH 0 	 	 B%RR!6!64 !" " "
 !( : :>]b]v : w w"/"7"=2!D!D!F!F #[ ," " (34HN=1#/"))%*A*A%BR*S*STTT'39MN#56% F3EN<0!&!D!D: "E " " $9#8"UUUU !$ $ $ 
 !& 4 4 6 6 I IJZ [ ["/"7"=2!D!D!F!F b..%'V,Db.`b`i%j%j%j%p%p%r%rN! f+4(" !,HH   
 &fNN!a ~ ~ ~;Q???}e>R}}uxyzu{u{}}~ 	$#####''"( 	( 	
 	
 	
 	
 	$#####''"( 	( 	
 	
 	
 	

 s   Hf7 "I+ *f7 +I<9f7 ;I<<G f7 =AR f7 
Rf7 RCf7 *U? >f7 ?Vf7 VP!f7 6h! 7
h 5g;6h! ;h  h! !i task_idc                   	 t          |          r | j        rt          j        d| d           n!t	                                          |           n:# t          $ r-}| j        rt                              d||           Y d}~nd}~ww xY w	 d}	 ddl	m
}  |            }n<# t          $ r/ t          t          j                            d                    }Y nw xY w|r#| j        rt          j        d	| d           dS dS t	                                          |           dS # t          $ r4}| j        r"t                              d
||           Y d}~dS Y d}~dS d}~ww xY w)a  Clean up VM and browser resources for a given task.

    Skips ``cleanup_vm`` when the active terminal environment is marked
    persistent (``persistent_filesystem=True``) so that long-lived sandbox
    containers survive between turns. The idle reaper in
    ``terminal_tool._cleanup_inactive_envs`` still tears them down once
    ``terminal.lifetime_seconds`` is exceeded. Non-persistent backends are
    torn down per-turn as before to prevent resource leakage (the original
    intent of this hook for the Morph backend, see commit fbd3a2fd).

    Skips ``cleanup_browser`` in headed mode so the browser window stays
    visible between turns. The inactivity reaper in
    ``browser_tool._cleanup_inactive_browser_sessions`` still handles
    idle sessions.
    z0Skipping per-turn cleanup_vm for persistent env z; idle reaper will handle it.z$Failed to cleanup VM for task %s: %sNFr   )_is_headed_modeAGENT_BROWSER_HEADEDz5Skipping per-turn cleanup_browser for headed session z)Failed to cleanup browser for task %s: %s)r   r  r  r4  rN   
cleanup_vmrC   rF   rG   tools.browser_toolr2  r   rI  ra  rd   cleanup_browser)r@   r0  rA  headedr2  s        r0   cleanup_task_resourcesr8  {  s    OW%% 	&$ 3w 3 3 3  
 EEW%%% O O O  	ONNA7ANNNOT	B::::::$_&&FF 	B 	B 	B"*..)?@@AAFFF	B 	+$ 3G 3 3 3      EE!!'***** T T T  	TNNFQRSSSSSSSSS	T 	T 	T 	T 	T 	TTsZ   AA 
B
#BB
D& B" !D& "6CD& C$D& !D& &
E$0#EE$dropped_tool_namesc                   t          | |d|          }t          d|t                    }t          t          ||g||pd          S )a  Build a partial-stream-stub response for mid-stream drop scenarios.

    Used when the SSE stream ends without a ``finish_reason`` after
    delivering content (text-only drops, tool-call-arg drops).  The stub
    is tagged ``PARTIAL_STREAM_STUB_ID`` with ``FINISH_REASON_LENGTH`` so
    the conversation loop enters its continuation/retry path instead of
    silently accepting truncated output as a complete turn (#32086).
    Nr  rQ  rT  rR  r   r   ra   r   r$   r  rO  usage_dropped_tool_names)r   r   r
   )r  full_contentfull_reasoningr  	usage_objr:  mock_messagemock_choices           r0   _build_partial_stream_stubrF    sr     #(	  L "*  K
 !.6$   r2   )r  c                  )*+,-./0123456789:;<=>?@ABCDEFGHIJ  j         rt          d          dd>d fd3d fd2t                     r                               S  j        dk    r _         3             	                                } 2 >|          dd           |d _        S # t          $ r!} 2ddt          |                      d}~ww xY w# d _        w xY w j        dk    r>dddHddiAddi@t          j                    }d|i)ddi*	                    dd          }t                     }t                      Afd4)*4 @Hfd} 3             	 t          j        t          |          d          }	|	                                 |	                                r|	                    d            j         rLt%           t          j                    |z
  *d                    t'          |	d !           t          d"          t          j                    )d         z
  }
|
|k    rt(                              d#|
||	                    d$d%                                          d&t/          |
           d'	                    d$d%           d(           t1                      	 d)d*lm}  ||           n2# t          $ r%}t(                              d+|           Y d}~nd}~ww xY wt          j                    )d<   t                      t9          d,t/          |
           d-t/          |           d.          Hd
<   n|	                                 j         r;t%           t          j                    |z
  *d                    t          d/          Hd
         Hd
         Hd0         t;                       2 >Hd0                   dd           Hd0         S # t          $ r!} 2ddt          |                      d}~ww xY wddg d1Ht                      dddd2Ed3d4iFt          j                    Gd3di6d4d5dEFGfd78d8 ==EFGfd99d=fd;0d0 EFGfd</ddiAddi@ddiDdt          j                    iBd?t          j                    Id)t?                      d)d)d=Jd>diCdCfd@7dCfdA.dDIJfdC:dIJfdD-dIJfdF;dIJfdG<dIJfdH1AfdI5d.15789;<? @BDEHfdJ,.57 @BEfdK++,-./2368:> @ADEHfdL}tA           j!         j"                  }||}ntG          dMdN          }|dNk    r j$        rtK           j$                  rdO}	 d)dPl&m'}  |            }tQ          |tR                    r|	                    dQ          nd}tQ          |tR                    r@|	                    dR          }tQ          |t.          tT          f          rtU          |          }n# t          $ r Y nw xY wtG          dS|          ?t(                              dT j$        ?           nutW                    }|dUk    rtY          |dV          ?n|dWk    rtY          |dX          ?n|?d)dYl-m.}  |	                    dZ                    }|tY          ?|          ?t          j        t          |          d          }	|	                                 t          j                    }d[}|	                                r|	                    d           t          j                    }||z
  |k    r|}t/          |Bd         z
            }||k    r_?'?tU          d\          k    rd]t/          ?           d^}nd} /                    d_	                    dZd`           da| db| dc           n 0                    dd| de           t          j                    Bd         z
  }
|
?k    r*tW                    }t(                              df|
?	                    dZd%          |dg                                dht/          |
           d'	                    dZd%           di|dgdj           	  -dk            /dk           n# t          $ r Y nw xY wt1                       j        dlk    rn	 t          j                    Bd<    /                    dmt/          |
           dn            0                    dot/          |
           dp            j         r|
?k    rt%           |
@d                    d6d3<   t(                              dq           	  -dr            /dr           n# t          $ r Y nw xY wt'          |	ds!           t          dt          |	                                 j         rt          du          Hd
         3@d         r"tc           dvd          pd2                                pd}tg          H	                    dw          pg           }|rdx                    |ddy                   } ti          |          dyk    r| dzti          |          dyz
   d{z  } d||  d}}!|pd|!z   }	  5                    |!           n# t          $ r Y nw xY wt(                              d~|ti          |pd          Hd
                    tl          }"n8t(                              dti          |pd          Hd
                    tl          }"to          d|dd          }#d}$	 d)dl8m9}%m:}&  |%Hd
         t          tc           dd          pd          t          tc           dZd          pd                    }'|'j;        |&j<        k    }$n# t          $ r d}$Y nw xY wto          tz          tc           dZd%          to          d)|#|"          gd|pd          }(|$rd|(_>        t;                      |(S Hd
         Hd0         t;                      Hd0         S )u  Streaming variant of _interruptible_api_call for real-time token delivery.

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

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

    Falls back to _interruptible_api_call on provider errors indicating
    streaming is not supported.
    z+Agent interrupted before streaming API callr8   r7   c                Z   	 t          | dd           }t          |t          t          f          r
|r|d         nd }t          |dd           }t          |dd           }t          |t                    r|S n# t
          $ r Y nw xY w	 t          | dd           }t          |t                    r|S t          |t                    rWg }|D ]=}t          |dd           }t          |t                    r|                    |           >d                    |          S n# t
          $ r Y nw xY wdS )NrO  r   ra   rQ  rh   r   )r   rc   r   tupler7   rC   re   rD   )rY   rO  first_choicera   rQ  rg   partrh   s           r0   _stream_final_textz<interruptible_streaming_api_call.<locals>._stream_final_text  sb   	h	488G)3GdE])K)KaPWa71::]aLlIt<<Ggy$77G'3''  	 	 	D		h	488G'3'' '4(( &# + +D"466D!$,, +T***wwu~~%&  	 	 	D	rs+   A1A5 5
BB'D .A+D 
D('D(r9   c                 F    t          dd           } |  |              d S d S )N_emit_stream_startr   )emitr@   s    r0   rN  z<interruptible_streaming_api_call.<locals>._emit_stream_start  s2    u2D99DFFFFF r2   
final_textfinishedr   r"   
str | Nonec                N    t          dd           }| || ||           d S d S )N_emit_stream_endrQ  rR  r"   rO  )rQ  rR  r"   rP  r@   s       r0   rU  z:interruptible_streaming_api_call.<locals>._emit_stream_end  s@    u0$77DJGGGGGG r2   r  TNrV  r   Fr  r-  r  rL  ru  r  r  c                 f     d         s%r%d d<   	               d S # t           $ r Y d S w xY wd S d S Nr  TrC   first_delta_firedr  s   r0   _fire_firstz5interruptible_streaming_api_call.<locals>._fire_first6  sq    $V,  ,0!&)"N$$$$$    DD	      
 
,,c                 4   d } 	 ddl m} ddlmmmmmm g dd id/fd}fd}fd	}fd
}fd}d0fd}d1fd}	 ddl	m
}	  |	            }
n.# t          $ r! t                              dd           d}
Y nw xY w|                    t                    |t!          t#          dd          pd          t!          t#          dd          pd          t!          t#          dd          pd          ||j        d |d d t#          d!d           t#          d"d          rd#n't'          t#          d$d          pd          dk    rd%nd&d'd(          }  d)| i                                r|nd |j        s	j        s|
r|nd fd*fd+,          }| j        p|d-<   n# t          $ r}|d.<   Y d }~nd }~ww xY w| |                                  d S d S # | |                                  w w xY w)2Nr   r  )r  r  r   is_streaming_access_denied_errorr  stream_converse_with_callbacksro   next_api_kwargsdict[str, Any]c                
   t          |           }|                    dd          }|                    dd             |          }	  |j        di |}n# t          $ r} 
|          rdd_                            d           t                              dt          |          j	                     |j
        di |          cY d }~S  	|          r |            d }~ww xY w|                    dg           S )	Nr  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   r   )rV   r  converse_streamrC   _disable_streamingr  rF   rb  r   rj   r  rd   )ra  final_kwargsr  r  r  r  r  r@   r  r  r_  r  s         r0   _open_bedrock_streamzUinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._open_bedrock_streamM  sx   #'#8#8L)--.BKPPF $$%;TBBB88@@F'=v'='M'M'M'M$   
 <;LII 7;E4!--!V  
 #KK!S $\ 2 2 ;  
 $?#> / ? ?, ? ?$ $       54\BB >55f===-. (++Hb999s%   	A 
C,!A)C'
C,C''C,c                Z    dd<                                      |            dd<   d S NTrL  )_fire_stream_delta)rh   _bedrock_response_startedr\  r@   deltas_were_sents    r0   _on_textzIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_textm  s>    7;-e4KMMM,,T222.2$U+++r2   c                P    dd<                                      |            d S ri  )_fire_tool_gen_started)rF  rk  r\  r@   s    r0   _on_toolzIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_tools  s3    7;-e4KMMM0066666r2   c                P    dd<                                      |            d S ri  )_fire_reasoning_delta)rh   rk  r\  r@   s    r0   _on_reasoningzNinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._on_reasoningx  s3    7;-e4KMMM//55555r2   c                 8     dt                     i          S Nr   )r   )intercepted_eventsr`  s   r0   _finalize_bedrock_streamzYinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._finalize_bedrock_stream}  s)    99!4(:#;#;<  r2   _streamr   r8   r9   c                ,    t                    d<   d S Nro   )r   )rx  r@   writer_tokens    r0   _bedrock_stream_createdzXinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._bedrock_stream_created  s    ,?,F,FL)))r2   _eventr   c                <    d         }|d u pt          |          S rz  )r   )r}  tokenr@   r{  s     r0   _accept_bedrock_eventzVinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>._accept_bedrock_event  s'    (1E D=R,DUE,R,RRr2   )#has_reasoning_stream_observer_hooksz-plugin reasoning stream observer check failedTr1  Fr>  r   r  rj  r  c                    | S r+   r   )rL  s    r0   r1   zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>  s     r2   c                >    t          t          | dd                     S NrO  )r   r   r   s    r0   r1   zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>  s!    $)T::C C r2   r  _current_api_request_idis_subagent	delegatedr  fallbackprimaryr  r  r  )r>  rF  r  	finalizeron_stream_createdon_chunkchunk_adapteraccept_chunkcompleted_response_predicater  r  r   c                      j         S r+   )r  rs  s   r0   r1   zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>  s
    u/I r2   c                 R                          dt          j                              S )Nru  )__setitem__r  )_bedrock_last_events   r0   r1   zIinterruptible_streaming_api_call.<locals>._bedrock_call.<locals>.<lambda>  s    %8%D%DS$)++%V%V r2   )on_text_deltaon_tool_starton_reasoning_deltaon_interrupt_checkon_eventrY   r"   ra  rb  )rx  r   r8   r9   r}  r   r8   r   )r@   r  r  r  r  r  r_  r  r`  agent.plugin_stream_hooksr  rC   rF   r4  r   rV   r7   r   re   rs   _has_stream_consumersr  r  r"  close)r   r  rg  rm  rp  rs  rw  r|  r  r  plugin_reasoning_observerstreamed_responserA  r  rv  r  r  r_  r  r`  r{  r  rk  r\  r@   r  rl  rC  s                @@@@@@@@r0   _bedrock_callz7interruptible_streaming_api_call.<locals>._bedrock_call>  s   F}#++++++                &(" ': : : : : : : : : : :@3 3 3 3 3 3 3 37 7 7 7 7 7 7
6 6 6 6 6 6 6
     
G G G G G G GS S S S S S S6]]]]]]0S0S0U0U--  6 6 6LL!P[_L```05---6 #))$$("75,#C#C#IrJJWUJ;;HyII"75'2#>#>#D"EE6&=/6"5"5!62 2 %-*1!#<d+ +
  'umUCC+KK  #752CQ#G#G#L1MMPQQQ ",!*  .27 *  : %C$Bv&.3.I.I.K.K"U((QU"*/(383N(Rk(}}'I'I'I'IVVVV	% 	% 	%! &,%:%O>Oz"" $ $ $"#w$ %LLNNNNN &%6%LLNNNN &sU   AG A0 /G 0(BG BD,G G> 
G!GG> G!!G> >HrP  rQ  r>   r\  zBedrock streamingr^  z)Agent interrupted during Bedrock API calluk   Bedrock stream stale for %.0fs (threshold %.0fs) — no events received. region=%s model=%s. Aborting call.r  r  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.z7Agent interrupted during Bedrock API call (post-worker)rY   )rY   r"   partial_tool_names)r  diagr.  ro   r   r  r  c               |    5  | d<   |d<   t          j                    d<   d d d            n# 1 swxY w Y   | S r0  r1  r3  s     r0   r6  z=interruptible_streaming_api_call.<locals>._set_request_client<  s      	G 	G.4!(++/(1:1D1F1F!+.		G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G
 r7  c                    t          | dd           }t          |          r|S t          | dd           }t          |dd           }t          |          r|S d S )Nr  rY   )r   r   )r   r  rY   s      r0   _stream_close_callablez@interruptible_streaming_api_call.<locals>._stream_close_callableD  s`    ..E?? 	L6:t44'400E?? 	Ltr2   c                     |           | S 5  | d<   dd<   t          j                    d<   d d d            n# 1 swxY w Y   | S )Nr  r   ro   r.  r1  )r   r  r4  r5  r  s    r0   _set_request_stream_handlezDinterruptible_streaming_api_call.<locals>._set_request_stream_handleN  s     "!&))1M  	G 	G.4!(++3(1:1D1F1F!+.	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G s   !>AAr  c                     |           }|d S 	  |             t                               d|           d S # t          $ r'}t                               d||           Y d }~d S d }~ww xY w)Nz%Streaming response handle closed (%s)z/Streaming response handle close failed (%s): %s)rF   rb  rC   r4  )r   r  r  rD  r  s       r0   _close_request_stream_handlezFinterruptible_streaming_api_call.<locals>._close_request_stream_handle\  s    &&v..=F	EGGGKK?HHHHH 	 	 	LLA        	s   %9 
A*A%%A*c                h   	5                       d          }                     dd          }                     d          }|dk    o|d uo|d uo|t          j                    k    }|rW                     dd          dk    r                    ||            n                    ||            	 d d d            d S d d<   d d<   d d d            n# 1 swxY w Y   |d S |dk    r ||            d S |dk    r                    ||            d S                     ||            d S )Nr  ro   r   r.  r   r  r  r9  )
r  r  request_kindr.  r<  r  r@   r4  r5  r  s
        r0   r=  zDinterruptible_streaming_api_call.<locals>._close_request_client_oncej  s   
 ! 	6 	6266x@@N.227HEEL-11+>>I ( 7"$.7T)7 !4!6!66	   
 '**7H==AUUU99&v :     66~f6UUU1	6 	6 	6 	6 	6 	6 	6 	62 /3!(+15!+.5	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	66 !F 8##((@@@@@11111.1PPPPP..~f.MMMMMs   B2C
CC C)r   r  discarded_chunksdiscarded_bytesr   r   c                    | d<   | S ru  r   )r   managed_stream_holders    r0   _set_managed_streamz=interruptible_streaming_api_call.<locals>._set_managed_stream  s    *0h'r2   c                                          dd           } | d S t          | dd           }t          |          r:	  |             d S # t          $ r  t                              dd           Y d S w xY wd S )Nr   r  z&Managed provider stream cleanup failedTr1  )r  r   r   rC   rF   r4  )r   r  r  s     r0   _close_managed_streamz?interruptible_streaming_api_call.<locals>._close_managed_stream  s    &**8T::>F..E?? 	VV V V VEPTUUUUUUV	V 	Vs   
A	 	&A32A3rs   c                     5  dxx         dz  cc<   t          d                   } d d d            n# 1 swxY w Y   dd<   | S )Nr   rr   FrL  )rs   )
attempt_idprovider_tool_in_flightstream_attempt_lockstream_attempt_states    r0   _start_stream_attemptz?interruptible_streaming_api_call.<locals>._start_stream_attempt  s      	> 	> +++q0+++1)<==J	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> */&s   &6::c                    5  t                              d          pd          }|rd                             |           d d d            n# 1 swxY w Y   |rt                              d||            d S d S )Nr   r   r  z&Marked stream attempt %s cancelled: %s)rs   rd   r  rF   r4  )r  r   r  r  s     r0   _cancel_current_stream_attemptzHinterruptible_streaming_api_call.<locals>._cancel_current_stream_attempt  s      	? 	?.229==BCCG ?$[155g>>>	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	?  	LL8    	 	s   AAAAstream_attempt_idc                    5  | t                              d          pd          k    o	| d         v	 cd d d            S # 1 swxY w Y   d S )Nr   r   r  )rs   rd   r  r  r  s    r0   _stream_attempt_is_activezCinterruptible_streaming_api_call.<locals>._stream_attempt_is_active  s      	 	!S)=)A)A))L)L)QPQ%R%RR O%-A+-NN	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   3AAAc                P    5  | d         v cd d d            S # 1 swxY w Y   d S )Nr  r   r  s    r0   _stream_attempt_was_cancelledzGinterruptible_streaming_api_call.<locals>._stream_attempt_was_cancelled  s      	J 	J$(<[(II	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	Js   
c                   	 t          t          |                    }n# t          $ r d}Y nw xY w5  dxx         dz  cc<   dxx         |z  cc<   d         }d         }d d d            n# 1 swxY w Y   |dk    rt                              d| ||           d S t                              d| ||           d S )Nr   r  rr   r  z[Discarding chunk from superseded stream attempt %s (discarded_chunks=%s discarded_bytes=%s)zUDiscarded stale stream chunk from attempt %s (discarded_chunks=%s discarded_bytes=%s))r   reprrC   rF   rG   r4  )r  rL  chunk_bytesr  r  r  r  s        r0   _discard_stale_stream_chunkzEinterruptible_streaming_api_call.<locals>._discard_stale_stream_chunk  si   	d5kk**KK 	 	 	KKK	  	F 	F !34449444 !2333{B33334FG23DEO		F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F
 q  NN;!      LL;!     s     //1A11A58A5c                 f     d         s%r%d d<   	               d S # t           $ r Y d S w xY wd S d S rX  rY  rZ  s   r0   _fire_first_deltaz;interruptible_streaming_api_call.<locals>._fire_first_delta  sq     ( 	^ 	(,f%        		 	 	 	r]  c                `   :;<=>?@ABCDEFGHI ddl =t          Sj        Sj                  }||nt	          dd          :||>nt	          dd          >>dk    r?Sj        r8t          Sj                  r$:>t                              dSj        >           n>>dk    r8R6Rt          d          k    r#R>k    rR>t                              d	>           |t          :d
          nd;g Bi Ht                      }i }i }dCdDdGg FdIS                                <<Xd<   ddi?ddi@ddiAdh:;=N>S@Vfd}di<?SAfd}djP?STVW fd}dkBCDFGHIfd}ddlm}	  M|	                    T|t!          t#          Sdd          pd          t!          t#          Sdd          pd          t!          t#          Sdd          pd          |||d  d!t#          Sd"d          t#          Sd#d$          rd%n't%          t#          Sd&d          pd          dk    rd'nd(d)d*+                    }
Sj        d,k    r O|
           g ELSUEHfd-}t'          |
Afd./          D ]_}t)          j                    Vd0<   S                    d1           	 t%          <                    d2d                    d3z   <d2<   <                    d4          Vd0         <d4<   	 t%          <                    d5d                    t/          |          z   <d5<   n# t0          $ r Y nw xY wn# t0          $ r Y nw xY wSj        rJ	 |
                                 n1# t0          $ r$ @d         }|S                    |d67           Y nw xY w n? P           s K |           ;|j        st;          |d          r|j        r|j        Dt;          |d8          r|j        r|j        It#          |d9d          }t#          |d:d          }|s|rZt?          ||d;          ptA          |          }tC          |tE          |pd<t!          |p|          d;|          | d=| >           |j        d         j#        }t;          |d          r|j        r|j        Dt#          |d?d          pt#          |d@d          }|rNtI          FrFdA         nd|          }F%                    |            L             S&                    |           t#          |dBd          }|rB%                    |           HsEstO          |j(                  rLE%                    |j(                   d)                    E          }tO          |          r" |             . L             S*                    |           d*UdC<   nCSj+        r<	 S+                    |           S,                    |           n# t0          $ r Y nw xY wt#          |dDd          }|rw |             |D ]i}t#          |dEd          }||nd}t#          |dFd          pd}||vr|||<   |r)||v r%|||         k    rt[          HdAG          d3z   }|||<   |r|||<   ||         }|HvrDt#          |dFd          }t]          |t$                    rt!          |          }|pddHdddIddJH|<   H|         }t#          |dFd          }|-|}t]          |t$                    rt!          |          }|r||dF<   t#          |dHd          } | rGt#          | dKd          }!|!r|!|dH         dK<   t#          | dLd          }"|"r|dH         dLxx         |"z  cc<   t#          |dMd          }#|#Ft;          |dN          r6t]          |j/        t`                    r|j/        ni                     dM          }#|#Qt;          |#dO          r<	 |#1                    d$P          }#n$# td          $ r |#1                                }#Y nw xY w|#|dM<   |dH         dK         }$|$rS||vrO|3                    |            L             S4                    |$           YdQ         %                    |$           kt#          |j        d         dRd          }%|%r|%Ct;          |d8          r|j        r|j        Ia J              Q           r=5                    dS  dT          |
j6        |
j6        }&t          7                    dUSj        pdVSj        pdV           d*S_8        |&j        }'t]          |'tr          tt          f          r
|'r|'d         nd}(t#          |(dWd          })|)t#          |)d?d          pt#          |)d@d          }t]          |t                     r!|r L             S&                    |           t#          |)dBd          }*t]          |*t                     r!|*r L             S*                    |*           |&S d)                    B          pd}+d},d$}-Hrg },tw          H          D ]}H|         }.|.dH         dL         }/|.dH         dK         pdX}0|/rZ|/<                                rF	 t{          j>        |/           n4# tz          j?        $ r t          |/|0          }1|1dYk    r|1}/nd*}-Y nw xY wCd*}-|,%                    t          |.dF         |.dZ         |.                    dM          t          |.dH         dK         |/I          [                     CBsFsHst          d\          |-oCdu }2|2rbHfd]tw          H          D             }3t          C                    d^|3           t          G|+d)                    F          pdDI|3pd_          S Cdu oBoH }4|4rBt          C                    d`           t          G|+d)                    F          pdDI          S Cpda}5|-rdb}5t          |+pd|5t#          |
dcd          /          }6|6|6 |             d)                    F          pd}7t          G|+|,|7d          }8t          d|8|5e          }9t          dft!          t          jG                              z   D|9gIg          S )lz#Stream a chat completions response.r   NHERMES_API_TIMEOUTg      @HERMES_STREAM_READ_TIMEOUTrF  uD   Local provider detected (%s) — stream read timeout raised to %.0fsr  uV   Cloud reasoning stream — read timeout raised to %.0fs to match stale-stream detectorr  ry  r  r  ro   ra  rb  c                H   i | d                               d}t          j                  sddi|d<                        d|                    }|	d<   t	          j                    
d	<                       d
            |j        j        j        di |S )NTr  )r   r?   include_usagestream_optionschat_completion_stream_requestr  ro   ru  z)waiting for provider response (streaming)r   )	r  r   r  r  r  r  r  r  r<   )ra  stream_kwargsr  _base_timeout	_conn_capr  r6  _stream_read_timeoutr@   attempt_request_clientlast_chunk_times      r0   _open_streamzVinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>._open_streamC  s    	!	!>>%-'"	 *  	 	 	M -U^<< J3BD2I./0033;, 4   N /="7+#'9;;OC !!"MNNN9>&29JJMJJJr2   
raw_streamr   r8   r9   c                   t          | dd           }|d<                       |                               |                               |                               |           t                    d<   d S )NrY   ro   )r   _capture_rate_limits_capture_credits_stream_diag_capture_response_check_openrouter_cache_statusr   )r  rY   _diag_writer_tokenr@   attempt_stream_responses     r0   _stream_createdzYinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>._stream_created\  s    z:t<<H/7#G,&&x000""8,,,//x@@@00:::%8%?%?M'"""r2   _chunkr   c                   	 t          | dd           }|rt          |d         dd           nd }t          |dd           rd	d<   n# t          $ r Y nw xY w 
          sdS d         }|At          |          s1t                              d	                    d
d                     dS t          j                    d<   dS )NrO  r   rP  rT  TrL  Fro   zxStreaming attempt superseded by a newer stream; stopping consumption to preserve the single-writer invariant (model=%s).r  r  ru  )r   rC   r   rF   rG   rd   r  )r  rO  rP  r  r  r  r@   r  r  r  r  s       r0   _accept_stream_chunkz^interruptible_streaming_api_call.<locals>._call_chat_completions.<locals>._accept_stream_chunke  s    !&)T::>EO
GT:::45,55 :59+E2   ,,->?? u!'*E )A%)O)O " NN7I66	   u
 $(9;;OC 4s   AA 
AAc                     fdt                    D             } d                              pd d                              pd | pd dpddgdS )Nc                     g | ]
}|         S r   r   )r   r   tool_calls_accs     r0   r  zsinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>._relay_final_response.<locals>.<listcomp>  s    TTTE./TTTr2   r   )r  rQ  rR  rT  stop)ra   r   )r  rO  r?  )r  rD   )rT  content_partsr   r  reasoning_partsr  r  rC  s    r0   _relay_final_responsez_interruptible_streaming_api_call.<locals>._call_chat_completions.<locals>._relay_final_response  s    TTTTVN=S=STTTJ# %)')ww}'='='E131I1I1QT*4*<	$ $ *7)@& 
 #  r2   r  r>  r   r  r  c                "    t          | d          S r  )r  r   s    r0   r1   zRinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>.<lambda>  s    75);T;T r2   r  r  r  Fr  r  r  r  r  T)	r>  rF  r  r  r  r  r  r  r  r  c                 B   sd S t                    }                                  s+| D ]&}                                  |           dd<   'd S j        r@| D ]?}	                     |                               |           .# t
          $ r Y :w xY wd S d S ri  )r   r  rj  r  _record_streamed_assistant_textrC   )pending_partsrh   r  r@   rl  pending_text_partsr  s     r0   _flush_pending_stream_textzdinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>._flush_pending_stream_text  s    %  !344M$$&&&! ) 3 3D%%''',,T222.2$U++* )  D33D999==dCCCC$     s   "*B
BBc                      d         S rz  r   )r  s   r0   r1   zRinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>.<lambda>  s    4W= r2   r   ru  receiving stream responsechunksrr   first_chunk_atbytesinterrupt_stream_close_failedr  r?  
error_typeerror_messager   provider_in_stream_errorrb   )rS   rU   rW   rR  rS  r=  rQ  rL  rT  r   r$   )rG  rU  r  )r$   r   rU  r  rF  rV  r  r  r  r  r  r   zstream attempt z was supersededz}Streaming request returned a final response object instead of an iterator; switching %s/%s to non-streaming for this session.r  ra   ?r  r   )r$   r   r  rU  zlProvider returned an empty stream with no finish_reason (possible upstream error or malformed SSE response).c                <    g | ]}|         d          d         pdS )rU  rF  r  r   )r   r  r  s     r0   r  zTinterruptible_streaming_api_call.<locals>._call_chat_completions.<locals>.<listcomp>.  s=         $Z08?C  r2   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.r9  zkStream ended with no finish_reason after delivering text with no tool calls; treating as a mid-stream drop.r  lengthrY   r<  r=  zstream-)r$   r  rO  r?  r  r  r   r8   r9   )r  r   r8   r   )r8   rb  )Hr  r   r  r  r   r  r   rF   r4  r  rn  r$  _stream_diag_initr@   r  r   r7   r   rs   r   r  r  rd   r^  rC   r  r  r  rO  r  r?  r   rz   rP   r   rP  r   re   rr  r   rQ  rD   rj  r  r  rm  rc   r  rV   r  r   r  ro  RemoteProtocolErrorr"  rb  re  r   rI  r  r   r   r   r   r   r   r   rG   rF  r   r  r  )Zr  _provider_timeout_cfgtool_gen_notified_last_id_at_idx_active_slot_by_idxr  r  r  r  r  r   r  rL  r  	_err_type_err_msg_statusrP  r"  delta_contentpending_textdelta_tool_callstc_delta	raw_indexraw_idxdelta_idnew_slotr  _tc_identrytc_id_new_idtc_functionfunction_namefunction_argumentsr7  rF  chunk_finish_reasonr"  rO  rJ  ra   rQ  rA  mock_tool_callshas_truncated_tool_argsr[  rV  r  repaired_tool_args_dropped_no_finish_dropped_names_text_only_dropped_no_finisheffective_finish_reasonr   rB  rD  rE  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  rC  r  r  r  r  r6  r  r  r  _stream_stale_timeoutr@   r  rl  r  r  r4  rC  sZ   `                                                         @@@@@@@@@@@@@@@@r0   _call_chat_completionsz@interruptible_streaming_api_call.<locals>._call_chat_completions  s    !=U^U[ Y Y %0 "!/88 	 !,#8  #,-I5#Q#Q 
 $u,,,DUV[VdDeDe,'4$ZN$8   
 %--)5)U5\\99),@@@ (=$23G   1F0QCt,,,W[	 !!$
 !#$&
 "	''))(-f% $")4#*D/	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K2	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@	 	 	 	 	 	 	 	 	 	 	 	>	 	 	 	 	 	 	 	 	 	 	 	$ 	$#####$$wulB??E2FF
B77E:FFwugr::@bAA/"11-T-T 2&-e5NPT&U&U #5-??' wu.?CCHqIIAMM (Z&
 
 *.+   
 
2 >U"" '&v...(*	 	 	 	 	 	 	 	 	& 2====
 
 
 c	( c	(E $(9;;OC !!"=>>>
"%eii!&<&<"="="Ah99-..6.=c.BE*+%(7A)>)>%?%?BWX]B^B^%^E'NN    D    ) LLNNNN  
 
 

 &<G%DN%1::*#B ;   
 ,,->?? ++,=uEEE= 5'** -u{ -!&J5'** ,u{ , %I $E<>>	"5/4@@  7!*x@@  <0;;  .$+1(1(O5O+.x/@5+A+A  $  %.!;!;!;!;
 
 
 
 M!$*Eug&& )5; )"[
 %U,?FFk'RWYdfjJkJkN <
 "A+:BOB''"" "  &&~666!!###++N;;; $E9d;;M $$]333% ) !-Mem-\-\ !*11%-@@@')ww/A'B'B;LII %$22444 %%''',,];;;.2$U++ 0 33MBBB==mLLLL$     'ulDAA PB**,,, 0 NB NBH ''4 @ @I+4+@iiaG&xt<<BH &9997>+G4 @#66$(@@@#&~r#B#B#BQ#F7?+G4 <3;0-g6C.00!(4!>!>%fc22 1%([[F"(,B$.13"(E(E-1	/ /s+ +3/E#HdD99E("'%gs33 3&)'llG" 2*1E$K")(J"E"EK" Q(/VT(J(J( 	F 9FE*-f5-4[+t-T-T*- Q!*-k:::>PP:::#HotDDE}=)I)I}9CHDXZ^9_9_!g!5!5eg l lm| } }("5,77 ;;(-(8(8%(8(H(H#, ; ; ;(-(8(8(:(:;16o. ,V4D B+< < <)--c222))+++44T::: 34;;DAAA")%-*:OT"R"R" 4 3 ug&& (5; (!K	(():;; 	,,D"3DDD    ,#2NKKR+)(y	   (,E$$,G ge}55:A

 
 lIt<<G"G%8$?? ;wT::  nc22 @~ @%%'''//???!'9d;;gs++ 6 6%%''',,W555!! ww}--5"' -	 On-- + +#C(zN;7	zN629c	 3!2!2 3;
9----/ ; ; ; $?y)#T#T#t++(0II 7;3; #* /3+&&$xF"$&&"9"9,
^F3"+  	( ( (     !! "# " # "
 #G  2 (?'X=TXCX$' 	   !.11  N NNN 	   .l((0DI#1#9T	    T! ##"" 	%
 ( 		NNE   .l((0DI   #0"96" 	/&.# @B#VZ66!
 !
 !

 !,''""$$$119T& &,	
 
 
 & 1
 
 

 3tz||,,, M	
 
 
 	
s   A	L0(6LL0
L,)L0+L,,L00
L=<L=M+N
N
*W55
XX+``#"`#j##*kkc                	    d}d}t          j                      d<                                   !d<   ddidddd}ddlm} dd	lm |                                }d= fd}d>fd}d?fd} |                    |t          t          dd          pd          t          t          dd          pd          t          t          dd          pd          |j
        ||j        |dt          dd          t          dd          rdn't          t          dd          pd          dk    rdnd d!d"#                    }		 |	D ]}
d"}t          j                      d<                       d$           	 t                              d%d                    d&z   d%<                       d'           d         d'<   t                              d(d                    t          |
          z   d(<   n# t           $ r Y nw xY wj        r nt          |
d)d          }|d*k    r^t          |
d+d          }|rIt          |d)d          d,k    r4d"}t          |d-d          }|r                                  |           @|d.k    rt          |
d/d          }|rt          |d)d          }|d0k    r;t          |d1d          }|r&|s$                                  |           d"d2<   |d3k    r2t          |d4d          }|r                                  |           j        sAd5         }|7	 |                                }n!# t,          $ r |st/          d6          d w xY w	               d7         }||                    ddd           n# d7         }||                    ddd           w w xY w# 	               d7         }||                    ddd           w w # d7         }||                    ddd           w w xY wxY wj        rdS d@d8}|1t          |d9d          s t          |d:d          t/          d;          |#|	j        s ||          rt/          d<          |S |                    |          }t          |d9d          s t          |d:d          t/          d;           ||          rt/          d<          |S )AaV  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).
        Fru  r  ro   N)managerr   r   r  )sanitize_anthropic_kwargsra  rb  c                    t          |           } |t          dd                      j        j        di |}|d<   |                                S )Nr  r   )r  r   r   )rV   r   r   r   	__enter__)ra  rf  r   _stream_contextr@   r  r!  s      r0   _open_anthropic_streamzYinterruptible_streaming_api_call.<locals>._call_anthropic.<locals>._open_anthropic_stream  su    00L%%"5,;;    5n-4DD|DDG)0OI&$$&&&r2   r  r   r8   r9   c                    | d<   	                      t          | dd                      n# t          $ r Y nw xY wt                    d<   d S )Nr   rY   ro   )r  r   rC   r   )r  r  r$  r  r@   s    r0   _anthropic_stream_createdz\interruptible_streaming_api_call.<locals>._call_anthropic.<locals>._anthropic_stream_created  s{    (2OH%33J
D99       %8%?%?M'"""s   %. 
;;r}  r   c                    d         }|t          |          rdS t                              d                    dd                     dS )Nro   TzAnthropic streaming attempt superseded by a newer stream; stopping consumption to preserve the single-writer invariant (model=%s).r  r  F)r   rF   rG   rd   )r}  r  r  r@   r  s     r0   _accept_anthropic_eventzZinterruptible_streaming_api_call.<locals>._call_anthropic.<locals>._accept_anthropic_event  s[    !'*E} 8 F F}tNN( w	22	   5r2   r>  r   r  rb  r  r  r  r  r  r  r  r  r  T)	r>  rF  r  r  r  r  r  r  r  r  r  rr   r  r  r   content_block_startcontent_blocktool_userF  content_block_deltarP  
text_deltarh   rL  thinking_deltathinkingr   zeProvider returned an empty stream with no events (possible upstream error or malformed event stream).r   c                    t          | dd          dS t          | dd          pg D ]}t          |dd          dk    r dS dS )u  True when the stream died mid tool call (#80498 sibling).

            Mirror of the chat_completions zero-byte/truncated-args gate: a
            legitimate completion always carries a ``stop_reason``
            (``tool_use``/``end_turn``/...), so a message that contains a
            ``tool_use`` block but NO stop_reason means the SSE closed after
            ``content_block_start`` and before ``message_delta`` — the
            block's ``input`` is whatever partial state the SDK snapshot
            accumulated (typically ``{}`` when no ``input_json_delta`` ever
            arrived). Without this gate the empty-input call passed the
            empty-stream guards (content is non-empty) and executed the tool
            with no arguments and no retry. Raising EmptyStreamError blocks
            that execution on every path; when no assistant text streamed
            before the drop it additionally rides the bounded stream-retry
            the eventless case uses (probe-verified recovery), while a
            drop after streamed preamble text degrades to the
            partial-stream-stub/continuation path instead — still never an
            empty-args execution.
            stop_reasonNFrQ  r   r,  TrO  )ra   blocks     r0   _tool_use_dropped_mid_streamz_interruptible_streaming_api_call.<locals>._call_anthropic.<locals>._tool_use_dropped_mid_stream  sc    ( wt44@u )T::@b    5&$//:==44 >5r2   rQ  r2  zjProvider returned an empty stream with no stop_reason (possible upstream error or malformed event stream).zStream ended with no stop_reason while a tool_use block was still incomplete; treating as a mid-tool-call stream drop (#80498).r  r  r  r8   r   )r  r  r@   r  r  r!  AnthropicStreamAccumulatorr   r7   r   finalizeobservers   r  rd   r^  rC   r  ro  rj  rr  get_final_messageAssertionErrorr   __exit__output_modifiedrY   )"r  has_tool_usesaw_stream_eventbase_final_messager  accumulatorr%  r'  r)  r   r&   
event_typer3  r  rP  
delta_typerh   thinking_textr  r   r4  final_messager  r$  r  r!  r  r  r  r@   r  rl  r  r4  s"   `                     @@@@r0   _call_anthropicz9interruptible_streaming_api_call.<locals>._call_anthropict  s     !#y{{''))(-f% $&*d;;!######EEEEEE::<<	' 	' 	' 	' 	' 	' 	' 	' 	'	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@
	 
	 
	 
	 
	 
	 
	 
	 %$&wulB??E2FF
B77F;GGwugr::@bAA%.";$,4 4&-e5NPT&U&U #5-??' wu.?CCHqIIAMM (Z&
 
 *.+   
 
29	7 %K %K#' '+y{{$%%&ABBB&)%))Ha*@*@&A&AA&EE(Oyy!122:2A#2F./%(7A)>)>%?%?BWX]B^B^%^E'NN    D- E$UFD99
!666#E?DAAE D!=!=!K!K'+$+E64$@$@	$ D--///!88CCC#888#E7D99E K%,UFD%A%A
%55#*5&"#=#=D# ?L ? 1 1 3 3 3 % 8 8 > > >:> 0 7'+;;;,3E:r,J,JM, K 1 1 3 3 3 % ; ;M J J J- ,X6
)-7-I-I-K-K**)   / ("2!W# # $(( 7%%'''))4&$$T4666 *)4&$$T46666 '	7%%'''))4&$$T46666 ' *)4&$$T46666 ' % 	4	 	 	 	8 *.	4@@ +*M4@@H"G   )&2H)++,>?? &:  
 &%#,,-?@@y$77	}d;;C"G   ('66 	"6  
 sn   2O A?HO 
HO HD8O M' &O 'NO 	
N5 5$OP2
P(#P2$P//P2c                    dd l } t          dd          }	 t          |dz             D ]D} "            }$j        r d           t	          d                        	 $j        dk    r0 !$                    d	          d
          } |          )d<   n |          )d<     #)d                   dd                            )d         dnd           d S # t          $ rw} ddt          |                                    d         rSt          
                    dt          |          j                   Y d }~                )d         dnd           d S t          || j        | j        | j        f          }t          || j        | j        t&          f          }$                    |          }t          |t*                    }	%d         rt-          )                    d                    p'd         }
d}|sg|seddlm} t          ||          rOt5          |dd           s>t          |                                          d}t9          fd|D                       }|p|p|p|}|
o|o||k     }|sFt                              d|           |)d<   Y d }~                )d         dnd           d S 	 $                    d           n# t          $ r Y nw xY w	 $                                 n# t          $ r Y nw xY wg )d<   d%d<   d&d<   $                     ||dz   |dz   d(                    d                      d             d            Y d }~]d}|sg|seddlm} t          ||          rOt5          |dd           s>t          |                                          d}t9          fd!|D                       }|s|s|s|s|	r||k     rO$                     ||dz   |dz   d(                    d                      d"            d"           Y d }~'$!                    d#||dz   |dz   d(                    d          $           |r
d%|dz    d&}n|	r
d'|dz    d&}n	d(|dz    d&}$"                    |           nt          |                                          }d)|v od*|v }d}|sd+|v rdd,l#m$}  ||          }|s|r d$_%        $&                    |rd-nd.           t          '                    d/|           |)d<   Y d }~                )d         dnd           d S d }~ww xY wn<# t          $ r/}|)d<   Y d }~               )d         dnd           d S d }~ww xY w	                )d         dnd           d S #                )d         dnd           w xY w)0Nr   HERMES_STREAM_RETRIESr[  rr   interrupt_before_stream_retryz%Agent interrupted before stream retryr  anthropic_stream_requestr  r  rY   TrV  stream_request_completestream_error_cleanupr   Fro   uP   Streaming worker caught %s after request cancellation — exiting without retry.rL  r  )APIErrorrS   )
zconnection lostzconnection resetzconnection closedzconnection terminatedznetwork errorznetwork connection
terminatedzpeer closedzbroken pipezupstream connect errorc              3      K   | ]}|v V  	d S r+   r   )r   phrase_err_lower_previews     r0   r   zBinterruptible_streaming_api_call.<locals>._call.<locals>.<genexpr>  s=       ?" ?"(. %+.@$@?" ?" ?" ?" ?" ?"r2   z9Streaming failed after partial delivery, not retrying: %sr"   u9   

⚠ Connection dropped mid tool-call; reconnecting…

r  r  )r"   attemptmax_attemptsmid_tool_callr  stream_mid_tool_retry_cleanupc              3      K   | ]}|v V  	d S r+   r   )r   rO  _err_lower_sses     r0   r   zBinterruptible_streaming_api_call.<locals>._call.<locals>.<genexpr>  s<       3 3$* !'. 83 3 3 3 3 3r2   stream_retry_cleanup	exhausted)r  r"   rQ  rR  rS  r  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 r   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)(r  r   ranger  r"  r  r@  rC   r7   rF   r4  r   rj   rc   ReadTimeoutConnectTimeoutPoolTimeoutConnectErrorr  ConnectionError_is_provider_stream_parse_errorr   r   rd   r   rL  r   r   r   rG   rj  _reset_stream_delivery_tracking_emit_stream_drop_log_stream_retryr  r  r_  re  r  	exception)*r  _max_stream_retries_stream_attemptr  r  rA  _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_  rP  rV  rE  r  r  r  r=  rU  rN  rB  r6  r  rL  r@   rl  r[  r  r4  rC  s*                          @@r0   rD  z/interruptible_streaming_api_call.<locals>._callR  sL
   %&=qAAL	#()<q)@#A#A { {$9$9$;$;! - T223RSSS*+RSSS""$$$o~)=== *=)<!BB'A C   "6	* * * .=_^-L-Lz**-C-CDU-V-Vz*$$#5#5fZ6H#I#I!%"   
 H	 "!### '&*%1 *)+    O	 ! [ [ [$$U#a&&QQQQ))+++ *'2 F GG,  
 d "!### '&*%1 *)+    k #-F.0EvGYZ# #K $.F/1K_]$ $L ,1+P+PQR+S+S('1!5E'F'F$ (. \!26"JJ';<<3 3 3<4U; 0 490* "< "DDDDDD)!Y77 "=Z^@_@_ "58VV\\^^ 28" 4 <? ?" ?" ?" ?"2F?" ?" ?" <" <" 8
 ( 4+474  4	 & 4 F -F /2E E *
  1 # #NN []^   /0F7O"FFFFZ "!### '&*%1 *)+    S!!44!6     ) ! ! ! D!!!AACCCC( ! ! ! D!
 8:3427(/49)&1//"#$3a$7)<q)@*.!6!:!:6!B!B 0    767VWWW223RSSS ! (-$& | @@@@@@%a33 GA}VZ<[<[ -0VV\\^^N1- 03 3 3 3 3.?3 3 3 0 0, $p'p ,p 0	p
 ,p +-@@@!33&'(7!(;-@1-D.3%:%>%>v%F%F 4    ;:;QRRR667MNNN %HHHH //!,"#$7!$;)<q)@*/!6!:!:6!B!B 0    0 !9#6#:!9 !9 !9 +N . !9)<q)@!9 !9 !9 +N!9#6#:!9 !9 !9 + ,,^<<<<%(VV\\^^
$
2 > /: = / 5:1 6 ?: M M      !A @ C C 6 2 5N 7;E4!-- $=!3 !V !V!3	 	 	 ((B   '(F7OFFFF "!### '&*%1 *)+    O	[A{x	   	 	 	  F7OFFF!!### '&*%1 *)+    	y	{F
 "!### '&*%1 *)+    	 "!### '&*%1 *)+   s   A
U2 $A&C,
U2 ,U.7AU)U2 7E U)7U2 K43U)4
L>U) LU)LU)
L'$U)&L''AU)U2 CU)U2 C1U)U2 )U..U2 1W 2
V+<V&W &V++W !W1r  r  r  )load_config_readonlyr@   local_stream_stale_timeout!HERMES_LOCAL_STREAM_STALE_TIMEOUTuB   Local provider detected (%s) — stale stream timeout set to %.0fsr  r  r  r  r  r  ry  r  ri  rj  rS  rT  rU  zRs with no output yet (provider may be slow or overloaded, or the model is thinkingrV  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.r  r  z, context: ~z tokens). Reconnecting...stale_stream_killr  u    ⚠ no output from provider for rZ  zstale stream detected after zs, reconnectingzLForce-closing streaming httpx client due to interrupt (not a network error).stream_interrupt_abort	Streamingz+Agent interrupted during streaming API callz9Agent interrupted during streaming API call (post-worker) _current_streamed_assistant_textr  r     z, +z moreu$   

⚠ Stream stalled mid tool-call (zH); the action was not executed. Ask me to retry if you want to continue.z[Partial stream dropped tool call(s) %s after %s chars of text; surfaced warning to user: %szPartial stream delivered before error; returning length-truncated stub with %s chars of recovered content so the loop can continue from where the stream died: %sr  r<  )classify_api_errorr   r  )r  r  r=  r>  ri   r  )rQ  r7   rR  r   r"   rS  r8   r9   r_  r`  )r   r   r8   r   r8   rs   )r  rs   r8   r   )r  rs   r8   r9   )r  rs   )?r  r"  r  _interruptible_api_callr  r  rC   r7   r  rd   r  r  r  r  r5   r   rE   rD   r}  rJ   rF   rG   r  rs   rv  r  r  r4  r  rx  r  r$  r	   r  r  r   r  r   r  rw  rc   rV   r  r  rm  r  r  rd  r  r   r   r   r   rj  r   r   agent.error_classifierr  r   r  content_policy_blockedr
   _content_filter_terminated)Kr@   r  r  rY   rD  _bedrock_started_atr  _bedrock_stale_timeoutr  ru  _stale_elapsedr  
_inval_excrD  r  _stream_stale_timeout_base_local_defaultrw  _cfg
_agent_cfg_vr  r  r  _last_heartbeat_HEARTBEAT_INTERVAL_hb_now_waiting_secsrx  _est_ctx_partial_text_partial_names	_name_str_warn_stub_finish_reason	_stub_msgr  r  r   _cls_stubr  rk  rE  r  r  r  r=  r  r  rU  rN  r\  r  rB  r  r6  r  r  r  r  r  rL  r  rl  r[  r  r  r  r4  r5  r  rC  r  r  sK   ```                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@r0    interruptible_streaming_api_callr    sB     ! NLMMM   2     
H H H H H H "%(( 9,,Z888~***
 '5#	/44Z@@H(:(:8(D(Dt[_````
 +/E''	  	 	 	U#c((KKKK	 +/E'.... ~+++"T22#UO!5> #ikk"$78%*EN! %..)={KK!=eZ!P!P
 	E"""	 	 	 	 	 		# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#B 	`	 -m<<T  A GGIII**,, @s###- X5	&99)B5)I    4A=PQQQQ*+VWWW
 "&/B3/G!G!$:::NNG&(>'	9)M)M	   ((XS=P=P X X#->>)Y#G#GX X X   'u---SSSSSS11/BBBB$   G        04y{{', (...
 '3J^ATAT J J&)*@&A&AJ J J' 'F7O
 A **,, @R ) b1IKK"55%>u%E   
 ''`aaag*Wo% j!-#E***(:(:6*;M(N(NY]eijjjj*%% 	 	 	U#c((KKKK	 RHHF
 '+TMM #H-#.** "5)3;                        )N )N )N )N )N )N )N )N )N )NV  u~$en DIKK(O !#.**UU	  &t,     	V 	V 	V 	V 	V 	V       
 
 
 
 
 
 
      J J J J J J J      6     u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
 u	
n\ \ \ \ \ \ \ \ \ \ \ \|Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Qh
 ,ENEKHHJ%/""%./Le%T%T" "U**u~*BSTYTbBcBc* 
	>>>>>>''))D.8t.D.DN'***$J*d++ /^^$@AAb3,// /%*2YYN 	 	 	D	 )*M~ ^ ^PN1	
 	
 	
 	
 6jAA  $'(BE$J$J!!6!!$'(BE$J$J!!$>! 	ONNNNN<<Z^^G=T=TUU'$'(=?O$P$P! 6u = =dKKKAGGIIIikkO
**,, DR	s )++_$(;;;%O/#*> >??M 333 *5-u== Ts;P7Q7Q T T TII "I''PjnnWn&M&M P P$P PCLP P P    %%TMTTT   s';;1116zBBHNNC 5w	22xOO	     #N8K8K # #%>>'9==# #%3# # #  ../BCCC**+>????    u%%% ~!555   $(9;;OC ###3~3F3F # # #   !!Ss>/B/BSSS   % #	R !6661"%5e%<    +/w'LL)  ../GHHH +*+CDDDD    ,A[AAAA"#PQQQI **,, DRT ! \Z[[[g"E" a	 A2FFL"egg  "&**-A"B"B"HbIIN ; IInRaR&899	~&&**!Es>':':Q'>!E!E!EEI@!@ @ @ 
 "/!4" =,,U3333    D<"C(;$<$<fWo  
 ';##& +,,7O   ';# ( -D"&  I */&3UUUUUUUU))7O 
B!?!?!E2FFgeWb99?R@@   K>#HH +*  3 3 3-2***3#)eWi88(Y>Q    $2$:d  E * 8370  &&&LWo j%E"""*s   -C 
C-C((C--C0 0	C9EP K* )P *
L4LP LC>P 
Q"P>>Q.BY   
YY
c! !
c.-c.4g 
ggk2 2
k?>k?
A(o3 3pp)r}  r  r8  r  r/  r8  r  )r6   r7   r8   r9   )ro   r   r8   rT   )r{   r   r8   rT   )rh   r7   r8   r   )rh   r7   r8   r   )r{   rV   rS   rT   r8   rV   )r"   r   rY   r   r8   rP   )rY   r   )r{   r   r8   r   )rh   r7   r8   r   )rh   r7   r   r   rY   r   r8   r   )r   r   r8   rs   r5  )r  rs   r8   r  )r  r   r8   r   )r8   r  )r8   r.  )r6  rV   r8   rV   )rF  r7   rG  r  r8   r  )rL  r   r8   rs   )r_  r  r`  r   ra  r  rb  rc  rd  r  re  r   rf  r  rg  r  r8   r7   r  r  )rg  r  rz  r   r8   r   )r  rV   rg  r  r_  r  r~  r   r  r   r8   r9   )rg  r  r8   r9   )r  rV   r8   r  )r  r  r8   r  )r  rV   )r_  r  r+   )r~  r   r  r  r8   rV   )r   r7   r8   rV   )r  r7   r  r7   r8   r9   )rD  rV   r8   rE  )rD  rV   r8   r   )r  rV  r8   r   )r   r   r  rs   r8   r7   )r0  r7   r8   r9   )trm   
__future__r   r3   r   r  rk  rI  rt   r  r  r  typesr   typingr   r   r   hermes_cli.timeoutsr   r	   r  r
   r   r  r   r   agent.errorsr   agent.turn_contextr   agent.gemini_native_adapterr   r  r   agent.message_contentr   agent.message_metadatar   r   agent.message_sanitizationr   r   agent.reasoning_summariesr   agent.stream_single_writerr   r   tools.terminal_toolr   utilsr   r   r   r   	getLoggerrj   rF   r  r   r   r   r  r5   rJ   rN   rC   rP   rz   r   r   r   r   r   r   r   r   r   r  r  r  r  r-  r5  rE  rK  r^  rp  rt  rv  rx  r|  r}  r  r  r  r  r  r  r  r  r  r  r+  r}  r  r8  rC  rH  rU  r  r/  r8  rF  r  __all__r   r2   r0   <module>r     s    # " " " " "        				 				       ! ! ! ! ! ! & & & & & & & & & & X X X X X X X X I I I I I I I I        * ) ) ) ) ) 5 5 5 5 5 5 A A A A A A 2 2 2 2 2 2 6 6 6 6 6 6 J J J J J J J J        F E E E E E T T T T T T T T 1 1 1 1 1 1 N N N N N N N N N N N N		8	$	$#E#E#E  )0.(A %>>> $( ! "% ) ) )
 
 
 
:      )   @      4: : : :@ @ @ @F' ' ' 'B " " " " " "J =A                N 	@ @ @ @ @ @F2$ 2$ 2$ 2$j	 	 	 	   &   "   &   $   2   , , , ,^9 9 9 9H          #'    > !E !E !E !E !E !EHC C C C
 
 
 
# # # #L> > > >BI@ I@ I@ I@X): ): ): ):b *. &   2   :` ` ` `Ff f f fT^ ^ ^ ^ ^D	z z z z|% % % %:      *b4 b4 b4 b4 b4LV V V Vt
-T -T -T -Td     @ QU N  N  N  N  N  N h@  r2   