Ë
    tPêj'� ã                   óÚ	  — U 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mZm	Z	m
Z
mZmZ d dlmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZ d dlZd dlZd dlZd dlm Z m!Z!m"Z" d dl#m$Z$m%Z%m&Z& d d	l'm(Z(m)Z)m*Z* d dl+Z+d d
l,m-Z-m.Z. d dl/m0Z0 d dl1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; d dl<m=Z= d dl>m?Z?m@Z@ d dlAmBZBmCZC d dlDmEZE d dlFmGZG d dlHmIZJ d dlKmLZL d dlMmNZN d dlOmPZP d dlQmRZR d dlSmTZTmUZU d dlVmWZW d dlXmYZY d dlZm[Z[m\Z\ d dl]m^Z^m_Z_m`Z`maZa d dlbmcZc d dldmeZe d dlfmgZgmhZh d dlimjZj d d lkmlZl d d!lmmnZn d d"lompZp d d#lqmrZr  ed$e%¬%«      Zs ed&«      Zted'   Zueevd(<   d d)lwmxZx e	egeyf   Zze	eTgeyf   Z{er	d d*l|m}Z~ e~Z}neZ}d d+lm€Z€m�Z�m‚Z‚ d d,lƒm„Z„m…Z…m†Z†m‡Z‡  eˆeCeB«       Z‰eevd-<    eye5«      d.d/d0œZŠee†   evd1<   d2e‹d3eŒfd4„Z�d5eŽeye‹f   d3eŒfd6„Z�d7eŽeye‹f   dz  d3dfd8„Z�	 dªd:e!dz  d5eŽd;eŒd3eŒfd<„Z‘d5eŽd3eŒfd=„Z’d>ee‹   d?e‹d3eŒfd@„Z“d5eeye‹f   d?e‹d3eŒfdA„Z”d5eŽd2e‹d3eŒfdB„Z•dCe–dD   d3dfdE„Z— edF¬G«      dHeyd3eŒfdI„«       Z˜dJe‹dKejdz  dLeydz  d3eŒfdM„Z™dNeeye‹f   dOeeye‹f   dPeydQe	g eŒf   d3eeye‹f   f
dR„Zšd«dSe‹dTeydUe‹d3e‹fdV„Z› G dW„ dXe«      Zœd2eœd3eœfdY„Z� G dZ„ d[e«      Zžd\ežd3ežfd]„ZŸ G d^„ d_e«      Z d`e d3e fda„Z¡dbe‹d3e¢eyeŽdz  f   fdc„Z£dde d\eŽeyeyf   d3eTfde„Z¤dNeeye‹f   d3e¥ey   fdf„Z¦dNeeye‹f   dgeUd3dfdh„Z§die‹djeeye‹f   dgeUdKejd3eydz  f
dk„Z¨dleye©z  d3eªdz  fdm„Z«dleye©z  d3eŽfdn„Z¬ G do„ dpe&«      Z­ G dq„ dre®«      Z¯d:e!d3dfds„Z°dteeydf   d:e!dz  d3eyfdu„Z±dde²d3e¢eªeeye‹f   f   fdv„Z³dweeye‹f   d3e¢eyeyf   fdx„Z´e"�jj                  dfdteeydf   dyeyd\eŽdzeªd:e!dz  d3e&e$z  fd{„Z¶ ed|d}d~œ«      Z·eeeyeyf      evd<   d«d5eeye‹f   dKejdz  d3e¸dz  fd€„Z¹d�e%d3dfd‚„Zºd�e%d3ee©df   fdƒ„Z»dde®d„d…d3e®fd†„Z¼	 	 d¬d‡ees   dˆe¸eyz  dz  dyeyd„e	e®gee dz     f   dz  d3ese&z  f
d‰„Z½d«dJeydŠeeye‹f   dz  d3eŒfd‹„Z¾d9dŒœd�e‹dieydŽeyd�eŒd3df
d�„Z¿ G d‘„ d’e«      ZÀd“e¸dz  d”e¸dz  d•e¸dz  d3e¸dz  fd–„ZÁ eÀd—d—d—d—d—d—d—¬˜«      ZÂeevd™<   	 dše¸eyz  dz  d3eŒfd›„ZÃ	 d«dœeJdz  dše¸eyz  dz  d3eÀfd�„ZÄd5eeye‹f   dz  d3e¸dz  fdž„ZÅdde®d3eŒfdŸ„ZÆd.ZÇeevd <   d¡e®d3dfd¢„ZÈd:e!d£d¤d¥e �j’                  d3dfd¦„ZÊd:e!d£d¤d3etfd§„ZË G d¨„ d©«      ZÌy)­é    N)ÚAsyncGeneratorÚ	AwaitableÚCallableÚ	CoroutineÚMappingÚSequence)Údatetime)Ú	lru_cache)ÚMappingProxyType)	ÚTYPE_CHECKINGÚAnyÚFinalÚLiteralÚ
NamedTupleÚProtocolÚ	TypeAliasÚTypeVarÚoverload)ÚHTTPExceptionÚRequestÚstatus)ÚJSONResponseÚResponseÚStreamingResponse)ÚReceiveÚScopeÚSend)Ú_redact_stringÚverbose_proxy_logger)Úuuid)
Ú(DD_TRACER_STREAMING_CHUNK_YIELD_RESOURCEÚDEFAULT_MAX_RECURSE_DEPTHÚLITELLM_DETAILED_TIMINGÚ'LITELLM_HTTP_STATUS_CLIENT_DISCONNECTEDÚMAX_PAYLOAD_SIZE_FOR_DEBUG_LOGÚNON_INFERENCE_CALL_TYPESÚ"RETURN_RAW_MODEL_NAME_METADATA_KEYÚSTREAM_SSE_DATA_PREFIXÚSTREAM_SSE_KEEPALIVE_PING_BYTESÚUNSAFE_PROXY_RESPONSE_HEADERS)ÚCustomGuardrail)Úget_or_create_metadata_bucketÚis_expected_client_error)Ú
NullTracerÚtracer)Úget_supported_openai_params)Ú*is_unbilled_non_inference_call_from_params)ÚLogging)Úguardrail_information_cost)Úget_response_headers)Ú
safe_dumps)Ú#backfill_missing_cache_usage_fields)ÚProxyExceptionÚUserAPIKeyAuth)Úcan_key_call_resolved_model)Úcheck_response_size_is_safe)Úget_logging_caching_headersÚ3get_remaining_tokens_and_requests_from_request_data)ÚSSE_COMMENT_PING_BYTESÚcoerce_keepalive_intervalÚresolve_ttft_keepalive_intervalÚ$wrap_sse_stream_with_keepalive_pings)ÚDDSpanTagger)Úroute_request)ÚProxyLoggingÚ'_check_and_merge_model_level_guardrails)ÚRouter)Úget_hidden_params_dict)Úresolve_model_group_alias)ÚGuardrailEventHooks)ÚRouterRateLimitErrorÚ_LateResponseT)ÚboundÚ	_LlmCallT)XÚacompletionÚ
aembeddingÚ
aresponsesÚ
_arealtimeÚ_aresponses_websocketÚacreate_realtime_client_secretÚarealtime_callsÚaget_responsesÚadelete_responsesÚacancel_responsesÚacompact_responsesÚacreate_batchÚaretrieve_batchÚalist_batchesÚacancel_batchÚafile_contentÚafile_retrieveÚafile_deleteÚatext_completionÚacreate_fine_tuning_jobÚacancel_fine_tuning_jobÚalist_fine_tuning_jobsÚaretrieve_fine_tuning_jobÚalist_input_itemsÚaimage_editÚagenerate_contentÚagenerate_content_streamÚallm_passthrough_routeÚavector_store_searchÚavector_store_createÚavector_store_retrieveÚavector_store_listÚavector_store_updateÚavector_store_deleteÚavector_store_file_createÚavector_store_file_listÚavector_store_file_retrieveÚavector_store_file_contentÚavector_store_file_updateÚavector_store_file_deleteÚaocrÚasearchÚavideo_generationÚavideo_listÚavideo_statusÚavideo_contentÚavideo_remixÚavideo_create_characterÚavideo_get_characterÚavideo_editÚavideo_extensionÚacreate_containerÚalist_containersÚaingestÚaretrieve_containerÚadelete_containerÚaupload_container_fileÚalist_container_filesÚaretrieve_container_fileÚadelete_container_fileÚ aretrieve_container_file_contentÚacreate_skillÚalist_skillsÚ
aget_skillÚadelete_skillÚanthropic_messagesÚacreate_interactionÚaget_interactionÚadelete_interactionÚacancel_interactionÚacreate_agentÚalist_agentsÚ
aget_agentÚadelete_agentÚalist_agent_versionsÚasend_messageÚcall_mcp_toolÚacreate_evalÚalist_evalsÚ	aget_evalÚaupdate_evalÚadelete_evalÚacancel_evalÚacreate_runÚ
alist_runsÚaget_runÚacancel_runÚadelete_runÚProxyRouteType)ÚAnthropicConfig)ÚProxyConfig)Úadd_litellm_data_to_requestÚ*refresh_proxy_server_request_body_snapshotÚreject_url_valued_destination)ÚModelResponseÚModelResponseStreamÚ&StandardLoggingPayloadErrorInformationÚUsageÚ_DD_STREAMING_TRACE_ENABLEDzClient disconnected the requestÚClientDisconnected)Ú
error_codeÚerror_messageÚerror_classÚ&_CLIENT_DISCONNECTED_ERROR_INFORMATIONÚresponseÚreturnc                 ó    — t        | dd«      du S )NÚhas_buffered_provider_outputFT©Úgetattr©rµ   s    úl/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/common_request_processing.pyÚ_withheld_provider_outputr½   Î   s   € Ü�8Ð;¸UÓCÀtÐKÐKó    Úrequest_datac                 óf   — t        d„ | j                  d«      | j                  d«      fD «       «      S )Nc              3   ón   K  — | ]-  }t        |t        «      xr |j                  t        «      d u –— Œ/ y­w)TN)Ú
isinstanceÚdictÚgetr'   )Ú.0Úmetadatas     r¼   ú	<genexpr>z0_should_return_raw_model_name.<locals>.<genexpr>Ó   s7   è ø€ ò àô 	�8œTÓ"Ò_ x§|¡|Ô4VÓ'WÐ[_Ð'_Ó_ñùs   ‚35rÆ   Úlitellm_metadata)ÚanyrÄ   )r¿   s    r¼   Ú_should_return_raw_model_namerÊ   Ò   s8   € Üñ à%×)Ñ)¨*Ó5°|×7GÑ7GÐHZÓ7[Ð\ôó ð r¾   Útarget_metadatac                 ó8   — | €y d| d<   t        t        «      | d<   y )NTÚclient_disconnectedÚerror_information)rÃ   r´   )rË   s    r¼   Ú!_apply_client_disconnect_metadatarÏ   Ù   s'   € ØÐØØ-1€OÐ)Ñ*Ü+/Ô0VÓ+W€OÐ'Ò(r¾   FÚrequestrÍ   c              ƒ   óž  K  — |s| €y	 | j                  «       ƒ d {  –—† }|sy|j                  d«      }|�z|j                  j	                  di «      }|j                  d«      }|€i }||d<   t        |«       |j                  j                  d«      }|€i }||j                  d<   t        |«       |j                  d«      }|€i }||d<   t        |«       |j                  d«      }	|	€i }	|	|d<   |	j                  d«      }
|
€i }
|
|	d<   t        |
«       t        j                  d|j                  d«      «       y7 �Œ# t        $ r Y yw xY w­w)NFÚlitellm_logging_objÚlitellm_paramsrÆ   zORecorded streaming client disconnect with error_code=499 for litellm_call_id=%sÚlitellm_call_idT)Úis_disconnectedÚ	ExceptionrÄ   Úmodel_call_detailsÚ
setdefaultrÏ   r   Údebug)rÐ   r¿   rÍ   ÚdisconnectedÚlogging_objrÓ   Ú_lp_metadataÚ_mcd_metadataÚ_rd_metadataÚ_rd_litellm_paramsÚ_rd_lp_metadatas              r¼   Ú-_record_streaming_client_disconnect_if_neededrá   à   s‰  è ø€ ñ
 Øˆ?Øð	Ø(/×(?Ñ(?Ó(A×"AˆLñ Øà%×)Ñ)Ð*?Ó@€KØÐØ +× >Ñ >× IÑ IÐJZÐ\^Ó _ˆØ%×)Ñ)¨*Ó5ˆØÐØˆLØ)5ˆN˜:Ñ&Ü)¨,Ô7à#×6Ñ6×:Ñ:¸:ÓFˆØÐ ØˆMØ9FˆK×*Ñ*¨:Ñ6Ü)¨-Ô8à×#Ñ# JÓ/€LØÐØˆØ#/ˆ�ZÑ Ü% lÔ3à%×)Ñ)Ð*:Ó;ÐØÐ!ØÐØ);ˆÐ%Ñ&Ø(×,Ñ,¨ZÓ8€OØÐØˆØ)8Ð˜:Ñ&Ü% oÔ6ä×ÑØYØ×ÑÐ*Ó+ôð ðS #BúÜò 	Ùð	üs8   ‚E‰D> œD;�D> ¡DEÄ;D> Ä>	E
ÅEÅ	E
Å
Ec                 ój   — | j                  d«      }|€yt        |dd «      d uxr t        |dd «      d uS )NrÒ   FÚ_on_deferred_stream_completeÚ_deferred_stream_complete_args)rÄ   rº   )r¿   rÛ   s     r¼   Ú!_deferred_stream_logging_is_armedrå     sL   € Ø%×)Ñ)Ð*?Ó@€KØÐØä�Ð;¸TÓBÈ$ÐNò 	UÜ�KÐ!AÀ4ÓHÐPTÐTðr¾   ÚchunksÚassembled_modelc                 óÔ   — | d   }t        |t        «      r|j                  d«      nt        |dd«      }t        |t        «      xr$ t        |t        «      xr t        |«      xr ||k7  S )a  Report whether stream_chunk_builder picked a model the first chunk did not carry.

    Azure Model Router puts the routed model on the chunks after the first one, and the
    proxy deliberately leaves those chunks unrestamped so the builder can recover it.

    A stored chunk that carries usage is a pre-restamp copy of the one the proxy saw, so
    an alias-restamped stream reaches the builder with the same shape: a first chunk that
    disagrees with the rest. Those two are only told apart by what the client asked for.
    r   ÚmodelN)rÂ   rÃ   rÄ   rº   ÚstrÚbool)ræ   rç   Úfirst_chunkÚfirst_chunk_models       r¼   Ú(_assembled_model_came_from_a_later_chunkrî     sr   € ð   ™€Kä$.¨{¼DÔ$Aˆ�‰˜Ô ÄwÈ{Ð\cÐeiÓGjð ô 	Ð$¤cÓ*ò 	1Ü�¬Ó,ò	1ä�Ó!ò	1ð Ð0Ñ0ð	r¾   c                 ó˜   — | j                  d«      }t        |t        «      r|n| j                  d«      }t        |t        «      xr ||k(  S )a­  Report whether the assembled model is the public name the proxy stamps onto chunks.

    That stamp is what leaves an unpriced alias on the partial response, so the deployment's
    own model has to go back on before the row is costed. Pre-call processing rewrites
    `request_data["model"]` for aliasing and routing, so the client's own name wins when it
    is there, in the same order the proxy picks the name it stamps.
    Ú_litellm_client_requested_modelré   )rÄ   rÂ   rê   )r¿   rç   Úclient_requested_modelÚstamped_models       r¼   Ú1_assembled_model_is_the_name_the_client_asked_forró   5  sP   € ð %1×$4Ñ$4Ð5VÓ$WÐä",Ð-CÄSÔ"IÑÈ|×O_ÑO_Ð`gÓOhð ô �m¤SÓ)ÒN¨oÀÑ.NÐNr¾   c              ƒ   ó²  K  — t         j                  du ry| j                  d«      }t        |t        «      sy|j
                  j                  d«      ryt        |dd«      }t        |t        «      r|syt        j                  dt        |«      | j                  d«      «       t        |d	d«      }	 t        j                  |t        |t        «      r|nd|¬
«      }|€yt        |dd«      }t        ||j                  «      xr t        | |j                  «       }t        |t         «      r|r	|s||_        t        |dd«      }	t        |	t"        «      rt%        |	«       	 |j'                  |dddd¬«      ƒ d{  –—†  y# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w7 Œ1# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)a’  
    A client disconnect throws GeneratorExit/CancelledError into the streaming
    generator, so neither the success nor the failure logging callback fires
    and the chunks already streamed (plus any sub-call cost folded into the
    logging object) would never reach spend tracking. Assemble the partial
    response from the wrapper's collected chunks and dispatch success logging
    for it; dispatch_success_handlers dedups against a natural end-of-stream
    dispatch via has_dispatched_final_stream_success.

    Awaited directly by the shielded cleanup rather than scheduled with
    create_task: the client is already gone so the extra latency is harmless,
    and an unrooted task could be garbage-collected before it bills.

    Returns True when a disconnect-time success event owns the request's
    max_parallel_requests slot release (one was dispatched here, or one had
    already been dispatched for this stream), so the caller can skip the
    explicit slot release and avoid a double release. Returns False when no
    success event fired (logging disabled, nothing streamed, or assembly
    failed) and the caller must release the slot itself.
    TFrÒ   Ú#has_dispatched_final_stream_successræ   NzXBilling partial streamed spend for %s chunks after client disconnect, litellm_call_id=%srÔ   Úmessages)ræ   rö   rÛ   zGFailed to assemble partial streamed response for disconnect billing: %sré   Úusage©Ú	cache_hitÚ
start_timeÚend_timeÚprefer_async_handlersz/Failed to dispatch disconnect billing event: %s)ÚlitellmÚdisable_streaming_loggingrÄ   rÂ   ÚLiteLLMLoggingObjr×   rº   Úlistr   rÙ   ÚlenÚstream_chunk_builderrÖ   rî   ré   ró   rê   r®   r6   Údispatch_success_handlers)
r¿   rµ   rÛ   ræ   rö   Úpartial_responseÚeÚwrapper_modelÚ"builder_recovered_the_routed_modelÚpartial_usages
             r¼   Ú*_bill_partial_streamed_spend_on_disconnectr	  G  sß  è ø€ ô* ×(Ñ(¨DÑ0ØØ%×)Ñ)Ð*?Ó@€KÜ�kÔ#4Ô5ØØ×%Ñ%×)Ñ)Ð*OÔPð Ü# H¨h¸Ó=€FÜ�fœdÔ#©6ØÜ×ÑØbÜˆF‹Ø×ÑÐ*Ó+ôô
 & h°
¸DÓA€HðÜ")×">Ñ">ØÜ!+¨H´dÔ!;‘XÀØ#ô#
Ðð ÐØÜ" 8¨W°dÓ;€MÜ0XØÐ ×&Ñ&ó1ò 1fä?ÀÐN^×NdÑNdÓeÐ
eð 'ô �-¤Ô%©-Ñ@bØ!.ÐÔÜ"Ð#3°W¸dÓC€MÜ�-¤Ô'Ü+¨MÔ:ð
Ø×3Ñ3ØØØØØ"&ð 4ó 
÷ 	
ð 	
ð øô3 ò Ü×"Ñ"Ð#lÐnoÔpÜûðúð	
ùô ò Ü×"Ñ"Ð#TÐVWÔXÜûðüsm   ‚B.GÂ1*E= ÃBGÅF+ Å7F)Å8F+ Å<GÅ=	F&ÆF!ÆGÆ!F&Æ&GÆ)F+ Æ+	GÆ4GÇ
GÇGÇGÚtaskszasyncio.Task[Any]c              ƒ   óê   K  — | D �cg c]  }|j                  «       rŒ|‘Œ }}|D ]  }|j                  «        Œ |D ]  }	 |ƒ d {  –—†  Œ y c c}w 7 Œ# t        j                  t        f$ r Y Œ3w xY w­w©N)ÚdoneÚcancelÚasyncioÚCancelledErrorrÖ   )r
  ÚtaskÚpending_taskss      r¼   Ú_cancel_pending_gather_tasksr  �  s{   è ø€ Ø-2ÖF T¸$¿)¹)½+šDÐF€MÐFØò ˆØ�‰�ðàò ˆð	Ø�J‰Jñùò Gð
 ùÜ×&Ñ&¬	Ð2ò 	Ùð	üsJ   ‚A3‡A�A¡A3Á AÁAÁAÁ
A3ÁAÁA0Á-A3Á/A0Á0A3i   )ÚmaxsizeÚlitellm_modelc                 óN   — 	 t        | ¬«      }|d uxr d|v S # t        $ r Y yw xY w)N)ré   FÚstream_options)r0   rÖ   )r  Úsupported_paramss     r¼   Ú&_litellm_model_supports_stream_optionsr  ›  s?   € ðÜ"=ÀMÔ"RÐð  4Ð'ÒPÐ,<Ð@PÐ,PÐPøô ò Ùðús   ‚ ˜	$£$ré   Ú
llm_routerÚteam_idc                 ó„   — t        | t        «      sy|�|j                  | |¬«      nd}|r|n| f}t        d„ |D «       «      S )NF)r  © c              3   ó2   K  — | ]  }t        |«      –— Œ y ­wr  )r  )rÅ   Úms     r¼   rÇ   z<_model_deployments_support_stream_options.<locals>.<genexpr>¯  s   è ø€ ÒS¸QÔ5°a×8ÑSùs   ‚)rÂ   rê   Úresolved_litellm_modelsÚall)ré   r  r  Údeployment_modelsÚcandidate_modelss        r¼   Ú)_model_deployments_support_stream_optionsr$  ¤  sS   € ô
 �eœSÔ!ØàFPÐF\ˆ
×*Ñ*¨5¸'Ð*ÔBÐbdð ñ 4EÑ/È5È(ÐÜÑSÐBRÔSÓSÐSr¾   ÚdataÚgeneral_settingsÚ
route_typeÚsupports_stream_optionsc                 ó¦  — d| v rddini }| j                  dd«      dur|S |j                  d«      }| j                  d«      }|du r2d| vr
i |¥dddii¥S t        |t        «      rd|vri |¥di |¥ddi¥i¥S |S |du s|dk7  r|S t        |t        «      r|j                  d«      du r|S  |«       s|S t        |t        «      ri |¥ni }i |¥ddi¥dd	œS )
NÚ_litellm_strip_stream_usageFÚstreamTÚalways_include_stream_usager  Úinclude_usagerM   )r  r*  )rÄ   rÂ   rÃ   )r%  r&  r'  r(  ÚscrubÚalways_includer  Úmerged_stream_optionss           r¼   Ú_stream_usage_tracking_updatesr1  ²  s)  € ð >[Ð^bÑ=bÐ1°5Ñ9Ðhj€EØ‡x�x�˜%Ó ¨Ñ,ØˆØ,×0Ñ0Ð1NÓO€NØ ŸH™HÐ%5Ó6€NØ˜ÑØ 4Ñ'ØG�eÐGÐ-°ÀÐ/FÑGÐGÜ�n¤dÔ+°À~Ñ0UØY�eÐYÐ-Ð/X°.Ð/XÀ/ÐSWÑ/XÑYÐYØˆØ˜Ñ *°Ò"=ØˆÜ�.¤$Ô'¨N×,>Ñ,>¸Ó,OÐSWÑ,WØˆÙ"Ô$ØˆÜ9CÀNÔTXÔ9YÐ#5 nÑ#5Ð_aÐàJÐ2ÐJ°OÀTÑJØ'+ñð r¾   ÚvalueÚnameÚdefaultc                 ó   — t        | ||«      S r  r¹   )r2  r3  r4  s      r¼   Ú_getattr_objectr6  Ð  s   € Ü�5˜$ Ó(Ð(r¾   c                   óX   — e Zd Zedefd„«       Zedej                  fd„«       Zde	fd„Z
y)Ú_UpstreamHttpResponser¶   c                  ó   — y r  r  ©Úselfs    r¼   Ústatus_codez!_UpstreamHttpResponse.status_codeÕ  s   € Ø"%r¾   c                  ó   — y r  r  r:  s    r¼   Úheadersz_UpstreamHttpResponse.headersØ  s   € Ø(+r¾   c              ƒ   ó   K  — y ­wr  r  r:  s    r¼   Úareadz_UpstreamHttpResponse.areadÛ  s   è ø� ùó   ‚N)Ú__name__Ú
__module__Ú__qualname__ÚpropertyÚintr<  ÚhttpxÚHeadersr>  Úbytesr@  r  r¾   r¼   r8  r8  Ô  s4   „ ØØ%˜SÒ%ó Ø%àØ+˜Ÿ™Ò+ó Ø+à'˜UÔ'r¾   r8  c                 ó   — | S r  r  r»   s    r¼   Ú_as_upstream_responserK  Þ  s   € Ø€Or¾   c                   ó"   — e Zd Zddededefd„Zy)Ú_ReadsHeaderValuesÚkeyr4  r¶   c                  ó   — y r  r  )r;  rN  r4  s      r¼   rÄ   z_ReadsHeaderValues.getã  s   � r¾   N)Ú )rB  rC  rD  rê   rÄ   r  r¾   r¼   rM  rM  â  s   „ Ù:�sÐ: SÐ:°#Ô:r¾   rM  r>  c                 ó   — | S r  r  )r>  s    r¼   Ú_as_header_readerrR  æ  s   € Ø€Nr¾   c                   ó8   — e Zd Z	 	 	 	 	 d	dedededededdfd„Zy)
Ú_DispatchesSuccessHandlersNÚresultrú   rû   rù   rü   r¶   c              ƒ   ó   K  — y ­wr  r  )r;  rU  rú   rû   rù   rü   s         r¼   r  z4_DispatchesSuccessHandlers.dispatch_success_handlersë  s   è ø€ ð ùrA  )NNNNF)rB  rC  rD  Úobjectrë   r  r  r¾   r¼   rT  rT  ê  sR   „ ð Ø!ØØ Ø&+ñàðð ðð ð	ð
 ðð  $ðð 
ôr¾   rT  rÛ   c                 ó   — | S r  r  )rÛ   s    r¼   Ú_as_success_dispatcherrY  õ  s   € ØÐr¾   Údetailc                 ó�  — t        | t        «      r| dfS t        | t        «      r–| j                  d«      }t        |t        «      r|| fS t        |t        «      r%|j                  d«      }t        |t        «      r|| fS | j                  d«      }t        |t        «      r|| fS t	        j
                  | «      | fS t        | «      dfS )aE  
    Convert an HTTPException.detail value into (message, structured_fields)
    for ProxyException / SSE error frames.

    Dict-detail HTTPExceptions raised by guardrails were previously str()-mangled
    into a Python repr blob, producing unparseable error responses on both the
    streaming and non-streaming proxy surfaces. This helper extracts a clean
    human-readable message while preserving the full payload as structured
    fields, so the dominant guardrail shapes (`{"error": "..."}` flat and
    `{"error": {"message": "..."}}` nested) both round-trip cleanly.
    NÚerrorÚmessage)rÂ   rê   rÃ   rÄ   ÚjsonÚdumps)rZ  ÚerrÚ
nested_msgÚmsgs       r¼   Ú _serialize_http_exception_detailrc  ù  s¶   € ô �&œ#ÔØ�tˆ|ÐÜ�&œ$ÔØ—Z‘Z Ó(ˆÜ�cœ3ÔØ˜�;ÐÜ�cœ4Ô Ø #§¡¨	Ó 2ˆJÜ˜*¤cÔ*Ø! 6Ð)Ð)Ø—Z‘Z 	Ó*ˆÜ�cœ3ÔØ˜�;ÐÜ�z‰z˜&Ó! 6Ð)Ð)Üˆv‹;˜ÐÐr¾   Úexcc           
      ó  — t        | dt        | «      «      }t        |«      \  }}t        | dd «      xs i }|ri |¥|¥n|xs d }t	        |t        | dd«      t        | dd«      t        | dt
        j                  «      ||¬«      S )NrZ  Úprovider_specific_fieldsÚtypeÚNoneÚparamr<  )r]  rg  ri  Úcoderf  r>  )r6  rê   rc  rº   r7   r   ÚHTTP_400_BAD_REQUEST)rd  r>  Ú
raw_detailr]  Ústructured_fieldsÚexisting_fieldsÚmerged_fieldss          r¼   Ú#proxy_exception_from_http_exceptionrp    s”   € Ü'¨¨X´s¸3³xÓ@€JÜ!AÀ*Ó!MÑ€GÐÜ$ SÐ*DÀdÓKÒQÈr€OÙGXÐC˜oÐCÐ1BÑCÐ_nÒ_vÐrv€MÜØÜ�S˜& &Ó)Ü�c˜7 FÓ+Ü�S˜-¬×)DÑ)DÓEØ!.Øôð r¾   c                 ó’  — t        «       }| j                  d«      }t        |t        «      s|S |D ]”  }t        |t        «      r|j                  d«      dk7  rŒ(|j                  d«      xs g }t        |t        «      st        dddi¬«      ‚|D ]4  }t        |t        «      r|st        dddi¬«      ‚|j                  |«       Œ6 Œ– |S )	NÚtoolsrg  Úfile_searchÚvector_store_idsé�  r\  z6file_search.vector_store_ids must be a list of strings©r<  rZ  )ÚsetrÄ   rÂ   r   rÃ   r   rê   Úadd)r%  rt  rr  ÚtoolÚidsÚvector_store_ids         r¼   Ú._collect_response_file_search_vector_store_idsr|  '  sÙ   € Ü(+«ÐØ—8‘8˜GÓ$€EÜ�eœTÔ"ØÐàò 2ˆÜ˜$¤Ô%¨¯©°&Ó)9¸]Ò)JØØ�h‰hÐ)Ó*Ò0¨bˆÜ˜#œtÔ$ÜØØÐ!YÐZôð ð  #ò 	2ˆOÜ˜o¬sÔ3¹?Ü#Ø #Ø#Ð%]Ð^ôð ð × Ñ  Õ1ñ	2ð2ð" Ðr¾   Úuser_api_key_dictc              ƒ   ó|   K  — t        | «      }|sy ddlm} t        |«      D ]  } |||¬«      ƒ d {  –—†  Œ y 7 Œ­w)Nr   )Ú&assert_user_can_access_vector_store_id)r{  r}  )r|  Ú*litellm.proxy.vector_store_endpoints.utilsr  Úsorted)r%  r}  rt  r  r{  s        r¼   Ú-_authorize_response_file_search_vector_storesr‚  A  sS   è ø€ ô MÈTÓRÐÙØõô "Ð"2Ó3ò 
ˆÙ4Ø+Ø/ô
÷ 	
ñ 	
ñ
ð	
ús   ‚0<²:³<Úrequested_modelÚrouter_settingsc              ƒ   ó¼   K  — t        | t        «      syt        |j                  d«      | «      }|�|| k(  ryt	        ||j
                  ||¬«      ƒ d{  –—†  |S 7 Œ­w)ac  
    Resolve ``router_settings.model_group_alias`` coming from a key or team.

    The Router only ever resolves aliases from its own instance attribute, which
    holds the global config map and is shared across requests, so a per-request
    map has to be applied here instead of being forwarded to the Router.

    Model access was authorized against the requested group, so the target is
    authorized in its own right before the rewrite; a key that may not call the
    target gets the usual 403 rather than being quietly served it.

    Returns the target model group, or None when no alias applies.
    NÚmodel_group_alias)ré   Úllm_model_listÚvalid_tokenr  )rÂ   rê   rG   rÄ   r9   Ú
model_list)rƒ  r„  r}  r  Útargets        r¼   Ú&_resolve_per_request_model_group_aliasr‹  T  sm   è ø€ ô& �o¤sÔ+ØÜ-¨o×.AÑ.AÐBUÓ.VÐXgÓh€FØ€~˜ ?Ò2ØÜ
%ØØ!×,Ñ,Ø%Øô	÷ ð ð €Mðús   ‚AAÁAÁAÚ
event_linec              ƒ   ó®  K  — t        | t        «      r| j                  d«      n| } | j                  d«      rÏ| t	        d«      d j                  «       }|r|dk(  ry	 t        j                  |«      }t        |t        «      r„d|v r€t        |d   t        «      rm|d   j                  d«      }d}t        |t        «      r|}nt        |t        «      r	 t        |«      }|�d|cxk  rd	k  r|S  |�t        j                  d
|«       yy# t        $ r t        j                  d|«       Y ŒKw xY w# t        j                  t         j                  f$ r Y yw xY w­w)zEParses an event line and returns an error code if present, else None.úutf-8údata: Nú[DONE]r\  rj  z2Error code is a string but not a valid integer: %séd   éW  z-Error has invalid or non-convertible code: %s)rÂ   rI  ÚdecodeÚ
startswithr  ÚstripÚorjsonÚloadsrÃ   rÄ   rF  rê   Ú
ValueErrorr   ÚwarningÚJSONDecodeErrorr^  )rŒ  Újson_strr%  Úerror_code_rawr±   s        r¼   Ú_parse_event_data_for_errorr�  u  sP  è ø€ ä/9¸*ÄeÔ/L�×"Ñ" 7Ô+ÐR\€JØ×Ñ˜XÔ&Ø$¤S¨£] _Ð5×;Ñ;Ó=ˆÙ˜8 xÒ/Øð	Ü Ÿ,™, xÓ0ˆDÜ˜$¤Ô%¨'°T©/¼jÈÈgÉÔX\Ô>]Ø(,¨W©×(9Ñ(9¸&Ó(A�Ø)-�
ä˜n¬cÔ2Ø!/‘JÜ ´Ô4ðÜ%(¨Ó%8˜
ð Ð)¨c°ZÔ.FÀ3Ò.FØ%Ð%ð /Gà#Ð/Ü(×0Ñ0Ð1`ÐbpÔqñ øô &ò Ü,×4Ñ4ØPÐR`öðûô ×&Ñ&¬×(<Ñ(<Ð=ò 	àØð	üs[   ‚AEÁA5D, ÃD ÃD, Ã+EÃ,D, ÄEÄD)Ä&D, Ä(D)Ä)D, Ä,#EÅEÅEÅEc                 ó   — t        | t        «      r| j                  d«      n| } dddddœ}| j                  d«      rh| t	        d«      d j                  «       }|r|dk(  r|S 	 t        j                  |«      }t        |t        «      rd	|v r|d	   }t        |t        «      r|S |S |S # t        j                  t        j                  f$ r Y |S w xY w)
zË
    Extract error dictionary from SSE format chunk.

    Args:
        event_line: SSE format event line, e.g. "data: {"error": {...}}

"

    Returns:
        Error dictionary in OpenAI API format
    rŽ  zUnknown errorÚinternal_server_errorNÚ500©r]  rg  ri  rj  r�  r�  r\  )rÂ   rI  r“  r”  r  r•  r–  r—  rÃ   rš  r^  )rŒ  Údefault_errorr›  r%  Ú	error_objs        r¼   Ú_extract_error_from_sse_chunkr¤  ˜  sâ   € ô 0:¸*ÄeÔ/L�×"Ñ" 7Ô+ÐR\€Jð #Ø'ØØñ	€Mð ×Ñ˜XÔ&Ø$¤S¨£] _Ð5×;Ñ;Ó=ˆÙ˜8 xÒ/Ø Ð ð	Ü Ÿ,™, xÓ0ˆDÜ˜$¤Ô%¨'°T©/Ø#'¨¡=�	Ü˜i¬Ô.Ø$Ð$ð Ðˆ=Ðøô ×&Ñ&¬×(<Ñ(<Ð=ò 	ØàÐð	ús   Á"?B& Â&#CÃCc                   óÄ   ‡ — e Zd ZdZddej
                  ddœdeedf   dedz  dedz  de	deedf   dz  d	dfˆ fd
„Z
ed	eedf   dz  fd„«       Zdededed	dfˆ fd„Zˆ xZS )Ú!_UpstreamClosingStreamingResponseaL  StreamingResponse that always closes its body iterator and the wrapped
    upstream generator.

    When the client disconnects mid-stream, Starlette abandons the body
    iterator without calling aclose(), leaving the upstream LLM connection
    open until garbage collection; the backend (e.g. vLLM) keeps generating
    into a dead pipe. The upstream generator is closed directly (not via the
    body iterator) because aclose() on a never-started generator skips its
    body, so a cascade through it would be a no-op if the client disconnects
    before the first chunk is sent.
    N©Ú
media_typer>  r<  Úupstream_generatorÚcontentr¨  r>  r<  r©  r¶   c                ó:   •— t         ‰| �  ||||¬«       || _        y )N)r<  r>  r¨  )ÚsuperÚ__init__Ú_upstream_generator)r;  rª  r¨  r>  r<  r©  Ú	__class__s         €r¼   r­  z*_UpstreamClosingStreamingResponse.__init__Ê  s$   ø€ ô 	‰Ñ˜¨kÀ7ÐWaÐÔbØ#5ˆÕ r¾   c                 ó   — | j                   S )zUThe upstream LLM stream, for a caller that has to run this response's cleanup itself.)r®  r:  s    r¼   r©  z4_UpstreamClosingStreamingResponse.upstream_generatorÖ  s   € ð ×'Ñ'Ð'r¾   ÚscopeÚreceiveÚsendc           	   ƒ   óª  •K  — 	 t         ‰| �  |||«      ƒ d {  –—†  t        j                  d¬«      5  | j                  | j
                  fD ]"  }t        |dd «      }|€Œ	  |«       ƒ d {  –—†  Œ$ 	 d d d «       y 7 Œb7 Œ# t        $ r }t        j                  d|«       Y d }~ŒWd }~ww xY w# 1 sw Y   y xY w# t        j                  d¬«      5  | j                  | j
                  fD ]O  }t        |dd «      }|€Œ	  |«       ƒ d {  –—†7   Œ%# t        $ r }t        j                  d|«       Y d }~ŒId }~ww xY w 	 d d d «       w # 1 sw Y   w xY wxY w­w)NT©ÚshieldÚaclosez%error closing streaming generator: %s)
r¬  Ú__call__ÚanyioÚCancelScopeÚbody_iteratorr®  rº   ÚBaseExceptionr   rÙ   )r;  r±  r²  r³  rŠ  r·  r  r¯  s          €r¼   r¸  z*_UpstreamClosingStreamingResponse.__call__Û  s]  øè ø€ ð	_Ü‘'Ñ" 5¨'°4Ó8×8Ð8ä×"Ñ"¨$Ô/ñ _Ø#×1Ñ1°4×3KÑ3KÐLò _�FÜ$ V¨X°tÓ<�FØ�~Ø ð_Ù$›hŸ™ñ_÷_ð _ð 9øð 'ùÜ(ò _Ü,×2Ñ2Ð3ZÐ\]×^Ñ^ûð_ú÷_ð _û”×"Ñ"¨$Ô/ñ _Ø#×1Ñ1°4×3KÑ3KÐLò _�FÜ$ V¨X°tÓ<�FØ�~Ø ð_Ù$›hŸšøÜ(ò _Ü,×2Ñ2Ð3ZÐ\]×^Ñ^ûð_úñ_÷_÷ _ñ _ÿsÌ   ƒE…B8 ™A<šB8 žE´,B,Á!
B Á+A>Á,B Á0B,Á3	EÁ<B8 Á>B Â 	B)Â	B$ÂB,Â$B)Â)B,Â,B5Â1EÂ8EÃ,EÃ<
DÄD	ÄDÄEÄ	D6ÄD1Ä,EÄ1D6Ä6EÄ;	EÅEÅ	EÅE)rB  rC  rD  Ú__doc__r   ÚHTTP_200_OKr   rê   rÃ   rF  r­  rE  r©  r   r   r   r¸  Ú__classcell__)r¯  s   @r¼   r¦  r¦  ½  sÏ   ø„ ñ
ð  "&Ø#Ø!×-Ñ-Ø?Cò
6à  T 	Ñ*ð
6ð ˜$‘Jð	
6ð
 ˜‘ð
6ð ð
6ð +¨3°¨9Ñ5¸Ñ<ð
6ð 
õ
6ð ð( N°3¸°9Ñ$=ÀÑ$Dò (ó ð(ð_ Eð _°Gð _À4ð _ÈD÷ _ñ _r¾   r¦  c                   ó   — e Zd ZdZy)Ú#_ClientDisconnectedBeforeFirstChunkz�Client went away during create_response's first-chunk buffering window.

    The upstream LLM stream has already been closed by the time this is raised.
    N)rB  rC  rD  r½  r  r¾   r¼   rÁ  rÁ  ê  s   „ òr¾   rÁ  c              ƒ   óB  K  — 	 	 | j                  «       ƒ d {  –—† }|j                  d«      dk(  ry Œ.7 Œ# t        j                  $ r ‚ t        $ rK}t        j                  d|«       t        j                  «       j                  «       ƒ d {  –—†7   Y d }~y d }~ww xY w­w)Nrg  úhttp.disconnectzicreate_response: request.receive() raised %s; first-chunk disconnect monitoring disabled for this request)	r²  rÄ   r  r  rÖ   r   r™  ÚEventÚwait)rÐ   r]  rd  s      r¼   Ú_wait_for_http_disconnectrÆ  ñ  sŠ   è ø€ ð%ØØ#ŸO™OÓ-×-ˆGØ�{‰{˜6Ó"Ð&7Ò7Øð Ø-ùô ×!Ñ!ò ØÜò %Ü×$Ñ$ØwØô	
ô
 �m‰m‹o×"Ñ"Ó$×$Ö$ûð%üsC   ‚B„5 ˜3™5 ±B²5 µBÁ;BÂBÂBÂBÂBÂBÚ	generatorc              ƒ   óà  K  — |€| j                  «       ƒ d{  –—† S t        j                  | j                  «       «      }t        j                  t        |«      «      }	 t        j                  ||ht        j
                  ¬«      ƒ d{  –—†  |j                  «       }|j                  «        	 |ƒ d{  –—†  |s0|j                  «       r |j                  «       s|j                  «       S |j                  «        t        j                  d¬«      5  	 |ƒ d{  –—†  	 | j                  «       ƒ d{  –—†  ddd«       t        j                   d«       t#        «       ‚7 �ŒE7 ŒÖ7 Œ­# t        $ r Y Œ¶w xY w# |j                  «        	 |ƒ d{  –—†7   w # t        $ r Y w w xY wxY w7 ŒŠ# t        $ r Y Œ“w xY w7 Œ‚# t        $ r }t        j                  d|«       Y d}~Œ¤d}~ww xY w# 1 sw Y   Œ­xY w­w)an  Fetch the first streamed chunk, cancelling the upstream LLM call if the
    client disconnects before it arrives.

    create_response buffers the first chunk to detect error-only streams before
    handing the StreamingResponse to Starlette, which only begins listening for
    client disconnects once it is serving that response. A disconnect during a
    long time-to-first-token would otherwise leave the upstream call running
    until the request timeout (LIT-3568). Cancelling the fetch propagates into
    async_streaming_data_generator, whose finally block records the 499 and
    closes the upstream stream.
    N)Úreturn_whenTrµ  z:create_response: error closing generator on disconnect: %szWcreate_response: client disconnected before first chunk, upstream LLM request cancelled)Ú	__anext__r  Úensure_futurerÆ  rÅ  ÚFIRST_COMPLETEDr  r  r¼  Ú	cancelledrU  r¹  rº  r·  r   rÙ   ÚinforÁ  )rÇ  rÐ   Ú
chunk_taskÚdisconnect_taskÚdisconnect_observedrd  s         r¼   Ú'_buffer_first_chunk_honoring_disconnectrÒ    sÎ  è ø€ ð €Ø×(Ñ(Ó*×*Ð*ä+2×+@Ñ+@À×ATÑATÓAVÓ+W€JÜ18×1FÑ1FÔG`ÐahÓGiÓ1j€OðÜ�l‰l˜J¨Ð8Äg×F]ÑF]Ô^×^Ð^ð
 &5×%9Ñ%9Ó%;Ðà×ÑÔ ð	Ø!×!Ð!ñ  :§?¡?Ô#4¸Z×=QÑ=QÔ=SØ× Ñ Ó"Ð"à×ÑÔÜ	×	Ñ	 $Ô	'ñ jð	Ø×Ðð	jØ×"Ñ"Ó$×$Ð$÷jô ×ÑÐwÔxÜ
-Ó
/Ð/ðA +ùð
 	_øð "ùÜò 	Ùð	ûð 	×ÑÔ ð	Ø!×!Ò!øÜò 	Ùð	ýð ùÜò 	Ùð	úð %ùÜò 	jÜ ×&Ñ&Ð'cÐeh×iÑiûð	jú÷jð jüs  ‚G.˜E™AG.Á*E3 Â	E Â
E3 ÂG.Â/E$ Â4E"Â5E$ Â9AG.ÄG"ÄF%ÄF#ÄF%ÄF6Ä1F4Ä2F6Ä6(G.Å E3 Å"E$ Å$	E0Å-G.Å/E0Å0G.Å3F ÆFÆ
FÆFÆF Æ	FÆF ÆFÆF Æ G.Æ#F%Æ%	F1Æ.G"Æ0F1Æ1G"Æ4F6Æ6	GÆ?GÇG"ÇGÇG"Ç"G+Ç'G.c                 ó  — t        | dt        j                  «      }t        | dd«      }t	        |«      \  }}t        | dd«      xs i }|ri |¥|¥n|xs d}|t        | dd«      t        | dd«      t        |«      d	œ}|r||d<   ||fS )
zÄBuild the ProxyException-shaped ``{"error": ...}`` body used in SSE error frames.

    Matches ``ProxyException.to_dict()`` so streaming and non-streaming error frames
    are byte-identical.
    r<  rZ  zError processing stream startrf  Nrg  rh  ri  r¡  )rº   r   ÚHTTP_500_INTERNAL_SERVER_ERRORr6  rc  rê   )rd  Úerror_statusrl  r]  rm  rn  ro  r£  s           r¼   Ú_sse_error_payloadrÖ  5  s®   € ô " # }´f×6[Ñ6[Ó\€LÜ'¨¨XÐ7VÓW€JÜ!AÀ*Ó!MÑ€GÐä$ SÐ*DÀdÓKÒQÈr€OÙGXÐC˜oÐCÐ1BÑCÐ_nÒ_vÐrv€Mð Ü˜˜V VÓ,Ü˜˜g vÓ.Ü�LÓ!ñ	€Iñ Ø0=ˆ	Ð,Ñ-Ø˜Ð"Ð"r¾   r£  c                 ó<   — dt        j                  d| i«      › d�dfS )zCThe two frames an SSE stream ends with once it can no longer raise.r�  r\  ú

zdata: [DONE]

)r^  r_  )r£  s    r¼   Ú_sse_error_framesrÙ  Q  s&   € à”D—J‘J ¨Ð3Ó4Ð5°TÐ:Ð<NÐNÐNr¾   r¨  Údefault_status_codec              ƒ   óÈ  ‡ ‡‡K  — i |¥dddœ¥}dŠ|}	 t        j                  ‰ «      r
‰ ƒ d{  –—† Š t        ‰ |«      ƒ d{  –—† Š‰�c	 t        ‰«      ƒ d{  –—† }|�L|}t	        j
                  d|«       t        ‰«      }	 ‰ j                  «       ƒ d{  –—†  t        |d|i|¬«      S 	 dt        t        df   fˆˆ fd„}t'         |«       |||‰ ¬«      S 7 Œ¨7 Œ–7 Œ‚7 ŒF# t        $ r Y ŒOw xY w# t        $ r }	t	        j
                  d|	«       Y d}	~	Œfd}	~	ww xY w# t        $ r- t        t        dt        d	d
t        t        «      dœi|¬«      cY S t        $ r* dt        t        df   fd„}
t!         |
«       |||¬«      cY S t        $ rW}	t	        j"                  d|	«       t%        |	«      \  }Šdt        t        df   fˆfd„}t!         |«       |||¬«      cY d}	~	S d}	~	ww xY w­w)zØ
    Create streaming response, checking if the first chunk is an error.
    If the first chunk is an error, return a standard JSON error response.
    Otherwise, return StreamingResponse and stream all content.
    úno-cacheÚno©zCache-ControlzX-Accel-BufferingNzXError detected in first stream chunk. Returning JSON error response with status code: %sr\  )r<  rª  r>  z#Error parsing first chunk value: %sÚclient_disconnectrh  r¡  r¶   c                 ó   K  — y ­wr  r  r  r¾   r¼   Ú	empty_genz"create_response.<locals>.empty_gen£  s	   è ø€ ØùrA  )r¨  r>  r<  z.Error consuming first chunk from generator: %sc                 ó8   •K  — t        ‰«      D ]  } | ­–— Œ	 y ­wr  )rÙ  )Úframer£  s    €r¼   Úerror_gen_messagez*create_response.<locals>.error_gen_message³  s    øè ø€ Ü*¨9Ó5ò �Ø”ñùs   ƒc                 ó@  •K  — t         s‰�‰­–— ‰2 3 d {  –—† } | ­–— Œ‰�'t        j                  t        «      5  ‰­–— d d d «       ‰2 3 d {  –—† } t        j                  t        «      5  | ­–— d d d «       Œ17 Œf6 y # 1 sw Y   Œ@xY w7 Œ<# 1 sw Y   ŒLxY w6 y ­wr  )r¯   r/   Útracer!   )ÚchunkÚfirst_chunk_valuerÇ  s    €€r¼   Úcombined_generatorz+create_response.<locals>.combined_generator¾  s©   øè ø€ Ý*à Ð,Ø'Ó'Ø(÷ ð �eØ”àÐ(Ü—‘ÔFÓGñ (Ø'Ó'÷(à$÷ 	ð 	�%Ü—‘ÔFÓGñ Ø“÷ð ðø˜yà÷(ð (úð	ø÷ð úñ %ùsr   ƒB“B —A>˜B ›"B½BÁ
BÁBÁBÁBÁBÁ/BÁ5	BÁ>B Â BÂBÂBÂBÂB	Â	Br§  )r  ÚiscoroutinerÒ  r�  r   rÙ   r¤  r·  rÖ   r   rÁ  r$   Ú_CLIENT_DISCONNECT_DETAILrê   ÚStopAsyncIterationr   r   Ú	exceptionrÖ  r¦  )rÇ  r¨  r>  rÚ  rÐ   Ústreaming_headersÚfinal_status_codeÚerror_code_from_chunkÚ
error_dictr  rá  rÕ  rä  ré  r£  rè  s   `             @@r¼   Úcreate_responserò  V  sN  úè ø€ ð Ø
ð à#Ø!ò Ðð
 %)ÐØ+ÐðP
ä×Ñ˜yÔ)Ø'ŸˆIô #JÈ)ÐU\Ó"]×]ÐàÐ(ðUÜ5PÐQbÓ5c×/cÐ%Ø(Ð4ð )>Ð%Ü(×.Ñ.ØrØ)ôô )FÐFWÓ(X�JðØ'×.Ñ.Ó0×0Ð0ô
 (Ø$5Ø!(¨*Ð 5Ø 'ôð ð' 5ðN¤n´S¸$°YÑ&?ö ô -ÙÓØØ!Ø%Ø$ôð ð} (øð ^øð 0døð 1ùÜ$ò Ùðûô ò UÜ$×*Ñ*Ð+PÐRS×TÑTûðUûô /ò 
ô Ü?àÜ8Ø/Ø#ÜÔ GÓHñ	ðð ô
ò 	
ô ò 
ð	¤´°T°	Ñ!:ó 	ô !Ù‹KØ!Ø%Ø+ô	
ò 	
ô ò 
ä×&Ñ&Ð'WÐYZÔ[ä"4°QÓ"7Ñˆ�ið	¬¼¸T¸	Ñ)Bõ 	ô !ÙÓØ!Ø%Ø$ô	
õ 	
ûð
üsç   …G"”D ®C¯D ÁCÁD Á
C. ÁCÁ)C. ÂC ÂCÂC ÂC. Â*G"Â+D Â,+G"ÃD ÃD ÃC. ÃC Ã	C+Ã(C. Ã*C+Ã+C. Ã.	DÃ7DÄD ÄDÄD Ä3GÅG"Å/GÅ>G"Æ GÆAGÇGÇG"ÇGÇG"rÜ  rÝ  rÞ  Ú_TTFT_KEEPALIVE_HEADERSc                 óÔ   — | j                  d«      dury| j                  d«      }|�&t        |t        «      r|j                  |¬«      xs dnd}t	        |t
        j                  «      S )a.  The operator's keepalive interval, but only for a request that asked to stream.

    Resolved through the deployments the request could land on, so a deployment's
    `keepalive_seconds: 0` stays the hard disable it is documented to be rather
    than being switched back on by the global default.
    r+  TNré   )Ú
model_namer  )rÄ   rÂ   rê   Úget_model_listr?   rý   Ú#sse_keepalive_ping_interval_seconds)r¿   r  rƒ  Údeploymentss       r¼   Úttft_keepalive_intervalrù  Þ  sp   € ð ×Ñ˜Ó!¨Ñ-ØØ)×-Ñ-¨gÓ6€Oð Ð!¤j°Ä#Ô&Fð 	×!Ñ!¨_Ð!Ó=ÒCÁàð ô
 +¨;¼×8cÑ8cÓdÐdr¾   Úproducedc              ƒ   óB  K  — t        | t        «      syt        | t        «      r| j                  | j                  fn| j                  f}|D ]"  }t        |dd«      }|€Œ	  |«       ƒ d{  –—†  Œ$ y7 Œ# t        $ r }t        j                  d|«       Y d}~ŒLd}~ww xY w­w)zÛRun the cleanup Starlette would have run, for a response it never called.

    Closing an already-closed async generator is a no-op, so this is safe to call
    from both the relay's own teardown and the outer one.
    Nr·  z-error closing relayed streaming generator: %s)	rÂ   r   r¦  r»  r©  rº   r¼  r   rÙ   )rú  ÚtargetsrŠ  r·  rd  s        r¼   Ú_aclose_late_responserý  ð  s­   è ø€ ô �hÔ 1Ô2Øô �hÔ AÔBð 
×	Ñ	 ×!<Ñ!<Ñ=à×$Ñ$Ð&ð ð
 ò ]ˆÜ˜ ¨4Ó0ˆØˆ>Øð	]Ù“(�N‰Nñ]ð
 ùÜò 	]Ü ×&Ñ&Ð'VÐX[×\Ñ\ûð	]üsB   ‚ABÁ
A3Á)A1Á*A3Á.BÁ1A3Á3	BÁ<BÂBÂBÂBc                ó  K  — t        | t        «      s(dt        | j                  «      xs dz   dz   ­–— d­–— y	 | j                  2 3 d{  –—† }t        |t
        «      r|j                  d«      n
t        |«      ­–— Œ97 Œ46 	 t        j                  d¬«      5  t        | «      ƒ d{  –—†7   ddd«       y# 1 sw Y   yxY w# t        j                  d¬«      5  t        | «      ƒ d{  –—†7   ddd«       w # 1 sw Y   w xY wxY w­w)	zOReplay a Response that was built after a keepalive had already opened the wire.s   data: s   {}s   

s   data: [DONE]

NrŽ  Trµ  )
rÂ   r   rI  Úbodyr»  rê   Úencoder¹  rº  rý  )rú  rç  s     r¼   Ú_relay_late_responser    sà   è ø€ ä�hÔ 1Ô2ð œ5 §¡Ó/Ò8°5Ñ9¸GÑCÓCØ!Ó!Øð2Ø#×1Ñ1÷ 	Tð 	T�%Ü+5°e¼SÔ+A�%—,‘,˜wÔ'ÄuÈUÃ|ÔSð	TøÑ1ô
 ×Ñ dÔ+ñ 	2Ü'¨Ó1×1Ñ1÷	2÷ 	2ñ 	2ûŒU×Ñ dÔ+ñ 	2Ü'¨Ó1×1Ñ1÷	2÷ 	2ñ 	2ÿsˆ   ‚9D	¼C ÁBÁBÁBÁ1C ÂBÂC ÂD	ÂB9Â*B-Â+B9Â0	D	Â9CÂ>D	ÃDÃC:Ã+C.
Ã,C:Ã1	DÃ:DÃ?DÄD	Úon_late_failurez=Callable[[Exception], Awaitable[HTTPException | None]] | Nonec              ƒ   óÆ   K  — |€| S 	  || «      ƒ d{  –—† }|�|S | S 7 Œ
# t         $ r}|cY d}~S d}~wt        $ r"}t        j                  d|«       | cY d}~S d}~ww xY w­w)a×  Report a late failure and return whatever should reach the client.

    ``post_call_failure_hook`` lets a callback replace the client-facing error, by
    returning a replacement or by raising one, and both are used elsewhere in this
    module. Serializing the original would leak provider detail a deployment had
    configured away, so the hook's answer wins. A callback that fails some other
    way is a bug in the callback, not a reason to lose the real error.
    Nz@post_call_failure_hook raised while reporting a late failure: %s)r   rÖ   r   rí  )rd  r  ÚreplacementÚraised_replacementÚhook_failures        r¼   Ú_sanitized_late_failurer    sq   è ø€ ð ÐØˆ
ðÙ#2°3Ó#7×7ˆð &Ð1ˆ;Ð:°sÐ:ð 8ùÜò "Ø!Õ!ûÜò Ü×&Ñ&Ð'iÐkwÔxØ�
ûðüsO   ‚A!ˆ  “”  ˜A!ž   	A©0ªA«A!°A¼AÁAÁA!ÁAÁA!Úproduce_responseÚping_interval_secondsc              ƒ   óx  ‡‡‡K  — t        |«      Š‰€
| ƒ d{  –—† S t        j                  | «      Št        j                  ‰f‰¬«      ƒ d{  –—†  ‰j	                  «       r‰j                  «       S dt        t        df   fˆˆˆfd„}t        j                  d‰«       t         |«       |t        ¬«      S 7 Œ�7 Œj­w)a  Write SSE keepalive comments while the upstream LLM call is still in flight.

    The whole time-to-first-token is spent inside `produce_response`: the upstream
    withholds its response headers until it emits its first token, so nothing has
    entered the ASGI response phase yet and the proxy writes zero bytes. An
    intermediary with an idle read timeout (AWS ALB and nginx both default to 60s)
    then drops a connection that is perfectly healthy.

    When `produce_response` does not finish within one interval, the response is
    opened immediately and `: ping` comments, which every conformant SSE client
    ignores, fill the wire until the real response is ready to be replayed onto it.
    Committing the status line that early is the cost: a failure discovered after
    the first ping reaches the client as an SSE error frame under a 200 rather than
    as an HTTP error status, and LiteLLM's own `x-litellm-*` response headers are
    not yet known. Both are why this stays off until an operator sets an interval.
    N©Útimeoutr¶   c            	     óf  •K  — 	 ‰j                  «       s:t        ­–— t        j                  ‰f‰¬«      ƒ d {  –—†  ‰j                  «       sŒ:	 ‰j	                  «       } t)        | «      2 3 d {  –—† }|­–— Œ7 Œ@# t
        $ �rw}t        j                  d|«       t        t        |‰«      ƒ d {  –—†7  «      \  }}t        |«      D ]  }|j                  «       ­–— Œ Y d }~‰j                  «       sv‰j                  «        t        j                  d¬«      5  t        j                   t"        «      5  ‰ƒ d {  –—†7   d d d «       n# 1 sw Y   nxY wd d d «       y # 1 sw Y   y xY w‰j%                  «       s}t        j                  d¬«      5  t        j                   t"        «      5  t'        ‰j	                  «       «      ƒ d {  –—†7   d d d «       n# 1 sw Y   nxY wd d d «       y # 1 sw Y   y xY wy d }~ww xY w7 �Œ‘6 	 ‰j                  «       sv‰j                  «        t        j                  d¬«      5  t        j                   t"        «      5  ‰ƒ d {  –—†7   d d d «       n# 1 sw Y   nxY wd d d «       y # 1 sw Y   y xY w‰j%                  «       s}t        j                  d¬«      5  t        j                   t"        «      5  t'        ‰j	                  «       «      ƒ d {  –—†7   d d d «       n# 1 sw Y   nxY wd d d «       y # 1 sw Y   y xY wy # ‰j                  «       sv‰j                  «        t        j                  d¬«      5  t        j                   t"        «      5  ‰ƒ d {  –—†7   d d d «       n# 1 sw Y   nxY wd d d «       w # 1 sw Y   w xY w‰j%                  «       s}t        j                  d¬«      5  t        j                   t"        «      5  t'        ‰j	                  «       «      ƒ d {  –—†7   d d d «       n# 1 sw Y   nxY wd d d «       w # 1 sw Y   w xY ww xY w­w)Nr  zBrequest failed after its SSE keepalive had opened the response: %sTrµ  )r  r=   r  rÅ  rU  rÖ   r   rí  rÖ  r  rÙ  r   r  r¹  rº  Ú
contextlibÚsuppressr¼  rÍ  rý  r  )	rú  rd  Ú_r£  rã  rç  Úintervalr  Úproduce_tasks	         €€€r¼   Úkeepalive_then_relayz8open_sse_before_first_byte.<locals>.keepalive_then_relayS  s“  øè ø€ ð 	KØ"×'Ñ'Ô)Ü,Ó,Ü—l‘l L ?¸HÔE×EÐEð #×'Ñ'Õ)ðØ".×"5Ñ"5Ó"7�ô  4°HÓ=÷ ð �eØ”ð! Fùô ó Ü$×.Ñ.ØXÐZ]ôô  2Ô8OÐPSÐUdÓ8e×2eÐ2eÓf‘��9Ü.¨yÓ9ò )�EØŸ,™,›.Ô(ð)ãð  ×$Ñ$Ô&Ø×#Ñ#Ô%Ü×&Ñ&¨dÔ3ñ +Ü#×,Ñ,¬]Ó;ñ +Ø*×*Ñ*÷+÷ +ñ +ú÷+÷ +ñ +úð "×+Ñ+Ô-ô ×&Ñ&¨dÔ3ñ KÜ#×,Ñ,¬]Ó;ñ KÜ3°L×4GÑ4GÓ4IÓJ×JÑJ÷K÷ Kñ Kú÷K÷ Kñ Kúð	 .ûð)úðùÑ=ð  ×$Ñ$Ô&Ø×#Ñ#Ô%Ü×&Ñ&¨dÔ3ñ +Ü#×,Ñ,¬]Ó;ñ +Ø*×*Ñ*÷+÷ +ñ +ú÷+÷ +ñ +úð "×+Ñ+Ô-ô ×&Ñ&¨dÔ3ñ KÜ#×,Ñ,¬]Ó;ñ KÜ3°L×4GÑ4GÓ4IÓJ×JÑJ÷K÷ Kñ Kú÷K÷ Kñ Kúð	 .øð  ×$Ñ$Ô&Ø×#Ñ#Ô%Ü×&Ñ&¨dÔ3ñ +Ü#×,Ñ,¬]Ó;ñ +Ø*×*Ñ*÷+÷ +ñ +ú÷+÷ +ñ +úð "×+Ñ+Ô-ô ×&Ñ&¨dÔ3ñ KÜ#×,Ñ,¬]Ó;ñ KÜ3°L×4GÑ4GÓ4IÓJ×JÑJ÷K÷ Kñ Kú÷K÷ Kñ Kúð	 .üsî  ƒP1…4L ¹A:ºL ÁA< Á L Á+HÁ/H Á0HÁ3L Á<
G=Â*G8Â0B3
Â1/G8Ã L Ã$6P1ÄEÄ4E	Ä:D=Ä;E	Å 	EÅ	E	ÅEÅ	P1ÅE'Å#-P1ÆG+Æ*GÇG
ÇGÇ	G+ÇG	ÇG+Ç"	P1Ç+G4Ç0P1Ç8G=Ç=L È HÈL È6P1È;I?ÉI*ÉIÉI*É!	I?É*I3	É/I?É6	P1É?JÊ-P1Ê1LËK7Ë(K+Ë)K7Ë.	LË7L 	Ë<LÌ	P1ÌLÌP1Ì7P.ÍNÍ*M?	Í0M3Í1M?	Í6	NÍ?NÎNÎ	P.ÎNÎ-P.ÏP!Ï P	Ï=P Ï>P	Ð	P!ÐPÐP!Ð	P.Ð!P*Ð&P.Ð.P1zUno upstream response after %ss, opening the SSE response early and sending keepalives)r¨  r>  )r>   r  rË  rÅ  r  rU  r   rI  r   rÎ  r   ró  )r  r	  r¨  r  r  r  r  s      ` @@r¼   Úopen_sse_before_first_byter  2  s¼   úè ø€ ô, 0Ð0EÓF€HØÐØ%×%Ð%ä!×/Ñ/Ð0@ÓA€LÜ
�,‰,˜�°Ô
9×9Ð9Ø×ÑÔð ×"Ñ"Ó$Ð$ð!K¬´u¸d°{Ñ(C÷ !KôF ×ÑØ_Ðaiôô ÙÓØÜ'ôð ð_ &øð :ús"   …B:˜B6™4B:ÁB8ÁA)B:Â8B:Úhidden_paramsc                 ó4   — ddl m} |j                  | |¬«      S )aQ  
    Check if a request went down the Azure Model Router route.

    ``model`` here is what the *client* sent, a model group alias with no ``model_router/``
    prefix, so matching on it alone only works when the operator happened to put "model-router"
    in the alias. Where the response is in hand its stamp answers this outright, so callers
    should pass ``hidden_params``.

    Args:
        model: The requested model name
        hidden_params: ``_hidden_params`` from the response, when the caller has it

    Returns:
        bool: True if this is an Azure Model Router request
    r   )ÚAzureFoundryModelInfo)ré   r  )Ú"litellm.llms.azure_ai.common_utilsr  Úis_model_router_call)ré   r  r  s      r¼   Ú_is_azure_model_router_requestr  €  s   € õ  Ià ×5Ñ5¸EÐQ^Ð5Ó_Ð_r¾   )Úreturn_raw_model_nameÚresponse_objÚlog_contextr  c           
      óf  — |s|syt        | «      }t        |t        «      r�|j                  di «      xs i }|j                  dd«      }|�|dkD  rt	        j
                  d||«       y|j                  d«      rE|j                  d«      }|rt	        j
                  d|||«       |}nt	        j
                  d	|«       yt        ||«      rt	        j
                  d
|«       yt        | t        «      r9d| vry| j                  d«      }||k7  rt	        j
                  d|||«       || d<   yt        | d«      syt        | dd«      }||k7  rt	        j
                  d|||«       	 t        | d|«       y# t        $ r7}	t	        j
                  d||t        | «      t        |	«      d¬«       Y d}	~	yd}	~	ww xY w)a*  
    Force the OpenAI-compatible `model` field in the response to match what the client requested.

    LiteLLM internally prefixes some provider/deployment model identifiers (e.g. `hosted_vllm/...`).
    That internal identifier should not be returned to clients in the OpenAI `model` field.

    Note: This is intentionally verbose at debug level. A model mismatch is a useful signal that an
    internal model identifier is being stamped/preserved somewhere in the request/response pipeline.
    We log mismatches as debug (and then restamp to the client-requested value) so these paths stay
    observable for maintainers without breaking client compatibility or alarming operators.

    Responses that omit an OpenAI-style `model` field are left unchanged (silent return),
    including dict responses with no `model` key.

    Exceptions:
    1. If a fallback occurred (indicated by x-litellm-attempted-fallbacks header),
       we preserve the actual model that was used (the fallback model).
    2. If the request was to an Azure Model Router, we preserve the actual model
       that was used (e.g., gpt-5-nano-2025-08-07) instead of the router model.
    3. If this was a fastest_response batch completion, use the winning model's
       model group name instead of the comma-separated list the client sent.
    NÚadditional_headerszx-litellm-attempted-fallbacksr   zv%s: fallback detected (attempted_fallbacks=%d), preserving actual model used instead of overriding to requested model.Ú!fastest_response_batch_completionzx-litellm-model-groupzT%s: fastest_response detected, using winning model group=%r instead of requested=%r.ze%s: fastest_response detected but no model group header found, preserving actual model from response.zs%s: Azure Model Router detected - preserving actual model used from response instead of overriding to router model.ré   zj%s: response model mismatch - requested=%r downstream=%r. Overriding response['model'] to requested model.zg%s: response model mismatch - requested=%r downstream=%r. Overriding response.model to requested model.zF%s: failed to override response.model=%r on response_type=%s. error=%sT)Úexc_info)rF   rÂ   rÃ   rÄ   r   rÙ   r  Úhasattrrº   ÚsetattrrÖ   rg  rê   )
r  rƒ  r  r  r  Úfallback_headersÚattempted_fallbacksÚwinning_modelÚdownstream_modelr  s
             r¼   Ú_override_openai_response_modelr(  •  sç  € ñ: ¡OØä1°,Ó?€MÜ�-¤Ô&à"/×"3Ñ"3Ð4HÈ"Ó"MÒ"SÐQSÐØ%5×%9Ñ%9Ð:YÐ[_Ó%`ÐØÐ*Ð/BÀQÒ/FÜ ×&Ñ&ð IØØ#ôð
 ð ×ÑÐ@ÔAØ#3×#7Ñ#7Ð8OÓ#PˆMÙÜ$×*Ñ*ØjØØ!Ø#ô	ð #0‘ä$×*Ñ*Ø{Øôð ô & o°}ÔEÜ×"Ñ"ð BØô	
ð 	ä�,¤Ô%Ø˜,Ñ&ØØ'×+Ñ+¨GÓ4ÐØ˜Ò.Ü ×&Ñ&Ø|ØØØ ô	ð !0ˆ�WÑØä�< Ô)Øä˜|¨W°dÓ;ÐØ˜?Ò*Ü×"Ñ"ØuØØØô		
ð

Ü�˜g Õ7øÜò 
Ü×"Ñ"ØTØØÜ�ÓÜ�‹FØ÷	
ò 	
ûð
ús   Å"E0 Å0	F0Å9-F+Æ+F0c                   óÖ   — e Zd ZU dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZ	edz  ed<   dZ
edz  ed<   dZedz  ed<   dZedz  ed	<   dZedz  ed
<   dZedz  ed<   y)ÚCostBreakdownHeaderValuesNÚoriginal_costÚdiscount_amountÚmargin_total_amountÚmargin_percentÚ
input_costÚoutput_costÚcache_read_costÚcache_creation_costÚreasoning_costÚtool_usage_cost)rB  rC  rD  r+  ÚfloatÚ__annotations__r,  r-  r.  r/  r0  r1  r2  r3  r4  r  r¾   r¼   r*  r*    s�   … Ø"&€M�5˜4‘<Ó&Ø$(€O�U˜T‘\Ó(Ø(,Ð˜ ™Ó,Ø#'€N�E˜D‘LÓ'Ø#€J�˜‘Ó#Ø $€K�˜‘Ó$Ø$(€O�U˜T‘\Ó(Ø(,Ð˜ ™Ó,Ø#'€N�E˜D‘LÓ'Ø$(€O�U˜T‘\Ô(r¾   r*  r/  r1  r2  c                 ó(   — | €y| |xs dz
  |xs dz
  S )zdThe stored input cost nests the cache costs inside it; headers advertise the additive split instead.Nç        r  ©r/  r1  r2  s      r¼   Ú_uncached_input_costr:    s(   € ð ÐØØ˜Ò/¨CÑ0Ð4GÒ4NÈ3ÑOÐOr¾   r8  )r+  r,  r-  r.  r/  r0  r4  Ú_ZERO_COST_BREAKDOWNÚresponse_costc                 óZ   — | �| dk(  ry	 t        | «      dk(  S # t        t        f$ r Y yw xY w)a  Whether the total these headers carry is zero, counting a total no route ever priced as one.

    A component split is only reported as zero alongside a total that agrees with it, so a read
    that did price normally never advertises a real total beside an all-zero split.
    rP  Tr8  F)r5  Ú	TypeErrorr˜  )r<  s    r¼   Ú_totals_to_zeror?  )  s@   € ð Ð °Ò 3ØðÜ�]Ó# sÑ*Ð*øÜ”zÐ"ò Ùðús   Š ˜*©*rÒ   c                 óR  — | rt        | d«      s
t        «       S | j                  }|s-| j                  t        v rt        |«      rt        S t        «       S t        |j                  d«      |j                  d«      |j                  d«      |j                  d«      t        |j                  d«      |j                  d«      |j                  d«      ¬	«      |j                  d
«      |j                  d«      |j                  d«      |j                  d«      |j                  d«      ¬«
      S )a¯  Extract discount, margin, and per-component cost information from logging object's cost breakdown.

    A non-inference call that priced at zero never records a breakdown, so its components are
    reported as zero here. Any such call that did price normally (retrieving a background response,
    and the cost poller's read of one) reports the breakdown it stored, or nothing at all when the
    breakdown has not landed yet.
    Úcost_breakdownr+  r,  r-  r.  r/  r1  r2  r9  r0  r3  r4  )
r+  r,  r-  r.  r/  r0  r1  r2  r3  r4  )	r"  r*  rA  Ú	call_typer&   r?  r;  rÄ   r:  )rÒ   r<  rA  s      r¼   Ú$_get_cost_breakdown_from_logging_objrC  7  s  € ñ ¤gÐ.AÐCSÔ&TÜ(Ó*Ð*à/×>Ñ>€NÙØ×(Ñ(Ô,DÑDÌÐYfÔIgÜ'Ð'Ü(Ó*Ð*ä$Ø$×(Ñ(¨Ó9Ø&×*Ñ*Ð+<Ó=Ø*×.Ñ.Ð/DÓEØ%×)Ñ)Ð*:Ó;Ü'Ø%×)Ñ)¨,Ó7Ø*×.Ñ.Ð/@ÓAØ .× 2Ñ 2Ð3HÓ Iô
ð
 #×&Ñ& }Ó5Ø&×*Ñ*Ð+<Ó=Ø*×.Ñ.Ð/DÓEØ%×)Ñ)Ð*:Ó;Ø&×*Ñ*Ð+<Ó=ôð r¾   c                 óÎ   — ddl m} | xs i }dD ]T  }|j                  |«      }t        |t        «      sŒ%|j                  d«      }t        |t        «      sŒG ||«      }|€ŒR|c S  y)aT  Cost of the auto-router's LLM classifier call, read from the request's routing_decision.

    The pre-routing hook records the decision in `litellm_metadata` on messages/batch-style
    routes and in `metadata` on chat-style routes, so both buckets are consulted, in the same
    precedence `get_or_create_metadata_bucket` writes them.
    r   )Úclassifier_cost_from_decision©rÈ   rÆ   Úrouting_decisionN)Ú$litellm.proxy.spend_tracking.savingsrE  rÄ   rÂ   rÃ   )r¿   rE  r%  Úmetadata_keyrÆ   ÚdecisionÚcosts          r¼   Ú"_classifier_cost_from_request_datarL  ]  st   € õ SàÒ$ "€DØ8ò 
ˆØ—8‘8˜LÓ)ˆÜ˜(¤DÔ)ØØ—<‘<Ð 2Ó3ˆÜ˜(¤DÔ)ØÙ,¨XÓ6ˆØˆ<ØØŠð
ð r¾   c                 óP  — | g}t        «       }d}|r•|t        k  rŒ|j                  «       }t        |«      }||v rŒ+|j	                  |«       t        |t        «      rydD ]4  }t        ||d«      }|€Œt        |t        «      sŒ$|j                  |«       Œ6 |dz  }|r
|t        k  rŒŒy)a  Walk the exception chain to find an AttributeError at any depth.

    Checks __cause__, __context__, and the litellm-specific original_exception
    attribute iteratively. Depth is capped at DEFAULT_MAX_RECURSE_DEPTH to
    avoid infinite loops from circular exception references.
    r   T)Ú	__cause__Ú__context__Úoriginal_exceptionNé   F)
rw  r"   ÚpopÚidrx  rÂ   ÚAttributeErrorrº   r¼  Úappend)rd  ÚstackÚseenÚdepthÚcurrentÚexc_idÚattrÚinners           r¼   Ú_has_attribute_error_in_chainr]  u  s®   € ð *-¨€EÜ›E€DØ€EÙ
�EÔ5Ò5Ø—)‘)“+ˆÜ�G“ˆØ�T‰>ØØ�‰�ÔÜ�gœ~Ô.ØØFò 	$ˆDÜ˜G T¨4Ó0ˆEØÑ ¤Z°´}Õ%EØ—‘˜UÕ#ð	$ð 	�‰
ˆñ �EÔ5Ó5ð r¾   rë  r  c                 ó   — t        | dd «      dk(  r*t        | dd «      t        k(  rt        j                  d«       y t	        | «      r t
        j                  st        j                  nt        j                  } |d| «       y )Nr<  éó  rZ  zklitellm.proxy.proxy_server._handle_llm_api_exception(): client disconnected, upstream LLM request cancelledzNlitellm.proxy.proxy_server._handle_llm_api_exception(): Exception occured - %s)	rº   rë  r   rÎ  r-   rý   Úlog_client_error_tracebacksr\  rí  )r  Úlog_fns     r¼   Ú_log_llm_api_exceptionrb  ’  ss   € Üˆq�- Ó&¨#Ò-´'¸!¸XÀtÓ2LÔPiÒ2iÜ×!Ñ!Øyô	
ð 	ô $ AÔ&¬w×/RÒ/Rô 	×"Ò"ä!×+Ñ+ð ñ
 Ð[Ð]^Õ_r¾   Úllm_api_callzasyncio.Future[_LlmCallT]Údisconnect_eventc              ƒ   óî   K  — 	 	 | j                  «       ƒ d {  –—† }|d   dk(  r!|j                  «        |j                  «        y ŒB7 Œ.# t        $ r }t	        j
                  d|«       Y d }~y d }~ww xY w­w)Nrg  rÃ  zhcancel_on_disconnect: request.receive() raised %s; upstream LLM call will not be cancelled on disconnect)r²  rw  r  rÖ   r   r™  )rÐ   rc  rd  r]  rd  s        r¼   Ú%_cancel_llm_call_on_client_disconnectrf     sw   è ø€ ð

ØØ#ŸO™OÓ-×-ˆGØ�v‰Ð"3Ò3Ø ×$Ñ$Ô&Ø×#Ñ#Ô%Øð Ø-ùô
 ò 
Ü×$Ñ$ØvØ÷	
ñ 	
ûð
üs>   ‚A5„A	 ˜A™,A	 ÁA5ÁA	 Á		A2ÁA-Á(A5Á-A2Á2A5c              ƒ   óH  K  — t        j                  «       }t        j                  t        | ||«      «      }	 |ƒ d {  –—† |j	                  «        S 7 Œ# t         j
                  $ r# |j                  «       rt        dt        ¬«      ‚‚ w xY w# |j	                  «        w xY w­w)Nr_  rv  )	r  rÄ  Úcreate_taskrf  r  r  Úis_setr   rë  )rÐ   rc  rd  Úmonitors       r¼   Ú(_await_llm_call_cancelling_on_disconnectrk  ³  s‘   è ø€ ô &Ÿm™m›oÐÜ×(Ñ(Ô)NÈwÐXdÐfvÓ)wÓx€Gð
Ø!×!ð 	�‰Õð "ùÜ×!Ñ!ò Ø×"Ñ"Ô$ÜØÜ0ôð ð 	ðûð 	�‰Õüs8   ‚5B"¸A ½A¾A ÁB"ÁA Á6B
Â
B ÂBÂB"c            )       ót	  — e Zd Zdefd„Zedddddddddi dddœdededz  dedz  dedz  d	edz  d
edz  dedz  deez  dz  de	ee
f   dz  dedz  dedz  deej                  z  dz  dedz  defd„«       Zede
dedededed
edz  dedeeef   fd„«       Z	 	 	 	 	 	 	 	 dodedededededed   d
edz  dedz  dedz  dedz  d edz  d!edz  d"edz  d#edz  deeef   fd$„Zdedededed
edz  dededz  dedz  dedz  d edz  d!edz  d"edz  ded#edz  deeef   fd%„Zd"ed#edededz  fd&„Zedededefd'„«       Zededz  dedz  fd(„«       Zedededeez  fd)„«       Zdpd*„Z 	 	 	 	 	 	 	 	 	 	 	 	 dqded+e!dede"dedeee
f   ded,e#d-e
f   dz  d#edz  d"edz  dedz  dedz  dedz  d edz  d!edz  d
edz  d.edz  d/ee
   dz  d0edef(d1„Z$	 	 	 	 	 	 	 	 	 	 	 	 dqded+e!dede"dedeee
f   ded,e#d-e
f   dz  d#edz  d"edz  dedz  dedz  dedz  d edz  d!edz  d
edz  d.edz  d/ee
   dz  d0edef(d2„Z%ede
deddfd3„«       Z&ed4e
de
fd5„«       Z'ed6e
d7edefd8„«       Z(	 	 	 	 	 	 	 	 doded+e!dedededed,e#d#edz  d"edz  dedz  dedz  dedz  d edz  d!edz  d
edz  fd9„Z)dedefd:„Z*drded.edz  defd;„Z+edefd<„«       Z,defd=„Z-defd>„Z.dedz  fd?„Z/dedd@ddAdBedCeeef   de!dz  fdD„Z0dEe1dd@ddAde1fdF„Z2ededGeddfdH„«       Z3edIedJdAdKedLedMe
ddfdN„«       Z4dOedPe5ddfdQ„Z6	 dsdPe5deded
edz  fdR„Z7edSedefdT„«       Z8e	 	 	 	 dtdedz  dededUedVededz  dedz  ddfdW„«       Z9eddXœdededededYe:dZe;dedz  de<edf   fd[„«       Z=e	 dsdedededededz  de<edf   fd\„«       Z>e?e	 dsdSe1d]ededz  de1fd^„«       «       Z@e?e	 dsdSe
d]ededz  de
fd_„«       «       Z@e	 dsdSe
d]ededz  de
fd`„«       Z@e	 dsdaed]ededz  dedz  fdb„«       ZAedce	eef   de	eef   fdd„«       ZBedee	ee
f   dce	eef   deCdz  fdf„«       ZDedgeEd]edhedz  dedz  fdi„«       ZFedgeEdededz  fdj„«       ZGedgeEd]edhedz  dedz  dedz  f
dk„«       ZHe	 dsdeed]ededz  dedz  fdl„«       ZIdmedz  dedz  fdn„ZJy)uÚProxyBaseLLMRequestProcessingr%  c                 ó   — || _         y r  )r%  )r;  r%  s     r¼   r­  z&ProxyBaseLLMRequestProcessing.__init__Ç  s	   € Øˆ�	r¾   N)Úcall_idÚmodel_idÚ	cache_keyÚapi_baseÚversionÚmodel_regionr<  r  r   r¿   r  rÒ   r}  ro  rp  rq  rr  rs  rt  r<  r  r   r¿   r  rÒ   r¶   c                 ól  — h d£}|xs i }t        ||¬«      }| j                  xs d}|}|�(	 t        |t        «      rt	        |«      n|}|dkD  r||z   }t        j                  |«      }t        |
«      }i d|“d|“d|“d|“d	|r|j                  d
«      d   nd “d|“d|“dt        |«      “d|j                  �t        |j                  «      nd “d|j                  �t        |j                  «      nd “d|j                  �t        |j                  «      nd “d|j                  �t        |j                  «      nd “d|j                  �t        |j                  «      nd “d|j                   �t        |j                   «      nd “d|j"                  �t        |j"                  «      nd “d|j$                  �t        |j$                  «      nd “d|j&                  �t        |j&                  «      nd “|j(                  �t        |j(                  «      nd |�t        |«      nd t        | j*                  «      t        | j,                  «      t        | j.                  «      t        |«      t        |j1                  dd «      «      t        |j1                  dd «      «      t        |j1                  dd «      «      dœ	¥t2        rkt        |j1                  dd «      «      t        |j1                  dd «      «      t        |j1                  dd «      «      t        |j1                  dd «      «      dœni ¥|	�t        |	«      nd |�t        |«      nd d œ¥|j5                  «       D ��ci c]  \  }}|t        |«      “Œ c}}¥}|
r:t7        |
«      }|j9                  |«       t;        |
«      }|r|j9                  |«       	 |j5                  «       D ��ci c]  \  }}||vsŒ|t        |«      “Œ c}}S # t
        t        f$ r Y �Œ¤w xY wc c}}w c c}}w # t<        $ r"}t?        j@                  d!|«       i cY d }~S d }~ww xY w)"N>   NrP  rh  )rÒ   r<  r8  r   úx-litellm-call-idzx-litellm-model-idzx-litellm-model-namezx-litellm-cache-keyzx-litellm-model-api-baseú?zx-litellm-versionzx-litellm-model-regionzx-litellm-response-costz x-litellm-response-cost-originalz'x-litellm-response-cost-discount-amountz%x-litellm-response-cost-margin-amountz&x-litellm-response-cost-margin-percentzx-litellm-response-cost-inputzx-litellm-response-cost-outputz"x-litellm-response-cost-cache-readz&x-litellm-response-cost-cache-creationz!x-litellm-response-cost-reasoningÚ_response_msÚlitellm_overhead_time_msÚcallback_duration_ms)	z"x-litellm-response-cost-tool-usagezx-litellm-classifier-costzx-litellm-key-tpm-limitzx-litellm-key-rpm-limitzx-litellm-key-max-budgetzx-litellm-key-spendzx-litellm-response-duration-mszx-litellm-overhead-duration-mszx-litellm-callback-duration-msÚtiming_pre_processing_msÚtiming_llm_api_msÚtiming_post_processing_msÚtiming_message_copy_ms)z"x-litellm-timing-pre-processing-mszx-litellm-timing-llm-api-msz#x-litellm-timing-post-processing-msz x-litellm-timing-message-copy-ms)z+x-litellm-fastest_response_batch_completionzx-litellm-timeoutz Error setting custom headers: %s)!rC  ÚspendrÂ   rê   r5  r˜  r>  rm  Ú_get_deployment_model_namerL  Úsplitr+  r,  r-  r.  r/  r0  r1  r2  r3  r4  Ú	tpm_limitÚ	rpm_limitÚ
max_budgetrÄ   r#   Úitemsr<   Úupdater;   rÖ   r   r\  )r}  ro  rp  rq  rr  rs  rt  r<  r  r   r¿   r  rÒ   ÚkwargsÚexclude_valuesrA  Úcurrent_spendÚupdated_spendÚ
cost_valuerõ  Úclassifier_costÚkÚvr>  Úremaining_tokens_headerÚlogging_caching_headersrN  r2  r  s                                r¼   Úget_custom_headersz0ProxyBaseLLMRequestProcessing.get_custom_headersÊ  sž  € ò$ !3ˆØ%Ò+¨ˆä DØ 3À=ô!
ˆð
  1×6Ñ6Ò=¸#ˆØ%ˆØÐ$ðä<FÀ}ÔVYÔ<Z¤E¨-Ô$8Ð`m�
Ø ’>Ø$1°JÑ$>�Mô
 :×TÑTÐUhÓiˆ
Ü!CÀLÓ!Qˆð@
Ø ð@
à  (ð@
ð # Jð@
ð " 9ð	@
ð
 'Ù*2�—‘˜sÓ# AÒ&¸ð@
ð   ð@
ð % lð@
ð &¤s¨=Ó'9ð@
ð /Ø5C×5QÑ5QÐ5]”�N×0Ñ0Ô1Ðcgð@
ð 6Ø7E×7UÑ7UÐ7a”�N×2Ñ2Ô3Ðgkð@
ð" 4Ø;I×;]Ñ;]Ð;i”�N×6Ñ6Ô7Ðosð%@
ð( 5Ø6D×6SÑ6SÐ6_”�N×1Ñ1Ô2Ðeið+@
ð. ,Ø2@×2KÑ2KÐ2W”�N×-Ñ-Ô.Ð]að1@
ð4 -Ø3A×3MÑ3MÐ3Y”�N×.Ñ.Ô/Ð_cð7@
ð: 1Ø7E×7UÑ7UÐ7a”�N×2Ñ2Ô3Ðgkð=@
ð@ 5Ø;I×;]Ñ;]Ð;i”�N×6Ñ6Ô7ÐosðC@
ðF 0Ø6D×6SÑ6SÐ6_”�N×1Ñ1Ô2ÐeiðI@
ðN 8F×7UÑ7UÐ7a”�N×2Ñ2Ô3ÐgkàBQÐB]¬#¨oÔ*>ÐcgÜ'*Ð+<×+FÑ+FÓ'GÜ'*Ð+<×+FÑ+FÓ'GÜ(+Ð,=×,HÑ,HÓ(IÜ#& }Ó#5Ü.1°-×2CÑ2CÀNÐTXÓ2YÓ.ZÜ.1°-×2CÑ2CÐD^Ð`dÓ2eÓ.fÜ.1°-×2CÑ2CÐDZÐ\`Ó2aÓ.bòa@
õp +ô ;>¸m×>OÑ>OÐPjÐlpÓ>qÓ:rÜ36°}×7HÑ7HÐI\Ð^bÓ7cÓ3dÜ;>¸}×?PÑ?PÐQlÐnrÓ?sÓ;tÜ8;¸M×<MÑ<MÐNfÐhlÓ<mÓ8nò	ð ðs@
ðx ;\Ð:g”Ð5Ô6Ðmqà18Ð1D¤ W¤È$ò}@
ð~ &,§\¡\£^×4™T˜Q ˆq”#�a“&‰yÓ4ð@
ˆñB Ü-`ÐamÓ-nÐ#Ø�N‰NÐ2Ô3ä-HÈÓ-VÐ#Ù&Ø—‘Ð6Ô7ð	Ø6=·m±m³o×e©
¨¨UÈÐVdÒId�Cœ˜U›‘OÓeÐeøôc ¤	Ð*ò âðüóL 5ùó føÜò 	Ü ×&Ñ&Ð'IÈ1ÔMØ�Iûð	úsM   ­'O& ÍO<Î4P ÏPÏPÏ"P Ï&O9Ï8O9ÐP Ð	P3ÐP.Ð(P3Ð.P3rµ   rÐ   rÛ   Úproxy_logging_objc              ƒ   ó„  K  — t        | t        «      rt        | «      }nt        | dd«      xs i }t        |t        «      si }t        j                  ||«      }|j                  dd«      xs d}	|j                  dd«      xs d}
|j                  dd«      xs d}|j                  dd«      }|j                  di «      xs i }t	        j                  d||j                  ||	|
||t        |d	d«      ||||d
œ|¤Ž}|j                  ||| t        |j                  «      ¬«      ƒ d{  –—† }|r|j                  |«       |S 7 Œ­w)z¯
        Build LiteLLM proxy response headers for routes that call the LLM directly
        (e.g. Google native :generateContent) instead of base_process_llm_request.
        Ú_hidden_paramsNrq  rP  rr  r<  r   r  Úallowed_model_region©r}  ro  rp  rq  rr  rs  r<  rt  r   r¿   r  rÒ   ©r%  r}  rµ   Úrequest_headersr  )rÂ   rÃ   rF   rº   rm  Ú_get_model_id_from_responserÄ   r‘  rÔ   Úpost_call_response_headers_hookr>  r†  )rµ   r¿   rÐ   r}  rÛ   rs  r’  r  rp  rq  rr  r<  r   r  Úcustom_headersÚcallback_headerss                   r¼   Ú5build_litellm_proxy_success_headers_from_llm_responsezSProxyBaseLLMRequestProcessing.build_litellm_proxy_success_headers_from_llm_responseB  sm  è ø€ ô �h¤Ô%Ü2°8Ó<‰Mä# HÐ.>ÀÓEÒKÈˆMÜ˜-¬Ô.ØˆMä7×SÑSÐTaÐcoÓpˆà(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆØ,×0Ñ0°À$ÓGÒMÈ2ˆØ3@×3DÑ3DÐEhÐjnÓ3oÐ)Ø$1×$5Ñ$5Ð6JÈBÓ$OÒ$UÐSUÐä =× PÑ Pð !
Ø/Ø×/Ñ/ØØØØØ'Ü Ð!2Ð4JÈBÓOØ.OØ%Ø'Ø +ñ!
ð !ñ!
ˆð  ):×(YÑ(YØØ/ØÜ  §¡Ó1ð	 )Zó )
÷ #
Ðñ Ø×!Ñ!Ð"2Ô3àÐð#
ús   ‚D"E Ä$D>Ä%E r&  Úproxy_configr'  )YrM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r}   r~   r   r€   r�   r‚   rƒ   r„   r…   r†   r‡   rˆ   r‰   rŠ   r‹   rŒ   r�   rŽ   r�   r�   r‘   r’   r“   r”   r•   r–   r—   r˜   r™   rš   r›   rœ   r�   rž   rŸ   r    r¡   r¢   r£   r¤   Úapply_guardrailÚ
user_modelÚuser_temperatureÚuser_request_timeoutÚuser_max_tokensÚuser_api_baseré   r  c           
   ƒ   óº
  ‡ ‡‡K  — t        j                  «       }t        ‰ j                  ||‰||¬«      ƒ d {  –—† ‰ _        |j	                  d«      s‰ j                  j                  dd «       |dv rt        ‰ j                  ‰¬«      ƒ d {  –—†  ‰ j                  j	                  di «      }|j	                  d«      }d }|�|j                  «       |z
  }|�idd	lm	}  ||«      }|‰ j                  vri ‰ j                  |<   t        ‰ j                  |   t        «      si ‰ j                  |<   |‰ j                  |   d
<   t        |t        «      rt        d|«       |j	                  dd «      xs$ |xs  |xs ‰ j                  j	                  dd «      ‰ j                  d<   |	r|	‰ j                  d<   |
r|
‰ j                  d<   |r|‰ j                  d<   |r|‰ j                  d<   t        ‰ j                  d   t        «      rL‰ j                  d   t        j                  v r-t        j                  ‰ j                  d      ‰ j                  d<   t        ‰ j                  d   t        «      rj‰j                   r^t        ‰j                   t        «      rD‰ j                  d   ‰j                   v r)‰j                   ‰ j                  d      ‰ j                  d<   ‰�v|�tddlm} |j'                  ‰||¬«      ƒ d {  –—† }|�P|‰ j                  d<   t)        ‰ j                  j	                  d«      |‰‰¬«      ƒ d {  –—† }|�|‰ j                  d<   |j*                  j	                  dt        t-        j.                  «       «      «      ‰ j                  d<   t1        j2                  ‰ j                  j	                  d«      «       t1        j4                  ‰‰ j                  j	                  d«      ¬«       ‰ j                  j7                  t9        ‰ j                  ||ˆˆ ˆfd„¬«      «       t        j:                  j<                  d!|t        j:                  j?                  «       |dœ‰ j                  ¤Ž\  }‰ _        |‰ j                  d<   tA        ‰ j                  ‰d¬«      ‰ _        |jC                  ‰‰ j                  |¬«      ƒ d {  –—† ‰ _        tE        ‰ j                  «       tG        jH                  d‰ j                  «       d ‰ j                  v r-‰ j                  d    r|jK                  ‰ j                  d    «       ‰ j                  |fS 7 �Œ7 �ŒÃ7 �Œ\7 �Œ7 Œ“­w)"N)r%  rÐ   r&  r}  rs  rž  Ú expose_fallback_errors_to_callerÚinclude_fallback_errors>   rO   rQ   )r%  r}  Úproxy_server_requestÚarrival_timer   )Ú_get_metadata_variable_nameÚqueue_time_secondsré   Úcompletion_modelÚtemperatureÚrequest_timeoutÚ
max_tokensrr  )Úprisma_client)r}  r°  r’  Úrouter_settings_override)rƒ  r„  r}  r  rv  rÔ   )r}  rƒ  c                  óf   •— t        ‰j                  j                  d«      ‰ ‰j                  ¬«      S )Nré   )ré   r  r  )r$  r%  rÄ   r  )r  r;  r}  s   €€€r¼   ú<lambda>zPProxyBaseLLMRequestProcessing.common_processing_pre_call_logic.<locals>.<lambda>]  s)   ø€ Ô0YØŸ)™)Ÿ-™-¨Ó0Ø)Ø-×5Ñ5ô1€ r¾   )r%  r&  r'  r(  )Úoriginal_functionÚ	rules_objrú   rÒ   F)r%  r  Útrust_client_model_info)r}  r%  rB  zreceiving data: %srö   r  )&r	   Únowr¨   r%  rÄ   rR  r‚  Ú	timestampÚ$litellm.proxy.litellm_pre_call_utilsrª  rÂ   rÃ   rê   rª   rý   Úmodel_alias_mapÚaliasesÚlitellm.proxy.proxy_serverr°  Ú!_get_hierarchical_router_settingsr‹  r>  r    Úuuid4rA   Útag_call_idÚtag_requestr†  r1  ÚutilsÚfunction_setupÚRulesrD   Úpre_call_hookr©   r   rÙ   Úupdate_messages)r;  rÐ   r&  r}  r’  rž  r'  rs  r   r¡  r¢  r£  r¤  ré   r  rú   r¨  r©  r«  rª  Ú_metadata_variable_namer°  r„  Úalias_targetrÛ   s   `  `          `          r¼   Ú common_processing_pre_call_logicz>ProxyBaseLLMRequestProcessing.common_processing_pre_call_logic{  sÓ  úè ø€ ôV %ŸL™L›Nˆ
ä5Ø—‘ØØ-Ø/ØØ%ô
÷ 
ˆŒ	ð  ×#Ñ#Ð$FÔGØ�I‰I�M‰MÐ3°TÔ:ØÐ@Ñ@Ü?Ø—Y‘YØ"3ô÷ ð ð '+§i¡i§m¡mÐ4JÈBÓ&OÐØ2×6Ñ6°~ÓFˆØ!ÐØÐ#Ø!+×!5Ñ!5Ó!7¸,Ñ!FÐð Ð)ÝXá-HÈÓ-QÐ#Ø&¨d¯i©iÑ7Ø57�—	‘	Ð1Ñ2Ü˜dŸi™iÐ(?Ñ@Ä$ÔGØ57�—	‘	Ð1Ñ2ØGYˆD�I‰IÐ-Ñ.Ð/CÑDä�eœSÔ!Ü)¨'°5Ô9ð × Ñ Ð!3°TÓ:ò ,Øò,àò,ð �y‰y�}‰}˜W dÓ+ð	 	�	‰	�'Ññ Ø'7ˆD�I‰I�mÑ$ÙØ+?ˆD�I‰IÐ'Ñ(ÙØ&5ˆD�I‰I�lÑ#ÙØ$1ˆD�I‰I�jÑ!ô
 �d—i‘i Ñ(¬#Ô.°4·9±9¸WÑ3EÌ×I`ÑI`Ñ3`Ü!(×!8Ñ!8¸¿¹À7Ñ9KÑ!LˆD�I‰I�gÑô �t—y‘y Ñ)¬3Ô/Ø!×)Ò)ÜÐ,×4Ñ4´dÔ;Ø—	‘	˜'Ñ"Ð&7×&?Ñ&?Ñ?à!2×!:Ñ!:¸4¿9¹9ÀWÑ;MÑ!NˆD�I‰I�gÑð Ð! lÐ&>Ý@à+7×+YÑ+YØ"3Ø+Ø"3ð ,Zó ,÷ &ˆOð Ð*Ø8G�—	‘	Ð4Ñ5Ü,RØ$(§I¡I§M¡M°'Ó$:Ø$3Ø&7Ø)ô	-÷ '�ð  Ð+Ø)5�D—I‘I˜gÑ&à'.§¡×':Ñ':Ð;NÔPSÔTX×T^ÑT^ÓT`ÓPaÓ'bˆ�	‰	Ð#Ñ$Ü× Ñ  §¡§¡Ð/@Ó!AÔBÜ× Ñ Ø/Ø ŸI™IŸM™M¨'Ó2õ	
ð 	�	‰	×ÑÜ*Ø—Y‘YØ!1Ø%õ)ô		ô	
ô  ")§¡×!=Ñ!=ð "
Ø(Ü—m‘m×)Ñ)Ó+Ø!ñ"
ð �i‰iñ	"
Ñˆ�T”Yð ,7ˆ�	‰	Ð'Ñ(ô <Ø—‘Ø!Ø$)ô
ˆŒ	ð ,×9Ñ9Ø/Ø—‘Ø ð :ó 
÷ 
ˆŒ	ô 	3°4·9±9Ô=Ü×"Ñ"Ð#7¸¿¹ÔCà˜Ÿ™Ñ" t§y¡y°Ò'<Ø×'Ñ'¨¯	©	°*Ñ(=Ô>à�y‰y˜+Ð%Ð%ðO
ùðùðR&ùð'ùðr
ús\   …3U¸U¹AUÂUÂI)UË7UË8A UÌ8UÌ9FUÓUÓBUÕUÕUÕUÕUc              ƒ   ób  K  — ddl m} 	 | j                  |||||||||	|
||||¬«      ƒ d {  –—† S 7 Œ# |$ rô}| j                  j	                  d«      }|r|r| j                  j	                  d«      r‚ | j                  |||¬«      }|s‚ t        j                  d||«       	 |D ]Q  }||k(  rŒ	|| j                  d<   	 | j                  |||||||||	|
||||¬«      ƒ d {  –—†7  c cY d }~S # |$ r Y ŒOw xY w n# t        $ r || j                  d<   ‚ w xY w|| j                  d<   |‚d }~ww xY w­w)Nr   )ÚProxyRateLimitError©rÐ   r&  r’  r}  rs  rž  r   r¡  r¢  r£  r¤  ré   r'  r  ré   Údisable_fallbacks)ré   r  r}  z;Local rate limit hit for model=%s, attempting fallbacks: %s)	Ú1litellm.proxy.common_utils.proxy_rate_limit_errorrÊ  rÈ  r%  rÄ   Ú_resolve_fallback_modelsr   rÎ  r¼  )r;  rÐ   r&  r’  r}  rs  rž  r   r¡  r¢  r£  r¤  ré   r'  r  rÊ  Úoriginal_excÚoriginal_modelÚfallback_modelsÚfallback_models                       r¼   Ú_pre_call_with_fallbacksz6ProxyBaseLLMRequestProcessing._pre_call_with_fallbacks‘  s£  è ø€ õ" 	ZðA	Ø×>Ñ>ØØ!1Ø"3Ø"3ØØ)Ø%Ø!1Ø%9Ø /Ø+ØØ%Ø%ð ?ó ÷ ð ð ùð  #ò 0	Ø$(§I¡I§M¡M°'Ó$:ˆNÙ!©°t·y±y·}±}ÐEXÔ7YØà%)×%BÑ%BØ$Ø%Ø"3ð &Có &ˆOñ
 #Øä ×%Ñ%ØMØØôðØ&5ò !�NØ%¨Ò7Ø Ø)7�D—I‘I˜gÑ&ð!Ø%)×%JÑ%JØ$+Ø-=Ø.?Ø.?Ø$+Ø)5Ø'1Ø-=Ø1EØ,;Ø*7Ø"0Ø'1Ø'1ð &Kó &÷  ð  ÷ øð  /ò !Ù ð!úñ+!øô. !ò Ø%3�—	‘	˜'Ñ"Øðúð "0ˆD�I‰I�gÑØÐûða0	üs…   ‚D/Š"3 ¬1­3 °D/±3 ³D,¸A)D'Â"C9Â="C,ÃC"Ã C,Ã$C9Ã&D,Ã'D/Ã,C4Ã1C9Ã3C4Ã4C9Ã8D'Ã9DÄD'Ä'D,Ä,D/c                 ó´   — ddl m} d }|j                  }t        |t        «      r	d|v r|d   }|€|j
                  }|sy  |||¬«      \  }}|€
|�||   d   }|S )Nr   )Úget_fallback_model_groupÚ	fallbacks)rÖ  Úmodel_groupÚ*)Ú,litellm.router_utils.fallback_event_handlersrÕ  r„  rÂ   rÃ   rÖ  )	r;  ré   r  r}  rÕ  rÖ  Úkey_router_settingsÚfallback_model_groupÚgeneric_fallback_idxs	            r¼   rÎ  z6ProxyBaseLLMRequestProcessing._resolve_fallback_modelsç  s‰   € õ 	Zàˆ	à%6×%FÑ%FÐÜÐ)¬4Ô0°[ÐDWÑ5WØ+¨KÑ8ˆIàÐØ"×,Ñ,ˆIáØá5MØØô6
Ñ2ÐÐ2ð  Ð'Ð,@Ð,LØ#,Ð-AÑ#BÀ3Ñ#GÐ Ø#Ð#r¾   c                 óº   — | j                  dd«      xs d}|sB|j                  di «      xs i }|j                  di «      xs i }|j                  dd«      xs d}|S )zFExtract model_id from hidden_params with fallback to litellm_metadata.rp  NrP  rÈ   Ú
model_inforS  )rÄ   )r  r%  rp  rÈ   rÞ  s        r¼   r™  z9ProxyBaseLLMRequestProcessing._get_model_id_from_response  sf   € ð !×$Ñ$ Z°Ó6Ò<¸"ˆÙØ&*§h¡hÐ/AÀ2Ó&FÒ&LÈ"ÐØ 0× 4Ñ 4°\À2Ó FÒ LÈ"ˆJØ!—~‘~ d¨BÓ/Ò5°2ˆHØˆr¾   c                 ó¨   — t        | dd«      }t        |t        «      sydD ]/  }|j                  |i «      xs i }|j                  d«      }|sŒ-|c S  y)a”  Extract the underlying deployment model string (e.g. ``azure/gpt-4o``).

        The router rewrites the response ``model`` field to the model-group alias
        the client requested, so neither the response body nor the existing
        headers expose the concrete deployment model. The router records it under
        ``litellm_params`` metadata as ``deployment``, so read it back from there.
        rÓ   NrF  Ú
deployment)rº   rÂ   rÃ   rÄ   )rÒ   rÓ   rN  rÆ   rà  s        r¼   r€  z8ProxyBaseLLMRequestProcessing._get_deployment_model_name  sc   € ô !(Ð(;Ð=MÈtÓ TˆÜ˜.¬$Ô/ØØ3ò 	"ˆCØ%×)Ñ)¨#¨rÓ2Ò8°bˆHØ!Ÿ™ lÓ3ˆJÚØ!Ò!ð		"ð
 r¾   c                 óÒ   — |j                   j                  d«      }t        |t        t        f«      rt	        |«      S |j                  | ¬«      }t        |t        t        f«      r|S dS )aÞ  
        Recover the response cost when the response never recorded one in its
        ``_hidden_params``: Anthropic /v1/messages returns a TypedDict that cannot
        hold the attribute at all, and Google :generateContent carries
        ``_hidden_params`` but no synchronously-populated ``response_cost``. In both
        cases the cost is read back from the logging object instead, recomputing from
        the same calculator only when it has not been stored yet.
        r<  ©rU  rP  )r×   rÄ   rÂ   rF  r5  Ú_response_cost_calculator)rµ   rÛ   Ústored_costÚrecomputed_costs       r¼   Ú_response_cost_from_logging_objz=ProxyBaseLLMRequestProcessing._response_cost_from_logging_obj"  s_   € ð )×;Ñ;×?Ñ?ÀÓPˆÜ�k¤C¬ <Ô0Ü˜Ó%Ð%Ø!,×!FÑ!FÈhÐ!FÓ!WˆÜ",¨_¼sÄE¸lÔ"KˆÐSÐQSÐSr¾   c           	      óð  — t        j                  t        j                  «      syt	        j
                  | j                  t        ¬«      }t        |«      t        kD  r…t        j                  dt        |«      t        t        | j                  t        «      r(t        | j                  j                  «       «      «       yt        | j                  «      j                   «       yt        j                  d|«       y)z<Log request payload at DEBUG level, truncating if too large.N)r4  zTRequest received by LiteLLM: payload too large to log (%d bytes, limit %d). Keys: %szRequest received by LiteLLM:
%s)r   ÚisEnabledForÚloggingÚDEBUGr^  r_  r%  rê   r  r%   rÙ   rÂ   rÃ   r   Úkeysrg  rB  )r;  Ú_payload_strs     r¼   Ú_debug_log_request_payloadz8ProxyBaseLLMRequestProcessing._debug_log_request_payload6  s¨   € ä#×0Ñ0´·±Ô?ØÜ"Ÿj™j¨¯©¼CÔ@ˆÜˆ|ÓÔ=Ò=Ü ×&Ñ&ØfÜ�LÓ!Ü.Ü+5°d·i±iÄÔ+F”�d—i‘i—n‘nÓ&Ó'õ	ô MQÐQU×QZÑQZËO×LdÑLdõ	ô !×&Ñ&Ø2Øõr¾   Úfastapi_responseÚselect_data_generator.Úis_streaming_requestÚcontentsÚskip_pre_call_logicc              ƒ   óÚ   ‡ ‡‡K  — dt         dt        dz  fˆˆ ˆfd„}t        ‰ j                  ||‰|‰||||	|
|||||||||¬«      t	        ‰ j
                  |	«      |¬«      ƒ d{  –—† S 7 Œ­w)a‘  Run the request, sending SSE keepalives while the upstream is still silent.

        Everything below this point, the upstream call included, happens before the
        proxy can write a byte, so a slow time-to-first-token leaves the response
        idle. See ``open_sse_before_first_byte``; unwrapped unless an operator sets
        ``litellm_settings.sse_keepalive_ping_interval_seconds``.
        rd  r¶   Nc              “   ó\   •K  — ‰j                  ‰| ‰j                  ¬«      ƒ d {  –—† S 7 Œ­w)N©r}  rP  r¿   )Úpost_call_failure_hookr%  )rd  r’  r;  r}  s    €€€r¼   Ú_audit_late_failurezSProxyBaseLLMRequestProcessing.base_process_llm_request.<locals>._audit_late_failuref  s9   øè ø€ ð +×AÑAØ"3Ø#&Ø!ŸY™Yð Bó ÷ ð ð ús   ƒ",¥*¦,)rÐ   rî  r}  r'  r’  r&  rž  rï  r  ré   r   r¡  r¢  r£  r¤  rs  rð  rñ  rò  )r	  r  )rÖ   r   r  Ú_process_llm_requestrù  r%  )r;  rÐ   rî  r}  r'  r’  r&  rž  rï  r  ré   r   r¡  r¢  r£  r¤  rs  rð  rñ  rò  r÷  s   `  ` `               r¼   Úbase_process_llm_requestz6ProxyBaseLLMRequestProcessing.base_process_llm_requestH  s—   úè ø€ ð<	¬9ð 	¼ÈÑ9M÷ 	ô 0Ø×%Ñ%ØØ!1Ø"3Ø%Ø"3Ø!1Ø)Ø&;Ø%ØØ%Ø!1Ø%9Ø /Ø+ØØ%9Ø!Ø$7ð' &ó ô* #:¸$¿)¹)ÀZÓ"PØ/ô/
÷ 
ð 	
ð 
ús   …AA+Á$A)Á%A+c              ƒ   ó¨  ‡=‡>‡?‡@K  — t        | j                  j                  d«      t        «      r| j                  j                  d«      nd}| j	                  «        |r(| j                  j                  d«      }|€:t        d«      ‚| j                  ||||||||||||
||	¬«      ƒ d{  –—† \  | _        }| j                  «       }|r$| j                  | j                  |¬«      sd|_	        g }|j                  t        j                  |j                  | j                  ||¬«      «      «       |r|| j                  d	<   t        | j                  ||	||¬
«      ƒ d{  –—† }t        j                  |«      }|j                  |«       t        j                  |Ž }	 |j                  dd«      rt!        ||«      ƒ d{  –—† }n
|ƒ d{  –—† }t#        |«      ƒ d{  –—†  |d   }d}	 t%        |«      }| j'                  || j                  «      }|j                  dd«      xs d|j                  dd«      xs d|j                  dd«      xs d}"}!} |j                  dd«      |j                  di «      xs i }$}#|	�|	j)                  |¬«      | j                  d<   t        j                  |j+                  | j                  j                  dd«      d¬«      «       | j                  | j                  |¬«      s| j-                  |«      �r t/        j0                  dC||j2                  || |!||"t5        |dd«      |#| j                  ||dœ|$¤Ž}%|j7                  | j                  ||t9        |j:                  «      ¬«      ƒ d{  –—† }&|&r|%j=                  |&«       |r|| j                  d<   ddlm }' |r:t        ||'«      r.| j                  Š>|Š@|Š?dtB        d tB        d!dfˆ>ˆ?ˆ@fd"„}(|(|_"        nE|rC|d#k(  r>| j-                  |«      r-dd$l#m$Š= d%tJ        tB        tB        tB        f   d!dfˆ=fd&„})|)|_"        |d'k(  �r| j-                  |«      råt        jL                  |«      r|ƒ d{  –—† }*n|}*| jO                  «       r-| jQ                  «       rd(jS                  |*2 �+cg c3 d{  –—† }+|+‘Œtm        |*t\        j^                  | ja                  «       |%¬+«      t.        jc                  ||¬,«       |rBt5        |d-d«      }1|1�2d|_"        	 t        j                  |je                  |dddd¬.«      «       S S S | jo                  ||||%t9        |j:                  «      ¬0«      ƒ d{  –—† }3|3�]|3t.        jc                  ||¬,«       |rBt5        |d-d«      }1|1�2d|_"        	 t        j                  |je                  |dddd¬.«      «       S S S tm        |jq                  «       |jr                  |%¬1«      t.        jc                  ||¬,«       |rBt5        |d-d«      }1|1�2d|_"        	 t        j                  |je                  |dddd¬.«      «       S S S |d#k(  rÁ| j-                  |«      �rVt.        ju                  ||| j                  ||¬2«      }4tw        ty        |4tz        j|                  ¬3«      d4|%|¬5«      ƒ d{  –—† t.        jc                  ||¬,«       |rBt5        |d-d«      }1|1�2d|_"        	 t        j                  |je                  |dddd¬.«      «       S S S |r¥ |||| j                  |¬6«      }4|d7k(  rt.        j                  ||4|¬8«      }4tw        |4d4|%|¬5«      ƒ d{  –—† t.        jc                  ||¬,«       |rBt5        |d-d«      }1|1�2d|_"        	 t        j                  |je                  |dddd¬.«      «       S S S t5        |d-d«      rd|_"        |d'k(  rÑt/        j0                  dC||j2                  || |!||"t5        |dd«      |#| j                  ||dœ|$¤Ž}5| jo                  ||||5t9        |j:                  «      ¬0«      ƒ d{  –—† }3|3�]|3t.        jc                  ||¬,«       |rBt5        |d-d«      }1|1�2d|_"        	 t        j                  |je                  |dddd¬.«      «       S S S |j�                  | j                  ||¬9«      ƒ d{  –—† }	 t.        jc                  ||¬,«       |r@t5        |d-d«      }1|1�1d|_"        	 t        j                  |je                  |dddd¬.«      «       t%        |«      }|j                  di «      xs i }$|" xr |j                  d«      du }6|6r| jƒ                  ||¬:«      xs dn|"}7t…        |j†                  |jˆ                  |«      rd;n|7}8t‹        | j                  «      \  }9}:t�        |:j                  d<«      «      };|;dkD  rt        |8tŽ        t�        f«      r|8nd;|;z   n|8}<|r/t“        ||d=|j2                  › �t•        | j                  «      ¬>«       |j:                  j=                  t/        j0                  dC||j2                  || |!||<t5        |dd«      |#| j                  ||dœ|$¤Ž«       t        |t8        «      r|j—                  d?d«       |j7                  | j                  ||t9        |j:                  «      ¬«      ƒ d{  –—† }&|&r|j:                  j=                  |&«       t™        |¬@«      ƒ d{  –—†  |dAv rt.        j›                  ||¬B«      ƒ d{  –—†  |S 7 �
Œt7 �	ŒÄ7 �	Œh7 �	Œ`7 �	ŒP# t#        |«      ƒ d{  –—†7   w xY w7 �ŒÈ7 �Œê7 �Œ°6 nc c}+w c}+«      },| jU                  |,||¬)«      ƒ d{  –—†7  }-|%jW                  «       D �.�/ci c]  \  }.}/|.jY                  «       d*k7  sŒ|.|/“Œ nc c}/}.w }0}.}/t[        |-t\        j^                  | ja                  «       |0¬+«      t.        jc                  ||¬,«       |rnt5        |d-d«      }1|1�^d|_"        	 t        j                  |je                  |dddd¬.«      «       S # tf        $ r }2ti        jj                  d/|2«       Y d}2~2S d}2~2ww xY wS S # tf        $ r }2ti        jj                  d/|2«       Y d}2~2S d}2~2ww xY w7 �Œ@# tf        $ r }2ti        jj                  d/|2«       Y d}2~2S d}2~2ww xY w# tf        $ r }2ti        jj                  d/|2«       Y d}2~2S d}2~2ww xY w7 �ŒP# tf        $ r }2ti        jj                  d/|2«       Y d}2~2S d}2~2ww xY w7 �ŒØ# tf        $ r }2ti        jj                  d/|2«       Y d}2~2S d}2~2ww xY w7 �Œ!# tf        $ r }2ti        jj                  d/|2«       Y d}2~2S d}2~2ww xY w7 �ŒË# tf        $ r d}‚ w xY w# tf        $ r!}2ti        jj                  d/|2«       Y d}2~2�Œ¤d}2~2ww xY w# t.        jc                  ||¬,«       |rnt5        |d-d«      }1|1�^d|_"        	 t        j                  |je                  |dddd¬.«      «       w # tf        $ r }2ti        jj                  d/|2«       Y d}2~2w d}2~2ww xY ww w xY w7 �Œ‡7 �ŒY7 �Œ9­w)Dzg
        Common request processing logic for both chat completions and responses API endpoints
        ré   NrÒ   z˜skip_pre_call_logic=True requires litellm_logging_obj to be set in data. Ensure common_processing_pre_call_logic was called before using this parameter.rË  )r%  rð  T)r%  r}  rB  rñ  )r%  r'  r  r   r}  Úcancel_on_disconnectFrQ  rq  rP  rr  r<  r   r  )rp  rà  rÔ   Úsuccess)rÔ   r   r•  r–  r—  rð   r   )ÚCustomStreamWrapperÚassembled_responserù   r¶   c              “   óV   •K  — t         j                  ‰‰‰| |¬«      ƒ d {  –—†  y 7 Œ­w)N)Úcaptured_dataÚcaptured_user_api_key_dictÚcaptured_logging_objrþ  rù   )rm  Ú_run_deferred_stream_guardrails)rþ  rù   Ú_captured_dataÚ_captured_logging_objÚ_captured_user_api_key_dicts     €€€r¼   rã   zXProxyBaseLLMRequestProcessing._process_llm_request.<locals>._on_deferred_stream_completeN	  s4   øè ø€ Ü;×[Ñ[Ø*8Ø7RØ1FØ/AØ&/ð \ó ÷ ò ús   ƒ)¡'¢)rŽ   )ÚGLOBAL_LOGGING_WORKERÚlogging_coroutinec              “   ó2   •K  — ‰j                  | ¬«       y ­w)N)Úasync_coroutine)Úensure_initialized_and_enqueue)r  r  s    €r¼   Ú#_on_deferred_native_stream_completez_ProxyBaseLLMRequestProcessing._process_llm_request.<locals>._on_deferred_native_stream_completea	  s   øè ø€ ð .×LÑLÐ]nÐLÕoùs   ƒrh   r¾   ©Ú
body_bytesr’  r}  zcontent-length©rª  r<  r¨  r>  )rÛ   Úexception_raisedrã   rø   z-Error in orphaned streaming async logging: %s)rµ   r’  r}  r›  r˜  ©rª  r<  r>  ©rµ   r}  r¿   r’  rÐ   )r+  r	  útext/event-stream)rÇ  r¨  r>  rÐ   )rµ   r}  r¿   rÐ   rO   )Úoriginal_stream_responseÚwrapped_generatorr}  ©r%  r}  rµ   )rµ   rÛ   r8  Ú&standard_logging_guardrail_informationzlitellm_call_id=)r  rƒ  r  r  r”  r»   >   rO   rT   ©rµ   r}  r  )NrÂ   r%  rÄ   rê   rí  r˜  rÓ  Ú_has_post_call_guardrailsÚ_is_streaming_requestÚ_defer_async_loggingrU  r  rh  Úduring_call_hookrB   Úgatherrk  r  rF   r™  Úget_deploymentÚupdate_request_statusÚ_is_streaming_responserm  r‘  rÔ   rº   rš  rÃ   r>  r†  Ú,litellm.litellm_core_utils.streaming_handlerrý  rW  rã   Ú)litellm.litellm_core_utils.logging_workerr  r   rê  Ú)_has_post_call_guardrails_for_passthroughÚ2_passthrough_endpoint_has_stream_guardrail_handlerÚjoinÚ+_handle_event_stream_allm_passthrough_router…  Úlowerr   r   r¾  Ú$_passthrough_event_stream_media_typeÚ_flush_deferred_async_loggingr  rÖ   r   rí  r   Ú,_handle_non_streaming_allm_passthrough_routeÚaiter_bytesr<  Úasync_sse_data_generatorrò  r@   rý   Ú#anthropic_sse_ping_interval_secondsÚ._wrap_responses_stream_for_container_ownershipÚpost_call_success_hookræ  r1   rB  rÓ   r,   r3   rF  r5  r(  rÊ   rR  r:   Ú1_record_container_owners_from_responses_if_needed)Ar;  rÐ   rî  r}  r'  r’  r&  rž  rï  r  ré   r   r¡  r¢  r£  r¤  rs  rð  rñ  rò  Úrequested_model_from_clientrÛ   Ú_post_call_guardrails_activer
  Úllm_callÚllm_call_taskÚllm_responsesÚ	responsesrµ   Ú_exception_raisedr  rp  rq  rr  r<  r   r  r›  rœ  rý  rã   r  rÇ  rç  r  Úmodified_bytesr�  rŽ  Úresponse_headersÚ_deferred_fnr  Ú_earlyÚselected_data_generatorÚ_non_streaming_custom_headersÚrecover_response_costÚcomputed_cost_for_headersÚllm_cost_for_headersr  Úrequest_metadata_bucketÚguardrail_cost_for_headersÚresponse_cost_for_headersr  r  r  r  sA                                                                @@@@r¼   rø  z2ProxyBaseLLMRequestProcessing._process_llm_request‰  sw  ûè ø€ ô4 '1°·±·±¸wÓ1GÌÔ&MˆD�I‰I�M‰M˜'Ô"ÐSWð 	$ð 	×'Ñ'Ô)áØŸ)™)Ÿ-™-Ð(=Ó>ˆKØÐ"Ü ðfóð ð
 ,0×+HÑ+HØØ!1Ø"3Ø"3ØØ)Ø%Ø!1Ø%9Ø /Ø+ØØ%Ø%ð ,Ió ,÷ &Ñ"ˆDŒI�{ð( /3×.LÑ.LÓ.NÐ$ñ (°×0JÑ0JØ—‘Ð1Eð 1Kô 1
ð 04ˆKÔ,àˆð 	�‰Ü×ÑØ!×2Ñ2ØŸ™Ø&7Ø(ð 3ó óô	
ñ Ø$,ˆD�I‰I�jÑ!ô !.Ø—‘Ø!Ø!Ø!Ø/ô!
÷ 
ˆô  '×2Ñ2°8Ó<ˆØ�‰�]Ô#ä&Ÿ~™~¨uÐ5ˆð	6Ø×#Ñ#Ð$:¸EÔBÜ"JÈ7ÐTaÓ"b×b‘	à"/×/�	ä.¨uÓ5×5Ð5à˜Q‘<ˆà!ÐðZ	kÜ2°8Ó<ˆMØ"×>Ñ>¸}ÈdÏiÉiÓXˆHð ×!Ñ! +¨tÓ4Ò:¸Ø×!Ñ! *¨dÓ3Ò9°rØ×!Ñ! /°4Ó8Ò>¸Bð "/�xˆIð ×!Ñ!Ð"EÀtÓLØ×!Ñ!Ð"6¸Ó;ÒA¸rð 0BÐ-ð Ð%Ø*4×*CÑ*CÈXÐ*CÓ*V�—	‘	˜,Ñ'Ü×ÑØ!×7Ñ7Ø$(§I¡I§M¡MÐ2CÀRÓ$HØ$ð 8ó ôð ×)Ñ)Ø—Y‘YÐ5Ið *ô à×,Ñ,¨XÕ6Ü(E×(XÑ(Xð )Ø&7Ø'×7Ñ7Ø%Ø'Ø%Ø#Ø"/Ü!(Ð):Ð<RÐTVÓ!WØ6WØ!%§¡Ø"/Ø(3ñ)ð )ñ)�ð" *;×)ZÑ)ZØŸ™Ø&7Ø%Ü$(¨¯©Ó$9ð	 *[ó *÷ $Ð ñ $Ø"×)Ñ)Ð*:Ô;ñ /ØC^�D—I‘IÐ?Ñ@õñ 0´J¸xÐI\Ô4]ð -1¯I©I�NØ9JÐ/Ø3>Ð)ðÌvð Ôbhð Ðmq÷ ð @\�KÕ<á0Ø"Ð&:Ò:Ø×3Ñ3°HÔ=õðpÜ+4´V¼VÄVÐ5KÑ+Lðpàõpð
 @c�KÔ<àÐ!9Ó9à×2Ñ2°8Ô<Ü"×.Ñ.¨xÔ8Ø.6¯™Ià(0˜Ið !×JÑJÔLØ $× WÑ WÔ Yà03·±ÐS\×9]Ô9]È%º%ô$  1Ø$-Ü(.×(:Ñ(:Ø'+×'PÑ'PÓ'RØ$2ô	 ôl *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õð ,ð !ðy (,×'XÑ'XØ%-Ø.?Ø.?Ø+9Ü,0°·±Ó,Að (Yó (÷ "˜ð "Ð-Ø#)ôN *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õð ,ð !ôg  1Ø$,×$8Ñ$8Ó$:Ø(0×(<Ñ(<Ø$2ô ôL *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õð ,ð !ð]  Ð#7Ò7ð
 ×2Ñ2°8Õ<Ü2O×2hÑ2hØ%-Ø.?Ø)-¯©Ø.?Ø$+ð 3ió 3Ð/ô &5Ü&JØ'>Ü6=×6aÑ6aô'ð (;Ø$2Ø$+ô&÷  ôh *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õð ,ð !ño +Ù.CØ!)Ø*;Ø%)§Y¡YØ 'ô	/Ð+ð " \Ò1ô :×hÑhØ9AØ2IØ2Cð ió ð 0ô "1Ø"9Ø#6Ø .Ø 'ô	"÷ ôd *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õð ,ð !ôg �{Ð$BÀDÔIØ;?�Ô8àÐ5Ò5Ü7T×7gÑ7gð 8Ø&7Ø'×7Ñ7Ø%Ø'Ø%Ø#Ø"/Ü!(Ð):Ð<RÐTVÓ!WØ6WØ!%§¡Ø"/Ø(3ñ8ð )ñ8Ð-ð  $×PÑPØ%Ø&7Ø&7Ø#@Ü$(¨¯©Ó$9ð  Qó  ÷ �ð Ð%Ø!ô *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õð ,ð !ð- /×EÑEØ—Y‘YØ"3Ø!ð Fó ÷ ‰Hô *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó ôô /¨xÓ8ˆØ*×.Ñ.Ð/CÀRÓHÒNÈBÐà+8Ð'8Ò'g¸]×=NÑ=NÈÓ=_ÐcgÐ=gÐñ %ð ×0Ñ0¸(ÐP[Ð0Ó\ÒbÑ`bàð 	"ô :¸+×:OÑ:OÐQ\×QkÑQkÐmuÔvñ à*ð 	ô
 &CÀ4Ç9Á9Ó%MÑ"ˆÐ"Ü,FØ#×'Ñ'Ð(PÓQó-
Ð"ð *¨AÒ-ô &0Ð0DÄsÌEÀlÔ%SÑ!ÐY\Ø(ò)ð &ð	 	"ñ 'Ü+Ø%Ø ;Ø.¨{×/JÑ/JÐ.KÐLÜ&CÀDÇIÁIÓ&Nõ	ð 	× Ñ ×'Ñ'Ü)×<Ñ<ð Ø"3Ø#×3Ñ3Ø!Ø#Ø!ØØ7Ü$Ð%6Ð8NÐPRÓSØ2SØ!ŸY™YØ+Ø$/ñð %ñô	
ô$ �h¤Ô%Ø�L‰LÐ)¨4Ô0ð "3×!RÑ!RØ—‘Ø/ØÜ  §¡Ó1ð	 "Só "
÷ 
Ðñ Ø×$Ñ$×+Ñ+Ð,<Ô=ä)°8Ô<×<Ð<àÐ9Ñ9Ü/×aÑaØ!Ø"3ð bó ÷ ð ð
 ˆðk&ùðp
ùð cùà/ùà5úÔ.¨uÓ5×5Ò5úð`$ùðF )7ùð :^ùÑ9]ùÔ9]Ó0^˜JØ:>×:jÑ:jØ+5Ø2CØ2Cð ;kó ;÷ 5ð 5˜Nð 2@×1EÑ1EÓ1G÷7Ù)-¨¨AÈ1Ï7É7Ë9ÐXhÓKh  1¡ñ7ùó 7Ð,ñ 7ô $,Ø(6Ü,2×,>Ñ,>Ø+/×+TÑ+TÓ+VØ(8ô	$ô~ *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õøô %ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkúð ,ð !øô %ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkúðU"úôT %ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkûœ9ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkúð_ úô^ %ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkúð[úôZ %ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkúð]úô\ %ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkúðIúô
 ò 	Ø $ÐØð	ûô> %ò kÜ,×6Ñ6Ð7fÐhi×jÒjûðkûô7 *×GÑGØ'Ø!2ð Hô ñ !Ü&-¨kÐ;YÐ[_Ó&`�ØÐ+Ø?C�KÔ<ðkÜ×+Ñ+Ø'×AÑAØ (Ø*.Ø+/Ø)-Ø6:ð Bó õøô %ò kÜ,×6Ñ6Ð7fÐhi×jÑjûðkúð ,ð !úðT
ùð 	=ùðûss  †B#yÂ)lÂ*B2yÅl Å<yÆ!l, Æ;l#Æ<
l, Çl&Çl, ÇyÇl)ÇyÇ&Fv  Í=mÍ>C v  ÑmÑ6v  ÒmÒm
ÒmÒm
ÒmÒ#*v  Ó/yÓ=)q)Ô&yÔ),v  ÕrÕv  Õ/yÖ)rÖ6yÖ9%v  ×/yØ)sØ7yØ:A&v  Ú s0Ú!v  Ú$/yÛ)s3Û=yÜ Av  ÝtÝv  Ý/yÝ;)t"Þ$yÞ'Bv  à-uà.v  à5/yá%)uâyâ!v  â2u=â3v  â8/yã()v äF1yëy	ë0yë3yë4"yìyìyì yì#l, ì&l, ì)yì,mì;l>ì<míyív  ív  ím
ímí$v  í3m6í4v  în.î(n.î-4v  ï!/yð)p;ð:yð;	q$ñqñyñq$ñ$yñ)	rñ2ròyòròyòv  ò	sò!r<ò7yò<sóyó	s-ós(ó#yó(s-ó-yó0v  ó3	tó<tôyôtôyôv  ô"	uô+uõyõuõyõv  õ	u:õu5õ0yõ5u:õ:yõ=v  ö vöv= ö	v:öv5ö/yö5v:ö:yö=0y÷.)xøyø	yø!x<ø7yø<yùyùyùyùyc              ƒ   ó    K  — ddl m} | €y	  || |¬«      ƒ d{  –—†  y7 Œ# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)zRRegister code-interpreter containers so follow-up file APIs pass ownership checks.r   )Ú/record_container_owners_from_responses_responseNr  z=Container ownership recording failed after responses call: %s)Ú+litellm.proxy.container_endpoints.ownershiprE  rÖ   r   rí  )rµ   r}  rE  r  s       r¼   r0  zOProxyBaseLLMRequestProcessing._record_container_owners_from_responses_if_neededf
  s]   è ø€ õ	
ð ÐØð		ÙAØ!Ø"3ô÷ ò ùô ò 	Ü ×*Ñ*ØOØ÷ñ ûð	üs6   ‚
A�" š ›" ŸA " ¢	A«AÁAÁAÁAÚstream_responsec                 óD   — t        | d«      }|€yt        |d«      }|�|S |S )a	  Pull the assembled ``ResponsesAPIResponse`` off a streaming iterator.

        ``ResponsesAPIStreamingIterator`` stores the terminal stream event
        (``response.completed`` / ``response.incomplete`` / ``response.failed``)
        in ``completed_response``; the actual response body hangs off
        that event's ``.response`` attribute. Some iterators store the
        ``ResponsesAPIResponse`` directly. Handle both shapes so the
        container-ownership recording path can walk ``.output`` either way.
        Úcompleted_responseNrµ   )r6  )rG  Ú	completedr  s      r¼   Ú%_extract_completed_responses_responsezCProxyBaseLLMRequestProcessing._extract_completed_responses_response~
  s8   € ô +¨?Ð<PÓQˆ	ØÐØÜ-¨i¸ÓDˆØÐ#ØÐØÐr¾   r  r  c                ó|  K  — 	 |2 3 d{  –—† }|­–— Œ7 Œ
6 	 	 t         j                  | «      }|�!t         j                  ||¬«      ƒ d{  –—†7   n*t        j                  dt        | «      j                  «       yy# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w# 	 t         j                  | «      }|�!t         j                  ||¬«      ƒ d{  –—†7   w t        j                  dt        | «      j                  «       w # t        $ r }t        j                  d|«       Y d}~w d}~ww xY wxY w­w)a›  Forward SSE chunks, then record container ownership at stream end.

        Streaming ``/v1/responses`` short-circuits out of
        ``base_process_llm_request`` before the non-streaming ownership
        tail runs, so without this wrap the
        ``LiteLLM_ManagedObjectTable`` row for any container created
        during the stream is never written and follow-up file API calls
        return 403.
        Nr  zøContainer ownership recording skipped on streaming /v1/responses: no completed_response on stream iterator %s. If this stream created any tool container (e.g. code_interpreter), follow-up /v1/containers/<id>/files calls will 403 for non-admin keys.zGContainer ownership recording failed after streaming responses call: %s)	rm  rK  r0  r   r™  rg  rB  rÖ   rí  )r  r  r}  rç  Úcompleted_objr  s         r¼   r.  zLProxyBaseLLMRequestProcessing._wrap_responses_stream_for_container_ownership‘
  sV  è ø€ ð"	Ø0÷ ð �eØ”ðøÑ0ðÜ'D×'jÑ'jØ,ó(�ð !Ð,Ü7×iÑiØ!.Ø*;ð jó ÷ ò ô )×0Ñ0ð*ô Ð5Ó6×?Ñ?õðøô* ò Ü$×.Ñ.Ø]Ø÷ñ ûðûð5Ü'D×'jÑ'jØ,ó(�ð !Ð,Ü7×iÑiØ!.Ø*;ð jó ÷ ò ô )×0Ñ0ð*ô Ð5Ó6×?Ñ?õøô ò Ü$×.Ñ.Ø]Ø÷ñ ûðÿs§   ‚D<„B) †Š‹ŽB) •—B) š1A= ÁAÁ/A= Á;D<Á=	B&ÂB!ÂD<Â!B&Â&D<Â)D9Â+1DÃCÃDÃ"D9Ã#)DÄD9Ä	D6ÄD1Ä,D9Ä1D6Ä6D9Ä9D<c              ƒ   óŠ  K  — ddl m} | j                  |||d||||||	|
|||||¬«      ƒ d {  –—† }t        |t        «      r|S t        |t
        «      r|S t        |«      }|j                  «       ƒ d {  –—† }t        ||j                  |j                  |j                  t        |j                  «      ¬«      ¬«      S 7 Œ‘7 ŒL­w)Nr   ©ÚHttpPassThroughEndpointHelpersrh   )rÐ   rî  r}  r'  r’  r  r&  rž  rï  ré   r   r¡  r¢  r£  r¤  rs  ©r>  r›  r  )Ú;litellm.proxy.pass_through_endpoints.pass_through_endpointsrP  rù  rÂ   r   r   rK  r@  r<  r4   r>  rÃ   )r;  rÐ   rî  r}  r’  r&  rž  rï  r  ré   r   r¡  r¢  r£  r¤  rs  rP  rU  Úupstreamrª  s                       r¼   Ú$base_passthrough_process_llm_requestzBProxyBaseLLMRequestProcessing.base_passthrough_process_llm_requestÄ
  sã   è ø€ õ$	
ð #×;Ñ;ØØ-Ø/Ø/Ø/Ø!Ø-Ø%Ø"7ØØ!Ø-Ø!5Ø+Ø'Øð! <ó 
÷ 
ˆô( �fÔ/Ô0ØˆMô �fœhÔ'ØˆMä/°Ó7ˆØ'Ÿ~™~Ó/×/ˆÜØØ ×,Ñ,Ø2×GÑGØ ×(Ñ(Ü#Ð$4×$<Ñ$<Ó=ð Hó ô
ð 	
ð=
øð: 0ús#   ‚+C­B?®ACÁ4CÁ5ACÃCc                 ó^   — ddl }ddlm}m} |j	                  |«      ryt        |||f«      ryy)zù
        Check if the response object is actually a streaming response by inspecting its type.

        This uses standard Python inspection to detect streaming/async iterator objects
        rather than relying on specific wrapper classes.
        r   N)r   ÚAsyncIteratorTF)ÚinspectÚcollections.abcr   rV  Ú
isasyncgenrÂ   )r;  rµ   rW  r   rV  s        r¼   r   z4ProxyBaseLLMRequestProcessing._is_streaming_response  s4   € ó 	ßAð ×Ñ˜hÔ'Øô �h °Ð ?Ô@Øàr¾   c                 ó&   — |du ryd|v r|d   du ryy)z¶
        Check if the request is a streaming request.

        1. is_streaming_request is a dynamic param passed in
        2. if "stream" in data and data["stream"] is True
        Tr+  Fr  )r;  r%  rð  s      r¼   r  z3ProxyBaseLLMRequestProcessing._is_streaming_request  s(   € ð   4Ñ'ØØ�tÑ  X¡°$Ñ 6ØØr¾   c                  ó¬   — t         j                  D ]A  } t        | t        «      sŒ| j                  €Œ!| j                  t        j                  «      sŒA y y)zý
        True when a guardrail explicitly registers post_call. event_hook=None
        matches all hooks in should_run_guardrail but must not defer async logging
        on non-streaming /chat/completions (no post_call_success_hook flush path).
        TF)rý   Ú	callbacksrÂ   r+   Ú
event_hookÚ_event_hook_is_event_typerH   Ú	post_call)Úcbs    r¼   r  z7ProxyBaseLLMRequestProcessing._has_post_call_guardrails"  sP   € ô ×#Ñ#ò 	ˆBÜ˜b¤/Ô2ØØ�}‰}Ð$ØØ×+Ñ+Ô,?×,IÑ,IÕJÙð	ð r¾   c                 óÖ   — ddl m} ddlm}  || j                  |¬«      }t
        j                  D ]6  }t        |t        «      sŒ|j                  |t        j                  ¬«      sŒ6 y y)a  
        True when a post_call guardrail will actually run for THIS request.

        Mirrors the gate in ProxyLogging.post_call_success_hook
        (should_run_guardrail against the request's merged guardrails) so that a
        guardrail registered globally but not configured for this key/team does
        not force the passthrough stream to be buffered into a single
        non-streaming response. An event_hook=None guardrail still counts here
        because should_run_guardrail treats it as matching every hook.
        r   ©r  ©rD   ©r%  r  ©r%  Ú
event_typeTF)r¼  r  Úlitellm.proxy.utilsrD   r%  rý   r\  rÂ   r+   Úshould_run_guardrailrH   r_  )r;  r  rD   Úguardrail_datar`  s        r¼   r#  zGProxyBaseLLMRequestProcessing._has_post_call_guardrails_for_passthrough2  sf   € õ 	:ÝOá GÈTÏYÉYÐcmÔ nˆÜ×#Ñ#ò 	ˆBÜ˜b¤/Ô2ØØ×&Ñ&Ø#Ü.×8Ñ8ð 'õ ñ ð	ð r¾   c                 ó–   — ddl m} |j                  | j                  j	                  d«      | j                  j	                  d«      «      S )a  
        True when the resolved passthrough provider AND endpoint have an
        event-stream guardrail handler that can rewrite buffered frames. Only such
        endpoints may have their stream buffered for post-call guardrails; every
        other endpoint must keep streaming so the response is not silently turned
        into a non-streaming body when no content modification would occur (e.g.
        Bedrock invoke-with-response-stream, whose frames the Converse handler
        leaves untouched).
        r   ©ÚLlmPassthroughRouteHandlerÚcustom_llm_providerÚendpoint)Ú7litellm.llms.pass_through.guardrail_translation.handlerrl  Ú&supports_event_stream_de_anonymizationr%  rÄ   ©r;  rl  s     r¼   r$  zPProxyBaseLLMRequestProcessing._passthrough_endpoint_has_stream_guardrail_handlerK  s=   € õ	
ð *×PÑPØ�I‰I�M‰MÐ/Ó0Ø�I‰I�M‰M˜*Ó%ó
ð 	
r¾   c                 ób   — ddl m} |j                  | j                  j	                  d«      «      S )aó  
        Content-type for a passthrough event-stream response, resolved from the
        provider handler so the proxy stays provider-agnostic. Mirrors the
        upstream content-type the non-streaming path forwards, since the
        streaming generator carries no headers of its own. Used for both the
        buffered (guardrail-rewritten) and the unbuffered relay paths so
        clients that enforce the event-stream content-type (e.g. Claude Code on
        Bedrock invoke-with-response-stream) see the correct header instead of
        no content-type at all, which they fall back to reading as
        application/octet-stream. Returns None for providers with no
        event-stream media type, leaving the response headers unchanged.
        r   rk  rm  )ro  rl  Úevent_stream_media_typer%  rÄ   rq  s     r¼   r(  zBProxyBaseLLMRequestProcessing._passthrough_event_stream_media_type^  s(   € õ	
ð *×AÑAÀ$Ç)Á)Ç-Á-ÐPeÓBfÓgÐgr¾   rC   r8   r›  r˜  c              ƒ   ój  K  — | j                  «       sy dd l}ddlm} ddlm} t        |«      }		 |	j                  }
t        |	j                  «      j                  dd«      }|
dk\  ry |j                  | j                  j                  d«      |«      }|sd|vry |j                  |	j                  |¬	«      }|j                  | j                  ||	|¬
«      ƒ d {  –—† }|r|j!                  |«       |rC|	j#                  «       ƒ d {  –—† }| j%                  |||¬«      ƒ d {  –—† }t'        ||
||¬«      S |	j#                  «       ƒ d {  –—† }	 |j)                  |«      }|j/                  | j                  ||¬«      ƒ d {  –—† }t1        |t2        «      r |j5                  |«      j7                  «       }n+t9        j:                  dt=        |«      j>                  «       |}t'        ||
d|¬«      S # t        $ r Y y w xY w7 �Œ&7 Œû7 Œá7 Œ¼# |j*                  t,        f$ r t'        ||
d|¬«      cY S w xY w7 Œ°­w)Nr   rk  rO  zcontent-typerP  i,  rm  zapplication/jsonrQ  r—  r  r  r  z\allm_passthrough_route: post_call_success_hook returned %s, leaving JSON response unmodified) r#  r^  ro  rl  rR  rP  rK  r<  rR  r>  rÄ   rT  Úis_event_stream_responser%  r4   rš  r†  r@  r&  r   r—  rš  ÚUnicodeDecodeErrorr/  rÂ   rÃ   r_  r   r   rÙ   rg  rB  )r;  rµ   r’  r}  r›  r˜  Ú_jsonrl  rP  rS  Úresponse_statusÚcontent_typeÚis_event_streamr9  rœ  r  r8  ÚparsedÚ	processedrª  s                       r¼   r*  zJProxyBaseLLMRequestProcessing._handle_non_streaming_allm_passthrough_routeq  sj  è ø€ ð ×=Ñ=Ô?Øãõ	
õ	
ô 0°Ó9ˆð	Ø*2×*>Ñ*>ˆOÜ'8¸×9IÑ9IÓ'J×'NÑ'NÈ~Ð_aÓ'bˆLð ˜cÒ!Øà!;×!TÑ!TØ�I‰I�M‰MÐ/Ó0°,ó"
ˆñ Ð#5¸\Ñ#IØà"@×"UÑ"UØ×$Ñ$Ø)ð #Vó #
Ðð ):×(YÑ(YØ—‘Ø/ØØ+ð	 )Zó )
÷ #
Ðñ Ø×#Ñ#Ð$4Ô5áØ'Ÿ~™~Ó/×/ˆJØ*.×*ZÑ*ZØ%Ø"3Ø"3ð +[ó +÷ %ˆNô
 Ø&Ø+Ø'Ø(ô	ð ð $Ÿ>™>Ó+×+ˆ
ð	Ø!ŸK™K¨
Ó3ˆFð "3×!IÑ!IØ—‘Ø/Øð "Jó "
÷ 
ˆ	ô
 �i¤Ô&Ø—k‘k )Ó,×3Ñ3Ó5‰Gä ×&Ñ&ØnÜ�Y“×(Ñ(ôð !ˆGÜØØ'Ø)Ø$ô	
ð 	
øô} ò 	Ùð	úð #
ùð 0øð%øð ,ùð ×%Ñ%Ô'9Ð:ò 	ÜØ"Ø+Ø-Ø(ô	ò ð	úð
úsœ   ‚-H3°1G/ Á!A7H3ÃG>Ã,H3ÄHÄH3Ä!HÄ"&H3ÅHÅ	H3ÅH Å!H3Æ H1ÆA.H3Ç/	G;Ç8H3Ç:G;Ç;H3ÈH3ÈH3ÈH3È$H.È+H3È-H.È.H3r  c              ƒ   óh   K  — ddl m} |j                  |||| j                  ¬«      ƒ d {  –—† S 7 Œ­w)Nr   rk  )r  r’  r}  r%  )ro  rl  Úde_anonymize_event_streamr%  )r;  r  r’  r}  rl  s        r¼   r&  zIProxyBaseLLMRequestProcessing._handle_event_stream_allm_passthrough_routeÎ  s@   è ø€ õ	
ð 0×IÑIØ!Ø/Ø/Ø—‘ð	 Jó 
÷ 
ð 	
ð 
ús   ‚)2«0¬2r  c                 ó    — t        | dd«      }|€yd| _        |ry	  |«        y# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w)uB  
        Fire the deferred async-success closure stored by wrapper_async, then
        clear the slot.

        Called from the finally block around post_call_success_hook so the
        StandardLoggingPayload is built after post-call guardrails write to
        metadata (deferred logging is enabled for non-streaming requests with
        a registered post_call guardrail).

        On exception (e.g. a post-call guardrail blocks the response), skip
        firing the closure â€” the exception propagates to post_call_failure_hook
        which writes its own failure spend log via async_failure_handler.
        Firing both produced a duplicate (Success + Failure) entry per request,
        with the Success row exposing the blocked LLM response.

        For streaming early-returns the closure is never stored (wrapper_async
        returns before the deferred block in litellm/utils.py), so this is a
        no-op there.

        Extracted as a static method so tests can exercise the production
        gating logic directly rather than reimplementing the finally block.
        Ú_enqueue_deferred_loggingNz!Error firing deferred logging: %s)rº   r€  rÖ   r   rí  )rÛ   r  Ú_enqueue_fnr  s       r¼   r)  z;ProxyBaseLLMRequestProcessing._flush_deferred_async_loggingß  s\   € ô6 % [Ð2MÈtÓTˆØÐØØ04ˆÔ-ÙØð	SÙ�MøÜò 	SÜ ×*Ñ*Ð+NÐPQ×RÑRûð	Sús   œ$ ¤	A­AÁAr   r  r  rþ  rù   c              ƒ   ó~  K  — |}	 ddl m} ddlm}  || |¬«      }t        j
                  D ]”  }	t        |	t        «      sŒ|	j                  |t        j                  ¬«      sŒ6	 d}
dt        |	«      j                  v r|	j                  sŒ]dt        |	«      j                  v rŒu|	j                  |||¬	«      ƒ d{  –—† }
|
�|
}Œ– 	 	 t1        j2                  t5        |«      j7                  ||ddd¬«      «       y7 Œ?# t        $ r{}t!        j"                  d
t%        |	dt        |	«      j&                  «      |«       t        |t(        «      r+t+        |d«      rd|j,                  j/                  di «      d<   Y d}~�ŒMd}~ww xY w# t        $ r }t!        j"                  d|«       Y d}~Œád}~ww xY w# t        $ r }t!        j"                  d|«       Y d}~yd}~ww xY w# 	 t1        j2                  t5        |«      j7                  ||ddd¬«      «       w # t        $ r }t!        j"                  d|«       Y d}~w d}~ww xY wxY w­w)uf  
        Run non-streaming post-call guardrail hooks on an assembled streaming
        response, then fire success logging via ``dispatch_success_handlers``.

        Called by ProxyLogging._fire_deferred_stream_logging after the full
        streaming pipeline (including unified_guardrail end-of-stream blocks)
        has completed.

        Guardrails routed through unified_guardrail are skipped, since they already ran
        via its streaming iterator.  Guardrails that override
        async_post_call_success_hook directly run here, including those that implement
        apply_guardrail but keep their native lifecycle hooks.

        This is audit-only â€” content has already been delivered to the client.

        Extracted as a static method so tests can call the production
        implementation directly rather than reimplementing the closure.
        r   rb  rc  rd  re  NrŸ  Ú'async_post_call_streaming_iterator_hook)r}  r%  rµ   z>Error running post-call guardrail %s on streaming response: %sÚguardrail_namer×   TrÆ   Úguardrail_blockedz8Error in deferred streaming guardrail initialization: %srø   z/Error in deferred streaming success logging: %s)r¼  r  rg  rD   rý   r\  rÂ   r+   rh  rH   r_  rg  Ú__dict__Úuse_native_lifecycle_hooksÚasync_post_call_success_hookrÖ   r   rí  rº   rB  r   r"  r×   rØ   r  rh  rY  r  )r   r  r  rþ  rù   Ú	_responseÚ_global_llm_routerrD   ri  r`  Úguardrail_resultr  s               r¼   r  z=ProxyBaseLLMRequestProcessing._run_deferred_stream_guardrails  sZ  è ø€ ð4 'ˆ	ðE	ÝSÝSáDÈ-ÐdvÔwˆNÜ×'Ñ'ò &w�Ü! "¤oÔ6ØØ×.Ñ.Ø'Ü2×<Ñ<ð /ô ð ðwØ'+Ð$Ø(¬D°«H×,=Ñ,=Ñ=Àb×FcÒFcð !Ø@ÄDÈÃH×DUÑDUÑUð
 !à13×1PÑ1PØ.HØ!/Ø%.ð 2Qó 2÷ ,Ð(ð
 (Ð3Ø$4˜	øñ=&wðZô ×#Ñ#Ü*Ð+?Ó@×ZÑZØ!Ø"+Ø#'Ø!%Ø.2ð [ó õð7,ùô !ò wÜ(×2Ñ2ØXÜ Ð$4´d¸2³h×6GÑ6GÓHØôô
 " !¤]Ô3¼Ð@TÐVjÔ8kØrvÐ,×?Ñ?×JÑJÈ:ÐWYÓZÐ[nÑoÿùðwûô ò 	Ü ×*Ñ*ØJØ÷ñ ûð	ûô* ò Ü$×.Ñ.ØEØ÷ñ ûðûðô ×#Ñ#Ü*Ð+?Ó@×ZÑZØ!Ø"+Ø#'Ø!%Ø.2ð [ó õøô ò Ü$×.Ñ.ØEØ÷ñ ûðÿsä   ‚H=†AF Á#%C:ÂF Â	C:Â F Â!C:Â8C8Â9C:ÃF ÃG Ã2F- Ã7H=Ã8C:Ã:	E>ÄA0E9Å3F Å9E>Å>F Æ	F*Æ
F%Æ G Æ%F*Æ*G Æ-	GÆ6GÇH=ÇGÇH=ÇH:Ç2HÈH:È	H7ÈH2È-H:È2H7È7H:È:H=r>  r  c                 óœ   — t        |t        «      r<|j                  dkD  r,t        t	        j
                  |j                  «      «      |d<   y y y )Nr   zretry-after)rÂ   rI   Úcooldown_timerê   ÚmathÚceil)r;  r>  r  s      r¼   Ú"_apply_router_cooldown_retry_afterz@ProxyBaseLLMRequestProcessing._apply_router_cooldown_retry_afterg  s=   € Ü�aÔ-Ô.°1·?±?ÀQÒ3FÜ%(¬¯©°1·?±?Ó)CÓ%DˆG�MÒ"ð 4GÐ.r¾   c              ƒ   ó  K  — t        |«       |j                  ||| j                  ¬«      ƒ d{  –—† }|�|}t        |dd«      }t	        j
                  d||«       t        |dd«      }| j                  j                  dd«      }| j                  |«      }	t        j                  ||r|j                  n| j                  j                  d«      |	|d	t        |d
d«      | j                  ||¬«	      }
t        |dd«      xs i }|s1t        |d«      }|�#t        |dd«      }|rt        t        |«      «      }|j                  |
«       	 |j                  | j                  |d| j                  j                  d«      xs i j                  di «      ¬«      ƒ d{  –—† }|r|j                  |«       |j#                  «       D ��ci c]  \  }}|j%                  «       t&        vsŒ||“Œ! }}}| j)                  ||«       t+        |t,        «      r�i |j.                  j#                  «       D ��ci c]  \  }}|j%                  «       t&        vsŒ||“Œ! c}}¥|j#                  «       D ��ci c]#  \  }}|t+        |t0        «      r|n
t1        |«      “Œ% c}}¥|_        |‚t+        |t2        «      rt5        ||«      ‚t+        |t6        j8                  «      rX|}|j:                  j=                  «       ƒ d{  –—† }|j?                  d«      }t3        |j:                  j@                  d|i¬«      ‚|› }tC        |«      }|r!t-        d|› �ddtD        jF                  |¬«      ‚t        |dd«      }|�!t+        |tH        «      rd|cxk  rdk  rn n|}ntD        jJ                  }t-        t        |d|«      t        |dd«      t        |dd«      t        |dd«      |t        |dd«      |¬«      ‚7 �Œ¯7 �ŒL# t         $ r Y �ŒCw xY wc c}}w c c}}w c c}}w 7 �Œ­w) zGRaises ProxyException (OpenAI API compatible) if an exception is raisedrõ  NÚlitellm_debug_inforP  zo[1;31mAn error occurred: %s %s

 Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`r  rÒ   rÔ   r   r•  )	r}  ro  rp  rs  r<  rt  r¿   r  rÒ   r>  rµ   r¨  r—  rŽ  r\  rv  zInvalid request format: Úinvalid_request_error)r]  rg  ri  rj  r>  r<  ru  r’  r]  rg  rh  ri  rj  rf  )r]  rg  ri  Úopenai_coderj  rf  r>  )&rb  rö  r%  rº   r   rÙ   rÄ   Úmaybe_get_model_idrm  r‘  rÔ   r6  r4   rÃ   r†  rš  rÖ   r…  r'  r*   r�  rÂ   r7   r>  rê   r   rp  rG  ÚHTTPStatusErrorrµ   r@  r“  r<  r]  r   rk  rF  rÔ  )r;  r  r}  r’  rs  Útransformed_exceptionr’  r  Ú_litellm_logging_objrp  r›  r>  r‰  Ú_response_headersrœ  r�  rŽ  Úsafe_headersÚhttp_status_errorÚ
error_bodyÚ
error_textÚ	error_msgÚhas_attribute_errorÚ_exc_status_codeÚ_codes                            r¼   Ú_handle_llm_api_exceptionz7ProxyBaseLLMRequestProcessing._handle_llm_api_exceptionk  s  è ø€ ô 	˜qÔ!à->×-UÑ-UØ/Ø ØŸ™ð .Vó .
÷ (
Ðð !Ð,Ø%ˆAÜ$+¨AÐ/CÀRÓ$HÐÜ×"Ñ"ð CØØô	
ô !Øˆy˜$ó
ˆð AEÇ	Á	ÇÁÐNcÐeiÓ@jÐð ×1Ñ1Ð2FÓGˆä =× PÑ PØ/á8LÐ$×4Ò4ÐRV×R[ÑR[×R_ÑR_Ð`qÓRràØØÜ Ð!2Ð4JÈBÓOØŸ™ØØ 4ð !Qó !
ˆô ˜!˜Y¨Ó-Ò3°ˆÙä.¨q°*Ó=ˆIØÐ$Ü+2°9¸iÈÓ+NÐ!Ù$Ü2´4Ð8IÓ3JÓK�GØ�‰�~Ô&ð
	Ø,=×,]Ñ,]Ø—Y‘YØ"3ØØ!%§¡§¡Ð/EÓ!FÒ!LÈ"× QÑ QÐR[Ð]_Ó `ð	 -^ó -÷ 'Ðñ  Ø—‘Ð/Ô0ð 18·±³×r©¨¨1À1Ç7Á7Ã9ÔTqÒCq˜q !™tÐrˆÑrà×/Ñ/°¸aÔ@ä�aœÔ(ðØ$%§I¡I§O¡OÓ$5×h™D˜A˜q¸¿¹»ÔJgÒ9g�1�a‘4ÓhðàFR×FXÑFXÓFZ×[¹d¸aÀ�1œ: a¬Ô-‘a´3°q³6Ñ9Ó[ðˆAŒIð ˆGä�aœÔ'Ü5°a¸ÓFÐFÜ˜œ5×0Ñ0Ô1ð ?@ÐØ&7×&@Ñ&@×&FÑ&FÓ&H× HˆJØ *× 1Ñ 1°'Ó :ˆJäØ-×6Ñ6×BÑBØ Ð,ôð ð  ˜Sˆ	ô
 &CÀ1Ó%EÐáÜ Ø2°9°+Ð>Ø,ØÜ×0Ñ0Ø$ôð ô #*¨!¨]¸DÓ"AÐØÐ'¬JÐ7GÌÔ,MÐRUÐYiÔRpÐmpÕRpØ$‰Eä×9Ñ9ˆEÜÜ˜A˜y¨)Ó4Ü˜˜F FÓ+Ü˜!˜W fÓ-Ü  6¨4Ó0ØÜ%,¨QÐ0JÈDÓ%QØ ô
ð 	
ða(
ùðh'úô ò 	Úð	üó sùó iùÛ[ð !Iûs†   ‚-P	¯O°DP	ÅAO$ ÆO!ÆO$ Æ-P	Ç O4ÇO4Ç$AP	È'O:ÉO:ÉP	É"(P Ê
A!P	Ë+PË,C3P	Ï!O$ Ï$	O1Ï-P	Ï0O1Ï1P	rç  c                 óR   — t        | t        «      rt        | «      }t        › |› d�S | S )zô
        Helper function to format streaming chunks for Anthropic API format

        Args:
            chunk: A string or dictionary to be returned in SSE format

        Returns:
            str: A properly formatted SSE chunk string
        rØ  )rÂ   rÃ   r5   r(   )rç  Ú	chunk_strs     r¼   Úreturn_sse_chunkz.ProxyBaseLLMRequestProcessing.return_sse_chunkó  s/   € ô �eœTÔ"ä)¨%Ó0ˆIÜ,Ð-¨i¨[¸Ð=Ð=àˆLr¾   Ústream_completedrÍ   c              ƒ   ó  K  — t        j                  d¬«      5  |xs | }d}|rt        | ||«      ƒ d {  –—† }|rWt        |«      }	t	        j
                  |«       |	}
|	st        ||«      ƒ d {  –—† }
|
s|�|�|j                  |«      ƒ d {  –—†  t        |d«      r	 |j                  «       ƒ d {  –—†  d d d «       y 7 Œ‹7 ŒS7 Œ67 Œ# t        $ r }t        j                  d|«       Y d }~Œ5d }~ww xY w# 1 sw Y   y xY w­w)NTrµ  Fr·  zAasync_streaming_data_generator: error closing response stream: %s)r¹  rº  rá   rå   rC   Ú_fire_deferred_stream_loggingr	  Ú-_arelease_max_parallel_requests_on_disconnectr"  r·  r¼  r   rÙ   )rÐ   r¿   rµ   r¦  rÍ   r}  r’  Úshould_record_client_disconnectÚrecorded_client_disconnectÚdeferred_stream_logging_armedÚsuccess_event_owns_slot_releaser  s               r¼   Ú%_finalize_streaming_generator_cleanupzCProxyBaseLLMRequestProcessing._finalize_streaming_generator_cleanup  s(  è ø€ ô ×Ñ dÔ+ñ &	Ø5HÒ5bÐQaÐMaÐ+Ø).Ð&Ù.Ü3`ØØ Ø'ó4÷ .Ð*ñ
 *Ü7XÐYeÓ7fÐ-Ü×:Ñ:¸<ÔHð 3PÐ/Ù4Ü<fØ$ hó=÷ 7Ð3ñ 8Ø)Ð5Ø)Ð5à+×YÑYÐZkÓl×lÐlä�x Ô*ðØ"Ÿ/™/Ó+×+Ð+÷C&	ð &	ð.øð"7øð møð ,ùÜ$ò Ü(×.Ñ.Ø[Ø÷ñ ûðú÷E&	ð &	üs†   ‚D™C5µC¶9C5Á/CÁ0C5ÂCÂC5Â C	Â3CÂ4C	Â8	DÃC5ÃC5ÃC5ÃC	Ã		C2ÃC-Ã(C5Ã-C2Ã2C5Ã5C>Ã:D)rÐ   Úserialize_chunkÚserialize_errorc               ó  K  — t        j                  d«       t        j                  «       }t	        t        t        dd«      «      }|j                   xr |j                   xr | }	t        j                  t        j                  «      }
d}d}d}	 d}|j                  || |¬«      2 3 d{  –—† }|
rt        j                  d|«       |	�s|j                  ||||¬«      ƒ d{  –—† }t        |t        t         f«      rt        j"                  |¬	«      }||z  }n}t%        |d
«      rC	 |j'                  dd¬«      }t        |t(        «      r|t+        |j-                  dd«      «      z  }n.t        |t(        «      r|t+        |j-                  dd«      «      z  }|j-                  dd«      }t0        j3                  |||j-                  d«      «      }|xs	 |t4        k7  } ||«      ­–— �ŒB7 �Œ>7 �Œ	# t.        $ r Y Œcw xY w6 d}�n-# t6        j8                  t:        f$ r5 |sd}|s-t=        | «      s"ddlm }  |t        |dd«      «      ƒ d{  –—†7   ‚ t.        $ rÕ}t        jB                  d|«       |jE                  |||¬«      ƒ d{  –—†7  }|�|}t        j                  d|«       t        |tF        «      r|‚tI        tK        jL                  «       «      }|› d|› �}tO        t        |d|«      t        |dd«      t        |dd«      t        |dd«      ¬«      }d} ||«      ­–— Y d}~nd}~ww xY wt0        jQ                  ||| ||||¬«      ƒ d{  –—†7   y# t0        jQ                  ||| ||||¬«      ƒ d{  –—†7   w xY w­w) zú
        Shared streaming data generator: runs proxy iterator hook, per-chunk hook,
        cost injection, then yields chunks via serialize_chunk; on exception runs
        failure hook and yields via serialize_error. Use for SSE or NDJSON.
        zinside generatorÚinclude_cost_in_streaming_usageFrP  )r}  rµ   r¿   Nz3async_data_generator: received streaming chunk - %s)r}  rµ   r%  Ú
str_so_far)r  Ú
model_dumpr^  T)ÚmodeÚexclude_nonerª  ré   rÒ   r   )Ú$release_budget_reservation_on_cancelÚbudget_reservationzIlitellm.proxy.proxy_server.async_data_generator(): Exception occured - %srõ  zl[1;31mAn error occurred: %s

 Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`rØ  r]  rg  rh  ri  r<  iô  r¡  )rÐ   r¿   rµ   r¦  rÍ   r}  r’  ))r   rÙ   rC   Ú_callback_capabilitiesrë   rº   rý   Úhas_streaming_chunk_overrideÚhas_guardrailrè  ré  rê  rƒ  Úasync_post_call_streaming_hookrÂ   r«   r¬   Úget_response_stringr"  r´  rÃ   rê   rÄ   rÖ   rm  Ú"_process_chunk_with_cost_injectionr)   r  r  ÚGeneratorExitr½   Ú/litellm.proxy.spend_tracking.budget_reservationr·  rí  rö  r   r   Ú	tracebackÚ
format_excr7   r®  )rµ   r}  r¿   r’  r¯  r°  rÐ   ÚcapsÚcost_injection_enabledÚ	fast_pathÚdebug_enabledr¦  rÍ   Údelivered_chunkr³  rç  Úresponse_strÚdrõ  r·  r  r—  Úerror_tracebackrž  Úproxy_exceptions                            r¼   Úasync_streaming_data_generatorz<ProxyBaseLLMRequestProcessing.async_streaming_data_generator7  sÈ  è ø€ ô  	×"Ñ"Ð#5Ô6ô #×9Ñ9Ó;ˆÜ(,¬W´WÐ>_ÐafÓ-gÓ(hÐØ×9Ñ9Ð9ÒsÀ$×BTÑBTÐ>TÒsÐ]sÐYsˆ	Ü3×@Ñ@ÄÇÁÓOˆØ ÐØ#ÐØˆðf	ØˆJØ0×XÑXØ"3Ø!Ø)ð  Yó  ÷ +-ð +-�eñ !Ü(×.Ñ.Ð/dÐfkÔlâ Ø"3×"RÑ"RØ*;Ø!&Ø)Ø#-ð	 #Só #÷ �Eô " %¬-Ô9LÐ)MÔNÜ'.×'BÑ'BÐPUÔ'V˜Ø" lÑ2™
Ü  ¨Ô5ð!Ø %× 0Ñ 0°fÈ4Ð 0Ó P˜AÜ)¨!¬TÔ2Ø *¬c°!·%±%¸	À2Ó2FÓ.GÑ G 
øô $ E¬4Ô0Ø"¤c¨%¯)©)°I¸rÓ*BÓ&CÑC˜
à!-×!1Ñ!1°'¸2Ó!>�JÜ9×\Ñ\Ø˜z¨<×+;Ñ+;Ð<QÓ+Ró�Eð #2Ò"]°UÔ>]Ñ5]�Ù% eÓ,Õ,ðW+-ùðúô  )ò !Ù ð!úð5 ðX  $ÒøÜ×&Ñ&¬Ð6ò 	ñ $Ø&*Ð#Ù"Ô+DÀXÔ+Nõñ ;¼7ÐCTÐVjÐlpÓ;qÓr×rÑrØÜò 	3Ü ×*Ñ*Ø[Ð]^ôð 2C×1YÑ1YØ"3Ø#$Ø)ð 2Zó 2÷ ,ð ,Ð!ð
 %Ð0Ø)�Ü ×&Ñ&ð DØôô
 ˜!œ]Ô+Ø�Ü%3´I×4HÑ4HÓ4JÓ%KˆOØ"#  D¨Ð(9Ð:ˆIÜ%3Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¨sÓ3ô	&ˆOð  $ÐÙ! /Ó2×2Ð2ûð7	3úô: 0×UÑUØØ)Ø!Ø!1Ø$7Ø"3Ø"3ð Vó ÷ ò øÔ/×UÑUØØ)Ø!Ø!1Ø$7Ø"3Ø"3ð Vó ÷ ò üsË   ‚BN ÂH Â'G>Â+G)Â,G>Â/4H Ã#G,Ã$AH Ä'AG/Å(BH Ç)G>Ç,H Ç/	G;Ç8H Ç:G;Ç;H ÈM ÈAL-É	IÉ
L-É-L(ÊJÊBL(Ì#M Ì(L-Ì-M Ì0N ÍMÍN Í M=Í6M9Í7M=Í=N c           	      óX   — t         j                  | |||t         j                  d„ |¬«      S )a�  
        Anthropic /messages and Google /generateContent streaming data generator require SSE events.

        Returns the underlying ``async_streaming_data_generator`` configured with
        SSE serializers directly (rather than re-wrapping it in another
        ``async for: yield`` trampoline), so a streamed chunk traverses one
        fewer async-generator layer / coroutine resume on the hot path.
        c                 ó^   — t         › t        j                  d| j                  «       i«      › d�S )Nr\  rØ  )r(   r^  r_  Úto_dict)Ú	proxy_excs    r¼   r³  zHProxyBaseLLMRequestProcessing.async_sse_data_generator.<locals>.<lambda>Ô  s/   € Ü)Ð*¬4¯:©:°wÀ	×@QÑ@QÓ@SÐ6TÓ+UÐ*VÐVZÐ[ð r¾   )rµ   r}  r¿   r’  r¯  r°  rÐ   )rm  rÌ  r¥  r  s        r¼   r,  z6ProxyBaseLLMRequestProcessing.async_sse_data_generator¾  s<   € ô  -×KÑKØØ/Ø%Ø/Ü9×JÑJñð ð Ló 

ð 
	
r¾   rõ  c                  ó   — y r  r  ©rç  rõ  rÒ   s      r¼   r¾  z@ProxyBaseLLMRequestProcessing._process_chunk_with_cost_injectionÚ  s   € ð r¾   c                  ó   — y r  r  rÒ  s      r¼   r¾  z@ProxyBaseLLMRequestProcessing._process_chunk_with_cost_injectionà  s   € ð r¾   c                 ó  — t        t        dd«      s| S 	 t        | t        «      rt        j                  | ||«      }|�¨|S t        | t        t        f«      rO	 | j                  d«      }|j                  d«      r*t        j                  |||«      }|�|j                  d«      S | S t        | t        «      r1t        j                  | ||«      }|�|j                  d«      r|S |dz   S | S # t        $ r Y | S w xY w# t        $ r Y | S w xY w)aŽ  
        Process a streaming chunk and inject cost information if enabled.

        Args:
            chunk: The streaming chunk (dict, str, bytes, or bytearray)
            model_name: Model name for cost calculation
            litellm_logging_obj: The call's logging object, used for pricing

        Returns:
            The processed chunk with cost information injected if applicable
        r²  FrŽ  )rØ  z

rØ  )rº   rý   rÂ   rÃ   rm  Ú_inject_cost_into_usage_dictrI  Ú	bytearrayr“  ÚendswithÚ_inject_cost_into_sse_frame_strr   rÖ   rê   )rç  rõ  rÒ   Úmaybe_modifiedÚsÚ	maybe_mods         r¼   r¾  z@ProxyBaseLLMRequestProcessing._process_chunk_with_cost_injectionæ  s6  € ô ”wÐ AÀ5ÔIØˆLð	Ü˜%¤Ô&Ü(E×(bÑ(bØ˜:Ð':ó)�ð "Ð-Ø)Ð)Ü˜E¤E¬9Ð#5Ô6ð	Ø$Ÿ|™|¨GÓ4�AØ—z‘zÐ"6Ô7Ü$A×$aÑ$aØ˜zÐ+>ó%˜	ð %Ð0Ø#,×#3Ñ#3°GÓ#<Ð<ð ˆô ˜E¤3Ô'ä9×YÑYØ˜:Ð':ó�	ð Ð(à(1×(:Ñ(:¸6Ô(B˜9Ð\ÈÐU[ÑI[Ð\ð
 ˆøô !ò Øð ˆðûô ò 	ààˆð		úsB   •*C8 Á C8 ÁAC( Â%;C8 Ã!C8 Ã(	C5Ã1C8 Ã4C5Ã5C8 Ã8	DÄDÚ	frame_strc                 óØ  — 	 | j                  d«      }t        |«      D ]»  \  }}|j                  «       }|j                  d«      sŒ(|j                  dd«      d   j                  «       }|sŒN|dk7  sŒTt	        j
                  |«      }t        j                  |||«      }	|	€Œƒdt        |	«      z   |j                  d«      rdndz   ||<   dj                  |«      c S  y# t        $ r Y yw xY w)	a¼  
        Inject cost information into an SSE frame string by modifying the JSON in the 'data:' line.

        Args:
            frame_str: SSE frame string that may contain multiple lines
            model_name: Model name for cost calculation
            litellm_logging_obj: The call's logging object, forwarded for pricing

        Returns:
            Modified SSE frame string with cost injected, or None if no modification needed
        ú
zdata:rQ  r�  Nr�  úrP  )r�  Ú	enumerater•  r”  r^  r—  rm  rÕ  r5   r×  r%  rÖ   )
rÜ  rõ  rÒ   ÚlinesÚidxÚlnÚstripped_lnÚ	json_partÚobjrÙ  s
             r¼   rØ  z=ProxyBaseLLMRequestProcessing._inject_cost_into_sse_frame_str  sï   € ð	à$Ÿ?™?¨4Ó0ˆEÜ$ UÓ+ò 4‘��RØ Ÿh™h›j�Ø×)Ñ)¨'Õ2Ø +× 1Ñ 1°'¸1Ó =¸aÑ @× FÑ FÓ H�IÚ  Y°(Ó%:Ü"Ÿj™j¨Ó3˜Ü)F×)cÑ)cØ Ð-@ó*˜ð *Ñ5Ø)1´J¸~Ó4NÑ)NÐZ\×ZeÑZeÐfjÔZkÑRVÐqsÑ)t˜E #™JØ#'§9¡9¨UÓ#3Ò3ð4ð øÜò 	Ùð	ús0   ‚AC Á%C Á,C Á2.C Â!9C ÃC Ã	C)Ã(C)r÷   c           
      óp  — t        | j                  dd«      xs d«      }t        | j                  dd«      xs d«      }t        | j                  d||z   «      xs ||z   «      }t        d|fd|fd|fd| j                  d«      fd| j                  d«      ffD ��ci c]
  \  }}|�||“Œ c}}«      S c c}}w )NÚprompt_tokensr   Úcompletion_tokensÚtotal_tokensÚcompletion_tokens_detailsÚprompt_tokens_details)rF  rÄ   r   )r÷   rè  ré  rê  rN  r2  s         r¼   Ú_openai_stream_usage_kwargsz9ProxyBaseLLMRequestProcessing._openai_stream_usage_kwargs:  sÜ   € ä" 5§9¡9¨_¸aÓ#@Ò#EÀAÓFˆÜ#& u§y¡yÐ1DÀaÓ'HÒ'MÈAÓ#NÐÜ!Ø�I‰I�n mÐ6GÑ&GÓHÒoÈ]Ð]nÑMnó
ˆô  ð % mÐ4Ø(Ð*;Ð<Ø# \Ð2Ø0°%·)±)Ð<WÓ2XÐYØ,¨e¯i©iÐ8OÓ.PÐQð#÷
á�C˜ð Ð$ð �U‘
ó
ó
ð 	
ùó
s   ÂB2
ræ  c                 óÆ   — | j                  d«      dk(  rt        «       j                  |d ¬«      S | j                  d«      dk(  rt        di t        j                  |«      ¤ŽS y )Nrg  Úmessage_delta)Úusage_objectÚreasoning_contentrW  zchat.completion.chunkr  )rÄ   r¦   Úcalculate_usager®   rm  rí  )ræ  r÷   s     r¼   Ú_stream_usage_for_eventz5ProxyBaseLLMRequestProcessing._stream_usage_for_eventO  s^   € ð �7‰7�6‹?˜oÒ-Ü"Ó$×4Ñ4À%Ð[_Ð4Ó`Ð`Ø�7‰7�8ÓÐ 7Ò7ÜÑ\Ô8×TÑTÐUZÓ[Ñ\Ð\Ør¾   Úmodel_responseÚservice_tierc                 óR   — 	 t        j                  | ||¬«      S # t        $ r Y y w xY w)N)Úcompletion_responseré   rõ  )rý   Úcompletion_costrÖ   )rô  rõ  rõ  s      r¼   Ú_completion_cost_or_nonez6ProxyBaseLLMRequestProcessing._completion_cost_or_noneY  s6   € ð	Ü×*Ñ*Ø$2¸*ÐS_ôð øô ò 	Ùð	ús   ‚ š	&¥&c                 óÌ  — t        |dd «      }t        |dd «      }d}t        «       }t        |t        «      r|j	                  ||«      nd }	 |j                  | ¬«      }	 t        |d«      r||_        t        |t        «      r||u r|j                  |d «       n|||<   	 t        |t        t        f«      rt        |t        «      st        |«      S d S # t        $ rC Y t        |d«      r||_        t        |t        «      r||u r|j                  |d «       y |||<   y y w xY w# t        |d«      r||_        t        |t        «      r||u r|j                  |d «       w |||<   w w xY w)NrA  r×   Ú'response_cost_failure_debug_informationrâ  )rº   rW  rÂ   rÃ   rÄ   rã  rÖ   r"  rA  rR  rF  r5  rë   )rô  rÒ   Úbreakdown_beforeÚcall_detailsÚ	debug_keyÚdebug_missingÚdebug_beforerK  s           r¼   Ú_logging_obj_cost_or_nonez7ProxyBaseLLMRequestProcessing._logging_obj_cost_or_noned  sy  € ô #*Ð*=Ð?OÐQUÓ"VÐÜ%Ð&9Ð;OÐQUÓVˆØDˆ	Ü%›xˆÜLVÐWcÔeiÔLj˜l×.Ñ.¨y¸-ÔHÐptˆð	;Ø-×GÑGÈ~ÐGÓ^‰Dô Ð*Ð,<Ô=Ø5EÐ#Ô2Ü˜,¬Ô-Ø =Ñ0Ø ×$Ñ$ Y°Õ5à.:�L Ò+Ü(¨´´U¨|Ô<ÄZÐPTÔVZÔE[Œu�T‹{ÐeÐaeÐeøô ò 	ØäÐ*Ð,<Ô=Ø5EÐ#Ô2Ü˜,¬Ô-Ø =Ñ0Ø ×$Ñ$ Y°Õ5à.:�L Ò+ð	 .ð	ûô Ð*Ð,<Ô=Ø5EÐ#Ô2Ü˜,¬Ô-Ø =Ñ0Ø ×$Ñ$ Y°Õ5à.:�L Ò+ð	 .ús%   ÁC Ã	DÃD! ÄDÄD! Ä!AE#c                 ól   — |�t         j                  | |«      nd }|�|S t         j                  | ||«      S r  )rm  r  rù  )rô  rõ  rõ  rÒ   Úcost_from_logging_objs        r¼   Ú_streamed_usage_costz2ProxyBaseLLMRequestProcessing._streamed_usage_cost  sJ   € ð #Ð.ô *×CÑCÀNÐTgÔhàð 	ð
 !Ð,Ø(Ð(Ü,×EÑEÀnÐV`ÐbnÓoÐor¾   c                 ó$  — | j                  d«      }t        |t        «      syt        j	                  | |«      }|€y| j                  d«      }t        j                  t        |¬«      |t        |t        «      r|nd|«      }|€yi | ¥di |¥d|i¥i¥S )aÚ  
        Inject cost information into the usage object of a streamed usage event
        (Anthropic ``message_delta`` or OpenAI ``chat.completion.chunk``).

        Args:
            obj: Dictionary containing the SSE event data
            model_name: Model name for cost calculation
            litellm_logging_obj: The call's logging object, used for pricing

        Returns:
            Modified dictionary with cost injected, or None if no modification needed
        r÷   Nrõ  )r÷   rK  )rÄ   rÂ   rÃ   rm  ró  r  r«   rê   )ræ  rõ  rÒ   r÷   Ústream_usagerõ  Úcost_vals          r¼   rÕ  z:ProxyBaseLLMRequestProcessing._inject_cost_into_usage_dict‘  s    € ð  —w‘w˜wÓ'ˆÜ˜%¤Ô&ØÜ;×SÑSÐTWÐY^Ó_ˆØÐØØ!Ÿg™g nÓ5ˆÜ7×LÑLÜ Ô-ØÜ& |´SÔ9‰L¸tØó	
ˆð ÐØØ<�#Ð<�wÐ ; 5Ð ;¨&°(Ñ ;Ñ<Ð<r¾   Ú_logging_objc                 óÖ  — d}|�rt        |d«      r…|j                  ry|j                  j                  d«      xs i }|j                  dd«      }|sF|j                  j                  d«      xs i }|j                  d«      xs i }|j                  dd«      }|s†t        |dd«      }|rw|j                  di «      }|j                  d«      xs i }|j                  dd«      }|s<|j                  d«      xs i }|j                  d«      xs i }|j                  dd«      }|sH| j                  j                  di «      xs i }|j                  di «      xs i }|j                  dd«      }|S )zø
        Get model_id from logging object or request metadata.

        The router sets model_info.id when selecting a deployment. This tries multiple locations
        where the ID might be stored depending on the request lifecycle stage.
        NrÓ   rÞ  rS  rÆ   r‡  rÈ   )r"  rÓ   rÄ   rº   r%  )r;  r  rp  rÞ  rÆ   Ú_kwargsrÓ   rÈ   s           r¼   r•  z0ProxyBaseLLMRequestProcessing.maybe_get_model_id²  sb  € ð ˆÚä�|Ð%5Ô6¸<×;VÒ;Và)×8Ñ8×<Ñ<¸\ÓJÒPÈb�
Ø%Ÿ>™>¨$°Ó5�ñ  Ø+×:Ñ:×>Ñ>¸zÓJÒPÈb�HØ!)§¡¨lÓ!;Ò!A¸r�JØ)Ÿ~™~¨d°DÓ9�Hñ Ü!(¨°xÀÓ!F�ÙØ,3¯K©KÐ8HÈ"Ó,M�Nà!/×!3Ñ!3°LÓ!AÒ!GÀR�JØ)Ÿ~™~¨d°DÓ9�Hñ $Ø#1×#5Ñ#5°jÓ#AÒ#GÀR˜Ø%-§\¡\°,Ó%?Ò%EÀ2˜
Ø#-§>¡>°$¸Ó#=˜ñ Ø&*§i¡i§m¡mÐ4FÈÓ&KÒ&QÈrÐØ)×-Ñ-¨l¸BÓ?ÒEÀ2ˆJØ!—~‘~ d¨DÓ1ˆHàˆr¾   )NNNNNNNN)r¶   N)NNNNNNNNNFNF©Fr  )FFNN)KrB  rC  rD  rÃ   r­  Ústaticmethodr8   rê   r5  r   rW  rë   rG  ÚTimeoutrÿ   r‘  r   rC   r�  r§   r   rF  rE   ÚtuplerÈ  rÓ  r   rÎ  r™  r€  r   ræ  rí  r   r¥   r   rù  rø  r0  rK  r.  rT  r   r  r  r#  r$  r(  r*  rI  r&  r)  r  rÖ   r�  r¢  r¥  r®  ÚStreamChunkSerializerÚStreamErrorSerializerr   rÌ  r,  r   r¾  rØ  rí  r®   ró  r«   rù  r  r  rÕ  r•  r  r¾   r¼   rm  rm  Æ  s  „ ð˜Tó ð ð #Ø#Ø $Ø#Ø"Ø#'Ø,0Ø59Ø9=Ø$&Ø04Ø8<òuà)ðuð �t‘ðuð ˜‘*ð	uð
 ˜‘:ðuð ˜‘*ðuð �t‘ðuð ˜D‘jðuð ˜s‘{ TÑ)ðuð ˜s F˜{Ñ+¨dÑ2ðuð ,0°$©;ðuð ˜T‘kðuð ˜Ÿ™Ñ&¨Ñ-ðuð /°Ñ5ðuð  
ò!uó ðuðn ð6àð6ð ð6ð ð	6ð
 *ð6ð 'ð6ð �t‘ð6ð (ð6ð 
ˆc�3ˆh‰ò6ó ð6ðt #Ø!%Ø)-Ø-1Ø&*Ø$(Ø Ø$(ñST&àðT&ð ðT&ð *ð	T&ð
 (ðT&ð "ðT&ð ðXñZ
ðT&ðD �t‘ðET&ðF ˜$‘JðGT&ðH   $™,ðIT&ðJ $ d™lðKT&ðL ˜t™ðMT&ðN ˜T‘zðOT&ðP �T‰zðQT&ðR ˜T‘MðST&ðT 
ˆtÐ&Ð&Ñ	'óUT&ðlTàðTð ðTð (ð	Tð
 *ðTð �t‘ðTð "ðTð ˜$‘JðTð   $™,ðTð $ d™lðTð ˜t™ðTð ˜T‘zðTð �T‰zðTð ðTð ˜T‘MðTð  
ˆtÐ&Ð&Ñ	'ó!Tðl$àð$ð ð$ð *ð	$ð
 
�‰ó$ð8 ð°4ð ¸tð Èò ó ðð ðØ.°Ñ5ðà	ˆt‰òó ðð( ðTàðTð 'ðTð 
�‰ò	Tó ðTó&ð6 ?CØ$(Ø Ø!%Ø)-Ø-1Ø&*Ø$(Ø"Ø,1Ø(,Ø$)ñ)?
àð?
ð #ð?
ð *ð	?
ð
 #ð?
ð (ð?
ð ˜s F˜{Ñ+ð?
ð "ð?
ð  (¨¨V¨Ñ4°tÑ;ð?
ð ˜T‘Mð?
ð �T‰zð?
ð ˜$‘Jð?
ð   $™,ð?
ð $ d™lð?
ð ˜t™ð?
ð  ˜T‘zð!?
ð" �t‘ð#?
ð$ # T™kð%?
ð& �v‘, Ñ%ð'?
ð( "ð)?
ð* 
ó+?
ðT ?CØ$(Ø Ø!%Ø)-Ø-1Ø&*Ø$(Ø"Ø,1Ø(,Ø$)ñ)[àð[ð #ð[ð *ð	[ð
 #ð[ð (ð[ð ˜s F˜{Ñ+ð[ð "ð[ð  (¨¨V¨Ñ4°tÑ;ð[ð ˜T‘Mð[ð �T‰zð[ð ˜$‘Jð[ð   $™,ð[ð $ d™lð[ð ˜t™ð[ð  ˜T‘zð![ð" �t‘ð#[ð$ # T™kð%[ð& �v‘, Ñ%ð'[ð( "ð)[ð* 
ó+[ðz ðØðà)ðð 
òó ðð. ð¸vð È&ò ó ðð$ ð0Ø"(ð0àð0ð *ò0ó ð0ðv %)Ø Ø!%Ø)-Ø-1Ø&*Ø$(Ø"ñ!;
àð;
ð #ð;
ð *ð	;
ð
 (ð;
ð ð;
ð "ð;
ð  (ð;
ð ˜T‘Mð;
ð �T‰zð;
ð ˜$‘Jð;
ð   $™,ð;
ð $ d™lð;
ð ˜t™ð;
ð ˜T‘zð;
ð  �t‘ó!;
ðz¨sð °tó ñ(¨$ð ÀdÈTÁkð Ð^bó ð ð tò ó ðð¸4ó ð2
ÀDó 
ð&h°c¸D±jó hð&[
àð[
ð *ð[
ð ,ð	[
ð
 ð[
ð ˜c 3˜h™ð[
ð 
�D‰ó[
ðz
àð
ð *ð
ð ,ð	
ð
 
ó
ð" ð#SØð#Sàð#Sð 
ò#Só ð#SðJ ð_Øð_à$4ð_ð 0ð_ð  ð	_ð
 ð_ð 
ò_ó ð_ðBE¸$ð EÀ9ð EÐQUó Eð #ñB
àðB
ð *ðB
ð (ð	B
ð
 �t‘óB
ðP ð ð ¨ò ó ðð" ð
 "'Ø$)Ø37Ø15ñ/Ø˜4‘ð/àð/ð ð/ð ð	/ð
 "ð/ð *¨DÑ0ð/ð (¨$Ñ.ð/ð 
ò/ó ð/ðb ð #'òDØðDà)ðDð ðDð (ð	Dð /ðDð /ðDð ˜4‘ðDð 
˜˜T˜	Ñ	"òDó ðDðL ð #'ñ
Øð
à)ð
ð ð
ð (ð	
ð
 ˜4‘ð
ð 
˜˜T˜	Ñ	"ò
ó ð
ð6 ØàW[ñØðØ"%ðØ<MÐPTÑ<Tðà	òó ó ðð ØàX\ñØðØ#&ðØ=NÐQUÑ=Uðà	òó ó ðð àX\ñ/Øð/Ø#&ð/Ø=NÐQUÑ=Uð/à	ò/ó ð/ðb àY]ñØðØ$'ðØ>OÐRVÑ>Vðà	ˆt‰òó ððB ð
¨7°3¸°8Ñ+<ð 
ÀÈÈcÈÑARò 
ó ð
ð( ð W¨S°&¨[Ñ%9ð À'È#ÈsÈ(ÑBSð ÐX]Ð`dÑXdò ó ðð ðØ%ðØ36ðØFIÈDÁjðà	�‰òó ðð ðfØ%ðfØ<Mðfà	�‰òfó ðfð4 ðpØ%ðpàðpð ˜D‘jðpð /°Ñ5ð	pð
 
�‰òpó ðpð" àTXñ=Øð=Ø"ð=Ø9JÈTÑ9Qð=à	�‰ò=ó ð=ð@*Ð/@À4Ñ/Gð *ÈCÐRVÉJô *r¾   rm  r  r  )r  N)Ír  r  r^  ré  rŽ  rÁ  rX  r   r   r   r   r   r   r	   Ú	functoolsr
   Útypesr   Útypingr   r   r   r   r   r   r   r   r   r¹  rG  r–  Úfastapir   r   r   Úfastapi.responsesr   r   r   Ústarlette.typesr   r   r   rý   Úlitellm._loggingr   r   Úlitellm._uuidr    Úlitellm.constantsr!   r"   r#   r$   r%   r&   r'   r(   r)   r*   Ú%litellm.integrations.custom_guardrailr+   Ú'litellm.litellm_core_utils.core_helpersr,   r-   Ú%litellm.litellm_core_utils.dd_tracingr.   r/   Ú6litellm.litellm_core_utils.get_supported_openai_paramsr0   Ú1litellm.litellm_core_utils.internal_call_metadatar1   Ú*litellm.litellm_core_utils.litellm_loggingr2   rÿ   Ú7litellm.litellm_core_utils.llm_cost_calc.guardrail_costr3   Ú9litellm.litellm_core_utils.llm_response_utils.get_headersr4   Ú*litellm.litellm_core_utils.safe_json_dumpsr5   r!  r6   Úlitellm.proxy._typesr7   r8   Úlitellm.proxy.auth.auth_checksr9   Úlitellm.proxy.auth.auth_utilsr:   Ú)litellm.proxy.common_utils.callback_utilsr;   r<   Ú(litellm.proxy.common_utils.sse_keepaliver=   r>   r?   r@   Úlitellm.proxy.dd_span_taggerrA   Úlitellm.proxy.route_llm_requestrB   rg  rC   rD   Úlitellm.routerrE   Ú/litellm.router_utils.add_retry_fallback_headersrF   Ú!litellm.router_utils.common_utilsrG   Úlitellm.types.guardrailsrH   Úlitellm.types.routerrI   rJ   rL   r¥   r6  Ú*litellm.llms.anthropic.chat.transformationr¦   rê   r  r  r¼  r§   Ú_ProxyConfigr¹  r¨   r©   rª   Úlitellm.types.utilsr«   r¬   r­   r®   rÂ   r¯   r´   rW  rë   r½   rÃ   rÊ   rÏ   rá   rå   rî   ró   r	  r   r  r  r$  r1  r6  r8  rK  rM  rR  rT  rY  r  rc  rp  rw  r|  r‚  r‹  rI  rF  r�  r¤  r¦  rÖ   rÁ  rÆ  rÒ  r¼  rÖ  rÙ  r¾  rò  ró  r5  rù  rý  r  r  r  r  r(  r*  r:  r;  r?  rC  rL  r]  rë  rb  rÄ  rf  rk  rm  r  r¾   r¼   ú<module>r2     s	  ðÜ Û Û Û Û Û ß ]× ]Ý Ý Ý "ß i× iÕ iã Û Û ß 2Ñ 2ß GÑ Gß 0Ñ 0ã ß AÝ ÷÷ ÷ õ Bß kß Dõõ iÝ SÝ ^õõ Bõ÷ @Ý FÝ E÷÷ó õ 6Ý 9ß UÝ !Ý RÝ GÝ 8Ý 5áÐ)°Ô:€Ù�KÓ €	à#ðWñY€�	ó Yõt Gð ! # ¨ Ñ,Ð à  .Ð!1°3Ð!6Ñ7Ð áÝFà�Kà€K÷ñ ÷
ó ñ *4°F¸JÓ)GÐ%GÐ ˜UÓ Gñ Ð=Ó>Ø6Ø'ñYÐ &¨Ð.TÑ(Uó ðL¨ð L°4ó Lð°°S¸&°[Ñ0Að Àdó ðX°t¸CÀ¸KÑ7HÈ4Ñ7Oð XÐTXó Xð !&ñ2Ø�t‰^ð2àð2ð ð2ð 
ó	2ðj°Dð ¸Tó ð°X¸fÑ5Eð ÐX^ð Ðcgó ð,OØ˜#˜v˜+Ñ&ðOàðOð 
óOð$FÀ4ð FÐSYð FÐ^bó FðR¨dÐ3FÑ.Gð ÈDó ñ �3ÔðQ¸#ð QÀ$ò Qó ðQðTØðTà˜‘ðTð �4‰ZðTð 
ó	TðØ
�#�v�+Ñ
ðà˜c 6˜kÑ*ðð ðð & b¨$ hÑ/ð	ð
 ˆS�&ˆ[Ñóñ<)˜6ð )¨ð )°vð )Èó )ô(˜Hô (ðÐ$9ð Ð>Só ô;˜ô ;ðÐ1ð Ð6Hó ô ô ðÐ(Bð ÐGaó ðØðà
ˆ3��t‘ÐÑóð>¨]ð ÀTÈ#ÈsÈ(Á^ð ÐXfó ð¸ÀÀfÀÑ9Mð ÐRUÐVYÑRZó ð4
Ø
�#�v�+Ñ
ð
à%ð
ð 
ó
ð&Øðà˜S &˜[Ñ)ðð &ðð ð	ð
 	ˆ4�ZóðB °#¸±+ð  À#ÈÁ*ó  ðF"¨c°E©kð "¸dó "ôJ*_Ð(9ô *_ôZ¨)ô ð%¨Wð %¸ó %ð"00Ø˜c 4˜iÑ(ð00à�t‰^ð00ð 	ó00ðf#˜Mð #¨e°C¸ÀÀfÀÑ9MÐ4MÑ.Nó #ð8O ¨¨f¨Ñ!5ð O¸%ÀÀSÀ¹/ó Oð  &×1Ò1Ø"ñ}Ø˜c 4˜iÑ(ð}àð}ð ð}ð ð	}ð
 �t‰^ð}ð ˜Ñ%ó}ñ@ 5Eà#Ø!ñó5Ð ˜˜w s¨C xÑ0Ñ1ó ñe¨'°#°v°+Ñ*>ð eÈFÐUYÉMð eÐejÐmqÑeqó eð$]¨(ð ]°tó ]ð.2¨ð 2°nÀUÈDÀ[Ñ6Qó 2ð&;Ø	ð;àTð;ð ó;ð6 *ØUYñ	KØ Ñ/ðKà  3™;¨Ñ-ðKð ðKð ˜y˜k¨9°]ÀTÑ5IÑ+JÐJÑKÈdÑRð	Kð
 Ð'Ñ'óKñ\`¨#ð `¸gÀcÈ6ÀkÑ>RÐUYÑ>Yð `Ðeió `ð4 #(òl
àðl
ð ðl
ð ð	l
ð
  ðl
ð 
ól
ô^
) 
ô 
)ðPØ˜‘ðPà˜T‘\ðPð  ™ðPð ˆT�\ó	Pñ 8ØØØØØØØôÐ �eó ð`ð 5¨3¡;°Ñ#5ð ¸$ó ð  )-ñ#Ø*¨TÑ1ð#à˜3‘; Ñ%ð#ð ó#ðL°W¸SÀ&¸[Ñ5IÈDÑ5Pð ÐUZÐ]aÑUaó ð0 yð °Tó ð4 $EÐ ˜5Ó Dð`˜ið `¨Dó `ð
Øð
à-ð
ð —m’mð
ð 
ó	
ð&Øðà-ðð ó÷&V$ò V$r¾   