Ë
    uPê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mZ d dlmZm	Z	 d dl
mZ d dlmZmZmZ d dlmZmZ d dlmZ d dlmZ d dlZd d	lmZmZ d d
lmZ d dlmZm Z m!Z!m"Z"m#Z#m$Z$ d dl%m&Z& d dl'm(Z(m)Z)m*Z* d dl+m,Z, d dl-m.Z. d dl/m0Z0m1Z1 d dl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; d dl<m=Z=m>Z>m?Z? d dl@mAZA d dlBmCZC  eDd„ e9jŠ                  j�                  «       D «       «      ZGeeHd<   dZIeeHd<    e9j”                  «        eDddh«      z  ZKeeHd<    eDh d£«      ZLeeHd<    ejš                  dejœ                  «      ZOeeHd<    eDd d!h«      ZPeeHd"<   d#ZQeeHd$<    ejš                  d%ejœ                  «      ZReeHd&<    ejš                  d'«      ZSeeHd(<    ejš                  d)«      ZTeeHd*<    ejš                  d+ejœ                  «      ZUeeHd,<   d-eVd.eVdz  fd/„ZWd0eVd.eVdz  fd1„ZXd2e;d.eVdz  fd3„ZY ejš                  d4«      ZZeeHd5<   d6ed.eVfd7„Z[d d8l\m]Z] d d9l^m_Z_ d d:l`maZa d d;lbmcZc d d<ldmeZemfZfmgZgmhZhmiZi  e«       ZjeeHd=<   d>ZkeeHd?<    e«       ZleeeVdf      eHd@<   damendz  eHdA<   erd dBlompZq d dClrmsZs eqZpneZpeZsdD„ ZtdEZueeHdF<    eDh dG£«      ZveeHdH<   g dI‘dJ‘dK‘dL‘dM‘dN‘dO‘dP‘dQ‘dR‘dS‘dT‘dU‘dV‘eC‘dW‘dX‘dY‘dZ‘d[‘d\‘d]‘d^‘d_‘d`‘da‘db‘dc‘dd‘de‘df‘­ZweeHdg<   dNdOdQdWdhdidjdkdldmdRdSdTdUdVeCe$ee dJdIdKdXdYdndoe#fZxeeHdp<    eDdqh«      ZyeeHdr<    eDdLdMh«      ZzeeHds<   dtZ{eeHdu<   dvZ|eeHdw<    eDeejú                  jý                  «       «      ZeeHdx<    eDdydzh«      Z€eeHd{<    eDd|d}h«      Z�eeHd~<   dZ‚eeHd€<   d�ZƒeeHd‚<   dƒe„eVef   d.dfd„„Z…d…eVd6eVd.dfd†„Z† eend‡e‡dˆeˆd‰eVdŠe‰d‹i«      ZŠeee‹eVf      eHdŒ<   d…eVd6eŒd.e8fd�„Z�d…eVd6eŒd.eeVef   fdŽ„ZŽd�d�œd‘edvend.dfd’„Z�d6ed.enfd“„Z�d2e;d”eVd.enfd•„Z‘d2e;d.enfd–„Z’d2e;d.enfd—„Z“d2e;d.enfd˜„Z”dƒe„eVef   d.dfd™„Z•dƒe„eVef   d.dfdš„Z–dƒe„eVef   d.dfd›„Z—dƒe„eVef   d.dfdœ„Z˜d�ed.eVfdž„Z™dŸeeVef   d eeVef   d.ešešeVef   d¡f   fd¢„Z›d£e„eVeVf   d.eVdz  fd¤„Zœd£eeVeVf   d.eVdz  fd¥„Z�d‘e„eVeVf   dz  d.eVdz  fd¦„Zžd§eŒd.eVdz  fd¨„ZŸd©eVd.enfdª„Z d©eVd.enfd«„Z¡d©eVdƒe„d¬epd.enfd­„Z¢dƒe„d�efd®„Z£dƒe3d¯e:dz  d.e:fd°„Z¤d±e„d²eVd.e3dz  fd³„Z¥ G d´„ dµ«      Z¦d2e;d¬epd.e:dz  fd¶„Z§	 	 	 dôd‘ed·eVdz  d¸end¹eVdz  d.e„f
dº„Z¨d»eVd.enfd¼„Z©d‘eeVeVf   d.eeVeVf   fd½„Zª G d¾„ d¿«      Z«dƒe	eVeŒf   d.dfdÀ„Z¬	 	 dõdƒe„d�ed2e;d¬epdÁe„eVef   dz  dÂeVdz  fdÃ„Z­dÄeVdÅeVdÆeVd.dfdÇ„Z®dƒe„d2e;d.dfdÈ„Z¯dƒe„d2e;d.dfdÉ„Z°	 	 dõdƒe„d2e;dÊeVdz  dËe]dz  d.df
dÌ„Z±	 dödËe]dÍeVdÊeVdz  d.eVdz  fdÎ„Z²	 	 dõdÍeVdÏe„dz  dÐe„dz  dÊeVdz  dÑeVdz  d.eVdz  fdÒ„Z³dödÓe„dÑeVdz  d.eVdz  fdÔ„Z´dÁe„dz  d2e;d.e‰dz  fdÕ„ZµdÖe;d.enfd×„Z¶dØe„dÁe„dz  d2e;dÙend.enf
dÚ„Z·	 dödÛe„dz  dÜe„dz  dƒe„dÝeVdÞe„dz  d.dfdß„Z¸	 dödÛe„dz  dÜe„dz  dƒe„dÝeVdÞe„dz  d.dfdà„Z¹dƒe„dáeVd2e;fdâ„ZºdãeVd.enfdä„Z»dãeVd.eVdz  fdå„Z¼	 dödƒe„dædçdèedée„eVef   dz  d.eše‰eV   e„eVeVf   f   f
dê„Z½	 	 dõdƒe„dÝeVdædçdëe‰eV   dz  dìe„eVef   dz  d.dfdí„Z¾dƒe„dÝeVd2e;d.dfdî„Z¿dï�j�                  ef�j‚                  �j„                  ef�j†                  �j„                  ef�jˆ                  �j„                  f«      ZÅeeHdð<   ef�j‚                  �j„                  ZÆeeHdñ<   dƒe„d‘e„fdò„ZÇdƒe„d�efdó„ZÈy)÷é    N)ÚOrderedDict)ÚMappingÚMutableMapping)ÚMappingProxyType)ÚTYPE_CHECKINGÚAnyÚFinal)ÚHTTPExceptionÚRequest)ÚValidationError)ÚHeaders)Úverbose_loggerÚverbose_proxy_logger)ÚServiceLogging)Ú"CONSUMED_REQUEST_TAGS_METADATA_KEYÚ!INTERNAL_CALL_ORIGIN_METADATA_KEYÚLITELLM_PROXY_MASTER_KEY_ALIASÚOTEL_SERVICE_NAME_METADATA_KEYSÚ PRE_CALL_EXECUTED_GUARDRAILS_KEYÚ,SESSION_DEPLOYMENT_AFFINITY_TTL_METADATA_KEY)ÚCredentialAccessor)ÚTRUSTED_CALLBACK_VARS_FIELDÚ _request_blocked_callback_paramsÚ#iter_client_callback_metadata_dicts)ÚMODEL_ACCESS_GROUP_METADATA_KEY©Úsafe_json_loads)Ú"is_url_destination_allowed_by_hostÚ#provider_url_destination_candidates)	ÚAddTeamCallbackÚCommonProxyErrorsÚLitellmDataForBackendLLMCallÚLitellmUserRolesÚProxyErrorTypesÚProxyExceptionÚSpecialHeadersÚTeamCallbackMetadataÚUserAPIKeyAuth)Údecrypt_callback_varsÚ&get_metadata_variable_name_from_kwargsÚstrip_callback_config)Ú_safe_get_request_headers)Ú#GATEWAY_INJECTED_CACHE_METADATA_KEYc              #   óP   K  — | ]  }|j                   j                  «       –— Œ  y ­w©N)ÚvalueÚlower)Ú.0Úvs     úi/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/litellm_pre_call_utils.pyú	<genexpr>r5   :   s   è ø€ Ò)h¸a¨!¯'©'¯-©-¯/Ñ)hùs   ‚$&Ú_SPECIAL_HEADERS_CACHEz***REDACTED***Ú_REDACTED_HEADER_VALUEÚcookiezproxy-authorizationÚ_CREDENTIAL_HEADER_NAMES>   Úapi_keyÚheadersÚprovider_specific_headerÚ_TRANSPORT_ONLY_CREDENTIAL_KEYSz^x-.+-session-id$Ú_GENERIC_SESSION_ID_HEADER_REúx-litellm-trace-idúx-litellm-session-idÚ_EXPLICIT_SESSION_HEADERS)z
session-idÚ
session_idz	thread-idÚconversation_idÚ_CODEX_SESSION_ID_HEADERSz^codex[-_ /]Ú_CODEX_CLIENT_PREFIX_REz^[a-zA-Z0-9_\-]{8,}$Ú_SESSION_ID_VALUE_REz^[0-9a-f]{64}$Ú_SHA256_HEX_REz5^[0-9a-f]{2}-([0-9a-f]{32})-[0-9a-f]{16}-[0-9a-f]{2}$Ú_TRACEPARENT_REÚtraceparentÚreturnc                 óž   — t         j                  | j                  «       «      }|sy|j                  d«      j	                  «       }|dk7  r|S dS )a!  Extract the trace-id from a W3C Trace Context traceparent header, e.g.
    "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" -> the 32-hex
    trace-id in the middle. An all-zero trace-id is invalid per spec and is
    rejected, matching how the OpenTelemetry SDK itself treats it.Né   Ú 00000000000000000000000000000000)rH   ÚmatchÚstripÚgroupr1   )rI   rN   Útrace_ids      r4   Ú_trace_id_from_traceparentrR   Z   sK   € ô
 #×(Ñ(¨×):Ñ):Ó)<Ó=€EÙØØ—k‘k !“n×*Ñ*Ó,€HØ 8Ò+ˆ8Ð5°Ð5ó    Úbaggagec                 óâ   — | j                  d«      D ][  }|j                  «       j                  d«      \  }}}|j                  «       dk(  sŒ:|j                  «       sŒK|j                  «       c S  y)z€Extract a session.id entry from a W3C Baggage header
    (https://www.w3.org/TR/baggage/), e.g. "session.id=abc-123,user.id=42".ú,ú=z
session.idN)ÚsplitrO   Ú	partition)rT   ÚpairÚkeyÚ_r0   s        r4   Ú_session_id_from_baggager]   f   s_   € ð —‘˜cÓ"ò !ˆØŸ
™
›×.Ñ.¨sÓ3‰ˆˆQ�Ø�9‰9‹;˜,Ó&¨5¯;©;­=Ø—;‘;“=Ò ð!ð rS   Úuser_api_key_dictc                 óz   — | j                   }| j                  r|€y|t        k(  st        j	                  |«      r|S y)a{  Only proxy-validated keys are stamped, proven by the unforgeable
    via_virtual_key marker AND a known non-secret shape: the sha256 hex digest
    UserAPIKeyAuth stores virtual keys in, or the master key's stable alias.
    Custom-auth credentials arrive raw (never forward auth material) and hashed
    JWTs rotate on re-issue (useless as a stable ban id), so both are skipped.N)r:   Úvia_virtual_keyr   rG   Ú	fullmatch)r^   r:   s     r4   Ú_stampable_key_hashrb   p   s=   € ð '×.Ñ.€GØ×,Ò,°°ØØÔ0Ò0´N×4LÑ4LÈWÔ4UØˆØrS   z^[a-zA-Z0-9_\-]+$Ú_ANTHROPIC_SESSION_ID_VALUE_REr0   c                 ó’   — 	 t        | «      }|j                  dd«      j                  dd«      S # t        $ r t        | «      }Y Œ8w xY w)zÔ
    Basic log sanitization helper to reduce log-injection risk.

    Removes newline and carriage-return characters so user-controlled
    values cannot forge additional log lines when written to text logs.
    úÚ ú
)ÚstrÚ	ExceptionÚreprÚreplace)r0   Útexts     r4   Ú_sanitize_for_logrm   �   sJ   € ðÜ�5‹zˆð
 �<‰<˜˜bÓ!×)Ñ)¨$°Ó3Ð3øô	 ò ä�E‹{Šðús   ‚/ ¯AÁA)ÚRouter)Úget_secret_bool)ÚANTHROPIC_API_HEADERS)ÚServiceTypes)ÚCustomPricingLiteLLMParamsÚLlmProvidersÚProviderSpecificHeaderÚ!StandardLoggingUserAPIKeyMetadataÚSupportedCacheControlsÚservice_logger_obji'  Ú_MAX_STALE_ALIAS_WARNING_KEYSÚ_STALE_TEAM_ALIAS_WARNING_KEYSÚ_ENABLE_TEAM_STALE_ALIAS_BYPASS)ÚProxyConfig©ÚPolicyMatchContextc                 ó€   — i }| j                  d«      }|D ]%  }d|v r|j                  d«      \  }}|||<   Œ!d||<   Œ' |S )Nú, rW   T)rX   )Úcache_controlÚ
cache_dictÚ
directivesÚ	directiver[   r0   s         r4   Úparse_cache_controlr„   ¯   s[   € Ø€JØ%×+Ñ+¨DÓ1€Jàò )ˆ	Ø�)ÑØ"Ÿ™¨Ó-‰JˆC�Ø#ˆJ�sŠOà$(ˆJ�yÒ!ð)ð ÐrS   )ÚbatchesÚbedrockz/v1/messagesÚ	responsesÚfilesÚLITELLM_METADATA_ROUTES>	   rQ   Ú
mask_inputrB   Ú
trace_nameÚmask_outputÚtrace_releaseÚtrace_user_idÚtrace_versionÚtrace_metadataÚ%LITELLM_TRACE_CONTROL_METADATA_FIELDSÚproxy_server_requestÚstandard_logging_objectÚsecret_fieldsÚmock_responseÚmock_tool_callsÚdisable_global_guardrailsÚdisable_global_guardrailÚenable_prompt_cachingÚopted_out_global_guardrailsÚapplied_guardrailsÚapplied_policiesÚpolicy_sourcesÚguardrail_scan_idsÚrouting_decisionÚpillar_response_headersÚ_guardrail_pipelinesÚ_pipeline_managed_guardrailsÚ	callbacksÚservice_callbackÚ	logger_fnÚlitellm_disabled_callbacksÚ_agentic_loop_depthÚ_agentic_loop_fingerprintsÚ%_code_interpreter_interception_activeÚ/_code_interpreter_interception_converted_streamÚ*_code_interpreter_interception_sandbox_keyÚ-_code_interpreter_interception_session_scopedÚ'_headroom_interception_converted_streamÚmax_agentic_loopsÚclient_side_timeoutÚ_UNTRUSTED_ROOT_CONTROL_FIELDSÚ _pillar_response_headers_trustedÚpillar_flaggedÚpillar_scannersÚpillar_evidenceÚpillar_evidence_truncatedÚpillar_session_id_responseÚclient_disconnectedÚerror_informationÚ"_UNTRUSTED_METADATA_CONTROL_FIELDSz!litellm-disable-message-redactionÚ'UNTRUSTED_REQUEST_HEADER_CONTROL_FIELDSÚ_CLIENT_MOCK_CONTROL_FIELDSÚallow_client_mock_responseÚ(_ALLOW_CLIENT_MOCK_RESPONSE_METADATA_KEYÚ&allow_client_message_redaction_opt_outÚ4_ALLOW_CLIENT_MESSAGE_REDACTION_OPT_OUT_METADATA_KEYÚ_CLIENT_PRICING_CONTROL_FIELDSÚ
model_infoÚ&standard_logging_guardrail_informationÚ_CLIENT_PRICING_METADATA_FIELDSÚattempted_fallbacksÚoriginal_model_groupÚ _ROUTER_RESERVED_METADATA_FIELDSÚallow_client_pricing_overrideÚ+_ALLOW_CLIENT_PRICING_OVERRIDE_METADATA_KEY)ÚmodelÚfile_idÚ_URL_DESTINATION_REQUEST_FIELDSÚdatac                 óv   — t         D ]0  }| j                  |«      }t        |t        «      sŒ%t	        ||«       Œ2 y)uJ  Reject URL-valued ``model``/``file_id`` unless admin-allowlisted.

    Some providers (HuggingFace, Oobabooga, Gemini files) accept a URL in the
    identifier field and use it as the outbound destination. On the proxy that
    is an SSRF primitive â€” a low-privilege caller can point traffic at any
    host the proxy can reach, including internal services. Reject here at the
    proxy boundary so SDK users (who legitimately pass URL-valued identifiers)
    are unaffected, while admins can opt specific hosts back in via
    ``litellm.provider_url_destination_allowed_hosts``.
    N)rË   ÚgetÚ
isinstancerh   Úreject_url_valued_destination)rÌ   Úfieldr0   s      r4   Ú_reject_url_valued_destinationsrÒ   K  s4   € ô 1ò 8ˆØ—‘˜“ˆÜ�eœSÕ!Ü)¨%°Õ7ñ8rS   rÑ   c           	      óÐ   — t        t        dg «      xs g }t        |«      D ]C  }|j                  «       j	                  d«      sŒ#t        ||«      rŒ0t        dd| d| › d�dœ¬«      ‚ y	)
zâReject a URL-valued destination identifier unless admin-allowlisted.

    Operates on one field/value pair. ``_reject_url_valued_destinations`` applies
    it across ``_URL_DESTINATION_REQUEST_FIELDS`` for a request body.
    Ú&provider_url_destination_allowed_hosts)zhttp://zhttps://é�  Úinvalid_requestzURL-valued 'z ' is not allowed. Configure custom endpoints with api_base instead, or add the destination host to `provider_url_destination_allowed_hosts` in litellm_settings.)ÚerrorÚparamÚmessage)Ústatus_codeÚdetailN)ÚgetattrÚlitellmr   r1   Ú
startswithr   r
   )rÑ   r0   Úallowed_hostsÚ	candidates       r4   rÐ   rÐ   \  s€   € ô #¤7Ð,TÐVXÓYÒ_Ð]_€MÜ8¸Ó?ò 
ˆ	Ø�‰Ó ×+Ñ+Ð,CÔDØÜ-¨i¸ÔGØÜØà*Øà" 5 'ð *(ð (ñ		ô
ð 	
ñ
rS   z	a booleanz
an integerza numberza stringzan arrayÚ_METADATA_JSON_TYPE_NAMESc                 ó´   — t         j                  t        |«      dt        |«      j                  › �«      }t	        d| › d|› d�t
        j                  | d¬«      S )Nza zInvalid type for 'z': expected an object, but got z	 instead.rÕ   )rÙ   ÚtyperØ   Úcode)rá   rÎ   rã   Ú__name__r%   r$   Úbad_request_error)rÑ   r0   Úreceived_types      r4   Ú_invalid_metadata_type_errorrè   |  s[   € Ü4×8Ñ8¼¸e»ÈÌ4ÐPUË;×K_ÑK_ÐJ`ÐFaÓb€MÜØ$ U GÐ+JÈ=È/ÐYbÐcÜ×.Ñ.ØØô	ð rS   c                 óš   — t        |t        «      r|S t        |t        «      rt        t        |«      x}t        «      r|S t	        | |¬«      ‚)a›  Return ``value`` as a metadata object or raise a 400 like OpenAI does.

    A JSON string that parses to an object is accepted because multipart/form-data
    and ``extra_body`` callers can only send metadata as a string. The caller pops
    the raw value from the request body before validating so the failure-logging
    hooks that inspect the body afterwards don't crash on it and mask the 400 as a 500.
    )rÑ   r0   )rÏ   Údictrh   r   rè   )rÑ   r0   Úparseds      r4   Ú_normalized_metadata_objectrì   †  sC   € ô �%œÔØˆÜ�%œÔ¤*¼ÈÓ8NÐ.N¨fÔQUÔ"VØˆÜ
&¨U¸%Ô
@Ð@rS   F©r¾   r;   c                óÜ   — t        | t        «      sy t        | j                  «       «      D ]?  }t        |t        «      sŒ|j                  «       t        v sŒ+|rŒ.| j                  |d «       ŒA y r/   )rÏ   rê   ÚlistÚkeysrh   r1   rº   Úpop)r;   r¾   Úheader_names      r4   Ú(_strip_untrusted_request_header_controlsró   •  sZ   € ô
 �gœtÔ$Øä˜GŸL™L›NÓ+ò +ˆÜ�k¤3Õ'¨K×,=Ñ,=Ó,?ÔCjÒ,jÙ5ØØ�K‰K˜ TÕ*ñ	+rS   c                 óŒ   — t        | t        «      r| du S t        | t        «      r | j                  «       j	                  «       dv S y)NF>   Ú0ÚnoÚoffÚfalse)rÏ   Úboolrh   rO   r1   )r0   s    r4   Ú_is_false_likerú   ¤  s>   € Ü�%œÔØ˜ˆ~ÐÜ�%œÔØ�{‰{‹}×"Ñ"Ó$Ð(CÐCÐCØrS   Úmetadata_keyc                 óŠ   — | j                   | j                  fD ](  }t        |t        «      sŒ|j	                  |«      du sŒ( y y)NTF)ÚmetadataÚteam_metadatarÏ   rê   rÎ   )r^   rû   Úadmin_metadatas      r4   Ú"_key_or_team_metadata_flag_is_truer   ¬  sJ   € ð -×5Ñ5Ð7H×7VÑ7VÐWò ˆÜ�n¤dÕ+°×0BÑ0BÀ<Ó0PÐTXÒ0XÙðð rS   c                 ó$   — t        | t        ¬«      S ©N)r^   rû   )r   r½   ©r^   s    r4   Ú(_key_or_team_allows_client_mock_responser  ¶  s   € ô .Ø+Ü=ôð rS   c                 ó$   — t        | t        ¬«      S r  )r   r¿   r  s    r4   Ú4_key_or_team_allows_client_message_redaction_opt_outr  ¿  s   € ô .Ø+ÜIôð rS   c                 ó$   — t        | t        ¬«      S r  )r   rÈ   r  s    r4   Ú+_key_or_team_allows_client_pricing_overrider  È  s   € ô .Ø+Ü@ôð rS   c                 ó\  — g }d| v r1t        | d   «      r#|j                  d«       | j                  dd «       t        | «      D ]?  \  }}d|v sŒt        |d   «      sŒ|j                  |› d�«       |j                  dd «       ŒA |r&t	        j
                  ddj                  |«      «       y y )NÚturn_off_message_loggingz.turn_off_message_loggingzµStripped client-supplied message-redaction opt-out fields from request body: %s. Set `allow_client_message_redaction_opt_out: true` on the key or team metadata to keep these values.r   )rú   Úappendrñ   r   r   ÚdebugÚjoin)rÌ   ÚstrippedÚ
slot_labelrý   s       r4   Ú'_strip_client_message_redaction_opt_outr  Ñ  s´   € Ø!#€HØ! TÑ)¬n¸TÐB\Ñ=]Ô.^Ø�‰Ð2Ô3Ø�‰Ð+¨TÔ2Ü CÀDÓ Iò ;Ñˆ
�HØ%¨Ò1´nÀXÐNhÑEiÕ6jØ�O‰O˜z˜lÐ*CÐDÔEØ�L‰LÐ3°TÕ:ð;ñ Ü×"Ñ"ð$ð �I‰I�hÓõ		
ð rS   c                 ó&  — d| fgt        | «      ¢­}t        d„ |D «       «      }|D ]"  \  }}t        D ]  }|j                  |d«       Œ Œ$ | j                  t        d«       |r/t        j                  ddj                  t        |«      «      «       yy)a†  Drop callback credentials and destinations supplied by the caller.

    ``_request_blocked_callback_params`` (Datadog + GCS credentials, sites and agent
    hosts) are already ignored when building ``standard_callback_dynamic_params``.
    Strip them from the body and every client metadata slot as well, so a caller
    cannot pair its own ``dd_site``/``dd_agent_host`` with the team's admin-configured
    ``dd_api_key`` and have the resulting logs shipped to a host it controls.

    ``TRUSTED_CALLBACK_VARS_FIELD`` is proxy-owned; it is cleared here and repopulated
    from team/key callback settings in ``add_litellm_data_to_request``.
    Úbodyc              3   óN   K  — | ]  \  }}t         D ]  }||v r	|› d |› �–— Œ Œ y­w)ú.N)r   )r2   ÚlabelÚ	containerrÑ   s       r4   r5   z5_strip_client_callback_credentials.<locals>.<genexpr>ò  sD   è ø€ ò áˆE�9Ü5òð Ø�IÑð ˆ'��5�'ÔðØñùs   ‚#%Nz}Stripped client-supplied callback credentials from request: %s. Configure these on the team or key callback settings instead.r   )	r   Útupler   rñ   r   r   r  r  Úsorted)rÌ   Ú
containersr  r\   r  rÑ   s         r4   Ú"_strip_client_callback_credentialsr  ã  s¢   € ð ! $˜ÐTÔ*MÈdÓ*SÑT€JÜñ à *ôó €Hð #ò '‰ˆˆ9Ü5ò 	'ˆEØ�M‰M˜% Õ&ñ	'ð'ð 	‡H�HÔ(¨$Ô/ÙÜ×"Ñ"ðLà�I‰I”f˜XÓ&Ó'õ	
ð rS   c                 ó€  — g }t         D ]*  }|| v sŒ|j                  |«       | j                  |d«       Œ, dD ]\  }| j                  |«      }t	        |t
        «      sŒ%t        D ]/  }||v sŒ|j                  |› d|› �«       |j                  |d«       Œ1 Œ^ |r&t        j                  ddj                  |«      «       yy)a™  Drop pricing overrides from the request body and any metadata variant.

    Skipped only when the calling key/team carries
    ``allow_client_pricing_override: True`` in its metadata. Emits a
    ``debug``-level log line naming the dropped fields so operators can
    trace why a client-supplied pricing override stopped being applied
    (otherwise the strip is invisible from the caller's perspective).
    N©rý   Úlitellm_metadatar  zšStripped client-supplied pricing fields from request body: %s. Set `allow_client_pricing_override: true` on the key or team metadata to keep these values.r   )
rÀ   r  rñ   rÎ   rÏ   rê   rÃ   r   r  r  )rÌ   r  rÑ   rû   rý   s        r4   Ú_strip_client_pricing_overridesr    sÌ   € ð "$€HÜ/ò "ˆØ�DŠ=Ø�O‰O˜EÔ"Ø�H‰H�U˜DÕ!ð"ð 9ò *ˆØ—8‘8˜LÓ)ˆÜ˜(¤DÔ)ØÜ4ò 	*ˆEØ˜Ò Ø—‘ < .°°%°Ð 9Ô:Ø—‘˜U DÕ)ñ	*ð	*ñ Ü×"Ñ"ð-ð �I‰I�hÓõ		
ð rS   c                 óÞ   — dD ]h  }t        | j                  |«      x}t        «      sŒ%t        |j	                  «       z  D ]*  }|j                  |«       t        j                  d||«       Œ, Œj y)zODrop the router-owned fallback stamps from any client-supplied metadata bucket.r  z@Stripped router-reserved metadata field from request body: %s.%sN)rÏ   rÎ   rê   rÆ   rð   rñ   r   r  )rÌ   rû   rý   rÑ   s       r4   Ú_strip_router_reserved_metadatar   #  sk   € ð 9ò ˆÜ d§h¡h¨|Ó&<Ð<˜(¼dÔCØÜ5¸¿¹»ÑGò 	ˆEØ�L‰L˜ÔÜ ×&Ñ&ØRÐT`Ðbgõñ	ñrS   Úrequestc                 óf   ‡— ddl m}  || «      Šd‰v sd‰v ryt        ˆfd„t        D «       «      ryy)zã
    Helper to return what the "metadata" field should be called in the request data

    For all /thread or /assistant endpoints we need to call this "litellm_metadata"

    For ALL other endpoints we call this "metadata"
    r   )Úget_request_routeÚthreadÚ	assistantr  c              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wr/   © )r2   ÚrouteÚpaths     €r4   r5   z._get_metadata_variable_name.<locals>.<genexpr>@  s   øè ø€ Ò
>˜Uˆ5�DŒ=Ñ
>ùó   ƒrý   )Úlitellm.proxy.auth.auth_utilsr#  Úanyr‰   )r!  r#  r)  s     @r4   Ú_get_metadata_variable_namer-  1  s:   ø€ õ @á# GÓ,€DØ�4Ñ˜;¨$Ñ.Ø!ä
Ó
>Ô&=Ô
>Ô>Ø!àrS   Úrequester_metadatar  .c                 óH   ‡— t        ˆfd„| j                  «       D «       «      S )zXReturn the caller's trace-control fields that ``litellm_metadata`` does not already set.c              3   óD   •K  — | ]  \  }}|t         v r
|‰vr||f–— Œ y ­wr/   )r‘   )r2   r[   r0   r  s      €r4   r5   z1_promoted_trace_control_fields.<locals>.<genexpr>K  s2   øè ø€ ò áˆC�ØÔ7Ñ7¸CÐGWÑ<Wð 
ˆeŒñùs   ƒ )r  Úitems©r.  r  s    `r4   Ú_promoted_trace_control_fieldsr3  F  s(   ø€ ô
 ó à,×2Ñ2Ó4ôó ð rS   Ú
normalizedc                 óÆ   — | j                  «       D ]N  \  }}|t        vsŒt        j                  |«      sŒ%t	        |t
        «      sŒ6t        j                  |«      sŒL|c S  y)aí  
    Scan a normalised (lower-cased keys) header dict for any header that looks
    like ``x-<vendor>-session-id`` and whose value is a plausible session/trace
    identifier (alphanumeric + hyphens/underscores, at least 8 chars).

    The two explicit LiteLLM headers (``x-litellm-trace-id`` /
    ``x-litellm-session-id``) are excluded here because they are handled with
    higher priority by the caller.

    Example: ``x-claude-code-session-id: e96634a3-fa28-4083-b354-55542e2dca01``
    N)r1  rA   r>   rN   rÏ   rh   rF   )r4  r[   r0   s      r4   Ú(_extract_generic_session_id_from_headersr6  R  sY   € ð !×&Ñ&Ó(ò ‰
ˆˆUàÔ0Ò0Ü-×3Ñ3°CÕ8Ü˜5¤#Õ&Ü$×*Ñ*¨5Õ1àŠLðð rS   c                 óž   ‡ — ‰ j                  d«      }t        |t        «      rt        |«      syt	        d„ ˆ fd„t
        D «       D «       d«      S )ag  
    Read Codex's conversation uuid off one of ``_CODEX_SESSION_ID_HEADERS``.

    Codex sends no request metadata the Anthropic path could parse and no
    ``x-``-prefixed session header, so without this every turn of a Codex session
    falls through to a freshly generated per-call trace id and lands as its own
    row in the logs instead of grouping.

    Unprefixed names like ``session-id`` are generic enough that another client
    could send one meaning something unrelated, and colliding values across
    callers would merge their traces, so this only applies to callers that
    identify as Codex.
    ú
user-agentNc              3   ój   K  — | ]+  }t        |t        «      rt        j                  |«      r|–— Œ- y ­wr/   )rÏ   rh   rF   rN   )r2   r0   s     r4   r5   z9_extract_codex_session_id_from_headers.<locals>.<genexpr>  s0   è ø€ ò 	
àÜ˜%¤Ô%Ô*>×*DÑ*DÀUÔ*Kô ñ	
ùs   ‚13c              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wr/   )rÎ   )r2   Úheaderr4  s     €r4   r5   z9_extract_codex_session_id_from_headers.<locals>.<genexpr>�  s   øè ø€ ÒY°V˜*Ÿ.™.¨×0ÑYùs   ƒ)rÎ   rÏ   rh   Úis_codex_user_agentÚnextrD   )r4  Ú
user_agents   ` r4   Ú&_extract_codex_session_id_from_headersr?  k  sM   ø€ ð  #Ÿ™ |Ó4€JÜ�j¤#Ô&Ô.AÀ*Ô.MØÜñ	
ãYÔ?XÔYô	
ð
 	óð rS   c                 ó  — | sy| j                  «       D ��ci c]'  \  }}t        |t        «      sŒ|j                  «       |“Œ) }}}|j	                  d«      xs+ |j	                  d«      xs t        |«      xs t        |«      S c c}}w )a¾  
    Extract chain id for call chaining from request headers.

    Priority order:
    1. ``x-litellm-trace-id`` (explicit, highest priority)
    2. ``x-litellm-session-id`` (explicit)
    3. Any ``x-<vendor>-session-id`` header whose value looks like a session id
       (alphanumeric / UUID, at least 8 chars).  E.g. ``x-claude-code-session-id``.
    4. Codex's unprefixed ``session-id`` / ``thread-id``, for Codex callers only.

    Header keys are matched case-insensitively so this works with raw header
    dicts from any transport.

    Used by MCP (and other paths that have raw_headers but no Request) to set
    litellm_trace_id/litellm_session_id for spend logs and logging consistency.
    Nr?   r@   )r1  rÏ   rh   r1   rÎ   r6  r?  )r;   Úkr3   r4  s       r4   Úget_chain_id_from_headersrB  ˆ  s‚   € ñ" ØØ29·-±-³/×X©$¨!¨QÄZÐPQÔSVÕEW˜Ÿ™› A™ÐX€JÑXà�‰Ð+Ó,ò 	>Ø�>‰>Ð0Ó1ò	>ä3°JÓ?ò	>ô 2°*Ó=ð	ùó Ys
   —B°Brý   c                 ó‚  — t        | t        «      sy | j                  d«      }t        |t        «      r9|j                  d«      }t        |t        «      rt        j                  |«      r|S y t        |t        «      sy d}|j                  |«      }|dk(  ry ||t        |«      z   d  }|rt        j                  |«      sy |S )NÚuser_idrB   Ú	_session_éÿÿÿÿ)rÏ   rê   rÎ   rh   rc   ra   ÚrfindÚlen)rý   rD  rB   Úsession_markerÚsession_marker_indexs        r4   Ú'_get_anthropic_session_id_from_metadatarK  ¤  sµ   € Ü�h¤Ô%Øà—\‘\ )Ó,€GÜ�'œ4Ô Ø—[‘[ Ó.ˆ
Ü�j¤#Ô&Ô+I×+SÑ+SÐT^Ô+_ØÐØÜ�gœsÔ#Øà'€NØ")§-¡-°Ó"?ÐØ˜rÒ!ØàÐ-´°NÓ0CÑCÐEÐF€JÙÔ;×EÑEÀjÔQØØÐrS   r>  c                 ó$   — | j                  d«      S )z—Claude Code identifies itself as ``claude-cli/<version> ...``; the IDE
    extensions and the Agent SDK run through the same CLI and share that prefix.zclaude-cli/)rÞ   ©r>  s    r4   Úis_claude_code_user_agentrN  ¼  s   € ð × Ñ  Ó/Ð/rS   c                 ó>   — t        t        j                  | «      «      S )aÄ  Codex builds its user agent as ``<originator>/<version> ...`` and ships
    several first-party originators: ``codex-tui``, ``codex_cli_rs``,
    ``codex_exec`` (exec mode), ``codex_vscode`` (IDE extension) and ``Codex ...``
    (see ``is_first_party_originator`` in codex-rs). They agree only on the
    ``codex`` stem, and the TUI sends a bare ``codex-tui`` with no version at all,
    so match the stem plus a separator rather than any one spelling.)rù   rE   rN   rM  s    r4   r<  r<  Â  s   € ô Ô'×-Ñ-¨jÓ9Ó:Ð:rS   Úproxy_configc                 óÈ   — t        | «      st        | «      syd|v ryt        |dd«      }t        |t        «      r|j                  d«      nd}t        |t        «      xr d|v  S )a:  drop_params defaults to on for agentic CLIs so their client-specific
    params (e.g. Claude Code's thinking, Codex's service_tier) don't fail
    requests routed to providers that reject them. An explicit drop_params
    from the caller or in the operator's ``litellm_settings`` always wins
    over this default.FÚdrop_paramsÚconfigNÚlitellm_settings)rN  r<  rÜ   rÏ   rê   rÎ   )r>  rÌ   rP  rS  rT  s        r4   Ú'should_auto_drop_params_for_agentic_clirU  Ì  si   € ô & jÔ1Ô5HÈÔ5TØØ˜ÑØÜ˜L¨(°DÓ9€FÜ@JÈ6ÔSWÔ@X˜fŸj™jÐ);Ô<Ð^bÐÜÐ+¬TÓ2ÒX°}ÐHXÐ7XÐYÐYrS   c                 óâ   — 	 t        |d«      r#t        |j                  «      }d|v r	|d   | d<   y y y # t        $ r Y y t        $ r)}t        j                  dt        |«      «       Y d }~y d }~ww xY w)NÚquery_paramsúapi-versionÚapi_versionz.error checking api version in query params: %s)Úhasattrrê   rW  ÚKeyErrorri   r   Ú	exceptionrh   )rÌ   r!  rW  Úes       r4   Ú&safe_add_api_version_from_query_paramsr^  Û  s}   € ð[Ü�7˜NÔ+Ü"& w×';Ñ';Ó"<ˆLØ Ñ,Ø&2°=Ñ&A��]Ò#ð -ð ,øô ò ÙÜò [Ü× Ñ Ð!QÔSVÐWXÓSY×ZÑZûð[ús   ‚-2 ²	A.½A.ÁA)Á)A.Úteam_callback_settings_objc                 ó˜  — |€
t        «       }| j                  dk(  rS|j                  €g |_        | j                  |j                  v�r”|j                  j	                  | j                  «       �nm| j                  dk(  rS|j
                  €g |_        | j                  |j
                  v�r2|j
                  j	                  | j                  «       �n| j                  r| j                  dk(  rð|j                  €g |_        |j
                  €g |_        |j                  €g |_        | j                  |j                  vr%|j                  j	                  | j                  «       | j                  |j
                  vr%|j
                  j	                  | j                  «       | j                  |j                  vr%|j                  j	                  | j                  «       | j                  j                  «       D ]Q  \  }}|j                  d«      r| j                  dk7  rŒ'|j                  €i |_        t        |«      |j                  |<   ŒS |S )NÚsuccessÚfailureÚsuccess_and_failureÚ	newrelic_Únewrelic)r'   Úcallback_typeÚsuccess_callbackÚcallback_namer  Úfailure_callbackr£   Úcallback_varsr1  rÞ   rh   )rÌ   r_  Úvarr0   s       r4   Ú(convert_key_logging_metadata_to_callbackrl  ç  s  € ð "Ð)Ü%9Ó%;Ð"Ø×Ñ˜YÒ&Ø%×6Ñ6Ð>Ø:<Ð&Ô7à×ÑÐ%?×%PÑ%PÒPØ&×7Ñ7×>Ñ>¸t×?QÑ?QÖRØ	×	Ñ	˜yÒ	(Ø%×6Ñ6Ð>Ø:<Ð&Ô7à×ÑÐ%?×%PÑ%PÒPØ&×7Ñ7×>Ñ>¸t×?QÑ?QÖRà×Ò $×"4Ñ"4Ð8MÒ"Mà%×6Ñ6Ð>Ø:<Ð&Ô7Ø%×6Ñ6Ð>Ø:<Ð&Ô7Ø%×/Ñ/Ð7Ø35Ð&Ô0à×ÑÐ%?×%PÑ%PÑPØ&×7Ñ7×>Ñ>¸t×?QÑ?QÔRà×ÑÐ%?×%PÑ%PÑPØ&×7Ñ7×>Ñ>¸t×?QÑ?QÔRà×ÑÐ%?×%IÑ%IÑIØ&×0Ñ0×7Ñ7¸×8JÑ8JÔKà×(Ñ(×.Ñ.Ó0ò 	C‰
ˆˆUð
 �>‰>˜+Ô&¨4×+=Ñ+=ÀÒ+KØØ%×3Ñ3Ð;Ø79Ð&Ô4Ü8;¸E»
Ð"×0Ñ0°Ò5ð	Cð &Ð%rS   ÚitemÚsourcec          
      ó¤   — 	 t        di | ¤ŽS # t        t        f$ r3}t        j                  d|t        t        |«      «      «       Y d }~y d }~ww xY w)Nz)Ignoring invalid %s callback metadata: %sr'  )r    ÚPydanticValidationErrorÚ
ValueErrorr   Úwarningrm   rh   )rm  rn  r]  s      r4   Ú _get_validated_callback_metadatars    sO   € ðÜÑ& Ñ&Ð&øÜ#¤ZÐ0ò Ü×$Ñ$Ø7ØÜœc !›fÓ%ô	
ô
 ûðús   ‚
 �Aœ)A
Á
Ac                   ó<   — e Zd ZdZedefd„«       Zedefd„«       Zy)ÚKeyAndTeamLoggingSettingszO
    Helper class to get the dynamic logging settings for the key and team
    r^   c                 ó€   — | j                   �2d| j                   v r$t        | j                   «      j                  d«      S y ©NÚlogging)rý   r)   rÎ   r  s    r4   Ú get_key_dynamic_logging_settingsz:KeyAndTeamLoggingSettings.get_key_dynamic_logging_settings+  s<   € à×%Ñ%Ð1°iÐCT×C]ÑC]Ñ6]Ü(Ð):×)CÑ)CÓD×HÑHÈÓSÐSØrS   c                 ó€   — | j                   �2d| j                   v r$t        | j                   «      j                  d«      S y rw  )rþ   r)   rÎ   r  s    r4   Ú!get_team_dynamic_logging_settingsz;KeyAndTeamLoggingSettings.get_team_dynamic_logging_settings1  s<   € à×*Ñ*Ð6¸9ÐHY×HgÑHgÑ;gÜ(Ð):×)HÑ)HÓI×MÑMÈiÓXÐXØrS   N)rå   Ú
__module__Ú__qualname__Ú__doc__Ústaticmethodr(   ry  r{  r'  rS   r4   ru  ru  &  s=   „ ñð ð¸Nò ó ðð
 ð¸^ò ó ñrS   ru  c                 ó*  — d }t         j                  | «      }t         j                  | «      }|�&|D ]  }t        |d¬«      }|€Œt	        ||¬«      }Œ! |S |�&|D ]  }t        |d¬«      }|€Œt	        ||¬«      }Œ! |S | j
                  �]d| j
                  v rO	 t        | j
                  «      }|j                  dd «      xs i }t        di |¤Ž}t        j                  d|«       |S | j                  �!t        j                  | j                  |¬«      }|S )	Nz	key-level)rm  rn  )rÌ   r_  z
team-levelÚcallback_settingsz$Team callback settings activated: %s)Úteam_idrP  r'  )ru  ry  r{  rs  rl  rþ   r)   rÎ   r'   r   r  r‚  ÚLiteLLMProxyRequestSetupÚ$add_team_based_callbacks_from_config)	r^   rP  Úcallback_settings_objÚkey_dynamic_logging_settingsÚteam_dynamic_logging_settingsrm  Úcallbackrþ   r�  s	            r4   Ú_get_dynamic_logging_metadatar‰  8  sr  € ð :>ÐÜ7P×7qÑ7qØó8Ð ô 9R×8sÑ8sØó9Ð!ð $Ð/Ø0ò 	ˆDÜ7¸TÈ+ÔVˆHØÐØÜ$LØØ+@ô%Ñ!ð		ðX !Ð ðC 
'Ð	2Ø1ò 	ˆDÜ7¸TÈ,ÔWˆHØÐØÜ$LØØ+@ô%Ñ!ð		ð@ !Ð ð+ 
×	(Ñ	(Ð	4Ð9LÐPa×PoÑPoÑ9oð	ô  5Ð5F×5TÑ5TÓUˆØ#0×#4Ñ#4Ð5HÈ$Ó#OÒ#UÐSUÐÜ 4Ñ IÐ7HÑ IÐÜ×"Ñ"Ð#IÐK`Ôað !Ð ð	 
×	"Ñ	"Ð	.Ü 8× ]Ñ ]Ø%×-Ñ-¸Lð !^ó !
Ðð !Ð rS   Úlitellm_key_header_nameÚ!forward_llm_provider_auth_headersÚauthenticated_with_headerc                 óš  — ddl m} i }|�|j                  «       nd}| j                  «       D ]›  \  }}|j                  «       }	|	dk(  r# ||«      r|�|j                  «       dk7  r|||<   Œ>|	dk(  r|sŒF|�|j                  «       dk7  sŒ\|||<   Œb|r"|	t        v r|r|	|k(  rŒt|	dk(  rŒz|	dk(  rŒ€|||<   Œ†|	t        vsŒ�|�|	|k7  sŒ—|||<   Œ� |S )a»  
    Removes litellm api key from headers

    Args:
        headers: Request headers
        litellm_key_header_name: Custom header name for LiteLLM API key
        forward_llm_provider_auth_headers: Whether to forward provider auth headers
        authenticated_with_header: Which header was used for LiteLLM authentication
            (e.g., "x-litellm-api-key", "authorization", "x-api-key")

    Returns:
        Cleaned headers dict
    r   ©Úis_anthropic_oauth_keyNÚauthorizationú	x-api-keyúx-litellm-api-key)Ú#litellm.llms.anthropic.common_utilsr�  r1   r1  r6   )
r;   rŠ  r‹  rŒ  r�  Úclean_headersÚlitellm_key_lowerr;  r0   Úheader_lowers
             r4   r”  r”  u  s  € õ& Kà€MØBYÐBeÐ6×<Ñ<Ô>ÐkoÐØ Ÿ™›ò *‰ˆ�Ø—|‘|“~ˆà˜?Ò*Ñ/EÀeÔ/LØ(Ð0Ð4M×4SÑ4SÓ4UÐYhÒ4hØ(-�˜fÑ%Øà˜[Ò(Ú0Ø)Ð1Ð5N×5TÑ5TÓ5VÐZeÓ5eà(-�˜fÒ%Ù.°<ÔCYÑ3YÙ  \Ð5FÒ%FØØ˜Ò.ØàÐ2Ò2ØØ$)ˆM˜&Ò!àÔ!7Ò7ØÐ%¨Ð9JÓ)Jà$)ˆM˜&Ò!ð5*ð6 ÐrS   r;  c                 ó.   — | j                  «       t        v S )zIWhether `header` carries a caller credential rather than request context.)r1   r9   )r;  s    r4   Ú_is_credential_headerr˜  ª  s   € à�<‰<‹>Ô5Ð5Ð5rS   c                 óx   — | j                  «       D ��ci c]  \  }}|t        |«      rt        n|“Œ c}}S c c}}w )aª  Return a copy of `headers` with credential-bearing values masked.

    `clean_headers` deliberately preserves some credential headers so they can be
    forwarded to the upstream provider; an Anthropic subscription OAuth token in
    `Authorization`, or a client-supplied provider key in `x-api-key`. Those values
    must never reach a logging callback or a spend log, so every observability-facing
    copy of the header dict is built through this helper while the copy that is
    forwarded upstream keeps the real values.

    The returned object is a plain dict; guardrail hooks stamp their own headers onto
    the stored copy and the logging callbacks JSON-serialize it.
    )r1  r˜  r7   )r;   r;  r0   s      r4   Úredact_credential_headersrš  ¯  s>   € ð %Ÿ]™]›_÷áˆF�Eð 	Ô+@ÀÔ+HÕ'ÈeÑSóð ùó s   ”6c                   óœ  — e Zd Zedededz  fd„«       Zedededz  fd„«       Zedee	e	f   dedz  fd„«       Z
edededz  fd„«       Zedededz  fd„«       Zedeez  fd	„«       Zeded
e	de	dz  fd„«       Zededz  dededefd„«       Zed-dededz  de	dz  fd„«       Zed-dededz  de	dz  fd„«       Zedededefd„«       Zededededefd„«       Zede	dz  fd„«       Zeddœdedee	ef   dedee	ef   dz  def
d„«       Zededede	defd„«       Zededefd„«       Zededede	defd„«       Zededede	defd„«       Zededz  dede	fd„«       Z ed e!dz  d!e!dz  de!fd"„«       Z"ed#e	d$e#de$dz  fd%„«       Z%ed&e&dz  dedede!e	   dz  fd'„«       Z'eded(e	ddfd)„«       Z(edededdfd*„«       Z)ed+e*dededdfd,„«       Z+y).rƒ  r;   rJ   Nc                 óB   — | j                  dd«      }|�t        |«      S y)a®  
        Workaround for client request from Vercel's AI SDK.

        Allow's user to set a timeout in the request headers.

        Example:

        ```js
        const openaiProvider = createOpenAI({
            baseURL: liteLLM.baseURL,
            apiKey: liteLLM.apiKey,
            compatibility: "compatible",
            headers: {
                "x-litellm-timeout": "90"
            },
        });
        ```
        zx-litellm-timeoutN©rÎ   Úfloat)r;   Útimeout_headers     r4   Ú_get_timeout_from_requestz2LiteLLMProxyRequestSetup._get_timeout_from_requestÃ  s)   € ð( !(§¡Ð,?ÀÓ FˆØÐ%Ü˜Ó(Ð(ØrS   c                 óB   — | j                  dd«      }|�t        |«      S y)zD
        Get the `stream_timeout` from the request headers.
        zx-litellm-stream-timeoutNr�  )r;   Ústream_timeout_headers     r4   Ú _get_stream_timeout_from_requestz9LiteLLMProxyRequestSetup._get_stream_timeout_from_requestÜ  s+   € ð
 (/§{¡{Ð3MÈtÓ'TÐØ Ð,ÜÐ.Ó/Ð/ØrS   c                 óB   — | j                  dd«      }|�t        |«      S y)aE  
        Get `keepalive_seconds` from the request headers, for clients (e.g. the
        Vercel AI SDK) that can set custom headers more easily than extra body
        fields. Subject to the same deployment-level allow_client_keepalive_override
        gate as the request body field: see _resolve_keepalive_seconds.
        zx-litellm-keepalive-secondsNr�  )r;   Úkeepalive_seconds_headers     r4   Ú#_get_keepalive_seconds_from_requestz<LiteLLMProxyRequestSetup._get_keepalive_seconds_from_requestæ  s,   € ð +2¯+©+Ð6SÐUYÓ*ZÐ Ø#Ð/ÜÐ1Ó2Ð2ØrS   c                 óB   — | j                  dd«      }|�t        |«      S y)zE
        Workaround for client request from Vercel's AI SDK.
        zx-litellm-num-retriesN)rÎ   Úint)r;   Únum_retries_headers     r4   Ú_get_num_retries_from_requestz6LiteLLMProxyRequestSetup._get_num_retries_from_requestó  s+   € ð
 %,§K¡KÐ0GÈÓ$NÐØÐ)ÜÐ)Ó*Ð*ØrS   c                 óH   — ddl m} | j                  dd«      }|� ||«      S y)zI
        Get the `spend_logs_metadata` from the request headers.
        r   r   zx-litellm-spend-logs-metadataN)Ú*litellm.litellm_core_utils.safe_json_loadsr   rÎ   )r;   r   Úspend_logs_metadata_headers      r4   Ú-_get_spend_logs_metadata_from_request_headerszFLiteLLMProxyRequestSetup._get_spend_logs_metadata_from_request_headersý  s0   € õ
 	Oà,3¯K©KÐ8WÐY]Ó,^Ð"Ø%Ð1Ù"Ð#=Ó>Ð>ØrS   c                 ó   — i }| j                  «       D ]h  \  }}|j                  «       j                  d«      r|j                  «       j                  d«      r |j                  «       j                  d«      sŒd|||<   Œj |S )zØ
        Get the headers that should be forwarded to the LLM Provider.

        Looks for any `x-` headers and sends them to the LLM Provider.

        [07/09/2025] - Support 'anthropic-beta' header as well.
        zx-zx-stainlesszanthropic-beta)r1  r1   rÞ   )r;   Úforwarded_headersr;  r0   s       r4   Ú_get_forwardable_headersz1LiteLLMProxyRequestSetup._get_forwardable_headers	  ss   € ð $&ÐØ$Ÿ]™]›_ò 	2‰MˆF�Eà—‘“×)Ñ)¨$Ô/ØŸ™›×1Ñ1°-Ô@Ø—<‘<“>×,Ñ,Ð-=Õ>à,1Ð! &Ò)ð	2ð !Ð rS   r[   c                 ó~   — | j                  «       D ]*  \  }}|j                  «       |j                  «       k(  sŒ(|c S  y)zL
        Get a case-insensitive header from the headers dictionary.
        N)r1  r1   )r;   r[   r;  r0   s       r4   Ú_get_case_insensitive_headerz5LiteLLMProxyRequestSetup._get_case_insensitive_header  s;   € ð
 %Ÿ]™]›_ò 	‰MˆF�EØ�|‰|‹~ §¡£Ó,Ø’ð	ð rS   Úgeneral_settingsr^   c                 ó¬   — | €|S | j                  d«      }|s|S t        j                  |«      }|s|S t        j                  ||«      }|r	||_        |S |S )NÚuser_header_mappings)rÎ   rƒ  Ú%get_internal_user_header_from_mappingr³  rD  )r´  r^   r;   Úuser_header_mappingrò   Úheader_values         r4   Ú#add_internal_user_from_user_mappingz<LiteLLMProxyRequestSetup.add_internal_user_from_user_mapping)  sq   € ð Ð#Ø$Ð$Ø%5×%9Ñ%9Ð:PÓ%QÐÙ"Ø$Ð$Ü5×[Ñ[Ð\oÓpˆÙØ$Ð$Ü6×SÑSÐT[Ð]hÓiˆÙØ(4ÐÔ%Ø$Ð$Ø Ð rS   c                 óê   — |€y|j                  d«      }|�|dk(  ryt        |t        «      st        dt	        |«      › �«      ‚t
        j                  | |«      }|�t        j                  d||«       |S )zg
        Get the user from the specified header if `general_settings.user_header_name` is set.
        NÚuser_header_namerf   z.Expected user_header_name to be a str but got zfound user "%s" in header "%s")	rÎ   rÏ   rh   Ú	TypeErrorrã   rƒ  r³  r   Úinfo)r;   r´  rò   Úusers       r4   Úget_user_from_headersz.LiteLLMProxyRequestSetup.get_user_from_headers=  sƒ   € ð
 Ð#Øà-×1Ñ1Ð2DÓEˆØÐ +°Ò"3Øä˜+¤sÔ+ÜÐLÌTÐR]ÓM^ÐL_Ð`ÓaÐaä.×KÑKÈGÐU`ÓaˆØÐÜ×ÑÐ @À$ÈÔTàˆrS   c                 óº   — |�|j                  d«      dury| j                  «       D ]2  \  }}|j                  «       dk(  sŒt        j                  d|«       |c S  y)z9
        Get the OpenAI Org ID from the headers.
        NÚforward_openai_org_idTzopenai-organizationz'found openai org id: %s, sending to llm)rÎ   r1  r1   r   r¾  )r;   r´  r;  r0   s       r4   Úget_openai_org_id_from_headersz7LiteLLMProxyRequestSetup.get_openai_org_id_from_headersR  se   € ð
 Ð'Ð,<×,@Ñ,@ÐAXÓ,YÐaeÑ,eØØ$Ÿ]™]›_ò 	‰MˆF�EØ�|‰|‹~Ð!6Ó6Ü×#Ñ#Ð$MÈuÔUØ’ð	ð rS   c                 óz  — t         j                  | «      }t        j                  du r“t         j	                  |¬«      }|j                  «       D ]j  \  }}|€Œ	t        |t        t        f«      rt        j                  |«      |d|› �<   Œ;t        |t        t        f«      r	||d|› �<   ŒZt        |«      |d|› �<   Œl |S )z«
        Add headers to the LLM call

        - Checks request headers for forwardable headers
        - Checks if user information should be added to the headers
        Tr  z
x-litellm-)rƒ  r±  rÝ   Ú#add_user_information_to_llm_headersÚ'get_sanitized_user_information_from_keyr1  rÏ   rê   rï   ÚjsonÚdumpsrh   Úbytes)r;   r^   Úreturned_headersÚ litellm_logging_metadata_headersrA  r3   s         r4   Úadd_headers_to_llm_callz0LiteLLMProxyRequestSetup.add_headers_to_llm_call_  sÎ   € ô #;×"SÑ"SÐT[Ó"\Ðä×6Ñ6¸$Ñ>Ü6N×6vÑ6vØ"3ð 7wó 7Ð,ð 9×>Ñ>Ó@ò @‘��1Ø�9Øô ˜a¤$¬ Ô.Ü9=¿¹ÀA»Ð$ z°!°Ð%5Ò6Ü ¤C¬ <Ô0Ø9:Ð$ z°!°Ð%5Ò6ä9<¸Q»Ð$ z°!°Ð%5Ò6ð@ð  ÐrS   rÌ   c                 óJ  — ddl m} ddlm} | j	                  d«      }|�ƒt
        j                  �st
        j                  j                  �Y |||t
        j                  j                  |j                  |j                  ¬«      r t        j                  ||«      }|i k7  r|| d<   | S )z<
        Add headers to the LLM call by model group
        r   )Ú_check_model_access_helper©Ú
llm_routerrÉ   )rÉ   rÐ  ÚmodelsÚteam_model_aliasesr‚  r;   )Úlitellm.proxy.auth.auth_checksrÎ  Úlitellm.proxy.proxy_serverrÐ  rÎ   rÝ   Úmodel_group_settingsÚ!forward_client_headers_to_llm_apirÒ  r‚  rƒ  rÌ  )rÌ   r;   r^   rÎ  rÐ  Ú
data_modelÚ_headerss          r4   Ú&add_headers_to_llm_call_by_model_groupz?LiteLLMProxyRequestSetup.add_headers_to_llm_call_by_model_group}  s˜   € õ
 	NÝ9à ŸH™H WÓ-ˆ
ð Ð"Ü×,Ñ,Ð8Ü×,Ñ,×NÑNÐZÙ*Ø Ø%Ü×3Ñ3×UÑUØ#4×#GÑ#GØ)×1Ñ1õô 7×NÑNÈwÐXiÓjˆHØ˜2Š~Ø"*��Y‘ØˆrS   c                 ó<  — | sy t        | t        «      r| n| g}|D ]  }t        |t        «      sŒ|j                  d«      }|j                  d«      }|�|sŒ;t	        |«      j                  «       t	        t        j                  «      j                  «       k(  sŒ}|c S  y )NÚlitellm_user_rolerò   )rÏ   rï   rê   rÎ   rh   r1   r#   ÚINTERNAL_USER)r¸  r1  rm  Úrolerò   s        r4   r·  z>LiteLLMProxyRequestSetup.get_internal_user_header_from_mapping˜  s”   € á"ØÜ.8Ð9LÌdÔ.SÑ*ÐZmÐYnˆØò 	#ˆDÜ˜d¤DÔ)ØØ—8‘8Ð/Ó0ˆDØŸ(™( =Ó1ˆKØˆ|¡;ØÜ�4‹y�‰Ó ¤CÔ(8×(FÑ(FÓ$G×$MÑ$MÓ$OÓOØ"Ò"ð	#ð rS   )r´  Úrequest_datac                 ó  — t        «       }|r3|j                  d«      du r t        j                  | |«      }|i k7  r||d<   t        j	                  | |«      }|�||d<   t        j                  | «      }|�||d<   t        j                  | «      }|�||d<   |€5|€3|j                  d«      €"|j                  d«      €|j                  d«      �d|d<   t        j                  | «      }	|	�|	|d	<   t        j                  | «      }
|
�|
|d
<   |S )zc
        - Adds user from headers
        - Adds forwardable headers
        - Adds org id
        rÖ  Tr;   ÚorganizationÚtimeoutÚstream_timeoutÚrequest_timeoutr¯   Únum_retriesÚkeepalive_seconds)	r"   rÎ   rƒ  rÌ  rÃ  r   r£  rª  r¦  )r;   rÞ  r^   r´  rÌ   rØ  Ú_organizationÚheader_timeoutÚheader_stream_timeouträ  rå  s              r4   Ú%add_litellm_data_for_backend_llm_callz>LiteLLMProxyRequestSetup.add_litellm_data_for_backend_llm_call¨  sE  € ô 3Ó4ˆáÐ 0× 4Ñ 4Ð5XÓ YÐ]aÑ aÜ6×NÑNÈwÐXiÓjˆHØ˜2Š~Ø"*��Y‘Ü7×VÑVÐW^Ð`pÓqˆØÐ$Ø#0ˆD�Ñ ä 8× RÑ RÐSZÓ [ˆØÐ%Ø,ˆD�‰Oä'?×'`Ñ'`ÐahÓ'iÐØ Ð,Ø%:ˆDÐ!Ñ"ð Ð&Ø$Ð0Ø×Ñ 	Ó*Ð6Ø×ÑÐ 1Ó2Ð>Ø×ÑÐ 0Ó1Ð=à*.ˆDÐ&Ñ'ä5×SÑSÐT[Ó\ˆØÐ"Ø"-ˆD�Ñä#;×#_Ñ#_Ð`gÓ#hÐØÐ(Ø(9ˆDÐ$Ñ%àˆrS   Ú_metadata_variable_namec           
      óP  — ddl m}  |«       }t        j                  | «      }|�||d<   | j	                  d«      }t        t        | «      «      }|r||d<   t        j                  d|«       |r+||d<   ||d<   ||d	<   ||d
<   t        j                  d|«       nq|j	                  d«      }t        |«      }	|	rS|	|d<   |	|d	<   t        |t        «      r$t        |j	                  d«      t        «      r|	|d<   t        j                  d«       t        | j                  «       D �
�ci c]'  \  }
}t        |
t        «      sŒ|
j                  «       |“Œ) c}}
«      }d
|vrN|j	                  d«      }t        |t        «      r-t        |«      }|r ||d<   ||d
<   t        j                  d|«       d	|vrM|j	                  d«      }t        |t        «      r,t!        |«      }|r||d<   ||d	<   t        j                  d«       t        ||   t        «      r||   j#                  |«       |S c c}}
w )z„
        Add litellm metadata from request headers

        Relevant issue: https://github.com/BerriAI/litellm/issues/14008
        r   )Ú!LitellmMetadataFromRequestHeadersÚspend_logs_metadatazx-litellm-agent-idÚagent_idz"Extracted agent_id from header: %srQ   rB   Úlitellm_session_idÚlitellm_trace_idz8Extracted chain_id from header (trace-id/session-id): %srý   rD  z4Extracted session_id from Anthropic metadata.user_idrI   z2Extracted trace_id from W3C traceparent header: %srT   z,Extracted session_id from W3C baggage header)Úlitellm.proxy._typesrì  rƒ  r®  rÎ   rB  rê   r   r  rK  rÏ   r   r1  rh   r1   rR   r]   Úupdate)r;   rÌ   rê  rì  Úmetadata_from_headersrí  Úagent_id_from_headerÚchain_idÚbody_metadatarB   rA  r3   Únormalized_headersrI   Útrace_id_from_traceparentrT   Úsession_id_from_baggages                    r4   Ú)add_litellm_metadata_from_request_headerszBLiteLLMProxyRequestSetup.add_litellm_metadata_from_request_headersá  s9  € õ 	Ká'HÓ'JÐÜ%=×%kÑ%kÐlsÓ%tÐØÐ*Ø;NÐ!Ð"7Ñ8ð '.§k¡kÐ2FÓ&GÐä3´D¸³MÓBˆáØ0DÐ! *Ñ-Ü ×&Ñ&Ð'KÐMaÔbáØ08Ð! *Ñ-Ø2:Ð! ,Ñ/Ø)1ˆDÐ%Ñ&Ø'/ˆDÐ#Ñ$Ü ×&Ñ&Ð'aÐckÕlà#'§8¡8¨JÓ#7ˆMÜ GÈÓ VˆJÙØ6@Ð% lÑ3Ø-7�Ð)Ñ*Ü˜m¬TÔ2´zÀ-×BSÑBSÐT]ÓB^Ô`dÔ7eØ/9�M )Ñ,Ü$×*Ñ*Ð+aÔbô %5ÈwÏ}É}Ë×5uÁtÀqÈ!ÔblÐmnÔpsÕbt°a·g±g³iÀ±lÓ5uÓ$vÐØ TÑ)Ø!3×!7Ñ!7¸Ó!FˆKÜ˜+¤sÔ+Ü3MÈkÓ3ZÐ)Ù,Ø8QÐ)¨*Ñ5Ø/H�DÐ+Ñ,Ü(×.Ñ.ØLÐNgôð   tÑ+Ø/×3Ñ3°IÓ>ˆGÜ˜'¤3Ô'Ü1IÈ'Ó1RÐ'Ù*Ø:QÐ)¨,Ñ7Ø1H�DÐ-Ñ.Ü(×.Ñ.Ð/]Ô^ä�dÐ2Ñ3´TÔ:ØÐ(Ñ)×0Ñ0Ð1FÔGØˆùó- 6vs   Ä"H"
Ä;H"
c                 ój  — t        di d| j                  “d| j                  “d| j                  “d| j                  “d| j
                  “d| j                  “d| j                  “d| j                  “d	| j                  “d
| j                  “d| j                  “d| j                  “d| j                  “d| j                  “d| j                  “d| j                   “d| j"                  “d| j$                  “d| j&                  r| j&                  j)                  «       nd “dt+        | j,                  «      “Ž}|S )NÚuser_api_key_hashÚuser_api_key_aliasÚuser_api_key_spendÚuser_api_key_max_budgetÚuser_api_key_user_spendÚuser_api_key_user_max_budgetÚuser_api_key_team_spendÚuser_api_key_team_max_budgetÚuser_api_key_team_idÚuser_api_key_project_idÚuser_api_key_project_aliasÚuser_api_key_user_idÚuser_api_key_org_idÚuser_api_key_org_aliasÚuser_api_key_team_aliasÚuser_api_key_end_user_idÚuser_api_key_user_emailÚuser_api_key_request_routeÚuser_api_key_budget_reset_atÚuser_api_key_auth_metadatar'  )ru   r:   Ú	key_aliasÚspendÚ
max_budgetÚ
user_spendÚuser_max_budgetÚ
team_spendÚteam_max_budgetr‚  Ú
project_idÚproject_aliasrD  Úorg_idÚorganization_aliasÚ
team_aliasÚend_user_idÚ
user_emailÚrequest_routeÚbudget_reset_atÚ	isoformatr+   rý   )r^   Úuser_api_key_logged_metadatas     r4   rÆ  z@LiteLLMProxyRequestSetup.get_sanitized_user_information_from_key.  sr  € ô /Pò /
Ø/×7Ò7ð/
à0×:Ò:ð/
ð  1×6Ò6ð/
ð %6×$@Ò$@ð	/
ð
 %6×$@Ò$@ð/
ð *;×)JÒ)Jð/
ð %6×$@Ò$@ð/
ð *;×)JÒ)Jð/
ð "3×!:Ò!:ð/
ð %6×$@Ò$@ð/
ð (9×'FÒ'Fð/
ð "3×!:Ò!:ð/
ð !2× 8Ò 8ð/
ð $5×#GÒ#Gð/
ð %6×$@Ò$@ð/
ð  &7×%BÒ%Bð!/
ð" %6×$@Ò$@ð#/
ð$ (9×'FÒ'Fð%/
ð( BS×AbÒAbÐ!×1Ñ1×;Ñ;Ô=Ðhløð)/
ô, (=Ð=N×=WÑ=WÔ'Xð-/
Ð$ð0 ,Ð+rS   c                 óT  — t         j                  |¬«      }| |   j                  |«       |j                  | |   d<   t	        |dd«      }| |   j                  d«      }|xs |}|| |   d<   t	        |dd«      | |   d<   |j                  �|j                  | |   d<   |j                  r|j                  | |   t        <   |j                  t        |j                  «      t        |j                  «      t        |j                  «      t        |j                  «      dœ¬	«      | |   d
<   | S )zK
        Adds the `UserAPIKeyAuth` object to the request metadata.
        r  Úuser_api_keyrî  NÚend_user_max_budgetÚuser_api_end_user_max_budgetÚuser_api_key_budget_reservation)rý   rþ   Úproject_metadataÚorganization_metadata)rò  Úuser_api_key_auth)rƒ  rÆ  rò  r:   rÜ   rÎ   Úbudget_reservationÚmatched_model_access_groupsr   Ú
model_copyr+   rý   rþ   r'  r(  )rÌ   r^   rê  r!  Ú_key_agent_idÚ_existing_agent_idÚ_resolved_agent_ids          r4   Ú)add_user_api_key_auth_to_request_metadatazBLiteLLMProxyRequestSetup.add_user_api_key_auth_to_request_metadataL  sd  € ô /G×.nÑ.nØ/ð /oó /
Ð$ð 	Ð$Ñ%×,Ñ,Ð-IÔJØ8I×8QÑ8QˆÐ$Ñ% nÑ5ô  'Ð'8¸*ÀdÓKˆØ$(Ð)@Ñ$A×$EÑ$EÀjÓ$QÐØ$1Ò$GÐ5GÐØ4FˆÐ$Ñ% jÑ1äHOØÐ4°dóI
ˆÐ$Ñ%Ð&DÑEð ×/Ñ/Ð;ØO`×OsÑOsˆDÐ(Ñ)Ð*KÑLØ×8Ò8à!×=Ñ=ð Ð(Ñ)Ô*IÑJð >O×=YÑ=Yä1Ð2C×2LÑ2LÓMÜ!6Ð7H×7VÑ7VÓ!WÜ$9Ð:K×:\Ñ:\Ó$]Ü)>Ð?P×?fÑ?fÓ)gñ	ð >Zó >
ˆÐ$Ñ%Ð&9Ñ:ð ˆrS   Úmanagement_endpoint_metadatac                 ó  — || vr| S ddl m}m} t        |«      xs i j	                  «       D ��ci c]  \  }}|||z   vr||“Œ }}}| |   j                  d«      €i | |   d<   | |   d   j                  |«       | S c c}}w )zŽ
        Adds the `UserAPIKeyAuth` metadata to the request metadata.

        ignore any sensitive fields like logging, api_key, etc.
        r   )Ú)LiteLLM_ManagementEndpoint_MetadataFieldsÚ1LiteLLM_ManagementEndpoint_MetadataFields_Premiumr  )rñ  r3  r4  r+   r1  rÎ   rò  )rÌ   r1  rê  r3  r4  rA  r3   Úadded_metadatas           r4   Ú4add_management_endpoint_metadata_to_request_metadatazMLiteLLMProxyRequestSetup.add_management_endpoint_metadata_to_request_metadatau  s°   € ð #¨$Ñ.ØˆK÷	
ô /Ð/KÓLÒRÐPR×YÑYÓ[÷!
á��1ØÐJÐMvÑvÑwð ˆq‰Dð!
ˆñ !
ð
 Ð'Ñ(×,Ñ,Ð-IÓJÐRØJLˆDÐ(Ñ)Ð*FÑGØÐ$Ñ%Ð&BÑC×JÑJÈ>ÔZØˆùó!
s   ¯A;Úkey_metadatac                 óö  — | €|S d| v rDi |d<   t        | d   t        «      r,| d   j                  «       D ]  \  }}|t        v sŒ||d   |<   Œ d| v r7| d   �2t        j                  ||   j                  d«      | d   ¬«      ||   d<   d| v rt        | d   t        «      r| d   ||   d<   d| v rmt        | d   t        «      rZd||   v rHt        ||   d   t        «      r2| d   j                  «       D ]  \  }}|||   d   vsŒ|||   d   |<   Œ n| d   ||   d<   d| v rt        | d   t        «      r| d   |d<   t        | j                  d«      t        «      r| d   |d<   t        j                  || |¬«      }|S )	NÚcacheÚtags©Úrequest_tagsÚtags_to_addr—   rí  Údisable_fallbacksr™   ©rÌ   r1  rê  )	rÏ   rê   r1  rv   rƒ  Ú_merge_tagsrÎ   rù   r6  )r7  rÌ   rê  rA  r3   r[   r0   s          r4   Úadd_key_level_controlsz/LiteLLMProxyRequestSetup.add_key_level_controls’  s  € àÐØˆKØ�lÑ"ØˆD�‰MÜ˜, wÑ/´Ô6Ø(¨Ñ1×7Ñ7Ó9ò -‘D�A�qØÔ2Ò2Ø+,˜˜W™ aÒ(ð-ð
 �\Ñ! l°6Ñ&:Ð&FÜ4L×4XÑ4XØ!Ð"9Ñ:×>Ñ>¸vÓFØ(¨Ñ0ð 5Yó 5ˆDÐ(Ñ)¨&Ñ1ð '¨,Ñ6¼:ÀlÐSnÑFoÔquÔ;vØIUÐVqÑIrˆDÐ(Ñ)Ð*EÑFØ  LÑ0´ZÀÐMbÑ@cÔeiÔ5jØ$¨Ð-DÑ(EÑEÌ*ØÐ,Ñ-Ð.CÑDÄdôKð #/Ð/DÑ"E×"KÑ"KÓ"Mò Z‘J�C˜à 4Ð(?Ñ#@ÐAVÑ#WÒWàTY˜Ð4Ñ5Ð6KÑLÈSÒQñ	Zð HTÐTiÑGj�Ð,Ñ-Ð.CÑDð  ,Ñ.´:¸lÐK^Ñ>_ÔaeÔ3fØ(4Ð5HÑ(IˆDÐ$Ñ%ä�l×&Ñ&Ð'>Ó?ÄÔFØ,8Ð9PÑ,QˆDÐ(Ñ)ô (×\Ñ\ØØ)5Ø$;ð ]ó 
ˆð
 ˆrS   r<  r=  c                 ó®   — g }| r!t        | t        «      r|j                  | «       |r-t        |t        «      r|D ]  }||vsŒ|j                  |«       Œ |S )a5  
        Helper function to merge two lists of tags, ensuring no duplicates.

        Args:
            request_tags (Optional[list]): List of tags from the original request
            tags_to_add (Optional[list]): List of tags to add

        Returns:
            list: Combined list of unique tags
        )rÏ   rï   Úextendr  )r<  r=  Ú
final_tagsÚtags       r4   r@  z$LiteLLMProxyRequestSetup._merge_tagsÀ  s\   € ð ˆ
áœJ |´TÔ:Ø×Ñ˜lÔ+áœ: k´4Ô8Ø"ò +�Ø˜jÒ(Ø×%Ñ% cÕ*ð+ð ÐrS   r‚  rP  c           	      ó  — |j                  | ¬«      }t        |t        «      rt        |«      dk(  ryi |j	                  d|«      ¥}|j                  dd«       |j                  dd«       |j                  dd«       |j                  «       D ��ci c]=  \  }}|t        |t        «      r%t        j                  j                  ||¬«      xs |n|“Œ? }}}t        |j	                  dd«      |j	                  dd«      |¬	«      S c c}}w )
z:
        Add team-based callbacks from the config
        )r‚  r   Nrj  r‚  rg  ri  )Údefault_value)rg  ri  rj  )Úload_team_configrÏ   rê   rH  rÎ   rñ   r1  rh   rÝ   ÚutilsÚ
get_secretr'   )r‚  rP  Úteam_configÚcallback_vars_dictr[   r0   s         r4   r„  z=LiteLLMProxyRequestSetup.add_team_based_callbacks_from_configØ  s  € ð *×:Ñ:À7Ð:ÓKˆÜ˜+¤tÔ,´°KÓ0@ÀAÒ0EØàN §¡°ÀÓ MÐNÐØ×Ñ˜y¨$Ô/Ø×ÑÐ1°4Ô8Ø×ÑÐ1°4Ô8ð 1×6Ñ6Ó8÷
á��Uð ÔS]Ð^cÔehÔSi”'—-‘-×*Ñ*¨5ÀÐ*ÓFÒOÉ%ÐotÑtð
Ðñ 
ô
 $Ø(Ÿ_™_Ð-?ÀÓFØ(Ÿ_™_Ð-?ÀÓFØ,ô
ð 	
ùó
s   ÂADrÐ  c                 ó  — d }d|v r]t        |d   t        «      r2|d   j                  d«      }|D �cg c]  }|j                  «       ‘Œ }}nt        |d   t        «      r|d   }d|v rt        |d   t        «      r|d   }|S c c}w )Núx-litellm-tagsrV   r:  )rÏ   rh   rX   rO   rï   )rÐ  r;   rÌ   r:  Ú_tagsrE  s         r4   Úadd_request_tag_to_metadataz4LiteLLMProxyRequestSetup.add_request_tag_to_metadataó  s”   € ð ˆð ˜wÑ&Ü˜'Ð"2Ñ3´SÔ9Ø&Ð'7Ñ8×>Ñ>¸sÓC�Ø/4Ö5¨˜Ÿ	™	�Ð5�Ñ5Ü˜GÐ$4Ñ5´tÔ<ØÐ/Ñ0�à�T‰>œj¨¨f©´tÔ<Ø˜‘<ˆDàˆùò 6s   ²Br(  c                 ó\   ‡— t        ˆfd„t        D «       «      r| j                  di «       yy)a  Pre-seed ``litellm_metadata`` for routes that track tags there.

        Routes in ``LITELLM_METADATA_ROUTES`` (e.g. Bedrock, ``/v1/messages``,
        responses, batches, files) store request-scoped tag metadata in
        ``litellm_metadata`` rather than the provider-facing ``metadata``
        field. ``get_metadata_variable_name_from_kwargs`` picks the target
        based on whether ``litellm_metadata`` is present, so it must be
        seeded BEFORE any tag merge runs; otherwise header tags from
        ``apply_client_tag_policy_pre_auth`` land in ``metadata`` while
        key tags from ``apply_key_tags_pre_auth`` and the read in
        ``_tag_max_budget_check`` resolve to ``litellm_metadata``, leaving
        header tags invisible to per-tag budget enforcement.
        c              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wr/   r'  )r2   Úmetadata_router(  s     €r4   r5   zOLiteLLMProxyRequestSetup.pre_seed_litellm_metadata_for_route.<locals>.<genexpr>  s   øè ø€ ÒU¨>ˆ~ Ô&ÑUùr*  r  N)r,  r‰   Ú
setdefault)rÞ  r(  s    `r4   Ú#pre_seed_litellm_metadata_for_routez<LiteLLMProxyRequestSetup.pre_seed_litellm_metadata_for_route  s+   ø€ ô$ ÓUÔ=TÔUÔUØ×#Ñ#Ð$6¸Õ;ð VrS   c                 ó´  — |j                   }|sy|j                  d«      }|rt        |t        «      syt	        | «      }| j                  |«      }t        |t
        «      r%t        |«      }t        |t        «      r|ni }|| |<   nt        |t        «      si }|| |<   |j                  d«      }t        j                  t        |t        «      r|nd|¬«      |d<   y)zGMerge key metadata tags into request_data before _tag_max_budget_check.Nr:  r;  )
rý   rÎ   rÏ   rï   r*   rh   r   rê   rƒ  r@  )rÞ  r^   r7  Úkey_tagsrê  rý   rë   Úexisting_tagss           r4   Úapply_key_tags_pre_authz0LiteLLMProxyRequestSetup.apply_key_tags_pre_auth  sÔ   € ð 0×8Ñ8ˆÙØà&×*Ñ*¨6Ó2ˆÙœz¨(´DÔ9Øä)OÐP\Ó)]ÐØ×#Ñ#Ð$;Ó<ˆÜ�h¤Ô$Ü+¨HÓ5ˆFÜ!+¨F´DÔ!9‘v¸rˆHØ4<ˆLÐ0Ò1Ü˜H¤dÔ+ØˆHØ4<ˆLÐ0Ñ1à'Ÿ|™|¨FÓ3ˆÜ3×?Ñ?Ü*4°]ÄDÔ*I™ÈtØ ð @ó 
ˆ�ÒrS   r!  c                 ó®  — t        | ¬«      }|j                  d«      }|syt        |t        «      r>|j	                  d«      D �cg c]#  }|j                  «       sŒ|j                  «       ‘Œ% }}n5t        |t        «      r$|D �cg c]  }t        |t        «      sŒ|sŒ|‘Œ }}ny|syt        |«      }|j                  |«      }t        |t        «      r%t        |«      }	t        |	t        «      r|	ni }|||<   nt        |t        «      si }|||<   |j                  d«      }
t        j                  t        |
t        «      r|
nd|¬«      |d<   yc c}w c c}w )aH  
        Merge ``x-litellm-tags`` header tags into ``request_data`` BEFORE
        auth budget gates run, so ``_tag_max_budget_check`` (which only
        inspects ``request_data``) sees them. Without this, header-tagged
        requests silently bypass per-tag budget enforcement.

        Why: ``add_litellm_data_to_request`` runs the equivalent merge
        post-auth, after ``_tag_max_budget_check`` has already executed.
        Header-supplied tags merged there are invisible to that check.
        Running the merge here closes that gap; the post-auth merge in
        ``add_litellm_data_to_request`` remains as defense-in-depth.

        How to apply: invoked from the auth chain just before
        ``common_checks``. Mutates ``request_data`` in place; idempotent
        when followed by ``add_litellm_data_to_request``.
        ©r!  rN  NrV   r:  r;  )r,   rÎ   rÏ   rh   rX   rO   rï   r*   r   rê   rƒ  r@  )r!  rÞ  r^   r;   Úraw_header_tagsÚtÚheader_tagsrê  rý   rë   rX  s              r4   Ú apply_client_tag_policy_pre_authz9LiteLLMProxyRequestSetup.apply_client_tag_policy_pre_auth;  s=  € ô2 3¸7ÔCˆØ!(§¡Ð-=Ó!>ˆÙØä�o¤sÔ+Ø9H×9NÑ9NÈsÓ9SÖ%a°AÐWX×W^ÑW^ÕW` a§g¡g¥iÐ%aˆKÑ%aÜ˜¬Ô.Ø&5ÖR ¼ÀAÄsÕ9KÒPQš1ÐRˆKÑRàáØô
 *PÐP\Ó)]ÐØ×#Ñ#Ð$;Ó<ˆô
 �h¤Ô$Ü+¨HÓ5ˆFÜ!+¨F´DÔ!9‘v¸rˆHØ4<ˆLÐ0Ò1Ü˜H¤dÔ+ØˆHØ4<ˆLÐ0Ñ1à'Ÿ|™|¨FÓ3ˆÜ3×?Ñ?Ü*4°]ÄDÔ*I™ÈtØ#ð @ó 
ˆ�Òùò7 &bùâRs   ÁEÁEÂEÂEÂEr/   ),rå   r|  r}  r  rê   rž  r   r£  r   rh   r¦  r¨  rª  r®  r   r±  r³  r(   rº  rÀ  rÃ  rÌ  rÙ  r·  r   r"   ré  rú  ru   rÆ  r0  r6  rA  rï   r@  r{   r'   r„  rn   rP  rU  rY  r   r_  r'  rS   r4   rƒ  rƒ  Â  sÔ  „ Øð¨4ð °E¸D±Lò ó ðð0 ð°$ð ¸5À4¹<ò ó ðð ð
°W¸SÀ#¸XÑ5Fð 
È5ÐSWÉ<ò 
ó ð
ð ð¨tð ¸¸d¹
ò ó ðð ð	¸tð 	ÈÈtÉò 	ó ð	ð ð!Ø˜4‘ò!ó ð!ð* ð¨dð ¸ð ÀÀtÁò ó ðð ð!Ø ™+ð!à)ð!ð ð!ð 
ò	!ó ð!ð& ñ tð ¸tÀd¹{ð ÐVYÐ\`ÑV`ò ó ðð( ñ
°ð 
ÈÈtÉð 
Ð_bÐeiÑ_iò 
ó ð
ð ð ¨ð  À.ð  ÐUYò  ó ð ð: ð°Tð ÀDð Ð]kð Ðptò ó ðð4 ðÀcÈDÁjò ó ðð ð 37ò6àð6ð ˜c 3˜hÑ'ð6ð *ð	6ð
 ˜s C˜x™.¨4Ñ/ð6ð 
&ò6ó ð6ðp ðJØðJàðJð "%ðJð 
ò	Jó ðJðX ð,Ø)ð,à	*ò,ó ð,ð: ð&Øð&à)ð&ð "%ð&ð 
ò	&ó ð&ðP ðØðà&*ðð "%ðð 
ò	ó ðð8 ð+¨T°D©[ð +Àð +Ð_bò +ó ð+ðZ ð $¨¡+ð ¸DÀ4¹Kð ÈDò ó ðð. ð
Øð
à!ð
ð 
 Ñ	$ò
ó ð
ð4 ðØ˜T‘Mðàðð ðð 
ˆc‰�TÑ	ò	ó ðð( ð<Øð<àð<ð 
ò<ó ð<ð( ð
Øð
à)ð
ð 
ò
ó ð
ð: ð<
Øð<
àð<
ð *ð<
ð 
ò	<
ó ñ<
rS   rƒ  c                 óÔ   — | j                  d«      }t        |t        «      syt        h d£«      t        z  }| j                  «       D ��ci c]  \  }}||vsŒ||“Œ c}}|d<   yc c}}w )a!  
    Re-snapshot ``data["proxy_server_request"]["body"]`` from the current state of ``data``.

    ``add_litellm_data_to_request`` takes the initial snapshot before guardrails
    (pre_call_hook) run. A guardrail that masks PII/PCI in place (e.g. Presidio)
    mutates ``data`` afterward, so callers that persist ``proxy_server_request.body``
    for audit/spend-tracking purposes must call this again post-guardrail, or the
    persisted body silently bypasses whatever masking the guardrail applied.

    By the time a caller refreshes post-guardrail, ``litellm.utils.function_setup``
    has already stamped ``data["litellm_logging_obj"]`` with a live (non-serializable)
    ``Logging`` instance, so it must be excluded here the same way ``secret_fields``
    and ``proxy_server_request`` are.
    r’   N>   r”   Úlitellm_logging_objr’   r  )rÎ   rÏ   rê   Ú	frozensetr=   r1  )rÌ   r’   Ú_body_snapshot_excluderA  r3   s        r4   Ú*refresh_proxy_server_request_body_snapshotrd  {  sg   € ð"  Ÿ8™8Ð$:Ó;ÐÜÐ*¬DÔ1ØäÒRÓSÔVuÑuð ð 6:·Z±Z³\×#e©T¨Q°ÀQÐNdÒEd A q¡DÓ#eÐ˜Ò ùÓ#es   Á
A$ÁA$r´  Úversionc           
   ƒ   ó,  K  — ddl m}m} ddlm}m}	 t        |«      }
t        |«      }t        D ]  }|
r	|t        v rŒ| j                  |d«       Œ! t        | «       dD �ci c]%  }| j                  |«      �|| j                  |«      “Œ' }}|j                  «       D ]  \  }}t        ||«      | |<   Œ | j                  d«      }t        |t         «      r3t#        |j%                  «       «      D ]  }|j'                  d«      sŒ||= Œ  |t)        |«      «      }d}|r|j                  d	d«      }|st+        t,        d	d«      }d}d
|j.                  v rd
}nd|j.                  v rd}nd}t1        |j.                  |�|j                  d«      nd||¬«      }t3        ||¬«       t5        |«      }t7        j8                  d|«       t7        j8                  d|«       |r!d|v r|d   | d<   t7        j8                  d«       t+        |j:                  dd«      }|�|j=                  «       nt?        j>                  «       }tA        |jB                  «      |jD                  |d|dœ| d<   tG        | |«       tI        |«      }| j                  |d«      €i | |<   | jK                  tL        jO                  || ||¬«      «       tL        jQ                  || |¬«       || v rt        | |   t         «      r|| |   d<   tL        jS                  | ||¬«      } tL        jU                  |||«      }tL        jW                  ||«      }|�|jX                  €||_,        d| vr|| d<   t,        jZ                  du rt]        |«      }|�|| d<    |	|¬«      | d<   	 |j^                  }t!        |«      }|j                  d«      }|�|| d <   tc        | |¬!«       |j                  d"d«      }|rte        |«      } | j                  d#«      | d$<   dD ]�  }!| j                  |!«      }"t        |"t         «      sŒ%t3        |"j                  d«      |¬«       |"D �#cg c]  }#|#j'                  d«      s	|#tf        v sŒ|#‘Œ  c}#D ]  }$|"j                  |$d«       Œ Œƒ ti        |«      stk        | «       tm        | «       to        | «       |st,        jp                  du rts        | «       tu        | «       d| v r^t        | d   t         «      rKtw        jx                  | d   «      | |   d%<   |d&k(  r(| |   jK                  t{        | |   d%   | |   ¬'«      «       d&| v r„t        | d&   t         «      rq| d&   j                  «       D ]  \  }%}&|%| |   vsŒ|&| |   |%<   Œ |dk(  rAtL        j}                  | d   j                  d(«      | d&   j                  d(«      ¬)«      | d   d(<   |dk(  r| j                  d&d«       tL        j                  | ||¬*«      } || |   d+<   |�|j                  d,d«      | |   d,<   |j€                  }'tL        jƒ                  |'| |¬-«      } |j„                  xs i }(d(|(v r7|(d(   �2tL        j}                  | |   j                  d(«      |(d(   ¬)«      | |   d(<   d.|(v rt        |(d.   t†        «      r|(d.   | |   d.<   d/|(v rt        |(d/   t"        «      r|(d/   | |   d/<   d0|(v rmt        |(d0   t         «      rZd0| |   v rHt        | |   d0   t         «      r2|(d0   j                  «       D ]  \  }%}&|%| |   d0   vsŒ|&| |   d0   |%<   Œ n|(d0   | |   d0<   |jˆ                  xs i })d(|)v r7|)d(   �2tL        j}                  | |   j                  d(«      |)d(   ¬)«      | |   d(<   |'xs t‹        i «      j                  d(«      xs d1}*|(j                  d(«      xs d1}+|)j                  d(«      xs d1},t�        t         j�                  g |*¢|+¢|,¢­«      «      | |   d2<   tL        j‘                  | |(|¬3«      } |'xs i j                  «       D �-�&ci c]0  \  }-}&|-t’        v r#t        |&t@        «      r|&j•                  «       r|-|&“Œ2 }.}-}&tL        j‘                  | |.|¬3«      } |j–                  | |   d4<   |j˜                  | |   d5<   |jš                  | |   d6<   |jœ                  | |   d7<   |jž                  | |   d8<   |j                   | |   d9<   |j¢                  | |   d:<   |j¤                  | |   d;<   |j¦                  | |   d<<   |j¨                  }/|/| |   d=<   t«        |j€                  «      | |   d><   t«        |j„                  «      | |   d?<   t+        |d@d«      | |   dA<   t+        |dBd«      | |   dC<   || |   d<   tA        |jB                  «      | |   dD<   t+        |j:                  dd«      | |   d<   |j¬                  | |   dE<   t¯        | |¬F«       |j°                  �|j°                  | dG<   t?        j>                  «       }0dH}1	 |�?|j                  dI«      du r,|�*t³        |d«      rdJ|j.                  v r|j.                  dJ   }1nF|�Dt³        |dK«      r8t³        |j´                  dL«      r"|j´                  �|j´                  j¶                  }1|1| |   dM<   dH}2|�)t³        |d«      rdN|j.                  v r|j.                  dN   }2|2| |   dO<   t¹        |2| |«      rd| dP<   tL        j»                  ||| ¬Q«      }3|3�/tL        j}                  | |   j                  d(«      |3¬)«      | |   d(<   |dk7  r| j                  d«      nd}4t        |4t         «      r0t        |4j                  d(«      t"        «      r|4j                  d(«      nd}5|5r/tL        j}                  | |   j                  d(«      |5¬)«      | |   d(<   t�        t         j�                  g |3xs d1¢|5xs d1¢­«      «      | |   dR<   t½        ||¬S«      }6|6�d|6j¾                  | dT<   |6jÀ                  | dU<   |6jÂ                  �:|6jÂ                  j                  «       D ]
  \  }#}7|7| |#<   Œ |6jÂ                  | tÄ        <   |j€                  r4dV|j€                  v r&|j€                  dV   }8|8rt        |8t"        «      r|8| dV<   tÇ        | ||¬W«      ƒ d{  –—†  | j                  dX«      }9tÉ        | |¬Y«       tË        | |¬Y«       t7        j8                  dZ| «       tÍ        | ||9|¬[«       tÏ        | |||¬\«       t?        j>                  «       }:tÑ        jÒ                  tÔ        j×                  tØ        jÚ                  |:|0z
  d]|0|:|j¬                  ¬^«      «       | S c c}w # t`        $ r i }Y �	Œìw xY wc c}#w c c}&}-w 7 Œä­w)_aÖ  
    Adds LiteLLM-specific data to the request.

    Args:
        data (dict): The data dictionary to be modified.
        request (Request): The incoming request.
        user_api_key_dict (UserAPIKeyAuth): The user API key dictionary.
        general_settings (Optional[Dict[str, Any]], optional): General settings. Defaults to None.
        version (Optional[str], optional): Version. Defaults to None.

    Returns:
        dict: The modified data dictionary.

    r   )rÐ  Úpremium_user)ÚRedactedDictÚSecretFieldsNr  rý   Úuser_api_key_Fr‹  r’  r�  r‘  rŠ  )rŠ  r‹  rŒ  rí   zRequest Headers: %szRaw Headers: %sr:   zUSetting client-provided x-api-key as api_key parameter (will override deployment key)Úlitellm_received_at)ÚurlÚmethodr;   r  Úarrival_timer’   )r;   rÞ  r^   r´  )r;   rÌ   rê  r;   )rÌ   r;   r^   r¿  T)Úraw_headersr”   rX  rY  )rÌ   r;   zCache-Controlzs-maxageÚttlr.  r  r2  r:  r;  )rÌ   r^   rê  Úlitellm_api_versionÚglobal_max_parallel_requests)r7  rÌ   rê  r—   rš   rí  r'  Úinherited_tagsr?  r  r  r  rþ  rÿ  Úuser_api_key_model_max_budgetÚ&user_api_key_end_user_model_max_budgetr   r  Ú"user_api_key_user_model_max_budgetÚuser_api_key_metadataÚuser_api_key_team_metadataÚobject_permission_idÚ!user_api_key_object_permission_idÚteam_object_permission_idÚ&user_api_key_team_object_permission_idÚendpointÚlitellm_parent_otel_spanr[  Úallowed_model_regionrf   Úuse_x_forwarded_forzx-forwarded-forÚclientÚhostÚrequester_ip_addressr8  r>  rR  )rÐ  r;   rÌ   Úcaller_tags)r^   rP  rg  ri  r¦   )rÌ   rê  r^   rÉ   )rÌ   r^   z5[PROXY] returned data from litellm_pre_call_utils: %s)rÌ   r^   Úpre_alias_model_namerÐ  )Úrequest_bodyr´  r^   rg  Úadd_litellm_data_to_request)ÚserviceÚdurationÚ	call_typeÚ
start_timeÚend_timeÚparent_otel_span)nrÔ  rÐ  rg  Ú*litellm.types.proxy.litellm_pre_call_utilsrh  ri  r  r  r°   r»   rñ   rÒ   rÎ   r1  rì   rÏ   rê   rï   rð   rÞ   r,   rÜ   rÝ   r;   r”  ró   rš  r   r  ÚstateÚ	timestampÚtimerh   rl  rm  r^  r-  rò  rƒ  ré  rú  rÙ  rº  rÀ  r  Úoverwrite_user_with_key_hashrb   rW  r[  Ú(add_provider_specific_headers_to_requestr„   r¹   r  r  r   r  r
  r  rd  ÚcopyÚdeepcopyr3  r@  r0  rý   rA  rþ   rù   r'  r   r  Úfromkeysr6  r   rO   r  r  r  r  r  Úmodel_max_budgetÚend_user_model_max_budgetr  r  Úuser_model_max_budgetr+   r�  Ú_add_otel_traceparent_to_datar  rZ  r�  r‚  rU  rP  r‰  rg  ri  rj  r   Úmove_guardrails_to_metadataÚ"_update_model_if_team_alias_existsÚ!_update_model_if_key_alias_existsÚ-_apply_credential_overrides_from_model_configÚ_enforced_params_checkÚasyncioÚcreate_taskrw   Úasync_service_success_hookrq   ÚPROXY_PRE_CALL);rÌ   r!  r^   rP  r´  re  rÐ  rg  rh  ri  Ú_allow_client_mock_responseÚ'_allow_client_message_redaction_opt_outÚ_internal_keyÚ_metadata_fieldÚ_raw_metadata_by_fieldÚ_raw_metadataÚ_user_metadataÚ_mkÚ_raw_headersÚforward_llm_authrŒ  rØ  Ú_logging_safe_headersÚ_litellm_received_atrn  rê  r¿  Ústampable_hashrW  Ú
query_dictÚdynamic_api_versionÚcache_control_headerr�   Ú	_meta_keyÚ
_user_metarA  Ú_kr[   r0   r7  rþ   r'  Ú	_key_tagsÚ
_team_tagsÚ_project_tagsrÑ   Ú_key_otel_service_namesÚuser_model_budgetr‹  rƒ  r>  r:  Ú_caller_body_metadataÚ_caller_body_tagsr…  r3   Údisabled_callbacksÚ_pre_alias_modelrŒ  s;                                                              r4   r‡  r‡  •  sé  è ø€ ÷. DßUô
 *RÐRcÓ)dÐÜ.bÐctÓ.uÐ+Ü7ò &ˆÙ&¨=Ô<WÑ+WØØ�‰� Õ%ð&ô $ DÔ)ð  @ö%àØ�8‰8�OÓ$Ð0ð 	˜Ÿ™ /Ó2Ñ2ð%Ðð %ð
 +A×*FÑ*FÓ*Hò \Ñ&ˆ˜Ü ;¸OÈ]Ó [ˆˆ_Òð\ð —X‘X˜jÓ)€NÜ�.¤$Ô'Ü˜×+Ñ+Ó-Ó.ò 	(ˆCØ�~‰~˜oÕ.Ø" 3Ñ'ð	(ñ +7Ô7PÐQXÓ7YÓ*Z€LàÐÙØ+×/Ñ/Ð0SÐUZÓ[ÐÙÜ"¤7Ð,OÐQVÓWÐð !%ÐØ˜gŸo™oÑ-à$7Ñ!Ø	˜GŸO™OÑ	+à$3Ñ!ð %0Ð!ä&3Ø�‰à?OÐ?[Ð× Ñ Ð!:Ô;Ðaeà*:Ø";ô'€Hô -ØØ/Võô $=¸XÓ#FÐÜ×ÑÐ4Ð6KÔLÜ×ÑÐ0°,Ô?á˜K¨8Ñ3Ø" ;Ñ/ˆˆY‰Ü×"Ñ"Øcô	
ô" #*¨'¯-©-Ð9NÐPTÓ"UÐØ>RÐ>^Ð.×8Ñ8Ô:Ôdh×dmÑdmÓdo€Lä�7—;‘;ÓØ—.‘.Ø(ØØ$ñ$€DÐ	Ñ ô +¨4°Ô9Ü%@ÀÓ%IÐØ‡x�xÐ'¨Ó.Ð6Ø(*ˆÐ$Ñ%à‡K�KÜ ×FÑFØØØ/Ø-ð	 	Gó 	
ôô ×FÑFØØØ 7ð Gô ð  $Ñ&¬:°dÐ;RÑ6SÔUYÔ+ZØ3HˆÐ$Ñ% iÑ0ô $×JÑJØ˜8Ð7Hð Kó €Dô 1×TÑTØÐ+¨XóÐô
 +×@Ñ@ÀÐK[Ó\€DØÐØ×(Ñ(Ð0Ø,0ÐÔ)Ø˜ÑØˆD�‰Lä×+Ñ+¨tÑ3Ü 3Ð4EÓ FˆØÐ%Ø)ˆD�‰Lá(°\ÔB€DˆÑðØ%×2Ñ2ˆä˜,Ó'ˆ
ð
 .8¯^©^¸MÓ-JÐàÐ&Ø1ˆˆ]Ñô -°$ÀÕIð #+§,¡,¨ÀÓ"EÐÙÜ/Ð0DÓEˆ
Ø —n‘n ZÓ0ˆˆU‰ð* 6ò 
)ˆ	Ø—X‘X˜iÓ(ˆ
Ü�j¤$Õ'Ü4Ø—‘˜yÓ)Ø8_õð
 &öØ¨¯©°oÔ)FÈ!ÔOqÒJq’òò )�ð —‘˜r 4Õ(ñ)ð
)ô" 7Ð7HÔIÜ'¨Ô-Ü# DÔ)ô ' tÔ,á2´w×7WÑ7WÐ[_Ñ7_Ü/°Ô5ô /¨tÔ4ð �TÑœj¨¨jÑ)9¼4Ô@Ü>B¿m¹mÈDÐQ[ÑL\Ó>]ˆÐ$Ñ%Ð&:Ñ;Ø"Ð&8Ò8ØÐ(Ñ)×0Ñ0Ü.Ø'+Ð,CÑ'DÐEYÑ'ZØ%)Ð*AÑ%Bôôð ˜TÑ!¤j°Ð6HÑ1IÌ4Ô&PØÐ1Ñ2×8Ñ8Ó:ò 	;‰JˆC�Ø˜$Ð6Ñ7Ò7Ø5:�Ð,Ñ-¨cÒ2ð	;ð # jÒ0Ü'?×'KÑ'KØ! *Ñ-×1Ñ1°&Ó9Ø Ð!3Ñ4×8Ñ8¸Ó@ð (Ló (ˆD�Ñ˜VÑ$ð  *Ò,Ø�‰Ð# TÔ*ä#×MÑMØØ+Ø 7ð Nó €Dð
 <C€DÐ	 Ñ!Ð"7Ñ8àÐ#ØHX×H\ÑH\Ø*¨DóI
ˆÐ$Ñ%Ð&DÑEð
 ,×4Ñ4€LÜ#×:Ñ:Ø!ØØ 7ð ;ó €Dð -×:Ñ:Ò@¸b€MØ�Ñ =°Ñ#8Ð#DÜ0H×0TÑ0TØÐ5Ñ6×:Ñ:¸6ÓBØ% fÑ-ð 1Uó 1
ˆÐ$Ñ% fÑ-ð # mÑ3¼
À=ÐQlÑCmÔosÔ8tØERÐSnÑEoˆÐ$Ñ%Ð&AÑBØ$¨Ñ5¼*ØÐ3Ñ4´dô;ð HUÐUrÑGsˆÐ$Ñ%Ð&CÑDØ Ñ-´*¸]ÐK`Ñ=aÔcgÔ2hØ  DÐ)@Ñ$AÑAÄjØÐ(Ñ)Ð*?Ñ@Ä$ôG
ð ,Ð,AÑB×HÑHÓJò V‘
��Uà˜tÐ$;Ñ<Ð=RÑSÒSàPU�DÐ0Ñ1Ð2GÑHÈÒMñ	Vð DQÐQfÑCgˆDÐ(Ñ)Ð*?Ñ@ð 0×@Ñ@ÒFÀBÐØÐ!Ñ!Ð&6°vÑ&>Ð&JÜ0H×0TÑ0TØÐ5Ñ6×:Ñ:¸6ÓBØ(¨Ñ0ð 1Uó 1
ˆÐ$Ñ% fÑ-ð  %Ò<Ô(8¸Ó(<×AÑAÀ&ÓIÒOÈR€IØ%×)Ñ)¨&Ó1Ò7°R€JØ+×/Ñ/°Ó7Ò=¸2€MÜ6;Ü�‰Ð?˜	Ð? JÐ?°Ñ?Ó@ó7€DÐ	 Ñ!Ð"2Ñ3ô
 $×XÑXØØ%2Ø 7ð Yó €Dð *Ò/¨R×6Ñ6Ó8÷&áˆE�5ØÔ3Ñ3¼
À5Ì#Ô8NÐSX×S^ÑS^ÔS`ð 	ˆu‰ð&Ðñ &ô
 $×XÑXØØ%<Ø 7ð Yó €Dð EV×DeÑDe€DÐ	 Ñ!Ð"@ÑAØ?P×?[Ñ?[€DÐ	 Ñ!Ð";Ñ<ØBS×BaÑBa€DÐ	 Ñ!Ð">Ñ?ð ;L×:QÑ:Q€DÐ	 Ñ!Ð"6Ñ7Ø?P×?[Ñ?[€DÐ	 Ñ!Ð";Ñ<ØEV×EgÑEg€DÐ	 Ñ!Ð"AÑBà×3Ñ3ð 	Ð	 Ñ!Ð"JÑKð @Q×?[Ñ?[€DÐ	 Ñ!Ð";Ñ<ØDU×DeÑDe€DÐ	 Ñ!Ð"@ÑAØ0×FÑFÐØJ[€DÐ	 Ñ!Ð"FÑGä=RÐSd×SmÑSmÓ=n€DÐ	 Ñ!Ð"9Ñ:ÜBWÐXi×XwÑXwÓBx€DÐ	 Ñ!Ð">Ñ?ÜIPØÐ1°4óJ€DÐ	 Ñ!Ð"EÑFô OVØÐ6¸óO€DÐ	 Ñ!Ð"JÑKð 0E€DÐ	 Ñ! )Ñ,Ü03°G·K±KÓ0@€DÐ	 Ñ! *Ñ-ô <CÀ7Ç=Á=ÐRgÐimÓ;n€DÐ	 Ñ!Ð"7Ñ8ð AR×@bÑ@b€DÐ	 Ñ!Ð"<Ñ=Ü! $°Õ8ð ×-Ñ-Ð9Ø'8×'MÑ'MˆÐ#Ñ$ÜŸ	™	›€Jð ÐØð
 Ð(Ø ×$Ñ$Ð%:Ó;¸tÑCØÐ#Ü˜ Ô+Ø! W§_¡_Ñ4à#*§?¡?Ð3DÑ#EÑ àÐÜ˜ Ô*Ü˜Ÿ™¨Ô/Ø—‘Ð*à#*§>¡>×#6Ñ#6Ð Ø<P€DÐ	 Ñ!Ð"8Ñ9ð €JØÐœw w°	Ô:¸|ÈwÏÉÑ?^Ø—_‘_ \Ñ2ˆ
Ø2<€DÐ	 Ñ! ,Ñ/ä.¨z¸4ÀÔNØ"ˆˆ]Ñô +×FÑFØØØð Gó €Dð ÐÜ0H×0TÑ0TØÐ5Ñ6×:Ñ:¸6ÓBØð 1Uó 1
ˆÐ$Ñ% fÑ-ð
 <SÐV`Ò;` 4§8¡8¨JÔ#7ÐfjÐô Ð+¬TÔ2´zÐBW×B[ÑB[Ð\bÓBcÔeiÔ7jð 	×!Ñ! &Ô)àð ñ
 Ü0H×0TÑ0TØÐ5Ñ6×:Ñ:¸6ÓBØ)ð 1Uó 1
ˆÐ$Ñ% fÑ-ô 49Ü�‰ÐA˜š ÐAÐ(9Ò(?¸RÑAÓBó4€DÐ	 Ñ! -Ñ0ô
 $AØ+¸,ô$Ðð Ð(Ø#8×#IÑ#IˆÐÑ Ø#8×#IÑ#IˆÐÑ à ×.Ñ.Ð:à-×;Ñ;×AÑAÓCò ‘��1Ø��Q’ðð 1F×0SÑ0SˆDÔ,Ñ-ð ×!Ò!Ð&BÐFW×F`ÑF`Ñ&`Ø$5×$>Ñ$>Ð?[Ñ$\ÐÙ¤*Ð-?ÄÔ"FØ1CˆDÐ-Ñ.ô &ØØ 7Ø+ô÷ ð ð #Ÿh™h wÓ/Ðô 'ØØ+õô &ØØ+õô
 ×ÑÐVÐX\Ô]ô 2ØØ+Ø-Øõ	ô ØØ)Ø+Ø!õ	ô —i‘i“k€HÜ×ÑÜ×5Ñ5Ü ×/Ñ/Ø 
Ñ*Ø3Ø!ØØ.×?Ñ?ð 	6ó 	
ô	ð €Kùò[%øôH ò Ø‹
ðüòXùóf&ðhús€   ‚AvÁ *u0Â
A7vÄI=vÎ u5 ÎA>vÐ vÐ6vÑvÑDvÕ%F+vÜD
và5váQvò-vò.Cvõ5vö vövövÚwarning_keyrÙ   Úargsc                 óÚ   — | t         v ry d t         | <   t        t         «      t        kD  r-t         j                  d¬«       t        t         «      t        kD  rŒ-t	        j
                  |g|¢­Ž  y )NF)Úlast)ry   rH  rx   Úpopitemr   rr  )rÀ  rÙ   rÁ  s      r4   Ú_warn_stale_team_alias_oncerÅ  É  s]   € ØÔ4Ñ4ØØ26Ô" ;Ñ/Ü
Ô,Ó
-Ô0MÒ
MÜ&×.Ñ.°EÐ.Ô:ô Ô,Ó
-Ô0MÓ
Mä× Ñ  Ð0¨4Ô0rS   c           	      ól  — | j                  d«      }|r|j                  r||j                  vryddlm} |j                  |   }t        €t        dd«      at        }|j                  d|j                  › d�«      }|r³|r±||j                  vrHt        d	|j                  › d
|› d
|› �dt        |«      t        |j                  «      t        |«      «       y|j                  |f}||j                  v r?|ryt        |j                  › d
|› d
|› �dt        |«      t        |j                  «      «       || d<   y)aÞ  
    Update the model if the team alias exists

    If a alias map has been set on a team, then we want to make the request with the model the team alias is pointing to

    eg.
        - user calls `gpt-4o`
        - team.model_alias_map = {
            "gpt-4o": "gpt-4o-team-1"
        }
        - requested_model = "gpt-4o-team-1"

    Note: model_aliases for team models are deprecated. This function only applies
    to legacy non-team-scoped aliases. Team-scoped deployments use team_public_model_name
    and are resolved via map_team_model in route_llm_request.

    An alias that targets a team-scoped internal name (``model_name_{team_id}_{uuid}``)
    with no live deployment behind it is never applied: the deployment was deleted, so
    the rewrite could only fail with an error naming a model the caller never sent.
    Keeping the requested model name lets it resolve against the deployments that still
    exist (e.g. a gateway-level model group shared with the team).
    rÉ   Nr   rÏ  Ú&LITELLM_ENABLE_TEAM_STALE_ALIAS_BYPASSFÚmodel_name_r\   zdeleted:ú:zÖTeam model alias for model='%s', team_id='%s' targets '%s', which has no live deployment. Routing with the requested model name instead; remove the stale entry from the team's model_aliases to silence this warning.zÀStale team model alias detected for model='%s', team_id='%s'. New sibling deployments may be unreachable. Set LITELLM_ENABLE_TEAM_STALE_ALIAS_BYPASS=true to enable team-scoped sibling routing.)rÎ   rÒ  rÔ  rÐ  rz   ro   rÞ   r‚  Ú model_name_to_deployment_indicesrÅ  rm   Ú team_model_to_deployment_indices)rÌ   r^   Ú_modelrÐ  Úaliased_targetÚenable_stale_alias_bypassÚis_stale_team_aliasr[   s           r4   rœ  rœ  Ò  s_  € ð4 —H‘H˜WÓ%€FÙÐ*×=Ò=ÀÐO`×OsÑOsÑAsØå5ð .×@Ñ@ÀÑH€Nô 'Ð.Ü*9Ð:bÐdiÓ*jÐ'Ü'FÐð "0×!:Ñ!:¸[ÐIZ×IbÑIbÐHcÐcdÐ;eÓ!fÐÙ™zØ ×!LÑ!LÑLÜ'ØÐ,×4Ñ4Ð5°Q°v°h¸aÀÐ?OÐPðOô " &Ó)Ü!Ð"3×";Ñ";Ó<Ü! .Ó1ôð ð (×/Ñ/°Ð8ˆØ�*×=Ñ=Ñ=Ù(àÜ'Ø$×,Ñ,Ð-¨Q¨v¨h°a¸Ð7GÐHð/ô " &Ó)Ü!Ð"3×";Ñ";Ó<ôð #€Dˆ‚MrS   c                 ó¾   — | j                  d«      }|rJ|j                  r=t        |j                  t        «      r"||j                  v r|j                  |   | d<   yyyyy)ap  
    Update the model if the key alias exists

    If an alias map has been set on a key, then we want to make the request with the model the key alias is pointing to

    eg.
        - user calls `modelAlias`
        - key.aliases = {
            "modelAlias": "xai/grok-4-fast-non-reasoning"
        }
        - requested_model = "xai/grok-4-fast-non-reasoning"
    rÉ   N)rÎ   ÚaliasesrÏ   rê   )rÌ   r^   rÌ  s      r4   r�  r�   	  sf   € ð  —H‘H˜WÓ%€FáØ×%Ò%ÜÐ(×0Ñ0´$Ô7ØÐ'×/Ñ/Ñ/à)×1Ñ1°&Ñ9ˆˆWŠð 0ð 8ð &ð 	rS   r…  rÐ  c                 ó^  — t         j                  sy| j                  d«      €| j                  d«      �y| j                  d«      }|sy|j                  xs i }|j                  xs i }|j                  d«      }|j                  d«      }|s|syd}	d|v r|j                  dd«      d   }	n|�t        |||¬	«      }	t        |||||	¬
«      }
|
syt        j                  |
«      }|sBt        |
«      j                  dd«      j                  dd«      }t        j                  d|«       ydD ]  }||v sŒ|| vsŒ||   | |<   Œ t        |«      j                  dd«      j                  dd«      }t        |
«      j                  dd«      j                  dd«      }t        j                  d||«       y)u  
    Walk the model_config precedence chain in team/project metadata.
    If a matching credential is found, set api_base/api_key/api_version on data
    so they override deployment defaults in the router.

    Precedence (highest to lowest):
    1. Clientside credentials (already in data â€” skip if present)
    2. Project model-specific override
    3. Project default override (defaultconfig)
    4. Team model-specific override
    5. Team default override (defaultconfig)
    6. Deployment default (no action needed)
    NÚapi_baser:   rÉ   Úmodel_configú/rL   r   )rÐ  Ú
model_namer…  )rÖ  Úproject_model_configÚteam_model_configr…  Úproviderrg   rf   re   zMmodel_config references credential '%s' but it was not found or has no values)rÓ  r:   rY  z/Applied credential override '%s' for model '%s')rÝ   Ú(enable_model_config_credential_overridesrÎ   r'  rþ   rX   Ú!_resolve_provider_from_deploymentÚ%_resolve_credential_from_model_configr   Úget_credential_valuesrh   rk   r   rr  r  )rÌ   r^   r…  rÐ  rÖ  r'  rþ   r×  rØ  rÙ  Úcredential_nameÚcredential_valuesÚ
_safe_credr[   Ú_safe_models                  r4   rž  rž  :	  sÔ  € ô( ×;Ò;Øð ‡x�x�
ÓÐ'¨4¯8©8°IÓ+>Ð+JØàŸ™ Ó)€JÙØà/×@Ñ@ÒFÀBÐØ,×:Ñ:Ò@¸b€Mà"2×"6Ñ"6°~Ó"FÐØ,×0Ñ0°Ó@ÐáÑ(9Øð  €HØ
ˆjÑØ×#Ñ# C¨Ó+¨AÑ.‰Ø	Ð	Ü4Ø!Ø!Ø!5ô
ˆô CØØ1Ø+Ø1Øô€Oñ Øä1×GÑGÈÓXÐÙÜ˜Ó)×1Ñ1°$¸Ó;×CÑCÀDÈ"ÓMˆ
Ü×$Ñ$Ø[Øô	
ð 	ð 6ò /ˆØÐ#Ò#¨°4ªØ)¨#Ñ.ˆD�ŠIð/ô ˜Z›×0Ñ0°°rÓ:×BÑBÀ4ÈÓL€KÜ�_Ó%×-Ñ-¨d°BÓ7×?Ñ?ÀÀbÓI€JÜ×ÑØ9ØØõrS   rÖ  c                 ó4  — |g}|r||k7  r|j                  |«       |D ]g  }	 | j                  |¬«      }|€Œt        |dd«      }|€Œ)t        |dd«      }|r|c S t        |dd«      xs d}d|v sŒR|j	                  dd«      d	   c S  y# t        $ r d}Y Œbw xY w)
a:  
    Resolve a provider hint from the deployment's litellm_params when the
    user-facing model name has no provider prefix.

    Tries the post-alias name first (the resolved model group), then the
    pre-alias name. Returns None if no deployment is found or the deployment
    has no usable provider info.
    )Úmodel_group_nameNÚlitellm_paramsÚcustom_llm_providerrÉ   rf   rÕ  rL   r   )r  Ú"get_deployment_by_model_group_nameri   rÜ   rX   )	rÐ  rÖ  r…  Ú
candidatesÚnameÚ
deploymenträ  Úcustom_providerÚdeployment_models	            r4   rÛ  rÛ  ’	  sØ   € ð $˜€JÙÐ 4¸
Ò BØ×ÑÐ.Ô/àò 5ˆð	Ø#×FÑFÐX\ÐFÓ]ˆJð ÐØä  Ð-=¸tÓDˆØÐ!Øä! .Ð2GÈÓNˆÙØ"Ò"ä" >°7¸BÓ?ÒEÀ2ÐØÐ"Ò"Ø#×)Ñ)¨#¨qÓ1°!Ñ4Ò4ð%5ð( øô# ò 	ØŠJð	ús   ¢B	Â	BÂBr×  rØ  rÙ  c                 ó¢  — | g}|r|| k7  r|j                  |«       ||fD ]­  }|rt        |t        «      sŒ|D ]l  }|j                  |«      }|sŒt	        ||¬«      }	|	r|	c c S t        |«      j                  dd«      j                  dd«      }
t        j                  d|
«       Œn |j                  d«      }|sŒ›t	        ||¬«      }	|	sŒ«|	c S  y)u9  
    Walk the precedence chain and return the first matching credential name.

    Checks (in order):
    1. project_model_config[model_name][provider] â€” project model-specific
    2. project_model_config[pre_alias_model_name][provider] â€” project pre-alias
    3. project_model_config["defaultconfig"][provider] â€” project default
    4. team_model_config[model_name][provider] â€” team model-specific
    5. team_model_config[pre_alias_model_name][provider] â€” team pre-alias
    6. team_model_config["defaultconfig"][provider] â€” team default

    When a model-specific entry exists but contains no litellm_credentials,
    the function falls through to defaultconfig. This is intentional â€”
    an entry without litellm_credentials is treated as incomplete config,
    not as an explicit "no override" signal.
    )rÙ  rg   rf   re   zSmodel_config entry '%s' found but has no litellm_credentials, trying next candidateÚdefaultconfigN)	r  rÏ   rê   rÎ   Ú_extract_credential_from_entryrh   rk   r   r  )rÖ  r×  rØ  r…  rÙ  Úmodel_names_to_tryrÔ  rè  Úmodel_entryrÞ  Ú
_safe_nameÚdefault_entrys               r4   rÜ  rÜ  º	  së   € ð0 ", ÐÙÐ 4¸
Ò BØ×!Ñ!Ð"6Ô7à-Ð/@ÐAò 'ˆÙ¤:¨l¼DÔ#AØð 'ò 
	ˆDØ&×*Ñ*¨4Ó0ˆKÚÜ"@ÀÐW_Ô"`�Ù"Ø*Ô*Ü  ›Y×.Ñ.¨t°RÓ8×@Ñ@ÀÀrÓJ�
Ü$×*Ñ*ØiØõð
	ð %×(Ñ(¨Ó9ˆÚÜ<¸]ÐU]Ô^ˆOÚØ&Ò&ð-'ð0 rS   Úentryc                 ó   — t        | t        «      sy|r.|| v r*| |   }t        |t        «      r|j                  d«      }|r|S | j                  «       D ]*  }t        |t        «      sŒ|j                  d«      }|sŒ(|c S  y)a  
    Extract litellm_credentials from a model_config entry.

    Entry structure: {"azure": {"litellm_credentials": "name"}, ...}

    When provider is given (e.g. "azure"), tries an exact provider match first.
    Falls back to the first credential found across all provider keys.
    NÚlitellm_credentials)rÏ   rê   rÎ   Úvalues)ró  rÙ  Úprovider_configrÞ  s       r4   rî  rî  ñ	  sŠ   € ô �eœTÔ"Øñ �H Ñ%Ø ™/ˆÜ�o¤tÔ,Ø-×1Ñ1Ð2GÓHˆOÙØ&Ð&ð !Ÿ<™<›>ò 'ˆÜ�o¤tÕ,Ø-×1Ñ1Ð2GÓHˆOÚØ&Ò&ð	'ð
 rS   c                 ó  — d }| �C| j                  d«      }d| v r.t        |«      du r!| d   }d|v r|€g }|j                  |d   «       |j                  j                  dd «      �"|€g }|j                  |j                  d   «       |S )NÚenforced_paramsÚservice_account_settingsT)rÎ   Ú!check_if_token_is_service_accountrC  rý   )r´  r^   rù  rú  s       r4   Ú_get_enforced_paramsrü  
  s°   € Ø#'€OØÐ#Ø*×.Ñ.Ð/@ÓAˆà&Ð*:Ñ:Ü1Ð2CÓDÈÑLà.>Ð?YÑ.ZÐ$Ø Ð$<Ñ<Ø"Ð*Ø&(�OØ×&Ñ&Ð'?Ð@QÑ'RÔSØ×!Ñ!×%Ñ%Ð&7¸Ó>ÐJØÐ"Ø ˆOØ×ÑÐ0×9Ñ9Ð:KÑLÔMØÐrS   Úvalid_tokenc                 ó:   — | j                   rd| j                   v ryy)zr
    Checks if the token is a service account

    Returns:
        bool: True if token is a service account

    Úservice_account_idTF)rý   )rý  s    r4   rû  rû  "
  s!   € ð ×ÒØ ;×#7Ñ#7Ñ7ØØrS   r†  rg  c                 óœ  — t        ||¬«      }|€y|r-|dur)t        d|› dt        j                  j                  › �«      ‚|D ]ˆ  }|j                  d«      }t        |«      dk(  r|d   | vsŒ*t        d|d   › d	�«      ‚t        |«      d
k(  sŒK|d   | vrt        d|d   › d	�«      ‚|d   | |d      vsŒrt        d|d   › d|d   › d�«      ‚ y)z]
    If enforced params are set, check if the request body contains the enforced params.
    )r´  r^   Tz;Enforced Params is an Enterprise feature. Enforced Params: z. r  rL   r   zBadRequest please pass param=z* in request body. This is a required paramé   zBadRequest please pass param=[z][z+] in request body. This is a required param)rü  rq  r!   Únot_premium_userr0   rX   rH  )r†  r´  r^   rg  rù  Úenforced_paramÚ_enforced_paramss          r4   rŸ  rŸ  0
  sV  € ô +?Ø)Ð=Nô+€Oð ÐØÙ˜<¨tÑ3ÜØIÈ/ÐIZÐZ\Ô]n×]Ñ]÷  ^Fñ  ^Fð  ]Gð  Hó
ð 	
ð *ò ˆØ)×/Ñ/°Ó4ÐÜÐÓ  AÒ%Ø Ñ"¨,Ò6Ü Ø3Ð4DÀQÑ4GÐ3HÐHrÐsóð ô Ð!Ó" aÓ'à Ñ"¨,Ñ6Ü Ø3Ð4DÀQÑ4GÐ3HÐHrÐsóð ð   Ñ"¨,Ð7GÈÑ7JÑ*KÒKÜ Ø4Ð5EÀaÑ5HÐ4IÈÐL\Ð]^ÑL_ÐK`ð  aLð  Móð ðð" rS   r7  rþ   Úmetadata_variable_namer'  c                 óê  — ddl m} t        «       }| rCd| v r?t        | d   t        «      r,t        | d   «      dkD  r |«        |j                  | d   «       |rCd|v r?t        |d   t        «      r,t        |d   «      dkD  r |«        |j                  |d   «       |rCd|v r?t        |d   t        «      r,t        |d   «      dkD  r |«        |j                  |d   «       |rt	        |«      ||   d<   yy)a  
    Helper add guardrails from key, team, or project metadata to request data

    Key guardrails are set first, then team and project guardrails are appended (without duplicates).

    Args:
        key_metadata: The key metadata dictionary to check for guardrails
        team_metadata: The team metadata dictionary to check for guardrails
        data: The request data to update
        metadata_variable_name: The name of the metadata field in data
        project_metadata: The project metadata dictionary to check for guardrails

    r   ©Ú_premium_user_checkÚ
guardrailsN)Úlitellm.proxy.utilsr  ÚsetrÏ   rï   rH  rò  )r7  rþ   rÌ   r  r'  r  Úcombined_guardrailss          r4   Ú)_add_guardrails_from_key_or_team_metadatar  W
  s  € õ( 8ô "%£Ðñ ˜¨Ñ4Ü�l <Ñ0´$Ô7¼CÀÈ\Ñ@ZÓ<[Ð^_Ò<_ÙÔ!Ø×&Ñ& |°LÑ'AÔBñ ˜¨Ñ6Ü�m LÑ1´4Ô8¼SÀÈ|ÑA\Ó=]Ð`aÒ=aÙÔ!Ø×&Ñ& }°\Ñ'BÔCñ ˜LÐ,<Ñ<ÜÐ& |Ñ4´dÔ;ÄÐDTÐUaÑDbÓ@cÐfgÒ@gÙÔ!Ø×&Ñ&Ð'7¸Ñ'EÔFñ Ü59Ð:MÓ5NˆÐ#Ñ$ \Ò2ð rS   c                 ó  — ddl m} ddlm} ddlm} ddlm} ddlm	}	 t        «       }
| rCd| v r?t        | d   t        «      r,t        | d   «      dkD  r |«        |
j                  | d   «       |rCd|v r?t        |d   t        «      r,t        |d   «      dkD  r |«        |
j                  |d   «       |rCd|v r?t        |d   t        «      r,t        |d   «      dkD  r |«        |
j                  |d   «       |
sy |j                  d	|
«        |«       }|j!                  «       s |j                  d
«       y |	|j#                  d«      ¬«      }|j%                  «       }t        «       }|
D ]t  }|j'                  |«      rN|j)                  |||¬«      }|j                  |j*                  «        |j                  d||j*                  «       Œb |j,                  d|«       Œv |sy||vri ||<   ||   j#                  dg «      }t        |t        «      sg }t        |«      }|j                  |«       t        |«      ||   d<   d||   vrg ||   d<   ||   d   j/                  t        |
«      «        |j                  dt        |«      «       y)a…  
    Helper to resolve guardrails from policies attached to key/team/project metadata.

    This function:
    1. Gets policy names from key, team, and project metadata
    2. Resolves guardrails from those policies (including inheritance)
    3. Adds resolved guardrails to request metadata

    Args:
        key_metadata: The key metadata dictionary to check for policies
        team_metadata: The team metadata dictionary to check for policies
        data: The request data to update
        metadata_variable_name: The name of the metadata field in data
        project_metadata: The project metadata dictionary to check for policies
    r   ©r   ©Úget_policy_registry©ÚPolicyResolverr  r|   ÚpoliciesNz>Policy engine: resolving guardrails from key/team policies: %szGPolicy engine not initialized, skipping policy resolution from metadatarÉ   )rÉ   )Úpolicy_namer  Úcontextz7Policy engine: resolved guardrails from policy '%s': %sz0Policy engine: policy '%s' not found in registryr	  rœ   zNPolicy engine: added guardrails from key/team policies to request metadata: %s)Úlitellm._loggingr   Ú+litellm.proxy.policy_engine.policy_registryr  Ú+litellm.proxy.policy_engine.policy_resolverr  r
  r  Ú!litellm.types.proxy.policy_enginer}   r  rÏ   rï   rH  rò  r  Úis_initializedrÎ   Úget_all_policiesÚ
has_policyÚresolve_policy_guardrailsr	  rr  rC  )r7  rþ   rÌ   r  r'  r   r  r  r  r}   Úpolicy_namesÚregistryr  Úall_policiesÚresolved_guardrailsr  Úresolved_policyÚexisting_guardrailsÚcombineds                      r4   Ú)_add_guardrails_from_policies_in_metadatar&  ‡
  sÄ  € õ, 6ÝOÝJÝ7ÝDô  #›u€Lñ ˜
 lÑ2Ü�l :Ñ.´Ô5¼#¸lÈ:Ñ>VÓ:WÐZ[Ò:[ÙÔ!Ø×Ñ ¨ZÑ 8Ô9ñ ˜ }Ñ4Ü�m JÑ/´Ô6¼3¸}ÈZÑ?XÓ;YÐ\]Ò;]ÙÔ!Ø×Ñ ¨jÑ 9Ô:ñ ˜JÐ*:Ñ:ÜÐ& zÑ2´DÔ9¼cÐBRÐS]ÑB^Ó>_ÐbcÒ>cÙÔ!Ø×ÑÐ 0°Ñ <Ô=áØàÐ×ÑÐ_ÐamÔnñ *Ó+€HØ×"Ñ"Ô$Ø"Ð×"Ñ"Ð#lÔmØñ (¨d¯h©h°wÓ.?Ô@€Gð #×3Ñ3Ó5€Lô '*£eÐØ#ò jˆØ×Ñ˜{Ô+Ø,×FÑFØ'Ø%Øð Gó ˆOð
  ×&Ñ& ×'AÑ'AÔBØ&Ð ×&Ñ&ØIÈ;ÐXg×XrÑXrõð )Ð ×(Ñ(Ð)[Ð]hÕiðjñ Øð  TÑ)Ø')ˆÐ#Ñ$àÐ5Ñ6×:Ñ:¸<ÈÓLÐÜÐ)¬4Ô0Ø Ðô Ð-Ó.€HØ‡O�OÐ'Ô(Ü15°h³€DÐ	Ñ  Ñ.ð  Ð&<Ñ!=Ñ=Ø;=ˆÐ#Ñ$Ð%7Ñ8ØÐ	Ñ Ð!3Ñ4×;Ñ;¼DÀÓ<NÔOàÐ×ÑØXÔZ^Ð_rÓZsõrS   rê  c              ƒ   óF  K  — |j                   }|j                  }|j                  xs i }|xr
 d|v xs d|v }|xr
 d|v xs d|v }|xr
 d|v xs d|v }d| v xs
 d| v xs d| v }	|s4|s2|s0|	s.ddlm}
  |
«       j                  «       s| j                  dd«       yt        |j                   |j                  || |¬«       t        |j                   |j                  || |¬«       t        | ||¬«      ƒ d{  –—†  d| v rN| j                  d«      }d| |   v r.t        | |   d   t        «      r| |   d   j                  |«       n|| |   d<   d| v rO| j                  d«      }d| |   v r.t        | |   d   t        «      r| |   d   j                  |«       y|| |   d<   yy7 Œª­w)	aa  
    Helper to add guardrails from request to metadata

    - If guardrails set on API Key metadata then sets guardrails on request metadata
    - If guardrails not set on API key, then checks request metadata
    - Adds guardrails from policies attached to key/team metadata
    - Adds guardrails from policy engine based on team/key/model context
    r	  r  Úguardrail_configr   r  N)r7  rþ   r'  rÌ   r  )rÌ   r  r^   )rý   rþ   r'  r  r  r  rñ   r  r&  Ú!add_guardrails_from_policy_enginerÏ   rï   rC  rê   rò  )rÌ   rê  r^   r7  rþ   r'  Úhas_key_configÚhas_team_configÚhas_project_configÚhas_request_configr  Úrequest_body_guardrailsÚrequest_body_guardrail_configs                r4   r›  r›  ó
  s  è ø€ ð ,×4Ñ4€LØ,×:Ñ:€MØ/×@Ñ@ÒFÀBÐà(Òi¨l¸lÐ.JÒ.hÈjÐ\hÐNh€NØ*Òm°ÀÐ0MÒ0lÐQ[Ð_lÐQl€OØ)Òr¨|Ð?OÐ/OÒ/qÐS]ÐaqÐSqÐØ ,°Ð 4Ò hÐ8JÈdÐ8RÒ hÐV`ÐdhÐVhÐñ ™oÑ1CÑGYÝSá"Ó$×3Ñ3Ô5à�H‰H�Z Ô&Øô .Ø&×/Ñ/Ø'×5Ñ5Ø)ØØ6õô .Ø&×/Ñ/Ø'×5Ñ5Ø)ØØ6õô ,ØØ6Ø+ô÷ ð ð �tÑØ)-¯©°,Ó)?ÐØ˜4Ð 7Ñ8Ñ8¼ZØÐ(Ñ)¨,Ñ7¼ô>
ð Ð(Ñ)¨,Ñ7×>Ñ>Ð?VÕWà:QˆDÐ(Ñ)¨,Ñ7ð ˜TÑ!Ø/3¯x©xÐ8JÓ/KÐ%Ø Ð&=Ñ!>Ñ>Ä:ØÐ(Ñ)Ð*<Ñ=¼tôD
ð Ð(Ñ)Ð*<Ñ=×DÑDÐEbÕcà@]ˆDÐ(Ñ)Ð*<Ò=ð "ð)ús   ‚C2F!Ã4FÃ5B+F!Úsc                 óT   — ddl m} t        | t        «      xr | j	                  |«      S )zPReturn True if string is a policy version ID (starts with policy_<uuid> prefix).r   ©ÚPOLICY_VERSION_ID_PREFIX)r  r3  rÏ   rh   rÞ   ©r0  r3  s     r4   Ú_is_policy_version_idr5  H  s!   € åTä�aœÓÒH !§,¡,Ð/GÓ"HÐHrS   c                 óf   — ddl m} t        | «      sy| t        |«      d j	                  «       xs dS )zNExtract raw UUID from policy_<uuid> string, or None if not a valid version ID.r   r2  N)r  r3  r5  rH  rO   r4  s     r4   Ú_extract_policy_idr7  O  s2   € åTä  Ô#ØØŒSÐ)Ó*Ð,Ð-×3Ñ3Ó5Ò=¸Ð=rS   r  r}   Úrequest_body_policiesÚpolicies_overridec                 óV  — ddl m} ddlm}m} ddlm} ddlm}  |«       }	|	j                  |«      }
|
D �cg c]  }|d   ‘Œ	 }}|
D �ci c]  }|d   |d   “Œ }} |j                  d|«       t        |«      }|r4t        |t        «      r$|j                  |«        |j                  d	|«       |sg i fS |j                  t        |«      ||¬
«      } |j                  d|«       |D ]  } || |¬«       Œ |D �ci c]  }||v sŒ|||   “Œ }} || |¬«       ||fS c c}w c c}w c c}w )z˜
    Match policies via attachments and request body, track them in metadata.

    Returns:
        Tuple of (applied_policy_names, policy_reasons)
    r   r  )Úadd_policy_sources_to_metadataÚ%add_policy_to_applied_policies_header)Úget_attachment_registry)ÚPolicyMatcherr  Úmatched_viaz3Policy engine: matched policies via attachments: %sz;Policy engine: added dynamic policies from request body: %s)r  r  r  z8Policy engine: applied policies (conditions matched): %s)rÞ  r  )rÞ  r�   )r  r   Ú)litellm.proxy.common_utils.callback_utilsr;  r<  Ú/litellm.proxy.policy_engine.attachment_registryr=  Ú*litellm.proxy.policy_engine.policy_matcherr>  Ú"get_attached_policies_with_reasonsr  r  rÏ   rï   rò  Ú%get_policies_with_matching_conditions)rÌ   r  r8  r9  r   r;  r<  r=  r>  Úattachment_registryÚmatches_with_reasonsÚmÚmatching_policy_namesÚpolicy_reasonsÚall_policy_namesÚapplied_policy_namesr  rè  Úapplied_reasonss                      r4   Ú_match_and_track_policiesrM  X  sw  € õ 6÷õ XÝHñ "9Ó!:ÐØ"5×"XÑ"XÐY`Ó"aÐØ>RÖ#S¸ A mÓ$4Ð#SÐÐ#SØI]Ö^ÀA˜Q˜}Ñ-¨q°Ñ/?Ñ?Ð^€NÐ^àÐ×ÑÐTÐVkÔlô "Ð"7Ó8ÐÙ¤Ð,AÄ4Ô!HØ×ÑÐ 5Ô6Ø"Ð×"Ñ"Ð#`ÐbwÔxáØ�2ˆvˆð #0×"UÑ"UÜÐ*Ó+ØØ"ð #Vó #Ðð Ð×ÑÐYÐ[oÔpð ,ò ZˆÙ-¸4È[ÖYðZð FZÖt¸TÐ]aÐesÒ]s˜d N°4Ñ$8Ñ8Ðt€OÐtÙ"°À_ÕUà Ð/Ð/ùò? $TùÚ^ùò6 us   ·DÁ	D!Ã:	D&ÄD&r  r  c                 ó,  — ddl m} ddlm} |j	                  |||¬«      } |j
                  d|«       |j                  |||¬«      }|| vri | |<   t        «       }	|r>|j                  |«      }	|| |   d<   |	| |   d<    |j
                  dt        |«      |	«       |s|sy	| |   j                  d
g «      }
t        |
t        «      sg }
t        |
«      }|j                  |«       ||	z  }t        |«      | |   d
<    |j
                  dt        |«      «       y	)z<Apply resolved guardrails and pipelines to request metadata.r   r  r  )r  r  r  z&Policy engine: resolved guardrails: %sr¡   r¢   z>Policy engine: resolved %s pipeline(s), managed guardrails: %sNr	  z7Policy engine: added guardrails to request metadata: %s)r  r   r  r  Úresolve_guardrails_for_contextr  Úresolve_pipelines_for_contextr  Úget_pipeline_managed_guardrailsrH  rÎ   rÏ   rï   rò  )rÌ   r  r  r  r  r   r  r"  Ú	pipelinesÚpipeline_managed_guardrailsr$  r%  s               r4   Ú&_apply_resolved_guardrails_to_metadatarT  ‘  s`  € õ 6ÝJð "0×!NÑ!NØØØ!ð "Oó "Ðð Ð×ÑÐGÐI\Ô]ð &×CÑCØØØ!ð Dó €Ið  TÑ)Ø')ˆÐ#Ñ$ô (+£uÐÙØ&4×&TÑ&TÐU^Ó&_Ð#Ø?HˆÐ#Ñ$Ð%;Ñ<ØGbˆÐ#Ñ$Ð%CÑDØ"Ð×"Ñ"ØLÜ�	‹NØ'ô	
ñ ¡yØàÐ5Ñ6×:Ñ:¸<ÈÓLÐÜÐ)¬4Ô0Ø Ðô Ð&Ó'€HØ‡O�OÐ'Ô(ØÐ+Ñ+€HÜ15°h³€DÐ	Ñ  Ñ.àÐ×ÑÐXÔZ^Ð_gÓZhÕirS   c              ƒ   ó   K  — ddl m} ddlm} ddlm} ddlm} | j                  dd«      } |«       } |j                  d|j                  «       t        |j                  «       «      «       |j                  «       s |j                  d	«       y || «      xs d}	|j                  }
|j                  } |t        |
t         «      r|
ndt        |t         «      r|nd| j#                  d
«      |	¬«      } |j                  d|j                  |j                  |j$                  |j&                  «       g }g }|rdt        |t(        «      rT|D ]O  }t        |t         «      sŒt+        |«      r t-        |«      }|sŒ-|j/                  |«       Œ?|j/                  |«       ŒQ t1        |j                  «       «      }g }|D ]Y  }|j3                  |¬«      }|�0|\  }}|||<   |j/                  |«        |j                  d||«       ŒG |j                  d|«       Œ[ ||z   }t5        | |||r|nd¬«      \  }}t7        | |||r|nd|r|¬«       yd¬«       y­w)ah  
    Add guardrails from the policy engine based on request context.

    This function:
    1. Extracts "policies" from request body (if present) for dynamic policy application
    2. Supports policy_<uuid> in policies to execute a specific version (e.g. published)
    3. Gets matching policies based on team_alias, key_alias, and model (via attachments)
    4. Combines dynamic policies with attachment-based policies
    5. Resolves guardrails from all policies (including inheritance)
    6. Adds guardrails to request metadata
    7. Tracks applied policies in metadata for response headers
    8. Removes "policies" from request body so it's not forwarded to LLM provider

    Args:
        data: The request data to update
        metadata_variable_name: The name of the metadata field in data
        user_api_key_dict: The user's API key authentication info
    r   r  )Úget_tags_from_request_bodyr  r|   r  Nz7Policy engine: registry initialized=%s, policy_count=%sz7Policy engine not initialized, skipping policy matchingrÉ   )r  r  rÉ   r:  z[Policy engine: matching policies for context team_alias=%s, key_alias=%s, model=%s, tags=%s)Ú	policy_idz3Policy engine: loaded version by ID policy_%s -> %sz=Policy engine: policy version %s not found in cache, skipping)r9  )r  r  )r  r   Ú-litellm.proxy.common_utils.http_parsing_utilsrV  r  r  r  r}   rñ   r  r  rH  r  r  r  rÏ   rh   rÎ   rÉ   r:  rï   r5  r7  r  rê   Úget_policy_by_id_for_requestrM  rT  )rÌ   r  r^   r   rV  r  r}   Úrequest_body_policies_rawr   Úall_tagsÚ_team_aliasÚ
_key_aliasr  Úrequest_body_namesÚrequest_body_version_idsrm  rW  Úmerged_policiesÚfetched_policy_namesÚresultÚpnameÚpolicyr8  rK  r\   s                            r4   r)  r)  Í  sl  è ø€ õ. 6ÝXÝOÝDð (,§x¡x°
¸DÓ'AÐá)Ó+€HØÐ×ÑØAØ×ÑÓ!ÜˆH×%Ñ%Ó'Ó(ôð
 ×"Ñ"Ô$Ø"Ð×"Ñ"Ð#\Ô]Øñ 1°Ó6Ò>¸$€HØ*×5Ñ5€KØ)×3Ñ3€JÙ'Ü",¨[¼#Ô">‘;ÀDÜ *¨:´sÔ ;‘*ÀØ�h‰h�wÓØô	€Gð Ð×ÑØeØ×ÑØ×ÑØ�‰Ø�‰ôð ,.ÐØ13ÐÙ ¤ZÐ0IÌ4Ô%PØ-ò 	0ˆDÜ˜d¤CÔ(ØÜ$ TÔ*Ü.¨tÓ4�	ÚØ,×3Ñ3°IÕ>à"×)Ñ)¨$Õ/ð	0ô .2°(×2KÑ2KÓ2MÓ-N€OØ-/ÐØ-ò sˆ	Ø×6Ñ6ÀÐ6ÓKˆØÐØ"‰MˆE�6Ø%+ˆO˜EÑ"Ø ×'Ñ'¨Ô.Ø&Ð ×&Ñ&Ð'\Ð^gÐinÕoà&Ð ×&Ñ&Ð'fÐhqÕrðsð $6Ð8LÑ#LÐô 8ØØØÙ-E™/È4ô	ÑÐ˜!ô +ØØØÙ-AÑ)ÀtÙ$<�öð
 CGöùs   ‚E3IÅ6CIrV   Ú_ANTHROPIC_API_HEADER_PROVIDERSÚ%_ANTHROPIC_OAUTH_CREDENTIAL_PROVIDERSc                 óz  — ddl m} t        D �ci c]  }||v sŒ|||   “Œ }}|j                  «       D ��ci c]#  \  }}|j	                  «       dk(  r ||«      r||“Œ% }}}t
        |ft        |ffD ��cg c]  \  }}|rt        ||¬«      ‘Œ }	}}|	rt        |	«      dk(  r|	d   n|	| d<   y y c c}w c c}}w c c}}w )Nr   rŽ  r�  )rå  Úextra_headersrL   r<   )	r“  r�  rp   r1  r1   re  rf  rt   rH  )
rÌ   r;   r�  r;  Úanthropic_api_headersr0   Ú"anthropic_oauth_credential_headersÚ	providersrh  Úscoped_headerss
             r4   r“  r“  @  sï   € õ KäJ_Ö#uÀÐciÐmtÒct F¨G°F©OÑ$;Ð#uÐÐ#uð %Ÿ]™]›_÷1áˆF�EØ�<‰<‹>˜_Ò,Ñ1GÈÔ1Nð 	�‰ð1Ð&ñ 1ô -Ð.CÐDÜ2Ð4VÐWð)
÷á$ˆI�}ñ ô 	°9ÈMÖZð€Nñ ñ Ü@CÀNÓ@SÐWXÒ@X¨>¸!Ò+<Ð^lˆÐ'Ò(ð ùò! $vùó1ùós   �	B,™B,¶(B1Á4B7c                 óÄ   — ddl m} | €y |€y t        j                  du rB|j                  r5d|j                  v r&d| vri | d<   | d   }d|vr|j                  d   |d<   y y y y y )Nr   )Úopen_telemetry_loggerTrI   rh  )rÔ  rn  rÝ   Ú#forward_traceparent_to_llm_providerr;   )rÌ   r!  rn  Ú_exra_headerss       r4   rš  rš  Z  s†   € Ý@à€|ØØÐ$ð 	ä×2Ñ2°dÑ:Ø�?Š?Ø §¡Ñ/ð #¨$Ñ.Ø,.�D˜Ñ)Ø'+¨OÑ'<�Ø ¨Ñ5Ø3:·?±?À=Ñ3Q�M -Ò0ð 6ð 0ð ð ;rS   )NFN)NNr/   )Ér   r”  rÇ  Úrer‘  Úcollectionsr   Úcollections.abcr   r   Útypesr   Útypingr   r   r	   Úfastapir
   r   Úpydanticr   rp  Ústarlette.datastructuresr   rÝ   r  r   r   Úlitellm._service_loggerr   Úlitellm.constantsr   r   r   r   r   r   Ú.litellm.litellm_core_utils.credential_accessorr   Ú=litellm.litellm_core_utils.initialize_dynamic_callback_paramsr   r   r   Ú1litellm.litellm_core_utils.internal_call_metadatar   r¬  r   Ú$litellm.litellm_core_utils.url_utilsr   r   rñ  r    r!   r"   r#   r$   r%   r&   r'   r(   r@  r)   r*   r+   rX  r,   Ú7litellm.types.integrations.anthropic_cache_control_hookr-   rb  Ú_member_map_rö  r6   Ú__annotations__r7   Úlitellm_credential_header_namesr9   r=   ÚcompileÚ
IGNORECASEr>   rA   rD   rE   rF   rG   rH   rh   rR   r]   rb   rc   rm   Úlitellm.routerrn   Úlitellm.secret_managers.mainro   Úlitellm.types.llms.anthropicrp   Úlitellm.types.servicesrq   Úlitellm.types.utilsrr   rs   rt   ru   rv   rw   rx   ry   rz   rù   rÔ  r{   Ú_ProxyConfigr  r}   r„   r‰   r‘   r°   r¹   rº   r»   r½   r¿   Úmodel_fieldsrð   rÀ   rÃ   rÆ   rÈ   rË   rê   rÒ   rÐ   r¨  rž  rï   rá   rã   Úobjectrè   rì   ró   rú   r   r  r  r  r  r  r  r   r-  r  r3  r6  r?  rB  rK  rN  r<  rU  r^  rl  rs  ru  r‰  r”  r˜  rš  rƒ  rd  r‡  rÅ  rœ  r�  rž  rÛ  rÜ  rî  rü  rû  rŸ  r  r&  r›  r5  r7  rM  rT  r)  r  Ú	ANTHROPICr0   ÚBEDROCKÚ	VERTEX_AIre  rf  r“  rš  r'  rS   r4   ú<module>r�     så  ðÜ Û Û Û 	Û Ý #ß 3Ý "ß ,Ñ ,ç *Ý ?Ý ,ã ß AÝ 2÷÷ õ N÷ñ õ
 ^Ý F÷÷
÷ 
õ 
÷ñ õ
 TÝ gñ !*Ñ)hÀ>×C^ÑC^×CeÑCeÓCgÔ)hÓ hÐ ˜Ó hà 0Ð ˜Ó 0Ø"P .×"PÑ"PÓ"RÑU^ØÐ$Ð%óVñ #Ð ˜%ó ñ *3Ò3eÓ)fÐ  Ó fð (2 r§z¡zÐ2FÈÏÉÓ'VÐ ˜uÓ VÙ#,Ð.BÐDZÐ-[Ó#\Ð ˜5Ó \ð
 $`Ð ˜5Ó _ð ", §¡¨O¸R¿]¹]Ó!KÐ ˜Ó Kð )˜bŸj™jÐ)@ÓAÐ �eÓ Aà"˜Ÿ
™
Ð#4Ó5€�Ó 5ð $˜Ÿ™Ð$\Ð^`×^kÑ^kÓl€�Ó lð	6¨Cð 	6°C¸$±Jó 	6ð cð ¨c°D©jó ð¨>ð ¸cÀD¹jó ð )3¨¯
©
Ð3GÓ(HÐ  Ó Hð4˜Sð 4 Só 4õ  "Ý 8Ý >Ý /÷õ ñ +Ó,Ð �EÓ ,à'-Ð ˜uÓ -Ù@KÃÐ   k°#°t°)Ñ&<Ñ =Ó Mà/3Ð  ¨¡Ó 3ñ ÝFÝDà�Kà€KØÐòð"Ð ˜ó ñ 09ò
ó0Ð % uó ð5)Øð5)àð5)ð ð5)ð ð	5)ð
 ð5)ð  ð5)ð ð5)ð ð5)ð "ð5)ð ð5)ð ð5)ð ð5)ð ð5)ð ð5)ð (ð5)ð  ð!5)ð" ð#5)ð$ #ð%5)ð8 ð95)ð: ð;5)ð< ð=5)ð> !ð?5)ðP ðQ5)ðR !ðS5)ðT ,ðU5)ðV 6ðW5)ðX 1ðY5)ðZ 4ð[5)ð\ .ð]5)ð^ ð_5)ðh ñi5)Ð  ó 5ðp  ØØ!ØØ&ØØØØØ ØØØØØØ'Ø0Ø&Ø%ØØØØØ"ØØØ$ð7-Ð " Eó ñ< 2;à+ðó2Ð '¨ó ñ
 &/°ÐARÐ/SÓ%TÐ ˜UÓ TØ2NÐ (¨%Ó NØ>fÐ 4°eÓ fñ )2Ð2L×2YÑ2Y×2^Ñ2^Ó2`Ó(aÐ  Ó añ *3°LÐBjÐ3kÓ)lÐ  Ó lñ +4Ð5JÐLbÐ4cÓ*dÐ   %Ó dØ5TÐ +¨UÓ Tð *>Ð  Ó =ð8¨$¨s°C¨x©.ð 8¸Tó 8ð"
¨ð 
°Sð 
¸Tó 
ñ6 8HØ	ˆ;˜˜\¨5°*¸cÀ:ÈtÐU_Ð`ó8Ð ˜5 ¨¨s¨Ñ!3Ñ4ó ð
¨ð °Fð ¸~ó ðA sð A°6ð A¸gÀcÈ3ÀhÑ>Oó Að$ 49ò+Øð+ð -1ð+ð 
ó	+ð˜#ð  $ó ðØ%ðàðð 
óðØ%ðà	óðØ%ðà	óðØ%ðà	óð
°$°s¸C°x±.ð 
ÀTó 
ð$
Ø
ˆs�Cˆx‰.ð
à	ó
ðB
¨$¨s°C¨x©.ð 
¸Tó 
ð>Ø
ˆs�Cˆx‰.ðà	óð¨ð °Só ð*	Ø  S Ñ)ð	à˜c 3˜hÑ'ð	ð ˆ5��c�‰?˜CÐÑ ó	ðØ�S˜#�X‘ðàˆ4�Zóð2Ø˜˜S˜Ñ!ðàˆ4�Zóð: t¨C°¨H¡~¸Ñ'<ð ÀÀtÁó ð8°fð ÀÀtÁó ð00¨#ð 0°$ó 0ð; Cð ;¨Dó ;ðZ¸ð ZÀ4ð ZÐWbð ZÐgkó Zð	[°ð 	[Àó 	[ð0&Ø
ð0&à 4°tÑ ;ð0&ð ó0&ðf	¨4ð 	¸Cð 	ÀOÐVZÑDZó 	÷ñ ð$:!Ø%ð:!Ø5@ð:!à˜DÑ ó:!ð~ +/Ø.3Ø,0ñ	2Øð2à  4™Zð2ð (,ð2ð  # T™zð	2ð
 
ó2ðj6 #ð 6¨$ó 6ð
 w¨s°C¨xÑ'8ð ¸WÀSÈ#ÀXÑ=Nó ÷&v

ñ v

ðrfØ
˜˜f˜Ñ
%ðfà	ófð> /3ØñqØ
ðqàðqð &ðqð ð	qð
 ˜3 ˜8‘n tÑ+ðqð �4‰Zóqðh1¨Sð 1¸3ð 1Àsð 1Ètó 1ðK#Ø
ðK#à%ðK#ð 
óK#ð\:Ø
ð:à%ð:ð 
ó:ð: (,Ø $ñ	UØ
ðUà%ðUð  ™*ðUð ˜‘ð	Uð
 
óUðv (,ñ%Øð%àð%ð  ™*ð%ð 	ˆ4�Zó	%ðX (,Øñ4Øð4à ™+ð4ð ˜d‘{ð4ð  ™*ð	4ð
 �D‰jð4ð 	ˆ4�Zó4ñn¨$ð ¸#À¹*ð ÐPSÐVZÑPZó ð:¨4°$©;ð È>ð Ð^bÐeiÑ^ió ð(°>ð Àdó ð$Øð$à˜T‘kð$ð &ð$ð ð	$ð
 
ó$ðX %)ñ-OØ˜‘+ð-Oà˜$‘;ð-Oð ð-Oð  ð	-Oð
 ˜T‘kð-Oð 
ó-Oðj %)ñiØ˜‘+ðià˜$‘;ðið ðið  ð	ið
 ˜T‘kðið 
óiðXR^Ø
ðR^à ðR^ð &óR^ðjI˜Sð I Tó Ið>˜#ð > #¨¡*ó >ð 04ñ	60Ø
ð60à!ð60ð ð60ð ˜C ˜H‘~¨Ñ,ð	60ð
 ˆ4�‰9�d˜3 ˜8‘nÐ$Ñ%ó60ðz &*Ø&*ñ9jØ
ð9jàð9jð "ð9jð �s‘)˜dÑ"ð	9jð
 �3˜�8‰n˜tÑ#ð9jð 
ó9jðxjØ
ðjàðjð &ðjð 
ó	jðZ *-¯ªØ×Ò×!Ò! <×#7Ò#7×#=Ò#=¸|×?UÒ?U×?[Ò?[Ð\ó*Ð  ó ð 0<×/EÒ/E×/KÒ/KÐ % uÓ KðmØ
ðmàómð4R¨ð R°wô RrS   