
    h                    @   U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlmZmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZm Z m!Z! d dl"m#Z#m$Z$m%Z% erd dl&m'Z( d dl)m*Z* ee(ef   Z'neZ'eZ*ddZ+e+e_+         ejX                  d	e-
       g Z.e/e0d<   ejb                  je                  d ejb                  jg                  d             	 d dl4Z4d dl5Z5d dl6Z6d dl7Z7d dl8Z8d dl9m:Z: g dZ=d Z>d dl?m@Z@ d dlAmBZB d dlCZCd dlCmDZD d dlEmFZFmGZG d dlHmIZImJZJ d dlmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZS d dlTmUZU d dlVmWZW d dlXmYZYmZZZ d dl[m\Z\ d dl]m^Z_ d dl`maZa d dlbmcZcmdZd d dlemfZg d d lhmiZj d d!lkmlZl d d"lm d dlnmfZo d dlpmfZq d d#lrmsZsmtZtmuZu d d$lvmwZw d d%lxmyZy d d&lzm{Z{ d d'l|m}Z}m~Z~mZmZmZ d d(lmZmZ d dlmfZ d dlmfZ d d)lmZmZ d d*lmZ d d+lmZ d dlmfZ d d,lmZmZ d d-lmZ d d.lmZmZmZ d d/lmZmZ d d0lmZ d d1lmZ d d2lmZ d d3lmZ d dlmfZ d d4lmZ d d5lmZ d d6lmZ d dlmfZ d d7lmZ d dlmfZ d dlmfZ d d8lmZmZ d d9lmZ d dlmfZ d d:lmZ d d;lmZ d d<lmZ d dlmfZ d d=lmZ d dlmfZ d dlmfZ d d>lmZ d dlmfZ d dlmfZ d d?lmZ d d@lmZmZmZ d dlmfZ d dlmfZ d dAlmZmZmZ d dlmfZ d dlmfZ d dBlmZ d dlmfZ d dlmfZ d dlmfZ d dClmZmZ d dDlmZ d dlmfZ d dElmZ d dFlmZ d dlmfZ d dGlmZ d dHlmZ d dlmfZ d dIlmZ d dlmfZ d dlmfZ d dlmfZ d dlmfZ d dJlmZ d dl mfZ d dlmfZ d dKlmZ d dLlmZ d dlmfZ	 d dMl
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmfZ d dlmfZ d dNlmZm Z m!Z!m"Z" d dOl#m$Z$m%Z% d dPl&m'Z' d dQl(m)Z) d dRl*m+Z+m,Z,m-Z-m.Z. d dSl/m0Z0 d dTl1m2Z2m3Z3m4Z4m5Z5 d dUl6m7Z7 d dVl8m9Z9 d dWl:m;Z;m<Z< d dXl=m>Z> d dYl?m@Z@ d dZl?mAZB d d[l?mCZCmDZD d d\lEmFZF d d]lGmHZHmIZI d d^l"mJZJmKZK d dZl"mAZL d d_l"mMZMmNZN d d`lOmPZP 	 d dalQmRZR dceC_T        d dlUZUd ddlmZ d del6mVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`maZambZb d dflcmdZd d dglemfZf d dhlgmhZh d dilimjZj d djlkmlZlmmZmmnZnmoZompZp d dklqmrZr d dllsmtZt d dmlumvZv d dnlwmxZx  er       Zy	 d dlzm{c m|Z| 	 d dl}mfZ~ d dolmZ e~Zy e       Zee   e0dp<    ej                  dqdr      Z e{       at        j                         aee0ds<   t        j                  Zedt   e0du<    ej                  dv      Zee   e0dw<    e       Z ea       Ze
dxZee0dy<   n ee      Z ej                  dz      Zee   e0d{<   e
d|Zee0d}<   n ee      Ze d~Ze dZde dZedz  Zede dz  ZdZt        r ej                  dd      ndZt        r ej                  dde de       n	de de Zd Zd ZeBdeWfd       Z eW e        e       eeeRee      Zid dlqmZ d Zd Z ej                  dd      dk(  rt        r	eei_         G d dejB                        ZeijG                  e      de^defd       Z er       ZfdgZ	 ejb                  jO                  ejb                  jg                  e            Zejb                  jU                  edd      ZdZeredk7  r ejZ                  e      D ]  \  ZZZeD ]  Zejb                  jU                  ee      Zejg                  d      r8	  eedd      5 Zejm                         Zddd       ejq                  e e       Zejq                  de d      Z eedd      5 Zeju                  e       ddd         eijy                  d exejb                  jU                  ed            d       eijy                  e d exejb                  jU                  ed            d       eijy                  d exedc      d        ejz                  e      D ]  Zejg                  d      sedk7  sejb                  j}                  e      d    Zejb                  jU                  ee      Z ej                  edc       ejb                  jU                  ee      Zejb                  jU                  ed      Z ej                  eeë        	 ejb                  jO                  ejb                  jg                  e            Zeij                  efedcdgdg       eij                  e       d Z eƫ        d dlmǐZ dadadadadadadcadZdadaee   e0d<   dcZdadaeeD   e0d<   daee/   e0d<   i a֐ee0d<   i aؐee0d<   dZdZdaee   e0d<   dadaee   e0d<    eIej                  j                        a et              ZeCj                  j                  e       daeeJ   e0d<   dadadadadadadadai aeǐeeeeeǐeef      f   f   e0d<   g Zee0d<   dĐZeNadŐaeed   ef   e0d<   eSaeRaePaeQadada ey       Zdaee   e0d<   daee0d<   daee*   e0d<    et        t        ˫      adZdZdZda eec   e0d<   de^fd̈́Zd΄ ZdefdЄZddѐefd҄Zdӄ Zdee   dee   dee   dee   dee   dee'   fdڄZdۄ Zd܄ Z G d݄ dސeS      Z	 G d߄ d      Z
 e
       ad Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd ZdedefdZdedefdZdedefdZi fdefdZd Zd Z G d d      Zefj/                  d eVe      gdg      efj/                  d eVe      gdg       eVe      ddddddfdedee   dee   dee   dee   dee   dee   fd              Zefj3                  d eVe      gdg      efj3                  d eVe      gdg      efj3                  d eVe      gdg      efj3                  d eVe      gdgddd iie      d eVe      fde^de_dee   defd                            Zefj3                  d eVe      gdg      efj3                  d eVe      gdg      efj3                  d eVe      gdg      efj3                  d eVe      gdg      d eVe      fde^de_dee   defd	                            Zefj3                  d
 eVe      gendg      efj3                  d eVe      gendg      efj3                  d eVe      gendg      efj3                  d eVe      gendg      d eVe      fde^de_dee   defd                            Zefj3                  d eVe      gendg      efj3                  d eVe      gendg       eVe      fde^de_defd              Zefj3                  d eVe      gdg      efj3                  d eVe      gdg       eVe      fde^de_defd              Zefj3                  d eVe      gdg      efj3                  d eVe      gdg       eXd       eVe      fde^de_de`defd              Zd dl6mWZWm Z m!Z! d dlCm"Z" eijG                  d       eijG                  d!       e6j                  dd"#       eVe      fd$e ded%efd&              Z$efj/                  d' eVe      gd(g      efj/                  d) eVe      gd(g       eVe      fde^de_defd*              Z%efj3                  d' eVe      gd(g      efj3                  d) eVe      gd(g       eVe      fde^de_defd+              Z&efjO                  d, eVe      gd(g      efjO                  d- eVe      gd(g       eVe      fde^d.ede_defd/              Z(efj3                  d0 eVe      gd(g      efj3                  d1 eVe      gd(g       eVe      fde^de_defd2              Z)efj/                  d3 eVe      gd(g      efj/                  d4 eVe      gd(g       eVe      fde^d5ede_defd6              Z*efj3                  d7 eVe      gd(g      efj3                  d8 eVe      gd(g       eVe      fde^d5ede_defd9              Z+efj/                  d7 eVe      gd(g      efj/                  d8 eVe      gd(g       eVe      fde^d5ede_defd:              Z,efj3                  d; eVe      gd(g      efj3                  d< eVe      gd(g       eVe      fde^d5ede_defd=              Z-efj3                  d>d?g eVe      ge.@      de/fdA       Z0efj/                  dBd?g eVe      gC      defdD       Z1efj3                  dEd?g eVe      geM@      de2fdF       Z3dGee   dedee   dee   fdHZ4dGee@   dIe5dee   fdJZ6dKee   deDdedee   fdLZ7dMee8   deDdϐeǐeee   f   fdNZ9dOeee   ed   f   dedeDdϐeǐeee   f   fdPZ:dQe5deDdee   fdRZ;dededeDdKee   dee   f
dSZ<efj/                  dTdUdg eVe      gdV       eVe       e6j                  ddW#       e6j                  ddX#       e6j                  ddY#      dfdedee   dZee   d[ee   d\ee   f
d]       Z=efj/                  d^d_dgd eVe      g`       eVe      dddfdedaee   dbee   dcee   fdd       Z>efj/                  dedfdgd eVe      g`       eVe      dgddddfdedaee   dbee   dcee   dhee   diee   fdj       Z?efj/                  dkdldgd eVe      g`       eVe      dgddddfdedaee   dbee   dcee   dhee   diee   fdm       Z@efj/                  dndodgd eVe      g`       eVe      dddddfdedaee   dbee   dcee   dhee   diee   fdp       ZAdedϐefdqZBefj/                  drdg eVe      gC      efj/                  dsdg eVe      gC       eVe      dfdedtee   fdu              ZCdeDdvee   dwee   dee9   fdxZDefj/                  dydg eVe      gC       eVe      dfdedwee   fdz       ZEefj/                  d{d|dg eVe      gdV      d}        ZFefj/                  d~ddg eVe      gdV       eVe      fdefd       ZGefj3                  ddg eVe      gd      d eVe      fde^de_dee   defd       ZHeij/                  ddgd      de^fd       ZIefj3                  dd      de^fd       ZJeij/                  dd      dede^fd       ZKeij3                  dd      deLfd       ZMeij/                  dd      d        ZNefj3                  ddg eVe      geOd       eVe      fdePdefd       ZQefj/                  ddg eVe      geOd       eVe      fdedefd       ZRefj3                  ddg eVe      geOd       eVe      fdeSdefd       ZTefj3                  ddg eVe      geOd       eVe      fdeUdefd       ZVefj3                  ddg eVe      gd      deWfd       ZX	 efj3                  ddg eVe      gd       eVe      fdeYdefd       ZZefj/                  ddg eVe      ge[d       eVe      fdedefd       Z\efj/                  ddg eVe      gd       eVe      fded   dedee]   fd       Z^efj3                  ddg eVe      gd       eVe      fde_defd       Z`efj3                  ddg eVe      gd       eVe      fdeadefd       Zbefj/                  ddgd eVe      g      d        Zcefj/                  ddg eVe      gd      deWfd       Zdefj/                  dd eVe      g      d        Zeefj/                  d eVe      g      de^fd       Zfefj/                  d eVe      g      d        Zgeij                  ef       eij                  e       eij                  e       eij                  e       eij                  e       eij                  e«       eij                  e       eij                  e       eij                  e       eij                  e       eij                  e֫       eij                  eq       eij                  e       eij                  e       eij                  e       eij                  e       eij                  eԫ       eij                  eΫ       eij                  e       eij                  e       eij                  e߫       eij                  eݫ       eij                  e̫       eij                  e       eij                  e       eij                  e       eij                  eo       eij                  e       eij                  eȫ       eij                  e       eij                  e	       eij                  e       eij                  e       eij                  eƫ       eij                  e۫       eij                  e       eij                  ey       eij                  e       eijy                  eej       eij                  eg       y# e;$ rZ< e;de< d      dZ<[<ww xY w# eS$ r dbZRY :w xY w# eS$ r 	 d dl|Z|n# eS$ r Y nw xY wY w xY w# e;$ r dZY ~w xY w# 1 sw Y   xY w# 1 sw Y   ZxY w# e$ r Y &w xY w# eS$ r Y w xY w(      N)datetime	timedelta)TYPE_CHECKINGAnyListLiteralOptionalSetTupleUnioncastget_args
get_originget_type_hints)BASE_MCP_ROUTEDEFAULT_MAX_RECURSE_DEPTH DEFAULT_SLACK_ALERTING_THRESHOLD<LITELLM_EMBEDDING_PROVIDERS_SUPPORTING_INPUT_ARRAY_OF_TOKENS"LITELLM_SETTINGS_SAFE_DB_OVERRIDES)ModelResponseModelResponseStreamTextCompletionResponse)Span)OpenTelemetryc                 \    | d| d|j                    d|  d}||j                  |       y y )N:: 
)__name__write)messagecategoryfilenamelinenofilelinetraceback_infos          V/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/proxy_server.pyshowwarningr)   6   s>     z6("X->->,?r'"MN

>"     default)r"   messagesz../..)AsyncIOSchedulerzMissing dependency z$. Run `pip install 'litellm[proxy]'`)z%'The thing I wish you improved is...'z'A feature I really want is...'z*'The worst thing about this product is...'z$'This product would be better if...'z 'I don't like how this works...'z&'It would help me if you could add...'z/'This feature doesn't meet my needs because...'z&'I get frustrated when the product...'c                     d} t        j                  t              }t                t        dd| z  z   dz          t        dd| z  z   dz          t        ddj	                  |      z          t        ddj	                  d      z          t        dd| z  z   dz          t        dd| z  z   dz          t                t        d	       t                t                t                t        d
       t                t                y )N<   z[1;37m#-z#[0m z[1;37mz# {:^59} #[0mz-https://github.com/BerriAI/litellm/issues/newz/ Thank you for using LiteLLM! - Krrish & IshaanzR[1;31mGive Feedback / Get Help: https://github.com/BerriAI/litellm/issues/new[0m)randomchoicelist_of_messagesprintformat)	box_widthr!   s     r(   generate_feedback_boxr8   ^   s    I mm,-G	G	
sY
.
;<	
sY
.
;<	,,33G<
<=	

$
$%T
U	V 

sY
.
;<	
sY
.
;<	G	
;<	G	G	G	b 
G	Gr*   )defaultdict)asynccontextmanager)Routerverbose_proxy_loggerverbose_router_logger)	DualCache
RedisCache)	DAYS_IN_A_MONTHDEFAULT_HEALTH_CHECK_INTERVALDEFAULT_MODEL_CREATED_AT_TIMELITELLM_PROXY_ADMIN_NAME)PROMETHEUS_FALLBACK_STATS_SEND_TIME_HOURSPROXY_BATCH_POLLING_INTERVALPROXY_BATCH_WRITE_AT!PROXY_BUDGET_RESCHEDULER_MAX_TIME!PROXY_BUDGET_RESCHEDULER_MIN_TIME)RejectedRequestError)SlackAlerting)!_get_parent_otel_span_from_kwargs get_litellm_metadata_from_kwargs)CredentialAccessor)Logging)SensitiveDataMasker)AsyncHTTPHandlerHTTPHandlerrouter)app)global_mcp_tool_registry)*)ExperimentalUIJWTTokenget_team_objectlog_db_metrics)check_response_size_is_safe)
JWTHandler)LicenseCheck)get_all_fallbacksget_complete_model_listget_key_modelsget_mcp_server_idsget_team_models)user_api_key_authuser_api_key_auth_websocket)ProxyBaseLLMRequestProcessingcreate_streaming_response)initialize_callbacks_on_proxy)init_verbose_loggers)decrypt_value_helperencrypt_value_helper)	html_form)_read_request_bodycheck_file_size_under_limitget_form_data)!get_config_file_contents_from_gcsget_file_contents_from_s3)%remove_sensitive_info_from_deployment)
ProxyState)ResetBudgetJob)ERROR_RESPONSES)SpendLogCleanup)PrismaDBExceptionHandler)ui_discovery_endpoints_router)set_fine_tuning_config)init_guardrails_v2initialize_guardrails)perform_health_check)&_PROXY_VirtualKeyModelMaxBudgetLimiter)"_OPTIONAL_PromptInjectionDetection)_ProxyDBLogger)add_litellm_data_to_request)_user_has_admin_view)user_update)delete_verification_tokensduration_in_secondsgenerate_key_helper_fn)_add_model_to_db_add_team_model_to_db"_deduplicate_litellm_router_models)scim_router)update_teamvalidate_membership),get_disabled_non_admin_personal_key_creation)create_audit_log_for_update)PrometheusAuthMiddleware)set_files_config)passthrough_endpoint_router)!initialize_pass_through_endpoints)route_request)get_logging_payload)get_instance_fn)PrismaClientProxyLoggingProxyUpdateSpend_cache_user_row_get_docs_url_get_projected_spend_over_limit_get_redoc_url_is_projected_spend_over_limit_is_valid_team_configsget_custom_urlget_error_message_strget_server_root_pathhandle_exception_on_proxy
hash_tokenupdate_spend)AssistantsTypedDict
DeploymentLiteLLM_ParamsModelGroupInfo)FlowItem	Scheduler)load_aws_kms)load_google_kms)
get_secretget_secret_boolget_secret_strstr_to_bool)SlackAlertingArgs)AnthropicMessagesRequestAnthropicResponse!AnthropicResponseContentBlockTextAnthropicResponseUsageBlock)HttpxBinaryResponseContent)ModelGroupInfoProxy)DefaultTeamSSOParams#LiteLLM_UpperboundKeyGenerateParams)RealtimeQueryParams)DeploymentTypedDict)	ModelInfo)RouterGeneralSettingsupdateDeployment)DefaultPriorities)KeyManagementSettingsKeyManagementSystem)CredentialItemCustomHuggingfaceTokenizer)RawRequestTypedDictStandardLoggingPayload)-_add_custom_logger_callback_to_specific_event)versionz0.0.0T)r   )DependsFastAPIFileFormHeaderHTTPExceptionPathQueryRequestResponse
UploadFileapplicationsstatus)jsonable_encoder)CORSMiddlewareget_swagger_ui_html)get_openapi)FileResponseJSONResponseORJSONResponseRedirectResponseStreamingResponse)	APIRouter)OAuth2PasswordBearer)APIKeyHeader)StaticFiles)EnterpriseProxyConfigenterprise_proxy_configSERVER_ROOT_PATH premium_userEnterpriseLicenseDatapremium_user_data+LITELLM_GLOBAL_MAX_PARALLEL_REQUEST_RETRIES'global_max_parallel_request_retries_env   #global_max_parallel_request_retries1LITELLM_GLOBAL_MAX_PARALLEL_REQUEST_RETRY_TIMEOUT-global_max_parallel_request_retry_timeout_envg      N@)global_max_parallel_request_retry_timeout/ui/z/ui/model_hub_tableu(   👉 [```LiteLLM Admin Panel on /ui```](z). Create, Edit Keys with SSOuB   

💸 [```LiteLLM Model Cost Map```](https://models.litellm.ai/).u!   

🔎 [```LiteLLM Model Hub```](z^). See available models on the proxy. [**Docs**](https://docs.litellm.ai/docs/proxy/model_hub)zr[**Customize Swagger Docs**](https://docs.litellm.ai/docs/proxy/enterprise#swagger-docs---custom-routes--branding)
DOCS_TITLEzLiteLLM APIDOCS_DESCRIPTIONzJEnterprise Edition 

Proxy Server to call 100+ LLMs in the OpenAI format. 

z5Proxy Server to call 100+ LLMs in the OpenAI format. c                  0    d a d ad ad ad ad ad ad ad ad a	d a
y N)
master_keyuser_config_file_pathotel_logginguser_custom_authuser_custom_auth_pathuser_custom_key_generateuser_custom_sso"user_custom_ui_sso_sign_in_handleruse_background_health_checkshealth_check_intervalprisma_client r*   r(   cleanup_router_config_variablesr    sB     J L #O)-&#'  Mr*   c                  b  K   t        j                  d       t        r1t        j                  d       t        j	                          d {    t
        j                  &t
        j                  j	                          d {    t        j                          d {    t        t        j                          d {    dt
        j                  v r.	 ddlm}  | | j                  j                          t!                y t!                y 7 7 7 u7 U# t        $ r Y t!                y w xY ww)Nz"Shutting down LiteLLM Proxy ServerzDisconnecting from Prismalangfuser   langFuseLogger)r=   infor   debug
disconnectlitellmcachejwt_handlerclosedb_writer_clientsuccess_callbacklitellm.utilsr  Langfuseflush	Exceptionr  r  s    r(   proxy_shutdown_eventr     s     BC""#>?&&(((}} mm&&(((



#$$&&& W---	4)''--/ $%#%/ 	) 	) 	'  	 $%	sl   AD/
D5D/ DD/D!D/>D?D/"D 8D/D/D/D/	D,D/+D,,D/rU   c                  K   dd l }t                t        j                  dj	                  t
                     t
        du rt        j                         at        d      a	t        d      }t        d      }t        j                  d|       |`t        j                  j                  |      r`t        j                  |      rIt        j!                  t"        |	       d {   \  aaan |t)        |t*              r]t        j                  j                  |      r>t        j                  |      r(t        j!                  t"        |	       d {   \  aaant        j,                  j/                  d
      8t)        |t*              r(t        j!                  t"        |	       d {   \  aaanYt)        |t0              rt3        di | d {    n5 |j4                  |      }t)        |t0              rt3        di | d {    t6        4t        dd       }t8        j;                  |t<        t>               d {   at8        jA                  t"        t<        tB               t8        jE                  t&        t6        t>               tF        rtI        jJ                  tM                      tN        tN        jQ                  t"               t        j                  dt6               t6        -tR        jT                  dkD  rt8        jW                  tX               t6        Wt8        j[                  t&        t6        t\        t^        t`        t<               d {    t8        jc                          d {    t8        je                          d  tg                d {    y 7 7 X7 7 7 7 u7 ^7 D7 w)Nr   zElitellm.proxy.proxy_server.py::startup() - CHECKING PREMIUM USER - {}FLITELLM_MASTER_KEYWORKER_CONFIGCONFIG_FILE_PATHzworker_config: %sconfig_file_pathrT   r  LITELLM_CONFIG_BUCKET_NAMEDATABASE_URL)database_urlproxy_logging_objuser_api_key_cache)
llm_routerr  redis_usage_cache)general_settingsr   r  rS   zprisma_client: %s)litellm_proxy_budget_name)r"  r   !proxy_budget_rescheduler_min_time!proxy_budget_rescheduler_max_timeproxy_batch_write_atr  r   )4jsonrh   r=   r  r6   r   _license_check
is_premiumr   r   r   ospathisfileproxy_configis_yamlload_configr   llm_model_listr"  
isinstancestrenvirongetdict
initializeloadsr   ProxyStartupEvent_setup_prisma_clientr  r  _initialize_startup_loggingr!  _initialize_jwt_authr   asynciocreate_task_run_background_health_checkprompt_injection_detection_objupdate_environmentr	  
max_budget_add_proxy_budget_to_dblitellm_proxy_admin_name$initialize_scheduled_background_jobsr$  r%  r&  "_update_default_team_member_budget_init_dd_tracerr  )rU   r'  worker_configenv_config_yaml_db_urls        r(   proxy_startup_eventrJ    sS     OVV	

 u%002   45J0:?0KM%34F%GO2MB"77>>/*|/C/C, 0D 0
 #..!O /  	  
	"}c*}-$$m$D #..!M /  	  ZZ^^89E*3K
 #..!M /  	  t,-}--- 'DJJ}5M-. 1=111 !+ND!A/DD /1 E 
 
 11++ 2  **)#- +  $(*	
 &1&999L2MB W%7%7!%;11&> 	2 	

  DD-'.O.O!5/ E 
 	
 	
  BBDDD %%' 
 
   u .
 2

F	
 	E !s   C!O#N)$A0ON,AO+N/,'ON25O	N5
9ON8DON;O8N=9*O#N?$O,O/O2O5O8O;O=O?O)docs_url	redoc_urltitledescriptionr   	root_pathlifespan)APIWebSocketRoutec            	         t         j                  rt         j                  S t        t         j                  t         j                  t         j
                  t         j                        } t         j                  D cg c]  }t        |t              s| }}|D ]  }|j                  j                  d      d   j                  d      }g }t        |d      rG|j                  j                  D ].  }|j                  |j                   d|j"                  ddid	       0 d
d|j                   xs | dd|j                   xs |j%                  dd       |dddiidgdi| d   |<    | t         _        t         j                  S c c}w )N)rM  r   rN  routes{r   ?	dependantquerytypestring)nameinrequiredschemar4  zWebSocket: zWebSocket connection endpoint
websocket_/_101rN  zWebSocket Protocol Switched	WebSocket)summaryrN  operationId
parameters	responsestagspaths)rU   openapi_schemar   rM  r   rN  rS  r1  rQ  r+  splitrstriphasattrrV  query_paramsappendrZ  r\  replace)ri  routewebsocket_routes	base_pathre  params         r(   get_openapi_schemart    sq   
!!! iiOOzz	N ::E;L)M 
 "JJ$$S)!,33C8	 
5+&55!! %

%$)NN"H#		 6 ()@y(AB>!+EJJ,U):K:KCQT:U+VW(#m5R%ST$	.
w	*' "< (CIs   :FFc                  0   t         j                  rt         j                  S t               } t        j                  j
                  }i }|D ]  }|| d   v s| d   |   ||<    || d<   ddlm} |j                  |       } | t         _        t         j                  S )Nrh  r   )CustomOpenAPISpec)	rU   ri  rt  LiteLLMRoutesopenai_routesvalue.litellm.proxy.common_utils.custom_openapi_specrv  add_llm_api_request_schema_body)ri  rx  paths_to_includerp  rv  s        r(   custom_openapir}    s    
!!!')N "//55MN7++&4W&=e&DU#  /N7 Q&FF~VN'Cr*   DOCS_FILTEREDFalseTruec                       e Zd ZdZy)UserAPIKeyCacheTTLEnumr/   N)r   
__module____qualname__in_memory_cache_ttlr   r*   r(   r  r    s    r*   r  requestexcc           	         K   |j                   }t        |j                  rt        |j                        nt        j
                  d|j                  |j                  |j                  |j                  di|      S w)Nerrorr!   rX  rs  code)status_codecontentheaders)	r  r   r  intr   HTTP_500_INTERNAL_SERVER_ERRORr!   rX  rs  )r  r  r  s      r(   openai_exception_handlerr    sg      kkG XXCM6+P+P ;;	
  s   A9A;rW   _experimentaloutz/litellm-asset-prefixr_  )	z.pngz.jpgz.jpegz.gifz.icoz.woffz.woff2z.ttfz.eotrzutf-8)encodingz&/litellm/.well-known/litellm-ui-configz/.well-known/litellm-ui-configwz/_next_next	directorynext_staticrZ  z/ui)r  htmluiz.htmlz
index.html)exist_ok)allow_originsallow_credentialsallow_methodsallow_headersc                     t         j                  j                  t        d      } t        dnt        }|j                  d      s|dz   }|dz   t        j                  dt        |       d       fd}|t        _
        y )Nswaggerr_  z/swaggerr  r  c                  8    t        | i | d d ddS )Nz/swagger-ui-bundle.jsz/swagger-ui.cssz/favicon.png)swagger_js_urlswagger_css_urlswagger_favicon_urlr   )argskwargscustom_root_path_swagger_paths     r(   swagger_monkey_patchz.mount_swagger_ui.<locals>.swagger_monkey_patch|  sD    "

 <<<QR<=_M#@"A N
 	
r*   )r*  r+  joincurrent_dirserver_root_pathendswithrU   mountr   r   r   )swagger_directoryswagger_pathr  r  s      @r(   mount_swagger_uir  s  so    [)<*238HL  %#c)$09$<!IIj+0ABIS
 (<L$r*   )DictFr   r   r0  r"  callback_settingszapi_log.jsonr   r   )default_in_memory_ttl)
dual_cacher!  health_check_resultsqueuezlitellm-proxy-budgetall)adminr  ui_access_moder?  store_model_in_dbopen_telemetry_logger)r  r   r  c                 L  K   t        j                          }t        j                          |z
  dk  rnt        j                  d       d{    | j                          d{   r|j	                          t        dd      t        j                          |z
  dk  rmyy7 V7 @w)am  
    Asynchronously checks if the request is disconnected at regular intervals.
    If the request is disconnected
    - cancel the litellm.router task
    - raises an HTTPException with status code 499 and detail "Client disconnected the request".

    Parameters:
    - request: Request: The request object to check for disconnection.
    Returns:
    - None
    X     Ni  zClient disconnected the requestr  detail)timer<  sleepis_disconnectedcancelr   )r  llm_api_call_task
start_times      r(   check_request_disconnectionr    s      J
))+

"S
(mmA((*** $$&8  ))+

"S
(*s*   AB$	B 
B$!B"";B$B$"B$c                     ddl m} t        |       }|t        u r!t	        |       D ]  }t        ||      s|c S  yt        | t              rt        | t              r| S y)CResolve the actual TypedDict class from a potentially wrapped type.r   )_TypedDictMetaN)typing_extensionsr  r   r   r   r1  rX  r5  )typr  originargs       r(   _resolve_typed_dict_typer    sT    0_FC=C#~.
 !
  
C	:c4#8
r*   returnc                 
   t        |       }g }|t        u rJt        |       D ]:  }|t        |t	        d            rdt        |      vs*|j                  |       < |S t        | t              rt        | t              r| gS |S )r  NNoneType)r   r   r   r1  rX  r2  rn  	BaseModel)r  r  typsr  s       r(   _resolve_pydantic_typer    sx    _FDC=C"3T
3c#h.C  ! K 
C	:c9#=uKr*   use_azure_key_vaultc                 F   | du ry 	 ddl m} ddlm} t	        j
                  dd       }|t        d       |       } |||      }|t        _        t        j                  t        _        y # t        $ r+}t        |      }t        j                  d|       Y d }~y d }~ww xY w)	NFr   )DefaultAzureCredential)SecretClientAZURE_KEY_VAULT_URIzMError when loading keys from Azure Key Vault: AZURE_KEY_VAULT_URI is not set.)	vault_url
credentialztError when loading keys from Azure Key Vault: %s .Ensure you run `pip install azure-identity azure-keyvault-secrets`)azure.identityr  azure.keyvault.secretsr  r*  getenvr  r	  secret_manager_clientr   AZURE_KEY_VAULT_key_management_systemr2  r=   	exception)r  r  r  KVUrir  cliente
_error_strs           r(   load_from_azure_key_vaultr    s    e#
97 		/6=_  ,-
 *E(.%)<)L)L& 
V
&& C	
 	

s   A$A, ,	B 5!BB c                  `    t         (t        j                  j                  t	                      y y r   )r   r	  logging_callback_manageradd_litellm_callbackr~   r   r*   r(   cost_trackingr  *  s$     ((==n>NO !r*   tokenuser_idend_user_idteam_idresponse_costparent_otel_spanc                 `  
K   g 
dt         dt        f
fd}
fd}
fd}
fd}	|  ||        d{     |        d{     |        d{     |	        d{    t        j                  t        j                  
d	|
             y7 c7 T7 E7 6w)z`
    Use this to update the cache with new user spend.

    Put any alerting logic in here.
    r  r  c           
        K   t        | t              r| j                  d      rt        |       }n| }t	        j
                  d|       t        j                  |       d {   }t	        j
                  d|        |y |j                  }||z   }|j                  du r|j                  t        ||j                  d         d	u rt        ||j                  j                  dd             \  }}|j                  j                  dt        d
            }t        |j                   xs d||j"                  ||j$                  ||t&        j(                        }	t+        j,                  t.        j1                  d|	             |'t3        |dd       |j4                  xs d}
|
|z   |_        |'t3        |dd       |j6                  xs d}||z   |_        ||_        j9                  ||f       y 7 w)Nzsk-r  z"_update_key_cache: hashed_token=%skeyz&_update_key_cache: existing_spend_obj=Fsoft_budget)current_spendsoft_budget_limitTinfr   )r  spend	key_aliasrA  r  projected_spendprojected_exceeded_dateevent_groupprojected_limit_exceeded)rX  	user_info
team_spendr   team_member_spend)r1  r2  
startswithr   r=   r  r  async_get_cacher   soft_budget_cooldownlitellm_budget_tabler   r   r4  floatCallInfor  r  r  Litellm_EntityTypeKEYr<  r=  r  budget_alertsgetattrr  r  rn  )r  r  hashed_tokenexisting_spend_objexisting_spend	new_spendr  r  
soft_limit	call_infoexisting_team_spendexisting_team_member_spendvalues_to_update_in_caches               r(   _update_key_cachez'update_cache.<locals>._update_key_cacheA  s&    eS!e&6&6u&=%E2L L""#GVBTBdBdiuBdBv<v""45G4HI	
 %/55N"]2	 33u<"77C."+&8&M&M%'  8W'"4"I"I"M"M!4#84O4 ,@@DDuU|J !(..4",66%*22 /(?.22	I !//3' 0  **L$?K"4"?"?"D1,?-,O) **,?FR);)M)M)RQR& +]: 0
 $- !((,8J)KLS =ws   A G6#G3$FG6c                     K   	g} 	 | D ]  }|t         j                  |       d {   }| y t        j                  d| d        t	        |t
              r|d   }n|j                  }|z   }t	        |t
              r||d<   
j                  ||f       ||_        
j                  ||j                         f        t         j                  dj                  t                     d {   }|y /|,|z   }
j                  dj                  t              |f       y y y 7 7 <# t        $ r@}t        j                  dt        |       dt        j                                 Y d }~y d }~ww xY ww)Nr  z!_update_user_db: existing spend: ; response_cost: r   z{}:spendz'An error occurred updating user cache: r   )r  r
  r=   r  r1  r5  r   rn  r'  r6   rC  r  r2  	traceback
format_exc)user_ids_idr  r  r  global_proxy_spend	incrementr  r  r  r  s           r(   _update_user_cachez(update_cache.<locals>._update_user_cache  s    9*	;+=+M+MRU+M+V%V"%-$**78J7KK\]j\kl 0$7%7%@N%7%=%=N*]:	 0$72;&w/-44c;M5NO/8&,-44c;M;R;R;T5UV3  6 (:'I'I%%&>? (J ( " ")*/A/M.>	)00&&'?@)L 0N*; &W."  	 &&9#a&iFZFZF\E]^ 	sg   E>!D2 D-D2 E>CD2 3D04D2 :E>;/D2 *E>-D2 0D2 2	E;;6E61E>6E;;E>c                     K   y dj                        } 	 t        j                  |        d {   }|y t        j                  d| d        |d}n"t        |t              r|d   }n|j                  }|z   }t        |t              r||d<   j                  | |f       y ||_        j                  | |j                         f       y 7 # t        $ r+}t        j                  dt        |              Y d }~y d }~ww xY ww)Nzend_user_id:{}r  z%_update_end_user_db: existing spend: r  r   r   +An error occurred updating end user cache: )r6   r  r
  r=   r  r1  r5  r   rn  r'  r  r  r2  )r"  r  r  r  r  r  r  r  s        r(   _update_end_user_cachez,update_cache.<locals>._update_end_user_cache  s0    -"7%%k2	'9'I'Ic'I'R!R!)  &&78J7KK\]j\kl ")!"0$7%7%@N%7%=%=N&6I ,d3.7"7+)00#7I1JK+4"()00#7I7N7N7P1QR1 "S2  	 **=c!fXF 	sU   DC CC DA/C +D,(C DC 	D !DDDDc                    K   y dj                        } 	 t        j                  |        d {   }|y t        j                  d| d        |d}n"t        |t              r|d   }n|j                  }|d}|z   }t        |t              r||d<   j                  | |f       y ||_        j                  | |f       y 7 # t        $ r+}t        j                  dt        |              Y d }~y d }~ww xY ww)Nz
team_id:{}r  z!_update_team_db: existing spend: r  g        r   r'  )r6   r  r
  r=   r  r1  r5  r   rn  r  r  r2  )r"  r  r  r  r  r  r  r  s        r(   _update_team_cachez(update_cache.<locals>._update_team_cache  s5    ?m3!!'*"	 )88S8AA  ") &&34F3GGXYfXgh ")250$7%7%@N%7%=%=N%!$&6I ,d3.7"7+)00#7I1JK+4"()00#7I1JK7 B8  	 **=c!fXF 	sU   DC CC DA3C /D0C 
DC 	D!C<7D<DDN)r  r  r/   )
cache_listttllitellm_parent_otel_span)r2  r  r<  r=  r  async_set_cache_pipeline)r  r  r  r  r  r  r  r%  r(  r*  r  s    ````     @r(   update_cacher/  0  s      8:PMs PM5 PMf-`#L'R ]6e=III """$&&& """330%5 	4 	
 	J 	# 	' 	#sG   ;B.B&B.B(B.$B*%B.5B,61B.(B.*B.,B.c                      	 ddg} t        t        j                  d      5 }t        j                  | ||       d d d        y # 1 sw Y   y xY w# t
        $ r#}t        j                  d| d       Y d }~y d }~ww xY w)Nollamaserver  )stdoutstderrzd
            LiteLLM Warning: proxy started with `ollama` model
`ollama serve` failed with Exceptionz). 
Ensure you run `ollama serve`
        )openr*  devnull
subprocessPopenr  r=   r  )commandr6  r  s      r(   run_ollama_server:  (  s    

W%"**c" 	FgWWWE	F 	F 	F 
""eefdg h		
 	

s3   A AA AA A 	A:A55A:c                  ~  K   t         t        t         t              r	t         dk  ry	 t        j                  t
              xs g } t        | t               d{   \  }}|t        d<   |t        d<   t        |      t        d<   t        |      t        d<   t        j                  t                d{    7 _7 w)z}
    Periodically run health checks in the background on the endpoints.

    Update health_check_results, based on this.
    Nr   )
model_listdetailshealthy_endpointsunhealthy_endpointshealthy_countunhealthy_count)r   r1  r  copydeepcopyr0  r{   health_check_detailsr  lenr<  r  )_llm_model_listr>  r?  s      r(   r>  r>  6  s      	%/5 A%
--7=27K&0D8
 2
..
 5F016I23034E0F_-256I2J./mm1222 2
 	3s%   AB=B9AB=3B;4B=;B=c                       e Zd Zy)StreamingCallbackErrorN)r   r  r  r   r*   r(   rH  rH  V  s    r*   rH  c            	          e Zd ZdZdLdZdedefdZdedefdZ		 dMde
e   defd	Zd
ededefdZdefdZdefd
edededefdZdedee   defdZdefdZdefdZdMde
e   defdZd
efdZd Zd
edee   fdZd
efdZde
ej:                     defdZd
efd Zd!efd"Z d#e
e   fd$Z!dNde"fd%Z#d&e$defd'Z%d&e$defd(Z&d)e$de$fd*Z'd)e$d+e(fd,Z)d-eddfd.Z*	 dMd/ed0e
e   defd1Z+d/edefd2Z,d-ed3e
e   d4e
e-   ddfd5Z.d-ed!ed+e(ddfd6Z/d7e
e0   fd8Z1d9ed:e2d;   d<e3defd=Z4d4e-d
ed>e
e   fd?Z5d4e-de$fd@Z6d4e-d+e(fdAZ7d4e-fdBZ8d4e-fdCZ9d4e-fdDZ:dE Z;dF Z<dGe=ee>f   defdHZ?dIee   fdJZ@d4e-fdKZAy)OProxyConfigz}
    Abstraction class on top of config loading/updating logic. Gives us one place to control all config updating logic.
    r  Nc                     i | _         y r   config)selfs    r(   __init__zProxyConfig.__init___  s	    &(r*   r  c                     t         j                  j                  |      syt         j                  j                  |      \  }}|j	                         dk(  xs |j	                         dk(  S )NFz.yamlz.yml)r*  r+  r,  splitextlower)rN  r  r`  file_extensions       r(   r.  zProxyConfig.is_yamlb  sW    ww~~./GG,,-=>>##%0TN4H4H4Jf4TTr*   	file_pathc           	          	 t        |d      5 }t        j                  |      xs i cddd       S # 1 sw Y   yxY w# t        $ r}t        d| dt	        |             d}~ww xY w)z,
        Load and parse a YAML file
        r  NzError loading yaml file r   )r5  yaml	safe_loadr  r2  )rN  rT  r%   r  s       r(   _load_yaml_filezProxyConfig._load_yaml_filei  sh    	Ni% 2~~d+1r2 2 2 	N6ykCF8LMM	Ns)   = 1	= := = 	A%A  A%c           	        K   |xs t         }||a t        j                  j                  |       r,t	        | d      5 }t        j                  |      }ddd       n|t        d|       g i i i d}t        d      | j                  |t        j                  j                  t        j                  j                  |xs d                  }|S # 1 sw Y   ixY ww)z
        Given a config file path, load the config from the file.
        Args:
            config_file_path (str): path to the config file
        Returns:
            dict: config
        Nr  zConfig file not found: )r<  r"  router_settingslitellm_settingszConfig cannot be None or Empty.r   )rM  base_dir)r   r*  r+  existsr5  rV  rW  r  _process_includesdirnameabspath)rN  r  rT  config_filerM  s        r(   _get_config_from_filez!ProxyConfig._get_config_from_files  s      %=(=	'$4! 77>>YK)c* 5k45 5"5i[ABB !$&#%$&	F >=>>''BGGOOBGGOOIOQS4T$U ( 

 )5 5s   <C CB C CC rM  r\  c                    d|vr|S t        |d   t              st        d      |d   D ]  }t        j                  j                  ||      }t        j                  j                  |      st        d|       | j                  |      }|j                         D ]3  \  }}t        |t              r||v r||   j                  |       /|||<   5  |d= |S )au  
        Process includes by appending their contents to the main config

        Handles nested config.yamls with `include` section

        Example config: This will get the contents from files in `include` and append it
        ```yaml
        include:
            - model_config.yaml

        litellm_settings:
            callbacks: ["prometheus"]
        ```
        includez&'include' must be a list of file pathszIncluded file not found: )r1  list
ValueErrorr*  r+  r  r]  FileNotFoundErrorrX  itemsextend)rN  rM  r\  include_filerT  included_configr  ry  s           r(   r^  zProxyConfig._process_includes  s     F"M&+T2EFF #9-LX|<I77>>),'*CI;(OPP"229=O-335
UeT*sf}3K&&u-"'F3K	 6 . 9r*   
new_configc                 :  K   	 t         Pt        j                  dd      du st        r2|j	                  dd        t         j                  |d       d {    y t        t         d      5 }t        j                  ||d       d d d        y 7 8# 1 sw Y   y xY ww)	Nr  FTr<  rM  )data
table_namer  )default_flow_style)
r   r"  r4  r  popinsert_datar5  r   rV  dump)rN  rl  ra  s      r(   save_configzProxyConfig.save_config  s     	
 $  !4e<D  NN<.+++QQQ ./#6 M+		*keLM M	 RM Ms*   ABBB+B
BBBr   depth	max_depthc                    ||kD  rt        j                  d| d       |S |j                         D ]  \  }}t        |t              r| j                  ||dz   |      ||<   1t        |t              r0|D ]*  }t        |t              s| j                  ||dz   |      }, qt        |t              s|j                  d      st        |      ||<    |S )a  
        Check for os.environ/ variables in the config and replace them with the actual values.
        Includes a depth limit to prevent infinite recursion.

        Args:
            config (dict): The configuration dictionary to process.
            depth (int): Current recursion depth.
            max_depth (int): Maximum allowed recursion depth.

        Returns:
            dict: Processed configuration dictionary.
        zMaximum recursion depth (z") reached while processing config.r  )rM  ru  rv  os.environ/)
r=   warningrh  r1  r5  _check_for_os_environ_varsre  r2  r	  r   )rN  rM  ru  rv  r  ry  items          r(   rz  z&ProxyConfig._check_for_os_environ_vars  s     9 ((+I;6XY M ,,.JC%&"== 	Y > s E4(!D!$-#>>#'uqyI  ?   " E3'E,<,<],K(/s ) r*   r  all_teams_configc                    i }|D ]3  }d|vr!t        dt        j                  |             ||d   k(  s1|} n |j                         D ]6  \  }}t	        |t
              s|j                  d      s)t        |      ||<   8 |S )Nr  zteam_id missing from team: rx  )r  SENSITIVE_DATA_MASKER	mask_dictrh  r1  r2  r	  r   )rN  r  r|  team_configteamkvs          r(   _get_team_configzProxyConfig._get_team_config  s    $D$12G2Q2QRV2W1XY  $y/)" %  %%'DAq!S!all=&A!+AA ( r*   c                     | j                         }|j                  di       }|j                  dd      }|i S | j                  ||      }|S )z^
        - for a given team id
        - return the relevant completion() call params
        r[  default_team_settingsN)r  r|  )get_config_stater4  r  )rN  r  rM  r[  r|  r  s         r(   load_team_configzProxyConfig.load_team_config  sh     &&( "::&8"=+//0GN#I++.> , 
 r*   cache_paramsc                 "   ddl m} d|v r|d   t         _        d|v r|d   t         _         |di |t         _        t         j                  Dt        t         j                  j                  t              rt         j                  j                  ay y y )Nr   Cacher  default_redis_ttlr   )r	  r  r  r  r
  r1  r@   r!  )rN  r  r  s      r(   _init_cachezProxyConfig._init_cache   sx    
 	""l2,89P,QG),.(45H(IG%--==$GMM4G4G)T ' 3 3 *U$r*   c                   K   t         j                  j                  d      t         j                  j                  d      }t         j                  j                  d      }t         j                  j                  d      }t        j                  d||       |dk(  rt        ||       d{   }nt        ||      }|%t        d      | j                  |	       d{   }t        ,t        d
u r$| j                  |t        t               d{   }t        j                  |      }|j                  dd       | j                  |      }| j!                  |       |S 7 7 7 Uw)a  
        Load config file
        Supports reading from:
        - .yaml file paths
        - LiteLLM connected DB
        - GCS
        - S3

        Args:
            config_file_path (str): path to the config file
        Returns:
            dict: config

        r  N LITELLM_CONFIG_BUCKET_OBJECT_KEYLITELLM_CONFIG_BUCKET_TYPEzbucket_name: %s, object_key: %sgcs)bucket_name
object_keyz(Unable to load config from given source.r  T)rM  r   r  environment_variablesrL  )r*  r3  r4  r=   r  ro   rp   r  rb  r   r  _update_config_from_dbrB  rC  rq  rz  update_config_state)rN  r  r  r  bucket_typerM  printed_yamls          r(   
get_configzProxyConfig.get_config3  sR    $ ::>>67C**..)EFK(JKJ**..)EFK &&1;
 e#@ +
   3 +
 ~ JKK  55GW5XXF$):d)B66+"3 7  F }}V,0$7000?   /9 Ys7   B)E*+E$,4E* E&!1E*E(AE*&E*(E*c                     || _         y r   rL  )rN  rM  s     r(   r  zProxyConfig.update_config_statek  s	    r*   c                     	 t        j                  | j                        S # t        $ r;}t	        j
                  dj                  | j                  |             i cY d}~S d}~ww xY w)z
        Returns a deep copy of the config,

        Do this, to avoid mutating the config state outside of allowed methods
        z^ProxyConfig:get_config_state(): Error returning copy of config state. self.config={}
Error: {}N)rB  rC  rM  r  r=   r  r6   )rN  r  s     r(   r  zProxyConfig.get_config_staten  sV    	==-- 	 &&qxxKK
 I	s   ! 	A%0A A% A%c                 j    |j                  d      }g }|r|D cg c]  }t        di | }}|S c c}w )z<
        Load the credential list from the database
        credential_listr   )r4  r   )rN  rM  credential_list_dictr  creds        r(   load_credential_listz ProxyConfig.load_credential_list~  sC      &zz*;<BVW$~55WOW Xs   0c                    |j                  dd       }|r|j                         D ]e  \  }}t        |t              r4|j	                  d      r#t        |      }|6|t        j                  |<   Jt        |      t        j                  |<   g d|v r3t        j                  dd       t        _
        t        j                         ay )Nr  rx  )secret_nameLITELLM_LICENSE)r4  rh  r1  r2  r	  r   r*  r3  r  r(  license_strr)  r   )rN  rM  r  r  ry  resolved_secret_strings         r(   _load_environment_variablesz'ProxyConfig._load_environment_variables  s     !'

+BD I 399;
U eS)e.>.>}.M<J$)=* .9*@

3 '*%jBJJsO- <2 !$99-/YY7H$-O*-88:r*   rT   c                 (  K   | j                  |       d{   }| j                  |       |j                  dd      a|j                  dd      }|i }|rd}d}|j	                         D ]x  \  }}|dk(  r|d	u rt        | d
       ddlm}	 i }
d|v r|d   }|
j                  |       |
j                  dd      }t        j                  d|       |dk(  s|dk(  rt        |
j                               dk(  rt        dd      }t        dd      }d}|
j                  |||d       t        dd      t        dd      }|
j                  d|i       t        j                  d|||       t        j                  d|||       t        j                  d|||       t        j                  d|||       |
j	                         D ]6  \  }}t        |t              s|j!                  d      s)t        |      |
|<   8 | j#                  |
       t$        j&                  t        j                  | d|        |dk(  r|du r|dk(  r t)        |t*        ||       }|t$        _        |d!k(  rt/        |t*        ||"       |d#k(  rdd$lm}  |d{i |t$        _        ;|d%k(  r?t7        ||&      gt$        _        t        j                  d't$        j8                          |d(k(  rt;        |      t$        _        |d)k(  rAt;        |      t$        _        t$        j<                  t$        j>                  t$        _        |d*k(  r<dd+l m!} |D cg c]  }|d,   t7        |d-   |&      d. c}t$        _"         |        !|d/k(  rg t$        _#        |D ]  }d0|v r*t$        jH                  jK                  t7        |1             1t$        jH                  jK                  |       d2|v sU	 dd3l&m'} |_t        j                  d4       |jS                  t*                t        | d5t$        jF                   d6|        |d7k(  rg t$        _*        |D ]O  }d0|v r*t$        jH                  jW                  t7        |1             1t$        jH                  jW                  |       Q t        | d8t$        jT                   d6|        h|dk(  ro|d9k(  rQtY        |      D ]  \  }}	 t[        d{i |  t        j                  | d<| d=| |        ta        t$        ||       |d>k(  r|ot        |t\              r_|j	                         D ]6  \  }}t        |t              s|j!                  d      s)t        |      ||<   8 tc        d{i |t$        _2        ;tQ        d?|       t        j                  | d<| d=| |        ta        t$        ||       { |j                  d@i       }|i }|r|j                  dAd      }| jg                  |B       |j                  dCd      }|ti        d{i |t$        _5        |j                  dDd      }tm        |E       |j                  dFd      }to        |G       | jq                  |H       |j                  dId      }|rG|j!                  d      r6t        j                  dJ       t        |      }t        j                  dK|       |j                  dLt        dMd            a9tr        r$tr        j!                  d      rt        tr              a9tr        #t        tr        t              rtu        tr              a;|j                  dNd      } |  tx        j{                  t;        |       dO       |j                  dPd      a>t|        da>|j                  dQd      }!|!t7        |!|&      a?|j                  dRd      }"|"t7        |"|&      a@|j                  dSd      }#|#t7        |#|&      aA|j                  dTd      }$|$t7        |$|&      aBt        t        j                  |       d{    |j                  dUd      t        |dU   V       d{    |j                  dWdX      aF|j                  dYd      }%|%t*        du rt        dZ      |j                  d[t              aH|j                  d\t              aI|j                  d]t              aJ|j                  d^t              aK|j                  d_t              aL|j                  d`d      aM|j                  dat              aO|j                  dbd	      aP|j                  dcd      }&|&|&D 'cg c]  }'t        d{i |' c}'|dc<   |j                  dd      .t*        d	ur&t        det        j                  j                  z         df|v r"|df   t        _V        t        j                         adgt$        j&                  dui}(|j                  dhd      })|)r|)|(dh<   t        di       |)D ]  }*|*dj   j	                         D ]9  \  }+},t        |,t              s|,j!                  d      s)t        |,      |*dj   |+<   ; t        dk|*j                  dldm       d       |*dj   dn   }-|*dj   j                  dod      }.dp|-v s|.t                 d}/|j                  dqd      }0|0rx|0dj   j	                         D ]W  \  }+},t        |,t              s|,j!                  d      s)|,j                  ddm      }t        j                  |      },|,|0dj   |+<   Y t        d{i |0}/|j                  drd      }1t        |1       |j                  dsd      }2t        |2       |j                  dtd      }3t        j                  |3       |j                  dud      }4|4rwt        |4t\              rgt        j                  t$        j                        }5dvdhh}6|5j                  D 7cg c]	  }7|7|6vs|7 }8}7|4j	                         D ]  \  }+},|+|8v s|,|(|+<    t%        j                  d{i |(|/t        d	w      d	dx}t        ,|j&                  j                  |j                  t        y       d}9||j                  dd      }9|9rt        |9|z       | j                  |      }:|:t$        _k        | j                  |       ||j                         |fS 7 c c}w # tP        $ r d}Y 	+w xY w# tP        $ rJ t        |t\              rtQ        d:| d;|j                                tQ        d:| d;t_        |             w xY w7 +7 c c}'w c c}7w w)|z<
        Load config values into proxy global state
        r  NrL  r  r[  z[94mz[0mr
  Tz
Setting Cache on Proxyr   r  r  rX  rediszpassed cache type=%szredis-semantic
REDIS_HOST
REDIS_PORT)rX  hostportREDIS_PASSWORDpasswordz%sCache Type:%s %sz%sCache Host:%s %sz%sCache Port:%s %sz%sCache Password:%s %srx  )r  zSet Cache on LiteLLM ProxyF
guardrails)guardrails_configr   r  r[  	callbacks)ry  r   r  r[  model_group_settings)ModelGroupSettingspost_call_rules)ry  r  zlitellm.post_call_rules: max_internal_user_budget default_max_internal_user_budgetcustom_provider_map)custom_llm_setupprovidercustom_handler)r  r  r  .ry  
prometheusPrometheusLoggerzmounting metrics endpointz! Initialized Success Callbacks - r1   failure_callbackz! Initialized Failure Callbacks - r  z4team_id missing from default_team_settings at index=z
passed in value=z setting litellm.=upperbound_key_generate_paramsz=Invalid value set for upperbound_key_generate_params - value=r"  key_management_system)r  key_management_settingsuse_google_kmsr  r  r  )r"  r  zGOING INTO LITELLM.GET_SECRET!zRETRIEVED DB URL: %sr   r  user_api_key_cache_ttl)r  r  r  custom_authcustom_key_generate
custom_ssocustom_ui_sso_sign_in_handlerpass_through_endpointsr  r  r  allowed_ipsz\allowed_ips is an Enterprise Feature. Please add a valid LITELLM_LICENSE to your envionment.r$  r%  proxy_batch_polling_intervalr&  disable_spend_logsbackground_health_checksr   rD  role_permissionsenforced_paramszTrying to use `enforced_params`litellm_licensecache_responsesr<  z<[32mLiteLLM: Proxy initialized with Config, Set models:[0mlitellm_paramsz	[32m    
model_namer   modelapi_baser1  assistant_settingsfinetune_settingsfiles_settingsdefault_vertex_configrZ  rN  async_only_mode)assistants_configrouter_general_settingsignore_invalid_deployments)r
  )all_guardrailsr  r   )nr  r  r4  r  rh  r5   litellm.caching.cachingr  updater=   r  rE  keysr   r1  r2  r	  r  r	  r
  rz   r   guardrail_name_config_maprg   litellm.types.routerr  r  r   r  r  r  r  r  r  r  r  r  add_litellm_success_callback*litellm_enterprise.integrations.prometheusr  r  _mount_metrics_endpointr  add_litellm_failure_callback	enumerateTeamDefaultSettingsr5  rX  setattrr   r  initialize_secret_managerr   _key_management_settingsr   r  _load_alerting_settingsr   r   litellm_master_key_hashr  update_cache_ttlr  r   r   r   r   r   load_enterprise_configr   r  rf  r$  r%  r  r&  r  r   rB   r   rD  RoleBasedPermissionsCommonProxyErrorsnot_premium_userry  r(  r  r)  r:  ro  r*  r  r   rx   r   r   set_default_vertex_configinspectgetfullargspecr;   r  r   r!  redis_cache_update_redis_cachery   r  r  _init_non_llm_configsget_model_list);rN  rT   r  rM  r[  blue_color_codereset_color_coder  ry  r  r  cache_params_in_config
cache_type
cache_host
cache_portcache_passwordr  r  r  r{  callbackr  idxteam_setting_k_vr"  r  r  r  r  r  r  r  r  r  r  r  rbac_role_permissionsrole_permissionrouter_paramsr<  r  r  r  litellm_model_namelitellm_model_api_baser  r  finetuning_configfiles_configr  rZ  arg_specexclude_argsxavailable_argsguardrails_v2r  s;                                                              r(   r/  zProxyConfig.load_config  s     "__>N_OO(((7 #JJ':DA "::&8$?#!(O(.446
U'>etm_--EFG=#%L%)991A.1Q.$++,BC!-!1!1&'!BJ(../EzR #g-?O1Ol//12a7%/d%C
%/d%C
)-$++(2(2(2 &&6=I-78H$-ON(//$.!" -220+,&	 -220+,&	 -220+,&	 -224+,*	 '3&8&8&:
U%eS1e6F6F}6U0:50AL- ';
 $$,$?}}0,22.//IJZI[\ G^L(0E*/%1)9)9	1- 9RG5K'1#%1)9)9	 22G3E3N3NG0--'eFVW/G+ )..3G4K4K3LM 667<U|G4>>?DU|G<77?#DD  8 11> %*	3 ! )-Z(8.=&*+;&<1A/	3G/ %&../1G, %*(?#<<YY /h ?
 $<<YY (  ,x7!<%& $4#?$8$>$>(C%& %5$L$L(4%&/ %*4 *++LWMeMeLffghxgyz ../1G, %*(?#<<YY /h ?
 $<<YY ( %* *++LWMeMeLffghxgyz N* 33-6.)\	/?,?	. )..*++<SE5'JZI[\ GS%0<<(Zt-D&+kkmFB)"c2r}}]7S,6rNb	 '4 @H%H  > ([\a[bc 
 )..*++<SE5'JZI[\ GS%0u 7z "::&8"=#!$4$8$89PRV$W!**AV*W&6&:&:)4'# '23H 4-40 .112BEJN>:"2"6"67Le"T%:MN((:J(K+//EL 7 7 F$**+KL),7$**+A<P)--j)=tDJ j33MB'
3
%*Z*E*4Z*@'%5%9%9($&" &1"33*/0F*G&* 4 
 !1 4 45H% P ($)! +..}dCK&#2%8H$  #3"6"67Ld"S".+:-@P,( *--lDAJ%"1$7G# -=,@,@/-) -85D7%562
 '2-DDEUVVV  ##$<dCO7+;<T+U   .11 %N +..}dCK&<5+@ r  1A0D0D35V1- 1A0D0D35V1- ,<+?+?.0L,( $4#7#7&(<$  "2!5!5$&8"
 ,<+?+?*E,( %5$8$8')F%! $4#7#78NPT#U  %5$8$89KT$R!$0 ,A8' );?;8 !34 !$$%67C , 5'88>>?  !$44-=>O-P*-88: w}} 

 ZZd3
*4M,'T $!"2399;DAq!!S)all=.I5?]./2 < UYY|R%@$AIJ%*+;%<W%E")./?)@)D)DZQU)V&116L6T$& $ <@#ZZ(<dC*+;<BBD1a%!,,}*E="5B		"A>?&'78;	 E
 !4 I6H I #JJ':DA&78 zz"2D9- !'

+BD I#==(	

 !**%6=z/4@--gnn=H L
 *2PA!<:OaPNP'--/1&'(M!$ 0  

/$9 $% (,
 (V\\-E-E-M&&->&? /3"JJ|T:M,?O
  $888G"6 	""&"1v,,.0@@@{ PF	3@ (1 !<7;$4!<R  ) ),=&/&Z[^Z__qr~  sD  sD  sF  rG  %H'" !" #,"VWZV[[mnrs  oA  nB  !C# b WZ8Z Qs   vtGvv12v%Dv3*vt:A;v7t=v C3v4t,?A1v1vKvv(v vC=v>vCv"v4AvvAvv)C9v"	v,v0vCvvt)%v(t))v,Au??vv
vc                    |j                  dd      }|rt        j                  |       |j                  dd      }|r<ddlm} |j                  di       }|j                  dd      }|j                  ||       |j                  dd      }|rEdd	lm} t        j                   |       t        _	        t        j                  j                  |       y)
zO
        Initialize non-LLM configs eg. MCP tools, vector stores, etc.
        	mcp_toolsNmcp_serversr   global_mcp_server_managerr[  mcp_aliasesvector_store_registryVectorStoreRegistry)r4  rV   load_tools_from_config9litellm.proxy._experimental.mcp_server.mcp_server_managerr  load_servers_from_config+litellm.vector_stores.vector_store_registryr"  r	  r   load_vector_stores_from_config)	rN  rM  mcp_tools_configmcp_servers_configr  r[  r  vector_store_registry_configr"  s	            r(   r   z!ProxyConfig._init_non_llm_configs  s    
 "::k48$;;<LM#ZZt<
  &zz*<bA*..}dCK%>>?QS^_ (.zz2I4'P$'W,,40C0E- ))HH, 	r*   r"  c                    ddl m} |j                  dd      }t        j                  d|        |y|D ]  }|dk(  rpt
        j                  |j                  dd      |j                  dd      |j                  d	d      |j                  d
d      |j                  dd      t               x|t        j                  v s ||ddd|j                  dd      i      }|t        j                  j                  |        y)z.
        Initialize alerting settings
        r   )$_init_custom_logger_compatible_classalertingNz_alerting_callbacks: slackalerting_thresholdr  alert_typesalert_to_webhook_urlalerting_args)r-  r/  r0  r1  r2  r  )logging_integrationinternal_usage_cacher   custom_logger_init_args)*litellm.litellm_core_utils.litellm_loggingr,  r4  r=   r  r  update_valuesr!  r	  )_known_custom_logger_compatible_callbacksr  r  )rN  r"  r,  _alerting_callbacks_alert_loggers         r(   r  z#ProxyConfig._load_alerting_settings  s   	
 /22:tD""%:;K:L#MN&)F !//-11*dC'7';';<PRU'V 0 4 4]D I)9)=)=.* #3"6"6"M 1 0 	 WNNNB,2-1#'+-=-A-A/SW-X1	G *88MMgV3 *4 	r*   r  c                 4   ||t         j                  j                  k(  rt        d       y|t         j                  j                  k(  rt        d       y|t         j                  j                  k(  rddlm} |j                  d       y|t         j                  j                  k(  rt        d       y|t         j                  j                  k(  rdd	lm}  |        y|t         j                  j                  k(  rdd
lm}  |        yt%        d      y)z_
        Initialize the relevant secret manager if `key_management_system` is provided
        NTr  r  r   )AWSSecretsManagerV2)use_aws_secret_manager)use_aws_kms)GoogleSecretManager)HashicorpSecretManagerz&Invalid Key Management System selected)r   r  ry  r  
GOOGLE_KMSr   AWS_SECRET_MANAGER-litellm.secret_managers.aws_secret_manager_v2r=  load_aws_secret_managerAWS_KMSr   GOOGLE_SECRET_MANAGER-litellm.secret_managers.google_secret_managerr@  HASHICORP_VAULT0litellm.secret_managers.hashicorp_secret_managerrA  rf  )rN  r  r=  r@  rA  s        r(   r  z%ProxyConfig.initialize_secret_manager  s     !,$(;(K(K(Q(QQ)dC&*=*H*H*N*NNt4%&99??@ $;;SW;X&*=*E*E*K*KK.%)<)R)R)X)XX $%&*=*M*M*S*SS '( !IJJC -r*   c                    t        |dd      }|||j                  d<   d|j                  d<   t        du rht        |dd      |j                  d<   t        |dd      |j                  d<   t        |dd      |j                  d<   t        |d	d      |j                  d	<   |j                  t        |j                  t              rld|j                  vr|j
                  |j                  d<   d|j                  v r |j                  d   d
u r||j                  d<   t        di |j                  }|S t        |j
                  |      }|S )z
        Common logic across add + delete router models
        Parameters:
        - deployment
        - db_model -> flag for differentiating model stored in db vs. config -> used on UI

        Return model info w/ id
        model_idNidTdb_model
created_at
updated_at
created_by
updated_byF)rM  rN  r   )r  
model_infor   r1  r5  rL  RouterModelInfo)rN  r  rN  r"  _model_infos        r(   get_model_info_with_idz"ProxyConfig.get_model_info_with_id	  sD    %UJ=?%(ET"+/EZ(4-4UL$-OE\*-4UL$-OE\*-4UL$-OE\*-4UL$-OE\*'Ju7G7G,N5+++).  &U---%2B2B:2NRW2W/7  ,)=E,<,<=K  *U^^hOKr*   	db_modelsc                   K   g }t         t        |      dk(  ry|D ]<  }| j                  |      }|j                  "|j	                  |j                         > | j                  t               d{   }|j                  dd      }|r|D ]  }|d   j                         D ]9  \  }}	t        |	t              s|	j                  d      s)t        |	      |d   |<   ; |j                  di       j                  d	d      }
|
t         j                  |d
   |d         }
nt        |
      }
|j	                  |
        t         j                         }d}|D ]%  }
|
|vst         j                  |
      }|!|dz  }' |S 7 w)a5  
        (Helper function of add deployment) -> combined to reduce prisma db calls

        - Create all up list of model id's (db + config)
        - Compare all up list to router model id's
        - Remove any that are missing

        Return:
        - int - returns number of deleted deployments
        Nr   r  r  r<  r  rx  rS  rM  r  )model_groupr  )rM  r  )r   rE  rV  rM  rn  r  r   r4  rh  r1  r2  r	  r   _generate_model_idget_model_idsdelete_deployment)rN  rW  combined_id_listmrS  rM  r<  r  r  r  rL  router_model_idsdeleted_deployments
is_deleteds                 r(   _delete_deploymentzProxyConfig._delete_deployment$	  s      Y1!4 A4414=J}}( ''
6  8MNNZZd3
#!"2399;DAq!!S)all=.I5?]./2 <
 !99\26::4F#)<<$),$7',-='>  =  H
  #8}H ''1! $$ &335  (H//'99X9F
)'1,'	 )
 #"= Os0   ;F6F4F5AF<FBF!F:
Fc                 b   ddl }t        t        t        t              st	        dt               t
        yd}|D ]  }|j                  }t        |t              rr|j                         D ]S  \  }}t        |t              st        ||      }|t	        dj                  |            t        |      dkD  sO|||<   U t        di |}nt        j                  d|        | j                  |d      }	t
        j!                  t#        |j$                  ||		      
      }
|
|dz  } |S )z
        Iterate through db models

        for any not in router - add them.

        Return - number of deployments added
        r   N7Master key is not initialized or formatted. master_key=ry  r  zUnable to decrypt value={}HInvalid model added to proxy db. Invalid litellm params. litellm_params=T)r  rN  r  r  rS  )
deploymentr  r   )base64r   r1  r2  r  r   r  r5  rh  ri   r6   rE  r   r=   r  rV  upsert_deploymentr   r  )rN  rW  rj  added_modelsr_  _litellm_paramsr  r  _valuerU  addeds              r(   _add_deploymentzProxyConfig._add_deployment^	  sM    	Z
C%@I*V  A..O/40+113DAq!!S)!5A1!E!>"+,H,O,OPQ,R"SSv;?17OA. 4 #1"C?"C %**^_n^op 55$ 6 K 00% ||#2* 1 E  !C D r*   
new_modelsc                    g }|D ]  }|j                   }t        |t              r6|j                         D ]  \  }}t	        ||      }|||<    t        di |}nt        j                  d|        n| j                  |      }|j                  t        |j                  ||      j                  d              |S )Nrf  rg  rY  rh  Texclude_noner   )r  r1  r5  rh  ri   r   r=   r  rV  rn  r   r  to_json)	rN  rq  _model_listr_  rm  r  r  decrypted_valuerU  s	            r(   decrypt_model_list_from_dbz&ProxyConfig.decrypt_model_list_from_db	  s    A..O/40+113DAq&:&JO)8OA& 4 #1"C?"C$**^_n^op 55A5>K ||#2* 't', . r*   r  c                 p  K   	 t         t        t        j                  dt	        |              | j                  |      }t	        |      dkD  rt        j                  d|        t        j                  |t        d      d      a t        j                  dt                 nMt        j                  dt	        |              | j                  |	       d {    | j                  |	       t         t         j                         at         j#                          d {   }| j%                  |       | j'                  |t         t(               d {    | j+                  |t,        |       y 7 # t        $ r+}t        j                  d
t        |              Y d }~d }~ww xY w7 7 Xw)Nzlen new_models: )rq  r   z_model_list: Tr  )r<  r  r  zupdated llm_router: )rW  z+Error adding/deleting model to llm_router: )config_datar   r   )rz  r"  r  )r   r   r=   r  rE  rx  r	  r;   r   rc  rp  r  r  r2  r  r0  r-  r  _add_callbacks_from_db_config#_add_router_settings_from_db_configr   $_add_general_settings_from_db_configr"  )rN  rq  r  rv  r  rz  s         r(   _update_llm_routerzProxyConfig._update_llm_router	  s    	!j&<$**-=c*o=N+OP$($C$C) %D % {#a'(..{m/LM!(#.0E,01 48"J )..1Ej\/RS$**-=c*o=N+OP--
-CCC $$z$: !'668N )3355**;7 66#
- 7 
 	
 	

 	11#-/ 	2 	
/ D
  	 **=c!fXF 	 6	
s_   F6CE; E9E; 51F6&F2'4F6F4F69E; ;	F/!F*%F6*F//F64F6rz  c                 $   |j                  di       xs i }|j                  dd      }|j                  dd      }|ht        |t              rX|D ]S  }|t        j                  v rt        |d       "|t        j                  vs5t        j                  j                  |       U |jt        |t              rY|D ]S  }|t        j                  v rt        |d       "|t        j                  vs5t        j                  j                  |       U yyy)z:
        Adds callbacks from DB config to litellm
        r[  r  Nr  successfailure)r4  r1  re  r	  r8  r   r  r  r  r  r  )rN  rz  r[  success_callbacksfailure_callbacksr  r  s          r(   r{  z)ProxyConfig._add_callbacks_from_db_config	  s    '??+=rBHb,001CTJ,001CTJ(Z8I4-P$5 $HHI B() &W-E-EE44QQ( %6 (Z8I4-P$5 $HHI B() &W-E-EE44QQ( %6 .Q(r*   r  new_encryption_keyc                 ^    i }|j                         D ]  \  }}t        ||      }|||<    |S )zR
        Encrypts a dictionary of environment variables and returns them.
        )ry  r  )rh  rj   )rN  r  r  encrypted_env_varsr  r  encrypted_values          r(   _encrypt_env_variablesz"ProxyConfig._encrypt_env_variables
  sF      )//1DAq2,>O %4q!	 2
 "!r*   c           	          i }|j                         D ]-  \  }}	 t        ||      }||t        j                  |<   |||<   / |S # t        $ r*}t        j                  d|t        |             Y d}~`d}~ww xY w)a!  
        Decrypts a dictionary of environment variables and then sets them in the environment

        Args:
            environment_variables: dict - dictionary of environment variables to decrypt and set
            eg. `{"LANGFUSE_PUBLIC_KEY": "kFiKa1VZukMmD8RB6WXB9F......."}`
        rf  Nz#Error setting env variable: %s - %s)rh  ri   r*  r3  r  r=   r  r2  )rN  r  decrypted_env_varsr  r  rw  r  s          r(   !_decrypt_and_set_db_env_variablesz-ProxyConfig._decrypt_and_set_db_env_variables
  s      )//1DAq"6QA"F".$3BJJqM,;&q) 2 "!	  $**91c!f s   'A	A8 A33A8r   r   c                    K   |b|_|j                   j                  j                  ddi       d{   }|,|j                  |j                  } |j                  di | yyyyy7 5w)zF
        Adds router settings from DB config to litellm proxy
        N
param_namerZ  wherer   )dblitellm_config
find_firstparam_valueupdate_settings)rN  rz  r   r   db_router_settings_router_settingss         r(   r|  z/ProxyConfig._add_router_settings_from_db_config1
  s      !m&?'4'7'7'F'F'Q'Q#%67 (R ( " #.&22>#5#A#A *
**>-=> ? / '@!"s   0A*A(6A*c                    |j                  di       }d|v r||j                  dd      tt        |d   t              ra|j                  dd      Ot        |d   t              r<t        j                  d       |d   |d<   |d   |_        |d   |j                  _        na|)i }|d   |d<   |d   |_        |d   |j                  _        n6t        |t              r&|d   |d<   |d   |_        |d   |j                  _        d|v r6|d   |d<   |d   |_        |j                  j                  |d   t               d|v r-|d   |d<   |j                  j                  |d   t               yy)	z
        Adds general settings from DB config to litellm proxy

        Args:
            config_data: dict
            general_settings: dict - global general_settings currently in use
            proxy_logging_obj: ProxyLogging
        r"  r-  Nz?Overriding Default 'alerting' values with db 'alerting' values.r0  )r0  r   r1  )r1  r   )r4  r1  re  r=   r  r-  slack_alerting_instancer5  r0  r7  r   )rN  rz  r"  r  _general_settingss        r(   r}  z0ProxyConfig._add_general_settings_from_db_configE
  s    (OO,>C** ,$((T:F/
;TB%))*d;G0<dC$**U 0A0 , .>j-I!*EUF!99B ")#% /@/L ,-=j-I!*EUF!99B ,d3/@/L ,-=j-I!*EUF!99B --.?.N]+,<],K)55CC,];
 D  "%667H&834 55CC%56L%M% D 	 7r*   db_general_settingsc                 R  K   |yt        |      }d|v r|d   t        d<   d|v r|d   t        d<   d|v r3|d   t        d<   t        j                  j	                  t        d          d|v r'|d   t        d<   t        t        d          d{    d|v r|d   t        d<   yy7 w)	z;
        Pull from DB, read general settings value
        Nmax_parallel_requestsglobal_max_parallel_requestsr2  )r2  r  r  r  )r5  r"  r  r  r7  r   )rN  r  r  s      r(   _update_general_settingsz$ProxyConfig._update_general_settings
  s     
 & !45"&778I'945 *->>?P.@;<
 //0A/0R_-55CC.? D 
 $'889J(:56 4'78P'Q  
 001BCS1T-. 1s   BB'B%B'current_configr  r"  rZ  r[  r  db_param_valuec                    |dk(  r4| j                  |      }|j                  di       j                  |       |S |dk(  rBt        |t              r2|j                         D ]  \  }}|t        v st        t        ||       ! ||vr|||<   |S t        ||   t              r<|j                         D ci c]  \  }}|s	|| }	}}||   j                  |	       |S |||<   |S c c}}w )am  
        Updates the config fields with the new values from the DB

        Args:
            current_config (dict): Current configuration dictionary to update
            param_name (Literal): Name of the parameter to update
            db_param_value (Any): New value from the database

        Returns:
            dict: Updated configuration dictionary
        r  r[  )	r  
setdefaultr  r1  r5  rh  r   r  r	  )
rN  r  r  r  r  r  ry  r  r  non_empty_valuess
             r(   _update_config_fieldsz!ProxyConfig._update_config_fields
  s   . 00!%!G!G!W%%&=rBII" "!--*^T2R,224
U==GS%0	 5 ^+)7N:&!! nZ0$71?1E1E1GMA11MM :&--.>?  *8N:&  Ns   2
C"=C"r  c                   K   |durt        j                  d       |S g }g d}|D ]'  }|j                  d|d      }|j                  |       ) t	        j
                  |  d {   }|D ]T  }|t        |dd       }	t        |dd       }
t        j                  d|	 d	|
        |	>|
A| j                  ||	|

      }V |S 7 _w)NTz4'store_model_in_db' is not True, skipping db updatesr  r  rM  )r  ry  ro  r  zparam_name=z, param_value=)r  r  r  )	r=   r  get_generic_datarn  r<  gatherr  r  r  )rN  r   rM  r  _tasksr  r  responserf  r  r  s              r(   r  z"ProxyConfig._update_config_from_db
  s     D( %%F M
 A$55 h 6 H MM(#	  "..&11	!H <>J!(M4@K &&j\}E %+*A33#))#. 4  "" % 2s   A#C%C&AC*C-Cc                    K   	 |j                   j                  j                          d {   }|S 7 # t        $ r:}t	        j
                  dj                  t        |                   g }Y d }~|S d }~ww xY ww)NzQlitellm.proxy_server.py::add_deployment() - Error getting new models from DB - {})r  litellm_proxymodeltable	find_manyr  r=   r  r6   r2  )rN  r   rq  r  s       r(   _get_models_from_dbzProxyConfig._get_models_from_db  su     	,//GGQQSSJ  T 	 **cjjF
 J	s6   A:'4 24 A:4 	A7/A2,A:2A77A:c                 J  K   	 t         t        t         t              st        dt                | j	                  |       d{   }| j                  ||       d{    |j                  j                  j                  ddi       d{   }|$| j                  |j                         d{    | j                  |       d{    y7 7 w7 I7 %7 # t        $ r7}t        j                  d	j                  t        |                   Y d}~yd}~ww xY ww)
z{
        - Check db for new models
        - Check if model id's in router already
        - If not, add to router
        Nre  r   )rq  r  r  r"  r  )r  z>litellm.proxy.proxy_server.py::ProxyConfig:add_deployment - {})r   r1  r2  rf  r  r~  r  r  r  r  r  _init_non_llm_objects_in_dbr  r=   r  r6   )rN  r   r  rq  r  r  s         r(   add_deploymentzProxyConfig.add_deployment  s>    	!J)D Mj\Z   $77m7TTJ ))%9J *    )6(8(8(G(G(R(R#%78 )S ) #
 #.33(;(G(G 4   
 222OOO% U#
 P 	 **PWWF 	s   D#AC  CC   C!/C  C%C  6C7C  CC  D#C  C  C  C  C   	D )-DD#D  D#c                    K   | j                  |       d{    | j                  |       d{    | j                          d{    | j                          d{    y7 O7 77 !7 w)z
        Use this to read non-llm objects from the db and initialize them

        ex. Vector Stores, Guardrails, MCP tools, etc.
        r  N)_init_guardrails_in_db_init_vector_stores_in_db_init_mcp_servers_in_db"_init_pass_through_endpoints_in_db)rN  r   s     r(   r  z'ProxyConfig._init_non_llm_objects_in_dbE  sl      )))FFF,,=,III**,,,55777 	GI,7sC   A0A(A0A*A0
A,A0"A.#A0*A0,A0.A0c                 d  K   ddl m}m}m} 	 |j	                  |       d {   }t        j                  dt        |             |D ]  }|j                  t        ||               y 7 G# t        $ r7}t        j                  dj                  t        |                   Y d }~y d }~ww xY ww)Nr   )IN_MEMORY_GUARDRAIL_HANDLER	GuardrailGuardrailRegistryr  zguardrails from the DB %s)	guardrailzFlitellm.proxy.proxy_server.py::ProxyConfig:_init_guardrails_in_db - {})+litellm.proxy.guardrails.guardrail_registryr  r  r  get_all_guardrails_from_dbr=   r  r2  initialize_guardrailr   r  r  r6   )rN  r   r  r  r  guardrails_in_dbr  r  s           r(   r  z"ProxyConfig._init_guardrails_in_dbP  s     	
 	
	'BB"/ C   
 !&&+S1A-B .	+@@"9i8 A  .  	 **X__F 	s?   B0A- A+AA- *B0+A- -	B-6-B(#B0(B--B0c                   K   ddl m} 	 |j                  |       d {   }t        |      dk  ry t        j
                   ||      t        _        y |D ]"  }t        j
                  j                  |       $ y 7 ^# t        $ r7}t        j                  dj                  t        |                   Y d }~y d }~ww xY ww)Nr   r!  r  )vector_stores)vector_storezIlitellm.proxy.proxy_server.py::ProxyConfig:_init_vector_stores_in_db - {})r&  r"  _get_vector_stores_from_dbrE  r	  r   add_vector_store_to_registryr  r=   r  r6   r2  )rN  r   r"  r  r  r  s         r(   r  z%ProxyConfig._init_vector_stores_in_dbk  s     S	"5"P"P+ #Q # M =!Q&,,40C"/1- %2L11NN%1 O  %2  	 **[bbF 	sT   CB  A>B  C"B  C'B  =C>B   	C 	-B;6C;C  Cc                   K   ddl m}  |       st        j                  d       y ddlm} 	 |j                          d {    y 7 # t        $ r7}t        j                  dj                  t        |                   Y d }~y d }~ww xY ww)Nr   )is_mcp_availablez<MCP module not available, skipping MCP server initializationr  zGlitellm.proxy.proxy_server.py::ProxyConfig:_init_mcp_servers_in_db - {}),litellm.proxy._experimental.mcp_server.utilsr  r=   r  r$  r  ._add_mcp_servers_from_db_to_in_memory_registryr  r  r6   r2  )rN  r  r  r  s       r(   r  z#ProxyConfig._init_mcp_servers_in_db  sx     Q! &&N 	
	+ZZ\\\ 	 **Y``F 	s@   *BA  AA BA 	B-B>BBBc                 :   K   ddl m}  |        d {    y 7 w)Nr   )'initialize_pass_through_endpoints_in_db);litellm.proxy.pass_through_endpoints.pass_through_endpointsr  )rN  r  s     r(   r  z.ProxyConfig._init_pass_through_endpoints_in_db  s     	
 6777s   r  c                    t        |t              rt        di |}n)t        |t              rt        di |j	                         }i }j
                  j                         D ]  \  }}t        ||      xs |||<    ||_        |S )Nrf  r   )r1  r5  r   r  
model_dumpcredential_valuesrh  ri   )rN  r  credential_objectdecrypted_credential_valuesr  r  s         r(   decrypt_credentialszProxyConfig.decrypt_credentials  s    j$' . < <
I. . I1F1F1H I&(#%77==?DAq-Aq-Q-VUV'* @ /J+  r*   db_credentialsc                   K   | j                  t               d{   }| j                  |      }||z   }g }t        t        j
                        D ]=  \  }}|j                  |D cg c]  }|j                   c}vs-|j                  |       ? t        |d      D ]!  }t        j
                  j                  |       # y7 c c}w w)z
        Create all-up list of db credentials + local credentials
        Compare to the litellm.credential_list
        Delete any from litellm.credential_list that are not in the all-up list
        r  NrL  T)reverse)
r  r   r  r  r	  r  credential_namern  sortedrq  )	rN  r  rM  r  combined_listidx_to_deleter
  r  r  s	            r(   delete_credentialszProxyConfig.delete_credentials  s      8MNN3363B '8 ()@)@AOC))1>2)-$$2  $$S)	  B
 -6C##'', 7 O2s)   CCAC(C;C ACCc                   K   	 |j                   j                  j                          d {   }|D cg c]  }| j                  |       }}| j	                  |       d {    t        j                  |       y 7 Qc c}w 7 !# t        $ r9}t        j                  dj                  t        |                   g cY d }~S d }~ww xY ww)NzSlitellm.proxy_server.py::get_credentials() - Error getting credentials from DB - {})r  litellm_credentialstabler  r  r  rN   upsert_credentialsr  r=   r  r6   r2  )rN  r   credentialsr  r  s        r(   get_credentialszProxyConfig.get_credentials  s     	 - 0 0 I I S S UUKFQRd433D9RKR))   11 VR  	 **ellF
 I	sa   C'B A=B A?B "B#B <C=B ?B 	C.C=C>CCC)r  Nr   F)Br   r  r  __doc__rO  r2  boolr.  r5  rX  r	   rb  r^  rt  r   r  rz  r   r  r  r  r  r  r  r  r   r  r  r	  r;   r/  r   r  r  rT  rV  re  rc  rp  rx  r   r~  r{  r  r  r   r|  r}  Jsonr  r   r   r  r  r  r  r  r  r  r  r  r   r  r  r  r  r   r*   r(   rJ  rJ  Z  s   )U U UN N N 15& (&	&P% % % %NMD M0 *+=V###&#7:#	#J tDz d  &44&6# 6$ 6p$  4 D4H !$ !FeAw~~.eABEeAN!D !F& &P%Kx} %KN @8#$ 8#3 8#t6 6# 6pT d 66
6
 (6
p# #$ #L PT"%)"?G}"	""t "PT "*?? V$?  -	?
 
?(::37:LX:	:x%U(4. %UN44 %
4 4 
4l+#+ + $D>	+Z|  +#+ (+Z	8| 	8, 6\ 6,8!eD)O.D ! !-tN7K -.< r*   rJ  c                  R    dd l } |j                  |       t        j                  d<   y )Nr   r  )r'  dumpsr*  r3  )rn  r'  s     r(   save_worker_configr    s    ",$**T"2BJJr*   c                   K   ddl m}  |        t        j                  dd      j	                         dk7  r
t                | a|a|du rddd l}ddl	m
}m}m} |j                  |j                          |j                  |j                          |j                  |j                         |du redd l}ddl	m
}m}m} |j                  |j                          |j                  |j                          |j                  |j                         n|d	u r|d	u rt        j                   j#                  d
d      }||j%                         dk(  rGdd l}ddl	m}m}  |j                  |j                          |j                  |j                         nY|j%                         dk(  rFdd l}ddl	m}m}  |j                  |j                          |j                  |j                         di t        i i}|r't&        j)                  t*        |       d {   \  aaa|r|a||t           d<   |r|a||t           d<   |r|t        j                   d<   |r||t           d<   |r|a||t           d<   |r|a||t           d<   |r||t           d<   |du rdt8        _        d|d   d<   |du rdt8        _        d|d   d<   |	r|	t8        _        |	|d   d<   t@        r	 |
a!y 7 ƭw)Nr   )show_bannerLITELLM_DONT_SHOW_FEEDBACK_BOXr   trueT)verbose_loggerr=   r>   )levelFLITELLM_LOGINFOr<   DEBUGgeneralr  r  r  AZURE_API_VERSION
max_tokenstemperaturerequest_timeoutaliasdrop_paramsadd_function_to_promptrA  )"!litellm.proxy.common_utils.bannerr  r*  r  rR  r8   
user_model
user_debuglogginglitellm._loggingr  r=   r>   setLevelr  r  r3  r4  upperr-  r/  r   r0  r"  user_headersuser_api_baseuser_temperatureuser_request_timeoutr	  r  r  rA  experimentaluser_telemetry)r  r  r  api_versionr  detailed_debugr  r  r  rA  	telemetryr  r  r  save	use_queuerM  r  r  r  r=   r>   litellm_log_settingdynamic_configs                           r(   r6  r6    s    ( >M	yy126<<>&HJJ}	
 	
 	gll3&&&W\\:%%%GLL9	
 	
 	gmm4&&&W]];%%%GMM:	%Ne3 jjnn]B?*"((*f4X /%..!,, .$--!,, %**,7X.%..!-- .$--!--  Z4N
 ***v*VV		
07z"9- 19z":. 	

&' 3=z"<0&4?z"=1.8Gz"#45.3z"7+d"37y!-0%)-&>By!":;'2<y!,/NA Ws   HK&K$CK&c              #     K   t        j                  d       | D ]B  }t        j                  d|       	 dt        j                  |j	                                d D y # t
        $ r dt        j                  |       d Y lw xY ww)Ninside generatorzreturned chunk: %sdata: r   )r=   r  r'  r  r5  r  )r  chunks     r(   data_generatorr  ]  s}     12""#7?	34::ejjl34D99   	34::e,-T22	3s(   1B
)A B
 $BB
BB
user_api_key_dictrequest_datac                  K   t        j                  d       	 t        j                          | 4 d {   }t        j	                  |||       d {   }|2 3 d {   }|j                  d      }	 d| d &7 L7 .7 %# t        $ r}dt        |       d Y d }~Ld }~ww xY w6 d d d       d {  7   n# 1 d {  7  sw Y   nxY wd}d| d y # t        $ r}t        j                  dj                  t        |                   t        j                  |||	       d {  7   t        j                  d
| d       t        |t              r|t        j                         }t        |       d| }t        t!        |d|      t!        |dd      t!        |dd      t!        |dd            }	t#        j$                  d|	j'                         i      }
d|
 d Y d }~y d }~ww xY ww)Nr  )r  r  rn  Trs  r  r   [DONE]zTlitellm.proxy.proxy_server.async_assistants_data_generator(): Exception occured - {}r  original_exceptionr  [1;31mAn error occurred: P

 Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`r!   rX  Noners  r    r  r  )r=   r  r  r  async_post_call_streaming_hookmodel_dump_jsonr  r2  r  r6   post_call_failure_hookr1  r   r  r   ProxyExceptionr  r'  r  to_dict)r  r  r  r  cr  done_messageerror_traceback	error_msgproxy_exceptionerror_returneds              r(   async_assistants_data_generatorr&  g  s     120,		 	0 	0u+JJ"3! K  E ! 0 0a%%4%80"1#T**	00 ! 0"3q6($///0	 !	0 	0 	0 	0 	0"  |nD)) ,&&biiA	

  66/ % 7 
 	
 	

 	""+A3  /A  B	
 a'G'224Oq6($&78I(Ay)4FF+!Wf-M3/	
 Wo.E.E.G$HI~&d+++7,s   G?C" B C" CBCB.BB."C6	B?C C" CB.	B+B&!C&B++C/C" :B=;C" CC
CC" !G?"
G<,AG74D75B=G72G?7G<<G?c                
  K   t        j                  d       	 d}d }t        j                  || |      2 3 d {   }t        j                  dj	                  |             t        j                  ||||       d {   }t        |t        t        f      rt        j                  |      }||z  }t        |t              r|j                  dd      }n%t        |t              r|j                  d	      r|} n	 d	| d
 || d}d	| d
 y 7 7 # t        $ r}d	t        |       d
 Y d }~d }~ww xY w6 B# t        $ r,}t        j                   dj	                  t        |                   t        j#                  |||       d {  7   t        j                  d| d       t        |t$              r|t        |t&              rt        |      }	n$t)        j*                         }
t        |       d
|
 }	t-        t/        |d|	      t/        |dd      t/        |dd      t/        |dd            }t1        j2                  d|j5                         i      }d	| d
 Y d }~y d }~ww xY ww)Nr  r   r  r  r  z3async_data_generator: received streaming chunk - {})r  r  rn  
str_so_far)response_objT)rt  exclude_unsetr  r   r  zIlitellm.proxy.proxy_server.async_data_generator(): Exception occured - {}r  r  r  r!   rX  r  rs  r  r  r  r  )r=   r  r  'async_post_call_streaming_iterator_hookr6   r  r1  r   r   r	  get_response_stringr  r  r2  r	  r  r  r  r   rH  r  r   r  r  r'  r  r  )r  r  r  r)  error_messager  response_strr  r!  r#  r"  r$  r%  s                r(   async_data_generatorr0    s     12H,
'+,TT/% U 
  	,  	,%
 !&&ELLUS ,JJ"3!%	 K  E %-1D!EF&::Nl*
%+--4t-TE3'E,<,<X,F %,ugT**
 $|nD))M 	,(  ,s1vhd+++,?
N  ,&&W^^A	

  66/ % 7 
 	
 	

 	""+A3  /A  B	
 a'G12AI'224Oq6($&78I(Ay)4FF+!Wf-M3/	
 Wo.E.E.G$HI~&d+++=,s   JE
 EDEAE
 >D?A>E
 >	DE
 JEE
 	E(E :E
  EE
 

J AI;FCI;6J;J  Jc                     t        | ||      S )Nr  r  r  )r0  r2  s      r(   select_data_generatorr3    s      +! r*   r  c                     | j                  di       }| j                  di       j                  dd       }	 d|v r|j                  dd       }t        j                  |      }|S # t        $ r i cY S w xY w)NrS  r  r  azure
base_model)r4  r	  get_model_infor  )r  rS  model_to_lookuplitellm_model_infos       r(   get_litellm_model_infor:    sz    <,Jii 0"599'4HOo%(nn\4@O$33OD!!  	s   ,A# #A10A1c                 6    t        j                  d| d          y )Nz$Backing off... this was attempt # %stries)r=   r  )r=  s    r(   
on_backoffr=    s    EwwGWXr*   c                 >   t        | t              xr; t        | dd       d uxr* t        | j                  t              xr d| j                  v  }t
        j                  d      du ry|r4t        j                  t        j                  dt	        |       d             |S )Nr!   z"Max parallel request limit reached1disable_retry_on_max_parallel_request_limit_errorTgiveup)eventr  )r1  r  r  r!   r2  r"  r4  r=   r  r'  r  )r  results     r(   r@  r@  
  s    1n% 	>Ay$'t3	>qyy#&	> 1AII=	F 	PQ	 !!$**xcRSf-U"VWMr*   c                       e Zd Zedee   dedee   fd       Zede	dee
   defd       Zed	efd
       Zed        Zede	de
dedededefd       Zedefd       Zedee   dededee
   fd       Zed        Zy)r8  r   r  r!  c                 >    t                |j                  ||       y)z*Initialize logging and alerting on startup)r   r!  N)r  startup_event)clsr   r  r!  s       r(   r:  z-ProxyStartupEvent._initialize_startup_logging  s"     	''!5F 	( 	
r*   r"  r   r  c                 (   |j                  dd      ^|d   j                         D ]9  \  }}t        |t              s|j	                  d      s)t        |      |d   |<   ; t        di |d   }n
t               }t        j                  |||       y)zInitialize JWT auth on startuplitellm_jwtauthNrx  )r   r  rH  r   )	r4  rh  r1  r2  r	  r   LiteLLM_JWTAuthr  r@  )rF  r"  r   r  r  r  rH  s          r(   r;  z&ProxyStartupEvent._initialize_jwt_auth-  s      148D():;AAC1a%!,,}*E=G]$%67: D .T0@AR0STO-/O&&'1+ 	' 	
r*   r#  c                    t         j                  t        d      t        j                  t        dd|dg i i dt         j                  t         j                  dt         j                  t         j                  d             y)z Adds a global proxy budget to dbNzPbudget_duration not set on Proxy. budget_duration is required to use max_budget.userr   update_data)rA  budget_duration)request_typero  r  durationmodelsaliasesrM  r   rA  rM  
query_typeupdate_key_values)r	  rM  r  r<  r=  r   rA  )rF  r#  s     r(   rB  z)ProxyStartupEvent._add_proxy_budget_to_dbB  s|     ""*b 
 	"#!1"-- ' 7 7(")"4"4'.'>'>#	
r*   c                 <  K   t         j                  yt         j                  j                  d      xs g }|r[t        d |D              rHddlm} |D cg c]  }t        di | }} ||t        t        t                           d{    yyyc c}w 7 w)	z%Update the default team member budgetNteamsc              3   <   K   | ]  }t        |t                y wr   )r1  r5  ).0r  s     r(   	<genexpr>zGProxyStartupEvent._update_default_team_member_budget.<locals>.<genexpr>f  s     DT*T40Ds   r   )!update_default_team_member_budgetr  )rU  r  r   )
r	  default_internal_user_paramsr4  r  7litellm.proxy.ui_crud_endpoints.proxy_setting_endpointsrY  NewUserRequestTeamUserAPIKeyAuthr   r   )rF  _teamsrY  r  teams_pydantic_objs        r(   rE  z4ProxyStartupEvent._update_default_team_member_budget_  s      //75599'BHbcDVDD JP!P"4"<t"<!P!P3(NQ[\fQg<h   E6
 "Qs   ABB'&BBBr$  r%  r&  c           	      T  K   t               }t        j                  ||      }t        j                  |dz
  |dz         }	|j                  dd      du r+t	        ||      }
|j                  |
j                  d|       |j                  t        d|	|t        |g       t        dt              xs t        a
t        d	u r|j                  t        j                  dd
||g       t        j                  ||       d{    |j                  t        j                  dd
|g       t        j                  |       d{    |M|j                  j                  6|3t!        d       |j                  dd      xs d}t#        |dd       }|d   j%                         dk7  rt'        d      |j                  |j                  j(                  d|t+        j,                         t/        d
      z   |g       |j                  |j                  j0                  dd       t3        j4                  d      r\ddlm} |j                  |j                  j:                  dt<        d |d             |j                  j;                          d{    | j?                  |       d{    |j                  d      HtA               }|j                  dd       }	 tC        |      }|j                  |jD                  d||g       tJ        8	 dd"l&m'}  |||tJ        #      }|j                  |jP                  dtR               |jY                          y7 Y7 7 7 # t&        $ r tG        jH                  d!       Y yw xY w# tT        $ r tG        jV                  d$       Y _w xY ww)%z%Initializes scheduled background jobsr   disable_reset_budgetF)r  r   interval)seconds)rc  r  STORE_MODEL_IN_DBT
   r   r  Nr  z3Alerting: Initializing Weekly/Monthly Spend Reportsspend_report_frequency7ddzBspend_report_frequency must be specified in days, e.g., '1d', '7d')daysnext_run_timer  cronr  )dayPROMETHEUS_URLr   )ZoneInfozAmerica/Los_Angeles)hourminutetimezone	scheduler#maximum_spend_logs_retention_period%maximum_spend_logs_retention_interval1dz3Invalid maximum_spend_logs_retention_interval value)CheckBatchCost)r  r   r   zSChecking batch cost for LiteLLM Managed Files is an Enterprise Feature. Skipping...)-r-   r2   randintr4  rs   add_jobreset_budgetr   r  r   r  r-  r  r  r  r-  r5   r  rR  rf  send_weekly_spend_reportr   nowr   send_monthly_spend_reportr*  r  zoneinforp  #send_fallback_stats_from_prometheusrE   *_initialize_spend_tracking_background_jobsru   r   cleanup_old_spend_logsr=   r  r   6litellm_enterprise.proxy.common_utils.check_batch_costry  check_batch_costr  r  r  start)rF  r"  r   r$  r%  r&  r  ru  rb  batch_writing_intervalbudget_reset_jobrg  rk  rp  spend_log_cleanupretention_intervalinterval_secondsry  check_batch_cost_jobs                      r(   rD  z6ProxyStartupEvent.initialize_scheduled_background_jobsp  s     %&	>>-/P
 "( 1$&:Q&>"

  6>%G-"3+ 
  --    	*!13DE	 	 	
 /1BCXGX 	 $++#%67	   --+?P .   
 ,,#_	   ..].KKK)!99BBN)GH !$$%=tDL #
 -cr23D%b)//1S8 X  !99RR&llnB'(,-   !99SS   yy)*-!!%==aaB%&;< "  (??cceee<<y<QQQ  EFR / 1!1!5!57"#67I#J !!%<<,'	 "  ! (6&7"/)($
 !!(998 "  	Q L\ fQ"  $**I,  $**i 	s   C;N(=M>AN(?M EN(MN()M*1N(+M  N(7N N(N(N(N( N>N( NN(N%"N($N%%N(ru  c                    K   ddl m}m}  |        d{   r |        d{    t        j                  du r	 ddlm} |j                  |       yy7 @7 3# t        $ r d}Y yw xY ww)z
        Initialize the spend tracking background jobs
        1. CloudZero Background Job
        2. Prometheus Background Job

        Args:
            scheduler: The scheduler to add the background jobs to
        r   )init_cloudzero_background_jobis_cloudzero_setup_in_dbNTr  rt  )	0litellm.proxy.spend_tracking.cloudzero_endpointsr  r  r	  $prometheus_initialize_budget_metricsr  r  "initialize_budget_metrics_cron_jobr  )rF  ru  r  r  r  s        r(   r  z<ProxyStartupEvent._initialize_spend_tracking_background_jobs  ss     	

 *+++/111
 774?(W CCiCX	 @ ,1  (#' (sB   A+AA+AA+A A+A+A(%A+'A((A+r  r  c                   K   	 d}|	 t        ||      }|j                          d{    t        j                  |j                                t        j                  |j                                t        dd      dur|j                          d{    |S # t        $ r}|d}~ww xY w7 7 # t        $ r}t        j                  |       Y d}~yd}~ww xY ww)zQ
        - Sets up prisma client
        - Adds necessary views to proxy
        N)r  r  &DISABLE_PRISMA_HEALTH_CHECK_ON_STARTUPFT)r   r  connectr<  r=  check_view_exists(_set_spend_logs_row_count_in_proxy_stater   health_checkrv   handle_db_exception)rF  r  r  r  r   r  s         r(   r9  z&ProxyStartupEvent._setup_prisma_client3  s     	48M'$0%1EV%M $++--- ##!335 ##!JJL $$LeT  (44666  ) ! G .  7 	$88;	sm   CB3 B B3 B/A+B3 B1B3 C	B,%B''B,,B3 1B3 3	C<CCCCc                     ddl m}m}  |       rddl}|j	                  dd        |       r3ddlm}  |       }|j                          t        j                  d       yy)	z
        Initialize dd tracer - if `USE_DDTRACE=true` in .env

        DD tracer is used to trace Python applications.
        Doc: https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/python/
        r   )_should_use_dd_profiler_should_use_dd_tracerNTF)r  openai)ProfilerzDatadog Profiler started......)
%litellm.litellm_core_utils.dd_tracingr  r  ddtrace	patch_allddtrace.profilingr  r  r=   r  )rF  r  r  r  r  profs         r(   rF  z!ProxyStartupEvent._init_dd_tracer^  sR    	

 !"d59"$2:DJJL &&'GH %r*   N)r   r  r  classmethodr	   r;   r   r@   r:  r5  r   r?   r;  r2  rB  rE  r  rD  r-   r  r9  rF  r   r*   r(   r8  r8    sl   
V$
 (
 $J/	
 
 

  -
 &	
 
( 
 
 
8    ^^ $^ ,/	^
 ,/^ "^ (^ ^@ ((( (B (sm( (( &	(
 
,	( (T I Ir*   r8  z
/v1/modelszmodel management)dependenciesrg  z/modelsreturn_wildcard_routesinclude_model_access_groupsonly_model_access_groupsinclude_metadatafallback_typec                   K   g }t        t              }t        g }	n(t        j                         }	t        j	                         }	 |du rd}t        | |	||      }
| j                  }|r>g }
t        |t        t        t               d{   }t        | |       |j                  }t        ||	||      }t        |
||	t        t         j#                  dd      |t        |||	
      }g }|D ]\  }|d
t$        dd}|r<i }||nd}g d}||vrt'        dd|       t)        |t        |      }||d<   ||d<   |j+                  |       ^ t-        |d      S 7 ͭw)a  
    Use `/model/info` - to get detailed model information, example - pricing, mode, etc.

    This is just for compatibility with openai projects like aider.

    Query Parameters:
    - include_metadata: Include additional metadata in the response with fallback information
    - fallback_type: Type of fallbacks to include ("general", "context_window", "content_policy")
                    Defaults to "general" when include_metadata=true
    NT)r  proxy_model_listmodel_access_groupsr  )r  r   r  r  )r  
team_table)team_modelsr  r  r  infer_model_from_keysF)

key_modelsr  r  r  r  r  r   r  r  r  r  r  )rM  objectcreatedowned_byr  )r  context_windowcontent_policy  z'Invalid fallback_type. Must be one of: r  )r  r   r  	fallbacksmetadatare  )rn  r  )r9   re  r   get_model_namesget_model_access_groupsr`   r  rY   r   r  r  r   rP  rb   r_   r  r"  r4  rC   r   r^   rn  r5  )r  r  r  r  r  r  r  
all_modelsr  r  r  r  team_object
model_datar  rS  r  effective_fallback_typevalid_fallback_typesr  s                       r(   r<  r<  y  s    4 J0;D0A%557(@@B
  4'&*#+)/$?	J /::K
+'1/	
 
 	.?KX!((!)/$?	K )).223JER5/$?!9J J4 	

 H "/!:	 $
 $S &.BB# #DEYDZ[ 
 *%5I
 %.H[!%-Jz"*%E H  G
s   BE	E
CEz/v1/chat/completionszchat/completionsz/chat/completionsz&/engines/{model:path}/chat/completionsz1/openai/deployments/{model:path}/chat/completions   rN  zSuccessful response)r  rg  rf  fastapi_responsec                   K   t        |        d{   }t        |      }	 |j                  | ||dt        t        t
        t        t        |t        t        t        t        t        t               d{   S 7 f7 # t        $ rN}|j                  }t        j!                  |||       d{  7   t#        j$                         }|j&                  |j(                  d   j&                  _        |j-                  dd      |d   d	u rt"        j.                  j1                  |d	
      }	t#        j2                  |	|j-                  dd      d|j-                  dd            }
t        |
||      }t5        |dt7        |d      r|j8                  nt:        j<                        cY d}~S t#        j>                  ddd      }||_         |cY d}~S d}~wtB        $ r&}|jE                  ||t               d{  7  d}~ww xY ww)a  

    Follows the exact same API spec as `OpenAI's Chat API https://platform.openai.com/docs/api-reference/chat`

    ```bash
    curl -X POST http://localhost:4000/v1/chat/completions 
    -H "Content-Type: application/json" 
    -H "Authorization: Bearer sk-1234" 
    -d '{
        "model": "gpt-4o",
        "messages": [
            {
                "role": "user",
                "content": "Hello!"
            }
        ]
    }'
    ```

    r  Nrn  acompletionr  r  r  
route_typer  r   r"  r-  r3  r  r  r  r  user_max_tokensr   r   r  r   streamTmodel_responseconvert_to_deltar  r   cached_responselitellm_logging_obj)completion_streamr  custom_llm_providerlogging_objr2  text/event-streamr  )
media_typer  prompt_tokenscompletion_tokenstotal_tokens)r  r  r  )#rl   re   base_process_llm_requestr  r   r"  r-  r3  r  r  r  r  r   r   rJ   r  r  r	  r   r!   choicesr  r4  utilsModelResponseIteratorCustomStreamWrapperr   rl  r  r   HTTP_400_BAD_REQUESTUsageusager  _handle_llm_api_exception)r  r  r  r  rn  base_llm_response_processorr  _data_chat_response	_iterator_streaming_responseselected_data_generator_usages                r(   chat_completionr    s    h $G44D"?T"J>
0II-/$/!-%"7!-!5+'! J 
 
 	
 5
$   %66/  7 
 	
 	

 !..045IIq!))188Hd#/DNd4J;;- < I #*"="="+hhw+$5 HH%:DA	# '<,"3"'# %'. q-0 MM44  Q!RST% 
/II// J 
 
 
 	

s   HA9HAA= 4A;5A= 8H;A= =
H'G.B1/C5G$H%H* G
HHHG=7G:8G==HHz/v1/completionscompletionsz/completionsz!/engines/{model:path}/completionsz,/openai/deployments/{model:path}/completionsc                 T  K   i }	 t        |        d{   }t        |      }|j                  | ||dt        t        t
        t        t        |t        t        t        t        t        t               d{   S 7 e7 # t        $ ro}|j                  }t        j!                  |||       d{  7   |j#                  dd      |d   du rt%        j&                         }t%        j(                  d	d	d	
      }	|	|_        |j,                  |j.                  d	   j,                  _        t$        j2                  j5                  |d      }
t%        j6                  |
|j#                  dd            }t        |||      }t9        |di t;        |d      r|j<                  nt>        j@                        cY d}~S t%        jB                         }|j,                  |j.                  d	   _"        |cY d}~S d}~wtF        $ r}t        j!                  |||       d{  7   tI        jJ                  djM                  tO        |                   tO        |       }tQ        tS        |d|      tS        |dd      tS        |dd      tS        |dd      tS        |dd            d}~ww xY ww)a  
    Follows the exact same API spec as `OpenAI's Completions API https://platform.openai.com/docs/api-reference/completions`

    ```bash
    curl -X POST http://localhost:4000/v1/completions 
    -H "Content-Type: application/json" 
    -H "Authorization: Bearer sk-1234" 
    -d '{
        "model": "gpt-3.5-turbo-instruct",
        "prompt": "Once upon a time",
        "max_tokens": 50,
        "temperature": 0.7
    }'
    ```
    r  Nr  atext_completionr  r  r  Tr   r  r  r  r   )r  r  r2  r  r  )r  r  r  z?litellm.proxy.proxy_server.completion(): Exception occured - {}r!   rX  r  rs  r  r  r!   rX  rs  openai_coder  )*rl   re   r  r  r   r"  r-  r3  r  r  r  r  r   r   rJ   r  r  r4  r	  r   r  r  r!   r  r  r  r  TextCompletionStreamWrapperr   rl  r  r   r  r   textr  r=   r  r6   r2  r  r  )r  r  r  r  rn  r  r  r  r  r  r  r  r  	_responser#  s                  r(   
completionr  p  s    R DQ
'88&C&N#0II-/)/!-%"7!-!5+'! J 
 
 	
 9
$   +66/  7 
 	
 	

 99Xt$0U8_5L$224N]]"#F
 $*N 89		N""1%--5;;- < I #*"E"E"+ii,#
 '<,"3!'# %'. q-0 MM44	 	  668I()		Ia % 
66/ATX 7 
 	
 	
 	&&MTTA	

 1vh	Ay)4FF+!Wf-640M3/
 	

s   J(A? A;A A? 6A=7A? :J(;A? =A? ?
J%	'G30B31DG34J%5J(:3G3-J%.J(3J%?J HBJ  J%%J(z/v1/embeddings
embeddings)r  response_classrg  z/embeddingsz /engines/{model:path}/embeddingsz+/openai/deployments/{model:path}/embeddingsc                  
  K   i }	 | j                          d{   }t        j                  |      }t        j                  dt        j                  |d             t        || t        |t        t               d{   }t        j                  dd      xs t        xs |xs |j                  dd      |d<   t        r	t        |d<   |d   t        j                  v rt        j                  |d      |d<   t        t        j                   ng }d|v rt#        |d   t$              rt'        |d         d	kD  rt#        |d   d	   t$              rt#        |d   d	   d	   t(              rt*        |d   |v rt*        D ]w  d
   |d   k(  sd   d   t        j,                  v st/        fdt0        D              r@g }|d   D ](  }|j3                  t        j4                  d|             * ||d<    n t6        j9                  ||d       d{   }g }	|	j3                  t6        j;                  ||d             t=        |dt        t               d{   }
|	j3                  |
       t?        j@                  |	 }| d{   }|d   }t?        jB                  t6        jE                  |j                  dd      d             tG        |di       xs i }|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j                  di       xs i }|jH                  jK                  tM        jN                  d/||||t        |tG        |dd      |||d 
|       tQ        |!       d{    |S 7 7 A7 7 m7 C7 # tR        $ r#}t6        jU                  |||"       d{  7   tG        |d#d      }t        j                  d$||       t        jV                  d%jY                  t[        |                   t#        |t\              rIt_        |      }ta        |tG        |d&d'      tG        |d(d'      tG        |d)tb        jd                        *      t[        |       }ta        tG        |d+|      tG        |d&d'      tG        |d(d'      tG        |d,d      tG        |d)d-      .      d}~ww xY ww)0a  
    Follows the exact same API spec as `OpenAI's Embeddings API https://platform.openai.com/docs/api-reference/embeddings`

    ```bash
    curl -X POST http://localhost:4000/v1/embeddings 
    -H "Content-Type: application/json" 
    -H "Authorization: Bearer sk-1234" 
    -d '{
        "model": "text-embedding-ada-002",
        "input": "The quick brown fox jumps over the lazy dog"
    }'
    ```

NzRequest received by LiteLLM:
%s   )indentrn  r  r"  r  r   r-  embedding_modelr  inputr   r  r  c              3   L   K   | ]  }d    d   j                  |        yw)r  r  N)r	  )rW  r  r_  s     r(   rX  zembeddings.<locals>.<genexpr>P  s1      E ( ./8CCHMEs   !$zgpt-3.5-turbo)r  tokensr  r  rn  	call_type)rn  r  r  
aembeddingrn  r  r   r  r  litellm_call_idr   r  r  r   _hidden_paramsrL  	cache_keyr  r  additional_headersallowed_model_region
r  rL  r  r  r   r  model_regioncall_idr  hidden_params)r  r  litellm_debug_infozo[1;31mAn error occurred: %s %s

 Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`z?litellm.proxy.proxy_server.embeddings(): Exception occured - {}rX  r  rs  r  r  r!   r  r  r  r   )3bodyorjsonr7  r=   r  r'  r  r   r"  r   r-  r4  r  r	  model_alias_mapr   model_namesr1  re  rE  r  r0  open_ai_embedding_modelsanyr   rn  decoder  pre_call_hookduring_call_hookr   r<  r  r=  update_request_statusr  r  r  re   get_custom_headersr[   r  r  r  r6   r2  r   r   r  r   r  )r  r  r  r  rn  r  router_model_names
input_listitasksllm_callllm_responsesrf  r  r
  rL  r  r  r  r  r  r  r  r!   r#  r_  s                            @r(   r  r    s;    ` Da\\^#||D!"".JJtA&	
 1-/%
 
   !2D9 ''' xx&	 	W &DM
 =G333#33DMBDM7A7MZ33SUtO4=$/DM"Q&4=+T24=+A.4 )d7m?Q.Q'A$w-7-.#$==>AD E,hE B ! *,J%)'] * 1 1$+NNQR$S!" &3 -7DM!# (( '44/dl 5 
 
 .."3& / 	
 '#!!	
 
 	X  
 ('	Q< 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"%))/4@FB'++,=tDJ#0#4#45I2#N#TRT  '')<< "3!#!+$%68NPRS'!+ %	
 *8<<< $
l

 (F 	=  66/ATX 7 
 	
 	
 %Q(<bA"" C	

 	&&MTTA	

 a'+A.G Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1#Avt4Qs3 3s   S>O N=A$O ?O  D
O BO OAO O,O O	D/O 6O7O <S>=O  O O O 	O O 
S;S63O64DS66S;;S>z/v1/moderationsmoderationsz/moderationsc                   K   i }	 | j                          d{   }t        j                  |      }t        || t        |t
        t               d{   }t        j                  dd      xs t        xs |j                  d      |d<   t        r	t        |d<   t        j                  ||d       d{   }t        j                          t        |dt        t               d{   }| d{   }t        j                  t        j!                  |j                  d	d
      d             t#        |di       xs i }|j                  dd      xs d
}|j                  dd      xs d
}	|j                  dd      xs d
}
|j$                  j'                  t)        j*                  |||	|
t
        t#        |dd
      ||             |S 7 7 |7 7 7 # t,        $ r}t        j/                  |||       d{  7   t1        j2                  dj5                  t7        |                   t9        |t:              rRt=        t#        |dt7        |            t#        |dd      t#        |dd      t#        |dt>        j@                              t7        |       }t=        t#        |d|      t#        |dd      t#        |dd      t#        |dd            d}~ww xY ww)a~  
    The moderations endpoint is a tool you can use to check whether content complies with an LLM Providers policies.
    Quick Start
    ```
    curl --location 'http://0.0.0.0:4000/moderations'     --header 'Content-Type: application/json'     --header 'Authorization: Bearer sk-1234'     --data '{"input": "Sample text goes here", "model": "text-moderation-stable"}'
    ```
    Nr  moderation_modelr  
moderationr  amoderationr   r  r   r  r  r  rL  r  r  r  r  rL  r  r  r   r  r  r
  r  z@litellm.proxy.proxy_server.moderations(): Exception occured - {}r!   rX  r  rs  r  r  r  )!r  r  r7  r   r"  r   r-  r4  r  r  r  r  r   r   r<  r=  r  r  r  r  re   r  r  r  r=   r  r6   r2  r1  r   r  r   r  )r  r  r  rn  r  r  r  r
  rL  r  r  r  r#  s                r(   r  r    s    8 DY\\^#||D! 1-/%
 
   !3T: !!xx  	W
 &DM '44/dl 5 
 
 			 '$!!	
 
 "> 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
  $
$

 ":  66/ATX 7 
 	
 	
 	&&NUUA	

 a' 9c!f5Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Qs3	 %s   K!G G9G GA"G 6G72G )G*	G 3G4CG K!G G G G G 	K"K=H >CKKK!z/v1/audio/speechaudioz/audio/speechc                 j  K   i }	 | j                          d{   }t        j                  |      }t        || t        |t
        t               d{   }|j                  dd      |j                  |j                  |d<   t        r	t        |d<   t        j                  ||d       d{   }t        |dt        t               d{   }| d{   }t        j                  t        j!                  |j                  d	d
      d             t#        |di       xs i }|j                  dd      xs d
}|j                  dd      xs d
}	|j                  dd      xs d
}
|j                  dd      xs d
}|j                  d	d      xs d
}dt$        fd}t'        j(                  |||	|
t
        |t#        |dd
      d|||      }t+        |||       d}|j                  dd
      }d|j-                         v r&d|j-                         v sd|j-                         v rd}t/         ||      ||      S 7 $7 7 7 x7 q# t0        $ r[}t3        j4                  dj7                  t9        |                   t3        j:                  t=        j>                                |d}~ww xY ww)z`
    Same params as:

    https://platform.openai.com/docs/api-reference/audio/createSpeech
    Nr  rK  r  image_generationr  aspeechr   r  r   r  r  r  rL  r  r  r  r  c                l   K   | j                  d       d {   }|2 3 d {   }| 7 7 6 y w)Ni   )
chunk_size)aiter_bytes)r  
_generatorr  s      r(   generatezaudio_speech.<locals>.generate  s?     (444EEJ)  e Fzs$   4.4202424r  )r  rL  r  r  r   r  r  !fastest_response_batch_completionr	  r  r
  r2  z
audio/mpeggeminittszpreview-ttsz	audio/wav)r  r  zAlitellm.proxy.proxy_server.audio_speech(): Exception occured - {}) r  r  r7  r   r"  r   r-  r4  r  r  r  r  r   r   r<  r=  r  r  r   re   r  r3  rR  r   r  r=   r  r6   r2  r  r  r   )r  r  r  rn  r  r  r  r
  rL  r  r  r  r  r+  custom_headersr  request_modelr  s                     r(   audio_speechr1  <  s    * D^\\^#||D! 1-/%
 
 88FD!).?.G.G.S,44DL&DM '44/dFX 5 
 

 ' !!	
 
 "> 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"%))/4@FB'++,=tDJ	&@ 	
 7II/' !24JBO.2#'
 	/	
 "
"-}**,,]((**m}?R?R?T.T$J X:~
 	
c $
 


 "l  ""OVVA	

 	""9#7#7#9:s   J3I H=9I I AI /I0I I	I I	E#I <J3=I  I I I 	I 	J0AJ++J00J3z/v1/audio/transcriptionsz/audio/transcriptions.r%   c                   K   i }	 t        |        d{   }|j                         D ci c]  \  }}|dk7  s|| }}}t        || t        |t        t
               d{   }|j                  dd      |j                  |j                  |d<   t        j                  dd      xs t        xs |j                  dd      |d<   t        r	t        |d<   t        t        j                  ng }|j                  t        dt        j                  dd	      t        |||
       |j!                          d{   }	t#        j$                  |	      }
|j                  |
_        |
|d<   	 t(        j+                  ||d       d{   }t-        |dt        t               d{   }| d{   }	 |
j5                          t7        j8                  t(        j;                  |j                  dd      d             t=        |di       xs i }|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j                  di       xs i }|j>                  jA                  tC        jD                  d'||||t        |t=        |dd      |||d
|       |S 7 c c}}w 7 7 7 g7 K7 D# t.        $ r}t1        dt3        |            d}~ww xY w# |
j5                          w xY w# t.        $ r}t(        jG                  |||       d{  7   tI        jJ                  djM                  t3        |                   tO        |t0              r\t        t=        |dt3        |jP                              t=        |d d!      t=        |d"d!      t=        |d#t        j                        $      t3        |       }t        t=        |d|      t=        |d d!      t=        |d"d!      t=        |d%d      t=        |d#d      &      d}~ww xY ww)(zq
    Same params as:

    https://platform.openai.com/docs/api-reference/audio/createTranscription?lang=curl
    Nr%   r  rK  r  r  z.File name is None. Please check your file namebad_request)r!   r  rX  rs  )r  r%   r  audio_transcriptionr  atranscriptionr   r  r  r  r   r  r  r  rL  r  r  r  r  r  r  r  zHlitellm.proxy.proxy_server.audio_transcription(): Exception occured - {}r!   rX  r  rs  r  r  r  r  r   ))rn   rh  r   r"  r   r-  r4  r  r  r   r  r#   r  r   r  rm   readioBytesIOrZ  r  r  r   r  r   r2  r  r<  r=  r  r  r  r  re   r  r  r=   r  r6   r1  r  )r  r  r%   r  rn  	form_datar  ry  r  file_contentfile_objectr  r  r  r
  rL  r  r  r  r  r  r#  s                         r(   audio_transcriptionsr<    sX    , D}'00	-6__->PzsE#-U
PP 1-/%
 
 88FD!).?.G.G.S,44DL   !3T: ''xx& 	W
 &DM7A7MZ33SU==  H00"	  	$1	
 "YY[(jj.=="V	 *88"3/ 9  D ++%%	 H &~H  	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"%))/4@FB'++,=tDJ#0#4#45I2#N#TRT  '')<< "3!#!+$%68NPRS'!+ %	
  E 1P
J ) & 	@CA??	@ F  66/ATX 7 
 	
 	
 	&&V]]A	

 a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1#Avt4Qs3 %s   QL2 KL2 K!K!#L2 "K'#CL2 :K*;/L2 +K6 K-K6 %K0&	K6 /K30K6 5D(L2 QL2 !L2 *L2 -K6 0K6 3K6 6	L?LLL L//L2 2
Q<Q	MC1Q		QQ)r   rb  WebSocketDisconnect)
_arealtime/v1/realtimez	/realtimez'The intent of the websocket connection.)rN  	websocketintentc                   K   dd l }| j                          d {    |d}| |d}t        | j                  j	                               }t        d|j	                         D 	cg c]3  \  }}	|j                         j                         |	j                         f5 c}	}ddd      }
| j                  |
_	        fd	}||
_
        t        |
      }	 |j                  |
t        |t        t        t         t"        t$        t&        t(        t*        d       d {   \  }}t-        |dt.        t"               d {   }| d {    y 7 2c c}	}w 7 :7 7 # |j0                  j2                  $ rE}t5        j6                  d       | j9                  |j:                  d       d {  7   Y d }~y d }~wt<        $ r4 t5        j6                  d       | j9                  dd       d {  7   Y y w xY ww)Nr   )r  rA  )r  r@  rm  httpPOSTr?  )rX  r  methodr+  )scopec                  8   K   d d} | j                         S w)Nz{"model": "z"})encode)return_stringr  s    r(   return_bodyz'websocket_endpoint.<locals>.return_bodyx  s$     &ugS1##%%s   r  r>  )r  r"  r  r   r  r-  r  r  r  r  r   r  r  r   zInvalid status code)r  reasonzInternal server errori  )
websocketsacceptr5  r  rh  r   rR  rH  url_urlr  re    common_processing_pre_call_logicr"  r   r  r-  r  r  r  r  r   r   r   
exceptionsInvalidStatusCoder=   r  r  r  r  )r@  r  rA  r  rL  rm  rn  r  r  r  r  rJ  r  r  r  r  s    `              r(   websocket_endpointrS  T  s     



 386(JL $D 9$$**,-GEL]]_UTQ))+QXXZ8U"	
G ==GL&
 GL #@T"J I .NN-//%!-!5+'# O 
 
	
  '#!!	
 
 w   V*

 	  22 P&&'<=oo1==9NoOOO I&&'>?oo40GoHHHIs   G8EAG8'8E6G8AE E!E =E>	E EE G8G8E E E G555F5*F-+F50G857G5,G/-G52G84G55G8z/v1/assistants
assistantsz/assistantsc                 b  K   i }	 | j                          d{    t        || t        |t        t               d{   }t
        't        ddt        j                  j                  i      t        j                  di | d{   }t        j                  t        j                  |j                  dd      d	             t!        |d
i       xs i }|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j"                  j%                  t'        j(                  ||||t        t!        |dd      ||             |S 7 H7 &7 # t*        $ r9}	t        j-                  ||	|       d{  7   t/        j0                  dj3                  t5        |	                   t/        j6                  t9        j:                                t=        |	t              r\t?        t!        |	dt5        |	j@                              t!        |	dd      t!        |	dd      t!        |	dtB        jD                              t5        |	       }
t?        t!        |	d|
      t!        |	dd      t!        |	dd      t!        |	dd      t!        |	dd            d}	~	ww xY ww)z
    Returns a list of assistants.

    API Reference docs - https://platform.openai.com/docs/api-reference/assistants/listAssistants
    Nr  r  r  r  r  r   r  r  r  rL  r  r  r  r"  r  zClitellm.proxy.proxy_server.get_assistants(): Exception occured - {}r!   rX  r  rs  r  r  r  r  r   )#r  r   r"  r   r-  r   r   r  no_llm_routerry  aget_assistantsr<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  r  r  r  rn  r  r
  rL  r  r  r  r#  s              r(   get_assistantsrY    s    * DIlln 1-/%
 
 2C2Q2Q2W2W(X  $33;d;; 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 [ 	
 <:  66/ATX 7 
 	
 	
 	""QXXA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1#Avt4Qs3 'si   J/E) E!$E) E$A	E) E'	CE)  J/!E) $E) 'E) )
J,3J'FDJ''J,,J/c                   K   i }	 | j                          d{   }t        j                  |      }t        || t        |t
        t               d{   }t        't        ddt        j                  j                  i      t        j                  di | d{   }t        j                  t        j!                  |j#                  dd      d	             t%        |d
i       xs i }|j#                  dd      xs d}|j#                  dd      xs d}|j#                  dd      xs d}	|j&                  j)                  t+        j,                  ||||	t
        t%        |dd      ||             |S 7 ]7 &7 # t.        $ r8}
t        j1                  ||
|       d{  7   t3        j4                  dj7                  t9        |
                   t3        j:                  t=        j>                                tA        |
t              r\tC        t%        |
dt9        |
jD                              t%        |
dd      t%        |
dd      t%        |
dtF        jH                              t9        |
       }tC        t%        |
d|      t%        |
dd      t%        |
dd      t%        |
dt%        |
dd                  d}
~
ww xY ww)z~
    Create assistant

    API Reference docs - https://platform.openai.com/docs/api-reference/assistants/createAssistant
    Nr  r  r  r  r  r   r  r  r  rL  r  r  r  r"  r  zElitellm.proxy.proxy_server.create_assistant(): Exception occured - {}r!   rX  r  rs  r  r  r  r   )%r  r  r7  r   r"  r   r-  r   r   r  rV  ry  acreate_assistantsr<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  )r  r  r  rn  r  r  r
  rL  r  r  r  r#  s               r(   create_assistantr\    s    * DI\\^#||D! 1-/%
 
 2C2Q2Q2W2W(X  $66>>> 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 ] $
 ?:  66/ATX 7 
 	
 	
 	""SZZA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Q=#(FG	 'sk   KE> E69E> E9A	E> E<CE> 5K6E> 9E> <E> >
K J;#F&$DJ;;K  Kz"/v1/assistants/{assistant_id:path}z/assistants/{assistant_id:path}assistant_idc                 .  K   i }	 t        || t        |t        t               d{   }t        't        ddt        j                  j                  i      t	        j                  dd|i| d{   }t        j                  t        j                  |j                  dd      d	
             t        |di       xs i }|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}	|j                   j#                  t%        j&                  ||||	t        t        |dd      ||             |S 7 %7 # t(        $ r8}
t        j+                  ||
|       d{  7   t-        j.                  dj1                  t3        |
                   t-        j4                  t7        j8                                t;        |
t
              r\t=        t        |
dt3        |
j>                              t        |
dd      t        |
dd      t        |
dt@        jB                              t3        |
       }t=        t        |
d|      t        |
dd      t        |
dd      t        |
dt        |
dd                  d}
~
ww xY ww)z~
    Delete assistant

    API Reference docs - https://platform.openai.com/docs/api-reference/assistants/createAssistant
    r  Nr  r  r  r]  r  r   r  r  r  rL  r  r  r  r"  r  zElitellm.proxy.proxy_server.delete_assistant(): Exception occured - {}r!   rX  r  rs  r  r  r  r   )"r   r"  r   r-  r   r   r  rV  ry  adelete_assistantr<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  )r  r]  r  r  rn  r  r
  rL  r  r  r  r#  s               r(   delete_assistantr`  p  s    , DG 1-/%
 
 2C2Q2Q2W2W(X  $55X<XSWXX 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 U
 Y:  66/ATX 7 
 	
 	
 	""SZZA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Q=#(FG	 'Y   J E EAE 2E3CE 
JE E 
JJ5E86DJJJz/v1/threadsz/threadsc                 `  K   i }	 | j                          d{    t        || t        |t        t               d{   }t
        't        ddt        j                  j                  i      t        j                  di | d{   }t        j                  t        j                  |j                  dd      d	             t!        |d
i       xs i }|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}|j"                  j%                  t'        j(                  ||||t        t!        |dd      ||             |S 7 H7 &7 # t*        $ r8}	t        j-                  ||	|       d{  7   t/        j0                  dj3                  t5        |	                   t/        j6                  t9        j:                                t=        |	t              r\t?        t!        |	dt5        |	j@                              t!        |	dd      t!        |	dd      t!        |	dtB        jD                              t5        |	       }
t?        t!        |	d|
      t!        |	dd      t!        |	dd      t!        |	dt!        |	dd                  d}	~	ww xY ww)zs
    Create a thread.

    API Reference - https://platform.openai.com/docs/api-reference/threads/createThread
    Nr  r  r  r  r  r   r  r  r  rL  r  r  r  r"  r  zClitellm.proxy.proxy_server.create_threads(): Exception occured - {}r!   rX  r  rs  r  r  r  r   )#r  r   r"  r   r-  r   r   r  rV  ry  acreate_threadr<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  rX  s              r(   create_threadsrd    s    * DHlln 1-/%
 
 2C2Q2Q2W2W(X  $22:T:: 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 [ 	
 ;:  66/ATX 7 
 	
 	
 	""QXXA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Q=#(FG	 'si   J.E) E!$E) E$A	E) E'	CE)  J.!E) $E) 'E) )
J+3J&FDJ&&J++J.z/v1/threads/{thread_id}z/threads/{thread_id}	thread_idc                 .  K   i }	 t        || t        |t        t               d{   }t        't        ddt        j                  j                  i      t	        j                  dd|i| d{   }t        j                  t        j                  |j                  dd      d	
             t        |di       xs i }|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}	|j                   j#                  t%        j&                  ||||	t        t        |dd      ||             |S 7 %7 # t(        $ r8}
t        j+                  ||
|       d{  7   t-        j.                  dj1                  t3        |
                   t-        j4                  t7        j8                                t;        |
t
              r\t=        t        |
dt3        |
j>                              t        |
dd      t        |
dd      t        |
dt@        jB                              t3        |
       }t=        t        |
d|      t        |
dd      t        |
dd      t        |
dt        |
dd                  d}
~
ww xY ww)zs
    Retrieves a thread.

    API Reference - https://platform.openai.com/docs/api-reference/threads/getThread
    r  Nr  r  r  re  r  r   r  r  r  rL  r  r  r  r"  r  z?litellm.proxy.proxy_server.get_thread(): Exception occured - {}r!   rX  r  rs  r  r  r  r   )"r   r"  r   r-  r   r   r  rV  ry  aget_threadr<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  r  re  r  r  rn  r  r
  rL  r  r  r  r#  s               r(   
get_threadri  2  s    , DE0-/%
 
 2C2Q2Q2W2W(X  $//L)LtLL 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 U
 M:  66/ATX 7 
 	
 	
 	""MTTA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Q=#(FG	 'ra  z /v1/threads/{thread_id}/messagesz/threads/{thread_id}/messagesc                   K   i }	 | j                          d{   }t        j                  |      }t        || t        |t
        t               d{   }t        't        ddt        j                  j                  i      t        j                  dd|i| d{   }t        j                  t        j!                  |j#                  dd      d	
             t%        |di       xs i }|j#                  dd      xs d}|j#                  dd      xs d}	|j#                  dd      xs d}
|j&                  j)                  t+        j,                  |||	|
t
        t%        |dd      ||             |S 7 _7 (7 # t.        $ r8}t        j1                  |||       d{  7   t3        j4                  dj7                  t9        |                   t3        j:                  t=        j>                                tA        |t              r\tC        t%        |dt9        |jD                              t%        |dd      t%        |dd      t%        |dtF        jH                              t9        |       }tC        t%        |d|      t%        |dd      t%        |dd      t%        |dt%        |dd                  d}~ww xY ww)zv
    Create a message.

    API Reference - https://platform.openai.com/docs/api-reference/messages/createMessage
    Nr  r  r  r  re  r  r   r  r  r  rL  r  r  r  r"  r  zAlitellm.proxy.proxy_server.add_messages(): Exception occured - {}r!   rX  r  rs  r  r  r  r   )%r  r  r7  r   r"  r   r-  r   r   r  rV  ry  a_add_messager<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  r  re  r  r  rn  r  r  r
  rL  r  r  r  r#  s                r(   add_messagesrm    s    , DI\\^#||D! 1-/%
 
 2C2Q2Q2W2W(X  $11NINNN 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 ] $
 O:  66/ATX 7 
 	
 	
 	""OVVA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Q=#(FG	 'sk   KF  E89F  E;AF  E> CF  7K8F  ;F  >F   
K
J=%F(&DJ==KKc                 .  K   i }	 t        || t        |t        t               d{   }t        't        ddt        j                  j                  i      t	        j                  dd|i| d{   }t        j                  t        j                  |j                  dd      d	
             t        |di       xs i }|j                  dd      xs d}|j                  dd      xs d}|j                  dd      xs d}	|j                   j#                  t%        j&                  ||||	t        t        |dd      ||             |S 7 %7 # t(        $ r8}
t        j+                  ||
|       d{  7   t-        j.                  dj1                  t3        |
                   t-        j4                  t7        j8                                t;        |
t
              r\t=        t        |
dt3        |
j>                              t        |
dd      t        |
dd      t        |
dt@        jB                              t3        |
       }t=        t        |
d|      t        |
dd      t        |
dd      t        |
dt        |
dd                  d}
~
ww xY ww)z
    Returns a list of messages for a given thread.

    API Reference - https://platform.openai.com/docs/api-reference/messages/listMessages
    r  Nr  r  r  re  r  r   r  r  r  rL  r  r  r  r"  r  zAlitellm.proxy.proxy_server.get_messages(): Exception occured - {}r!   rX  r  rs  r  r  r  r   )"r   r"  r   r-  r   r   r  rV  ry  aget_messagesr<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  rh  s               r(   get_messagesrp    s    , DE0-/%
 
 2C2Q2Q2W2W(X  $11NINNN 	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 U
 O:  66/ATX 7 
 	
 	
 	""OVVA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Q=#(FG	 'ra  z/v1/threads/{thread_id}/runsz/threads/{thread_id}/runsc                   K   i }	 | j                          d{   }t        j                  |      }t        || t        |t
        t               d{   }t        't        ddt        j                  j                  i      t        j                  dd|i| d{   }d|v r)|d   du r"t        t        |||	      d
i        d{   S t        j                   t"        j%                  |j'                  dd      d             t)        |di       xs i }|j'                  dd      xs d}|j'                  dd      xs d}	|j'                  dd      xs d}
|j*                  j-                  t/        j0                  |||	|
t
        t)        |dd      ||             |S 7 7 U7 7 # t2        $ r8}t"        j5                  |||       d{  7   t7        j8                  dj;                  t=        |                   t7        j>                  tA        jB                                tE        |t              r\tG        t)        |dt=        |jH                              t)        |dd      t)        |dd      t)        |dtJ        jL                              t=        |       }tG        t)        |d|      t)        |dd      t)        |dd      t)        |dt)        |dd                  d}~ww xY ww) zi
    Create a run.

    API Reference: https://platform.openai.com/docs/api-reference/runs/createRun
    Nr  r  r  r  re  r  Tr(  r  )	generatorr  r  r  r   r  r  r  rL  r  r  r  r"  r  z?litellm.proxy.proxy_server.run_thread(): Exception occured - {}r!   rX  r  rs  r  r  r  r   )'r  r  r7  r   r"  r   r-  r   r   r  rV  ry  arun_threadrf   r&  r<  r=  r  r  r4  r  r  r  re   r  r  r  r=   r  r6   r2  r  r  r   r1  r  r  r   r  rl  s                r(   
run_threadrt  S  s    , DT\\^#||D!0-/%
 
 2C2Q2Q2W2W(X  $//L)LtLL h4!729&7%!%
 /   	33 $):B ?	 4 	
  *:B?E2 $$Z6<"!%%k48>B	 $$Z6<"  '')<<"3!#!$%68NPRS!+		
 u $
 M
J  66/ATX 7 
 	
 	
 	""MTTA	

 	""9#7#7#9:a' 9c!((m<Q/a&1Qv/J/JK	  q6(I 9i8Q/a&1Q=#(FG	 's   K5F0 F%9F0 F(AF0 F+ ,F0 F.F0 K5CF0 $K5%F0 (F0 +F0 .F0 0
K2:K-GDK--K22K5z/utils/token_counterz	llm utils)rg  r  response_modelc                   K   ddl m} | j                  }| j                  }||t	        dd      d}d}d}t
        =t
        j                  D ]*  }|d   | j                  k(  s|}|j                  di       } n |:|j                  d	i       j                  d
      }d|v r|j                  dd      d   }|xs | j                  }d}	|'t        t        t           |j                  dd            }	t         j                  j                  ||	      }
t        |
d         } |||||
      }t!        || j                  ||      S w)r1   r   )token_counterNr  z#prompt or messages must be providedr  r  rS  r  r  r_  r  custom_tokenizer)r  rx  rX  )r  r  r,   rx  )r  r0  
model_usedtokenizer_type)r	  rw  promptr,   r   r   r<  r  r4  rj  r   r	   r   r  _select_tokenizerr2  TokenCountResponse)r  rw  r{  r,   ri  r  rS  _modelmodel_to_userx  _tokenizer_usedtokenizer_usedr  s                r(   rw  rw    s     & ^^FH~(*$I
 	
 J)-J ++Fl#w}}4#
'^^L"=
	 ,
 '^^,<bAEEgN$$!3!9!9#q!A!!D 	+gmm  >B/0NN-t4
 mm55-= 6 O 01N (	L !mm%	 s   A!E$C"Ez/utils/supported_openai_params)rg  r  c                    K   	 t        j                  |       \  } }}}dt        j                  | |      iS # t        $ r t	        dddj                  |       i      w xY ww)a*  
    Returns supported openai params for a given litellm model name

    e.g. `gpt-4` vs `gpt-3.5-turbo`

    Example curl:
    ```
    curl -X GET --location 'http://localhost:4000/utils/supported_openai_params?model=gpt-3.5-turbo-16k'         --header 'Authorization: Bearer sk-1234'
    ```
    rY  supported_openai_paramsr  r  r  r  zCould not map model={}r  )r	  get_llm_providerget_supported_openai_paramsr  r   r6   )r  r  r`  s      r(   r  r    sx     "

+2+C+C%+P("Aq%w'J'J1D(
 	

  
W.F.M.Me.T$U
 	

s   A#38 A#(A  A#z/utils/transform_requestc                 R   K   ddl m}  || j                  | j                        S w)Nr   )return_raw_request)endpointr  )r  r  r  request_body)r  r  s     r(   transform_requestr  )  s$      1w'8'8AUAUVVs   %'rP  c                 |  K   |'t        ddt        j                  j                  i      g }| D ]  }|j	                  di       j	                  dd      }|(|j
                  j                  j                  d|i       d{   }|[|j                  |j                  k(  su|j                  |        |S 7 6w)	
    Check if model is in db

    Check if db model is 'created_by' == user_api_key_dict.user_id

    Only return models that match
    Nr  r  r  rS  rM  rL  r  )r   r  db_not_connected_errorry  r4  r  r  find_uniquerQ  r  rn  )rP  r  r   filtered_modelsr  rM  rN  s          r(   _check_if_model_is_user_addedr  5  s      .EEKKL
 	
 OYY|R(,,T48:&))AAMMr" N 
 
 ""&7&?&??&&u-  
s   BB<B:B<B<%B<user_rowc                     g }| D ]U  }|j                  di       j                  dd      }|(||j                  v s7|j                  t        t        |             W |S )zm
    Check if model is a team model

    Check if user is a member of the team that the model belongs to
    rS  r  N)r4  rU  rn  r   r  )rP  r  user_team_modelsr  model_team_ids        r(   _check_if_model_is_team_modelr  T  s`     $&		,377	4H$. ''T5(9:  r*   r  c                   K   |'t        ddt        j                  j                  i      t	        | ||       d{   } |j
                  r]	 |j                  j                  j                  d|j
                  i       d{   }| t        |j                         xs g |
      z  } t        |       }|S 7 {7 6# t        $ r t        ddd	i      w xY ww)r  Nr  r  r  )rP  r  r   r  r  r  zUser not found)rP  r  )rP  )r   r  r  ry  r  r  r  litellm_usertabler  r  r  r  r   )r  r   r  r   r  unique_modelss         r(   non_admin_all_modelsr  h  s      .EEKKL
 	
 5+# J   	U*--??KK "3";";< L  H 	3,,.4"
 	

 7jIM-  	UCBR8STT	Us9   ;CB9C5B= B;B= 	1C;B= =CCteam_db_objects_typedc                    i }| D ]  }t        |j                        dk(  s&t        j                  j                  |j                  v r|j                         }|U|D ]  }|j                  di       j                  dd      }|(|j                  di       j                  dd      }d}|d}n||j                  v rd}|sd|j                  |t                     j                  |j                          |j                  D ]  }	|j                  |	|j                        }
|
#|
D ]Z  }|j                  di       j                  dd      }|(|j                  |t                     j                  |j                         \   |S )	z'
    Add team models to all models
    r   NrS  rM  r  FT)r  r  )rE  rP  SpecialModelNamesall_proxy_modelsry  r  r4  r  r  setadd)r  r   r  r  r<  r  rL  team_model_idcan_add_modelr  _modelss              r(   _add_team_models_to_all_modelsr    s    (*K, ""#q( 1177;;M;MM $224J%'E$yyr:>>tTJH' $)IIlB$?$C$CIt$TM$)M$,(,&+*=*==(,$#..x?CCKDWDWX ( *00
$33);3F3F 4  &!(#(99\2#>#B#B4#N#/'228SUCGG + 3 3 ") 11 -F r*   
user_teamsc           	        K   g }| dk(  rS|j                   j                  j                          d{   }|D cg c]  }t        di |j	                          }}nX|j                   j                  j                  dd| ii       d{   }|D cg c]  }t        di |j	                          }}t        ||      }i }|j                         D ]  \  }}	t        |	      ||<    |S 7 c c}w 7 hc c}w w)z
    Get all models across all teams user is in.

    1. Get all teams user is in
    2. Get all models across all teams
    3. Return {"model_id": ["team_id1", "team_id2"]}
    rW   Nr  r[  r  )r  r   r   )r  litellm_teamtabler  LiteLLM_TeamTabler  r  rh  re  )
r  r   r   r  team_db_objectsteam_db_objectr  returned_team_modelsrL  team_idss
             r(   get_all_team_modelsr    s)     68S - 0 0 B B L L NN #2!
 < 9 9 ;<!
 !

 !. 0 0 B B L LtZ01 !M !
 
 #2!
 < 9 9 ;<!
 !

 13K 24)//1()-hX& 2  3 O!


!
s>   /C:C,C: C.0C:
C3C: C53:C:.C:5C:user_db_objectc                     g }| j                   D ]T  }|j                  |      }||D ]8  }|j                  di       j                  dd      }|(|j                  |       : V |S )z7
    Get all models that user has direct access to
    r  NrS  rM  )rP  r  r4  rn  )r  r   direct_access_modelsr  deploymentsri  rL  s          r(   get_direct_access_modelsr    sv     ')&& //5/A")
%>>,;??dK'(//9 * '  r*   c                   K   d}g }| j                   t        j                  k(  rd}|j                  d      }n~| j                  r|j
                  j                  j                  d| j                  i       d{   }|6t        di |j                         }|j                  xs g }t        ||      }|t        |||       d{   }|D ]  }	|	j                  d	i       j                  d
d      }
|	j                  d	i       j                  dd      }|
Jd}||j                  |
g       }|r	||v rd}nd}|sn|j                  |
g       |	d	   d<    |D ]4  }	|	j                  d	i       j                  d
d      }
|
(|
|v s-d|	d	   d<   6 |D 	cg c]H  }	|	j                  d	i       j                  dd      s"|	j                  d	i       j                  dg       r|	J }}	|S 7 m7  c c}	w w)z5
    Get all models across all teams user is in.
    NrW   T)exclude_team_modelsr  r  )r  r   )r  r   r   rS  rM  r  Faccess_via_team_idsdirect_accessr   )	user_roleLitellmUserRolesPROXY_ADMINr\  r  r  r  r  LiteLLM_UserTabler  rU  r  r  r4  )r  r   r   r  r  r  r  user_objectr  r~  rL  team_only_model_idcan_use_modelr  s                 r(   %get_all_team_and_direct_access_modelsr    s>     <@J&(""&6&B&BB
)77 $  8  
 
	"	"	.,//AAMM/778  N  
 
 %+Jn.G.G.IJK$**0bJ#;*%$ 
 /!'!
 

 !Fzz,377dCH!'L"!=!A!A)T!R# %%1*x<H$6($B(,$(M BM// "CF<()>? !$ ::lB/33D$?H0D$D48F< 1	  !::lB'++OUC::lB'++,A2F 	J  a

<sR   A8G2:G';AG2
G*AG2#G2?AG2G2G2AG-#G2*G2-G2z/v2/model/infozv2 - returns models available to the user based on their API key permissions. Shows model info from config.yaml (except api key and api base). Filter to just user-added models with ?user_models_only=true)rN  rg  r  include_in_schemaz!Specify the model name (optional)z%Only return models added by this userz.Return all models across all teams user is in.user_models_onlyinclude_team_modelsr  c                    K   t         t        dddt          di      t        't        ddt        j                  j
                  i      t        j                          d{    t        j                  t         j                        }t        
|t        gz  }||D cg c]  }|d   |k(  s| }}|rt        |t         | t               d{   }|rt        | t        t         |	       d{   }|D ]6  }|j                  d
i       }|du r7d}	t         t         j                  |i d      xs d}	nd}	t!        |	      }
|
|d<   t#        |      }|i k(  r;|j                  di       }|j                  dd      }	 t%        j&                  |      }|i k(  rc|j                  di       }|j                  dd      }|j+                  d      }t-        |      dkD  r|d   }	 t%        j&                  ||d         }|j/                         D ]  \  }}||vs|||<    ||d
<   t1        |      }9 t3        j4                  d|       d|iS 7 c c}w 7 7 f# t(        $ r i }Y w xY w# t(        $ r i }Y {w xY ww)zQ
    BETA ENDPOINT. Might change unexpectedly. Use `/v1/model/info` for now.
    Nr  r  z$No model list passed, models router=zI. You can add a model through the config.yaml or on the LiteLLM Admin UI.r  r  )r  r   r  r   )r  r   r   r  rS  Tr  async)ri  r  client_typellm_router_is_Noneopenai_clientrY  r  r  r_  r   ri  r  all_models: %srn  )r   r   r   r  r  ry  r-  r  rB  rC  r<  r  r  r  r4  _get_clientr2  r:  r	  r7  r  rj  rE  rh  rq   r=   r  )r  r  r  r  r  r  r_  r~  rS  _openai_clientr  r9  r  litellm_modelsplit_modelr  r  s                    r(   model_info_v2r  H  s    2 ?
|  LU  V
 	
 .EEKKL
 	
 
!
!
###z445Jzl"
!+HAq%/GaH
H/!!/'	
 

 @/'!!	
 

 ZZb1
D=#N%**#)"' +   	  "6/M&3F?# 4&A ##ZZ(8"=N*..w=M(%,%;%;-%P" ##ZZ(8"=N*..w=M'--c2K;!# +B(%,%;%;'[^&"
 ',,.DAq
" !
1 /  *| 7v>e h /<J_ $ I

F  (%'"(  (%'"(s   A"I>$I%=I>"I0I4I>I I>3I4BI>IAI>%I-?I>5I>I>I>I*'I>)I**I>-I;8I>:I;;I>z/model/streaming_metricsz1View time to first token for models in spend logs)rN  rg  r  r  _selected_model_group	startTimeendTimec                   K   t         5t        t        j                  j                  ddt
        j                        |xs! t        j                         t        d      z
  }|xs t        j                         }|j                         |j                         k(  }|rd}nd}t               }t         j                  j                  ||||       d {   }i }||D ]  }	|	d   }
|	d	   }|	d
   }d}|r|	d   }|}||vri ||<   n|	d   }|}|	d
   }||vri ||<   t        |      }d|
v rt        |
      }d|v r|j                  d      d   }|j!                  |       |||   |<    	 g }t#        t%        |j'                         d             }|D ]@  }dt        |      i}||   j'                         D ]
  \  }}|||<    |j)                  |       B |t+        |      dS y 7 w)Ninternal_errorr  r     rk  a  
            SELECT
                api_base,
                model_group,
                model,
                "startTime",
                request_id,
                EXTRACT(epoch FROM ("completionStartTime" - "startTime")) AS time_to_first_token
            FROM
                "LiteLLM_SpendLogs"
            WHERE
                "model_group" = $1 AND "cache_hit" != 'True'
                AND "completionStartTime" IS NOT NULL
                AND "completionStartTime" != "endTime"
                AND DATE("startTime") = DATE($2::timestamp)
            GROUP BY
                api_base,
                model_group,
                model,
                request_id
            ORDER BY
                time_to_first_token DESC;
        a  
            SELECT
                api_base,
                model_group,
                model,
                DATE_TRUNC('day', "startTime")::DATE AS day,
                AVG(EXTRACT(epoch FROM ("completionStartTime" - "startTime"))) AS time_to_first_token
            FROM
                "LiteLLM_SpendLogs"
            WHERE
                "startTime" BETWEEN $2::timestamp AND $3::timestamp
                AND "model_group" = $1 AND "cache_hit" != 'True'
                AND "completionStartTime" IS NOT NULL
                AND "completionStartTime" != "endTime"
            GROUP BY
                api_base,
                model_group,
                model,
                day
            ORDER BY
                time_to_first_token DESC;
        r  r  time_to_first_tokenr   
request_idrn  https:///openai/r   c                     | d   S Nr   r   r{  s    r(   <lambda>z)model_streaming_metrics.<locals>.<lambda>9  	    dSTgr*   r  datern  all_api_bases)r   r  r  r  ry  r   r  r   r~  r   r  r  r  	query_rawr2  rj  r  r5  r  rh  rn  re  )r  r  r  r  is_same_day	sql_query_all_api_basesdb_response_daily_entriesr  	_api_baser~  r  
unique_key_request_id_day_combined_model_namer  rn  entry	model_keylatencys                         r(   model_streaming_metricsr    s9     %<<BB!66	
 	
 ?X\\^iQ.??I'G.."glln4K	0	. UN%((22()W K N%J":.I(F",-B"CJ(6(
n424N;/!%(!
&01F&G#~-+-N4(#&v; Y&'*9~$11';'A'A*'Ma'P$34?RN:&';<1 &4	  " f^%9%9%;AUVW!CSX&E&4S&9&?&?&A"	7#*i  'BOOE"	 " !.1
 	
_ 	s   CG&G#DG&z/model/metricsz>View number of requests & avg latency per model on config.yamlz	gpt-4-32kapi_keycustomerc                 P  K   t         t        dddt        j                        |xs% t	        j
                         t        t              z
  }|xs t	        j
                         }||dk(  rd}||dk(  rd}d}t               }t         j                  j                  ||||||       d {   }i }	||D ]n  }
|
d	   }|
d
   }|
d   }|
d   }||	vri |	|<   t        |      }|d|v rt        |      }|d|v r|j                  d      d   }|j                  |       ||	|   |<   p 	 g }t        t        |	j!                         d             }	|	D ]@  }dt        |      i}|	|   j!                         D ]
  \  }}|||<    |j#                  |       B |t%        |      dS y 7 w)N Prisma Client is not initializedr  r  r  r  	undefinednulla  
        SELECT
            api_base,
            model_group,
            model,
            DATE_TRUNC('day', "startTime")::DATE AS day,
            AVG(EXTRACT(epoch FROM ("endTime" - "startTime")) / NULLIF("completion_tokens", 0)) AS avg_latency_per_token
        FROM
            "LiteLLM_SpendLogs"
        WHERE
            "startTime" >= $2::timestamp AND "startTime" <= $3::timestamp
            AND "model_group" = $1 AND "cache_hit" != 'True'
            AND (
                CASE
                    WHEN $4 != 'null' THEN "api_key" = $4
                    ELSE TRUE
                END
            )
            AND (
                CASE
                    WHEN $5 != 'null' THEN "end_user" = $5
                    ELSE TRUE
                END
            )
        GROUP BY
            api_base,
            model_group,
            model,
            day
        HAVING
            SUM(completion_tokens) > 0
        ORDER BY
            avg_latency_per_token DESC;
    r  r  rn  avg_latency_per_tokenr  r  r   c                     | d   S r  r   r  s    r(   r  zmodel_metrics.<locals>.<lambda>  r  r*   r  r  r  )r   r  r   r  r   r~  r   rA   r  r  r  r2  rj  r  r5  r  rh  rn  re  )r  r  r  r  r  r  r  r  r  r  r  r  r~  r  _avg_latency_per_tokenr  r  rn  r  r  r  s                        r(   model_metricsr  F  s      6!66	
 	
 MX\\^i_.MMI'G'[08{2!ID UN%((22()Wgx K N%J":.I(Fe$D%/0G%H">)')t$#&v; $y)@'*9~$#/JBV4V';'A'A*'Ma'P$349ON4 !56 & 	  " f^%9%9%;AUVW!CSX&E&4S&9&?&?&A"	7#*i  'BOOE"	 " !.1
 	
K s   B*F&,F$-C8F&z/model/metrics/slow_responsesz/View number of hanging requests per model_groupc           	      ,  K   t         t        dddt        j                        ||dk(  rd}||dk(  rd}|xs% t	        j
                         t        t              z
  }|xs t	        j
                         }t        j                  j                  xs t        }t        |      }d}t         j                  j                  |||||||       d {   }|9|D ]4  }	|	j                  d	      xs d
}
d|
v r|
j!                  d      d   }
|
|	d	<   6 |S 7 Aw)Nr  r  r  r  r  r  r  a  
SELECT
    api_base,
    COUNT(*) AS total_count,
    SUM(CASE
        WHEN ("endTime" - "startTime") >= (INTERVAL '1 SECOND' * CAST($1 AS INTEGER)) THEN 1
        ELSE 0
    END) AS slow_count
FROM
    "LiteLLM_SpendLogs"
WHERE
    "model_group" = $2
    AND "cache_hit" != 'True'
    AND "startTime" >= $3::timestamp
    AND "startTime" <= $4::timestamp
    AND (
        CASE
            WHEN $5 != 'null' THEN "api_key" = $5
            ELSE TRUE
        END
    )
    AND (
        CASE
            WHEN $6 != 'null' THEN "end_user" = $6
            ELSE TRUE
        END
    )
GROUP BY
    api_base
ORDER BY
    slow_count DESC;
    r  r   r  r   )r   r  r   r  r   r~  r   rA   r  r  r/  r   r  r  r  r4  rj  )r  r  r  r  r  r  r/  r  r  rowr  s              r(   model_metrics_slow_responsesr    s8      6!66	
 	
 '[08{2MX\\^i_.MMI'G 	11DD 	,+  /0IB &((22 K C
+1rIY&%OOJ7:	'C
O	 
 !s   CDDADz/model/metrics/exceptionsz7View number of failed requests per model on config.yamlc                   K   t         t        dddt        j                        |xs% t	        j
                         t        t              z
  }|xs t	        j
                         }||dk(  rd}	 d}t         j                  j                  |||||       d {   }g }t               }		 ||D ]  }
|
j                  d	d
      }|
j                  dd      }|
j                  di       }||d}|j                  |       |j                  |       |j                         D ]  \  }}|	j                  |         |t!        |	      dS 7 w)Nr  r  r  r  r  r  r  aD  
        WITH cte AS (
            SELECT 
                CASE WHEN api_base = '' THEN litellm_model_name ELSE CONCAT(litellm_model_name, '-', api_base) END AS combined_model_api_base,
                exception_type,
                COUNT(*) AS num_rate_limit_exceptions
            FROM "LiteLLM_ErrorLogs"
            WHERE 
                "startTime" >= $1::timestamp 
                AND "endTime" <= $2::timestamp 
                AND model_group = $3
            GROUP BY combined_model_api_base, exception_type
        )
        SELECT 
            combined_model_api_base,
            COUNT(*) AS total_exceptions,
            json_object_agg(exception_type, num_rate_limit_exceptions) AS exception_counts
        FROM cte
        GROUP BY combined_model_api_base
        ORDER BY total_exceptions DESC
        LIMIT 200;
    combined_model_api_baser   total_exceptionsr   exception_counts)r  r  )rn  exception_types)r   r  r   r  r   r~  r   rA   r  r  r  r4  r  rn  rh  r  re  )r  r  r  r  r  r  r  r  r  r  r  r  r  r   curr_rowr  r  s                    r(   model_metrics_exceptionsr    s]      6!66	
 	
 MX\\^i_.MMI'G'[0I, &((229g'<g K HeO %JNN#<bAE)~~.@!D)~~.@"E$4H OO,-OOH%(..01##A& 1 & o1FGG?s   BE
EB/E
c                 <   | j                  di       }t        |       }|i k(  r;| j                  di       }|j                  dd       }	 t        j                  |      }|i k(  rc| j                  di       }|j                  dd       }|j                  d      }t        |      dkD  r|d   }	 t        j                  ||d         }|j                         D ]  \  }}||vs|||<    || d<   t        | 	      } | S # t        $ r i }Y w xY w# t        $ r i }Y Sw xY w)
NrS  rY  r  r  r_  r   ri  r  deployment_dict)	r4  r:  r	  r7  r  rj  rE  rh  rq   )r  rS  r9  r  r  r  r  r  s           r(   _get_proxy_model_infor  k  sF   <,J 0e< R#3R8&**7D9	$!(!7!7m!L R#3R8&**7D9#))#.{a'OM	$!(!7!7#Q"
 #((*1JJqM + %E,1%HEL/  	$!#	$  	$!#	$s$   	C< -D <D
	D
DDz/model/infoz/v1/model/infolitellm_model_idc           
      6  K   t         e	 t        t        t        j                  t                     }t        dt        t               |      }|j                         }t        |      }d|iS t        t        dddi	      t        t        ddd
i	      |Lt        j                  |      }|t        ddd| di	      t        |j                  d            }d|giS g }t        t               }t        g }n(t        j#                         }t        j%                         }t'        | ||      }	t)        | j*                  ||      }
t-        |	|
|t         t.        j1                  dd      t              }t3        |      dkD  rQg }|D ],  }t        j5                  |      }||j7                  |       . t        t9        j:                  |      }ng }|D ]  }t        |      } t=        j>                  d|       d|iS # t
        $ r i }Y w xY ww)a  
    Provides more info about each model in /models, including config.yaml descriptions (except api key and api base)

    Parameters:
        litellm_model_id: Optional[str] = None (this is the value of `x-litellm-model-id` returned in response headers)

        - When litellm_model_id is passed, it will return the info for that specific model
        - When litellm_model_id is not passed, it will return the info for all models

    Returns:
        Returns a dictionary containing information about each model.

    Example Response:
    ```json
    {
        "data": [
                    {
                        "model_name": "fake-openai-endpoint",
                        "litellm_params": {
                            "api_base": "https://exampleopenaiendpoint-production.up.railway.app/",
                            "model": "openai/fake"
                        },
                        "model_info": {
                            "id": "112f74fab24a7a5245d2ced3536dd8f5f9192c57ee6e332af0f0512e08bed5af",
                            "db_model": false
                        }
                    }
                ]
    }

    ```
    rY  rW   rh  r  rn  r  r  zLLM Model List not loaded in. Make sure you passed models in your config.yaml or on the LiteLLM Admin UI. - https://docs.litellm.ai/docs/proxy/configsr  zLLM Router is not loaded in. Make sure you passed models in your config.yaml or on the LiteLLM Admin UI. - https://docs.litellm.ai/docs/proxy/configs)rL  r  zModel id = z not found on litellm proxyTrs  r  r  r  r  r  r  r  Fr  r  r  r  r  r   r   r  r  ) r  r   r  r	  r7  r  r   r   r  rq   r0  r   r   get_deploymentr  r9   re  r  r  r`   rb   r  r_   r"  r4  rE  r  ri  rB  rC  r=   r  )r  r  rS  _deployment_info_deployment_info_dictdeployment_infor  r  r  r  r  all_models_str_relevant_modelsr  router_modelsin_place_models                   r(   model_info_v1r    sw    ` 	#D'*@*@z*RSJ &)  "
 !1 ; ; = E1!
 -..  r
 	
   q
 	
 #$33=M3N"{+;*<<WX  !6!,,$,?!
 ./00J0;D0A%557(@@B+)/J
 "%11)/K
 -).223JERN >Q#E&555GM( ''6 $ %'78JJ$.^D % /<Jq  	J	s/   H(H E6H)AHHHHHr  rZ  c           	      j   g }t        |      }|D ]e  }|||k7  r| j                  |      }|)|j                  t        di |j	                                Ht        |g       }|j                  |       g t
        j                  +|D ]&  }|j                  t
        j                  v s d|_        ( |S )N)rZ  )rZ  	providersTr   )	r  get_model_group_inforn  r   r  r	  public_model_groupsrZ  is_public_model_group)	r   r  rZ  model_groupsall_models_str_setr  _model_group_infomodel_group_infomgs	            r(   _get_model_group_infor   #  s     /1L^,#"{e';&;;;N( 3 U6G6R6R6T UV2!   01 $  "".B~~!<!<<+/(  r*   z/model_group/infoc           
      D  K   t         t        dddi      t        t        dddi      t        t              }t        g }n(t        j                         }t        j                         }t        | ||      }g }| j                  s| j                  t        |       st        't        ddt        j                  j                  i      t        j                  j                   j#                  d| j                  i	       d{   }t%        di |j'                         }g }|t)        |j*                  ||
      }|}nt)        | j,                  ||
      }t/        |||t0        t2        j5                  dd      t              }	t7        t        |	|      }
d|
iS 7 w)a  
    Get information about all the deployments on litellm proxy, including config.yaml descriptions (except api key and api base)

    - /model_group/info returns all model groups. End users of proxy should use /model_group/info since those models will be used for /chat/completions, /embeddings, etc.
    - /model_group/info?model_group=rerank-english-v3.0 returns all model groups for a specific model group (`model_name` in config.yaml)



    Example Request (All Models):
    ```shell
    curl -X 'GET'     'http://localhost:4000/model_group/info'     -H 'accept: application/json'     -H 'x-api-key: sk-1234'
    ```

    Example Request (Specific Model Group):
    ```shell
    curl -X 'GET'     'http://localhost:4000/model_group/info?model_group=rerank-english-v3.0'     -H 'accept: application/json'     -H 'Authorization: Bearer sk-1234'
    ```

    Example Request (Specific Wildcard Model Group): (e.g. `model_name: openai/*` on config.yaml)
    ```shell
    curl -X 'GET'     'http://localhost:4000/model_group/info?model_group=openai/tts-1'
    -H 'accept: application/json'     -H 'Authorization: Bearersk-1234'
    ```

    Learn how to use and set wildcard models [here](https://docs.litellm.ai/docs/wildcard_routing)

    Example Response:
    ```json
        {
            "data": [
                {
                "model_group": "rerank-english-v3.0",
                "providers": [
                    "cohere"
                ],
                "max_input_tokens": null,
                "max_output_tokens": null,
                "input_cost_per_token": 0.0,
                "output_cost_per_token": 0.0,
                "mode": null,
                "tpm": null,
                "rpm": null,
                "supports_parallel_function_calling": false,
                "supports_vision": false,
                "supports_function_calling": false,
                "supported_openai_params": [
                    "stream",
                    "temperature",
                    "max_tokens",
                    "logit_bias",
                    "top_p",
                    "frequency_penalty",
                    "presence_penalty",
                    "stop",
                    "n",
                    "extra_headers"
                ]
                },
                {
                "model_group": "gpt-3.5-turbo",
                "providers": [
                    "openai"
                ],
                "max_input_tokens": 16385.0,
                "max_output_tokens": 4096.0,
                "input_cost_per_token": 1.5e-06,
                "output_cost_per_token": 2e-06,
                "mode": "chat",
                "tpm": null,
                "rpm": null,
                "supports_parallel_function_calling": false,
                "supports_vision": false,
                "supports_function_calling": true,
                "supported_openai_params": [
                    "frequency_penalty",
                    "logit_bias",
                    "logprobs",
                    "top_logprobs",
                    "max_tokens",
                    "max_completion_tokens",
                    "n",
                    "presence_penalty",
                    "seed",
                    "stop",
                    "stream",
                    "stream_options",
                    "temperature",
                    "top_p",
                    "tools",
                    "tool_choice",
                    "function_call",
                    "functions",
                    "max_retries",
                    "extra_headers",
                    "parallel_tool_calls",
                    "response_format"
                ]
                },
                {
                "model_group": "llava-hf",
                "providers": [
                    "openai"
                ],
                "max_input_tokens": null,
                "max_output_tokens": null,
                "input_cost_per_token": 0.0,
                "output_cost_per_token": 0.0,
                "mode": null,
                "tpm": null,
                "rpm": null,
                "supports_parallel_function_calling": false,
                "supports_vision": true,
                "supports_function_calling": false,
                "supported_openai_params": [
                    "frequency_penalty",
                    "logit_bias",
                    "logprobs",
                    "top_logprobs",
                    "max_tokens",
                    "max_completion_tokens",
                    "n",
                    "presence_penalty",
                    "seed",
                    "stop",
                    "stream",
                    "stream_options",
                    "temperature",
                    "top_p",
                    "tools",
                    "tool_choice",
                    "function_call",
                    "functions",
                    "max_retries",
                    "extra_headers",
                    "parallel_tool_calls",
                    "response_format"
                ]
                }
            ]
            }
    ```
    Nr  r  zLLM Model List not loaded inr  zLLM Router is not loaded inr
  r  r  r  r  Fr  )r   r  rZ  rn  r   )r0  r   r   r9   re  r  r  r`   r  r  r   r   r  r  ry  r  r  r  r  r  rb   rP  r  r_   r  r"  r4  r   )r  rZ  r  r  r  r  r  user_object_typeduser_modelsr  r  s              r(   r  r  B  s    B W.L$M
 	
 W.K$L
 	

 1<D0A%557(@@B+)/J
 K%%%%1$%67 !2!I!I!O!OP  *,,>>II/778 J 
 
 .I0F0F0HI")-44!1$7K
 "%)55- 3
 -).223JERN /Dn+/L L!!?
s   DF FBF z/model/settingszMReturns provider name, description, and required parameters for each providerc            	         K   g } t         j                  D ]2  }| j                  t        |t        j                  |                   4 | S w)a?  
    Used by UI to generate 'model add' page
    {
        field_name=field_name,
        field_type=allowed_args[field_name]["type"], # string/int
        field_description=field_info.description or "", # human-friendly description
        field_value=general_settings.get(field_name, None), # example value
    }
    )r  )rZ  fields)r	  provider_listrn  ProviderInfoget_provider_fields)returned_listr  s     r(   model_settingsr*  &  sL     $ M))22xP	
 * s   A
Az/alerting/settingszFReturn the configurable alerting param, description, and current valuer-  c                   K   	 t         't        ddt        j                  j                  i      | j
                  t        j                  k7  rAt        dddj                  t        j                  j                  | j
                        i      t         j                  j                  j                  ddi       d {   }|E|j                  9t        |j                        }|j                  di       }|j                  d	      }ni }d }d
did
did
did
did
did
did
did
did
did	}t         j"                  }|j$                  j'                         }g }d}	t(        j                  d	      r$t+        t(        d	   t,              rdt(        d	   v rd}	t/        d|d   d
   d|	|dndd d      }
|j1                  |
       t2        j4                  j7                         D ]m  \  }}||v sd }||v rd}nd}t/        |||   d
   |j8                  xs d|j                  |d       ||j:                  |dk(  rdnd      }
|j1                  |
       o |S 7 w)Nr  r  r  {}, your role={}r  r"  r  r2  r-  rX  BooleanInteger)	slack_alertingdaily_report_frequencyreport_check_intervalbudget_alert_ttloutage_alert_ttlregion_outage_alert_ttlminor_outage_alert_thresholdmajor_outage_alert_thresholdmax_outage_alert_list_sizeFr.  Tr/  zhEnable slack alerting for monitoring proxy in production: llm outages, budgets, spend tracking failures.)
field_name
field_typefield_descriptionfield_valuestored_in_dbfield_default_valuepremium_fieldr   r4  )r   r   r  r  ry  r  r  r  r6   not_allowed_accessr  r  r  r  r5  r4  r  r  r2  r  r"  r1  re  
ConfigListrn  r   model_fieldsrh  rN  r+   )r  r  db_general_settings_dictalerting_args_dictalerting_valuesallowed_args_slack_alerting_slack_alerting_args_dict
return_valis_slack_enabled_response_objr8  
field_info_stored_in_dbs                 r(   alerting_settingsrM  G  s     .EEKKL
 	

 ""&6&B&BB+22%88>>%//
 	
 !. 0 0 ? ? J J/0 !K !  &+>+J+J+V#'(;(G(G#H #;#?#?QS#T*B*F*Fz*R "9-#)9"5"()!4#Y/#Y/$*I#6)/(;)/(;'-y&9
L &7%N%NO / = = H H JJJ'J$d- &z22## 01&9 E$,8Te M m$"3"@"@"F"F"H
J%,0M// $ %&%'
3F;","8"8">B599*dK*$.$6$6&*CCD
M m,' #I( Is   B<I>I?D)I)A(Iz/queue/chat/completionsr  )rg  r  r  c                   K   	 i }	 | j                          d {   }t        | j                        | j                  t	        | j
                        t        j                  |      d|d<   t        j                  d|       t        j                  dd       xs t        xs |xs |j                  dd       |d<   |j                  dd       |j                  |j                  |d<   d|vri |d<   |j                  |d   d<   |j                  |d   d	<   t	        | j
                        }|j                  d
d        ||d   d<   t!        |dd       |d   d<   |j                  |d   d<   t!        |dd       |d   d<   t        | j                        |d   d<   t"        r	t"        |d<   t$        r	t$        |d<   t&        r	t&        |d<   t(        r	t(        |d<   t*        't-        ddt.        j0                  j2                  i      t+        j4                  d)i | d {   }d|v r |d   du rt7        t9        |||      d      S |j
                  j;                  dt        |d         i       |S 7 R7 V# t<        $ r}t>        jA                  |||        d {  7   tC        |t,              rYtE        t!        |d!d"t        |       d#      tF        jH                  t!        |d$d%      t!        |d&tJ        jL                        '      tC        |tD              r|tE        d(t        |      z   tF        jH                  t!        |d$d%      tJ        jL                  '      d }~ww xY ww)*N)rN  rE  r  r  proxy_server_requestzreceiving data: %scompletion_modelr  rK  r  user_api_keyuser_api_key_metadataauthorizationr  r  user_api_key_aliasuser_api_key_user_idr  user_api_key_team_idr  r  r  r  r  r  r  r  r  Tr(  r  r  zx-litellm-prioritypriorityr  r  Authentication Error()rs  r  r  r  Authentication Error, r   )'r'  r2  rN  rE  r5  r  rB  r=   r  r"  r4  r  r  r  r  rq  r  r  r  r  r   r   r   r  rV  ry  schedule_acompletionr   r0  r  r  r  r  r1  r  ProxyErrorTypes
auth_errorr   r  )r  r  r  r  rn  _headersr  r  s           r(   async_queue_requestr`    sy     D\
\\^# w{{#nnGOO,IIdO	(
#$ 	""#7>  !3T: ''' xx&	 	W 88FD!).?.G.G.S,44DLT!!D+<+D+DZ(4E4N4NZ01(T	
 '/Z#18{D2
Z-. 4E3L3LZ/03:y$4
Z/0 (+7;;'7Z$ "2D&:D"#!0D,D2C2Q2Q2W2W(X  $88@4@@ h4!7$$&7%!%
 /  	  '')=s4
CS?T(UVQ $r A   
66/ATX 7 
 	
 	
 a' 8/DSVHA-NO$//a&1Qv/J/JK	  >*G,s1v5 ++!Wf-,,	
 	

sd   M I1 I,G=I1 I/'I1  M *I1 +M ,I1 /I1 1	M:MJCMMM z/fallback/login)rg  r  c                   K   ddl m} t        t        | j                              }t        j                  d      }|j                  d      r|dz  }n|dz  }|ddlm	}  |t        d	      S ddlm	}  |t        d	      S w)
z
    Create Proxy API Keys using Google Workspace SSO. Requires setting PROXY_BASE_URL in .env
    PROXY_BASE_URL should be the your deployed proxy endpoint, e.g. PROXY_BASE_URL="https://litellm-production-7002.up.railway.app/"
    Example:
    r   )ui_linkUI_USERNAMEr_  zsso/callbackz/sso/callback)HTMLResponser  )r  r  )litellm.proxy.proxy_serverrb  r   r2  base_urlr*  r  r  fastapi.responsesrd  rk   )r  rb  redirect_urlui_usernamerd  s        r(   fallback_loginrj  )  sz      3 "#g&6&6"78L))M*KS!&' 	3I3??2I3??s   B Bz/login)r  c                   K   ddl m} t        +t        dt        j
                  dt        j                        | j                          d {   }t        |j                  d            }t        |j                  d            }t        j                  dd	      }t        j                  d
d       }|t        t        t              nd }|+t        dt        j
                  d
t        j                        d }d }t        Kt        t        t            t        j"                  j$                  j'                  dd|ii       d {         }t)               }		 t+        j,                  ||      r5t+        j,                  ||      rt.        j0                  }t2        }
t2        }t        j                  dd       t        j4                  d   |
k(  s	|
t2        k(  rt        j                  dt2              }t7        t9        ||             d {    t        j                  d      <t;        d5ddit.        j0                  dt<        j>                  g i i d|dd	 d {   }n+t        dt        j
                  dt        j                        |d   }tA        t        | jB                              }|jE                  d      r|dz  }n|dz  }dd l#}tI        d      rLd }||}n|
t!        |
|g t<        j>                        }|tK        dd d!i"      tM        jN                  |      } ||
|d |d#tP        tR        j                  d$d%      |	tU               &	      }|jW                  t        tX        |      t        d'(      }|d)z  }t[        |d*+      }|j]                  d|,       |S |	 t_        |d-d.      }
t_        |d/t.        j`                        }t_        |dd.      }t_        |dd.      }|+t        d0t        j
                  dt        jb                        te        |1      }t+        j,                  ||      st+        j,                  ||      r=t        j                  d      .t;        d5ddi|dt<        j>                  g i i d|
dd	 d {   }n+t        dt        j
                  dt        j                        |d   }tA        t        | jB                              }|jE                  d      r|dz  }n|dz  }dd l#} ||
||t        t        |      d#tP        tR        j                  d$d%      |	tU               &	      }|jW                  t        tX        |      t        d'(      }|d)z  }t[        |d*+      }|j]                  d|,       |S t        d2| t        j
                  d3t        jb                        t        d4t        j
                  d3t        jb                        7 7 7 7 7 ew)6Nr   ReturnedUITokenObjectMaster Key not set for Proxy. Please set Master Key to use Admin UI. Set `LITELLM_MASTER_KEY` in .env or set general_settings:master_key in config.yaml.  https://docs.litellm.ai/docs/proxy/virtual_keys. If set, use `--detailed_debug` to debug issue.r   r  usernamer  rc  r  UI_PASSWORDzset Proxy master key to use UI. https://docs.litellm.ai/docs/proxy/virtual_keys. If set, use `--detailed_debug` to debug issue.
user_emailequalsr  PROXY_ADMIN_ID)r  r  r  r  rN  r  24hrlitellm-dashboard	r  rO  key_max_budgetrP  rQ  rM  r   r  r  z_No Database connected. Set DATABASE_URL in .env. If set, use `--detailed_debug` to debug issue.r  r_  zui/r   EXPERIMENTAL_UI_LOGIN)r  r  rP  rA    r  z6User Information is required for experimental UI loginr  username_passwordlitellm_key_header_nameAuthorization	r  r  rq  r  login_methodr   auth_header_name(disabled_non_admin_personal_key_creationr  HS256	algorithmz?login=successi/  )rN  r  )r  ry  r  unknownr  zPUser has no password set. Please set a password for the user via `/user/update`.r  zAInvalid credentials used to access UI.
Not valid credentials for invalid_credentialszVInvalid credentials used to access UI.
Check 'UI_USERNAME', 'UI_PASSWORD' in .env filer   )3litellm.types.proxy.ui_ssorm  r   r  r]  r^  r   r  formr2  r4  r*  r  r   r   r	   r  r  r  r  r   secretscompare_digestr  r  rC  r3  r   UpdateUserRequestr   r	  max_ui_session_budgetr   rf  r  jwtr   r   rX   (get_experimental_ui_login_jwt_auth_tokenr   r"  r   rH  r5  r   
set_cookier  INTERNAL_USER_VIEW_ONLYHTTP_401_UNAUTHORIZEDr   )r  rm  r  ro  r  ri  ui_password	_user_rowr  r  r  key_user_idr  r  litellm_dashboard_uir  r  returned_ui_token_object	jwt_tokenredirect_responserq  	_passwordhash_passwords                          r(   loginr  F  s?    
 A P ++66	
 	
 D488J'(H488J'(H))M73K))M40K)3)?c*oT V ++66	
 	
 .2I 	   &'""44??#h%9: @  
	 	56 -
 h49O9O+: %00	* /II&-9

+,700))$46NOK
 "##
 	
 	
 99^$03 " "2!=!= &&-&C&C ! *2
 H !y$//$::	  w-c'2B2B.CD((- E)  F* 2359I$%	#-#'&<<		  # #!Y  )QQC $9,%-11)? 6^13$
  JJ/0  
	
 	 00,1ESVW$$	$B  			
 )Y	:{$4$L$L
	 Yi@
Iz9=	 j$// 11	  #2!!(I6':P:P9;
 yy(4!7 "!&" &/$**1*G*G"$#%"$!"#*#6
"  %}(33(>>	  7#C#1#g6F6F2G#H #,,S1$-$$.$'<%sI.0)!1!5!5-" :b!5!7($ 

T34! # I
 !$44  0(c! ((WI(F$$ \]e\fg$//+11	  m ++'--	
 	
Q  8>	
Ps_   AW5W&C6W5W)
CW5W,AW5W/H1W5W2EW5)W5,W5/W52W5z/onboarding/get_tokeninvite_linkc                   K   ddl m} t        +t        dt        j
                  dt        j                        t        't        ddt        j                  j                  i	      t        j                  j                  j                  d
| i       d{   }|t        dddi	      t         j"                  j%                         j'                         }|j(                  j'                         }||k  rt        dddi	      t         j"                  j%                         }t        j                  j                  j+                  d
| i||d|j,                  d       d{   }t        j                  j.                  j                  d|j,                  i       d{   }|t        dddi	      |j0                  }	t3        d%ddi|j4                  dt         j6                  g i i d|j,                  dd	 d{   }
|
d   }t9        t;        |j<                              }|j?                  d      r|dz  }n|dz  }ddl }tC               } ||j,                  ||j0                  |j4                  dtD        tF        jI                  dd      |tK                	      }|jM                  tO        tP        |      t        d!"      }|d#jS                  ||	      z  }|||	d$S 7 K7 7 F7 w)&z
    - Get the invite link
    - Validate it's still 'valid'
    - Invalidate the link (prevents abuse)
    - Get user from db
    - Pass in user_email if set
    r   rl  Nrn  r   r  r  r  r  rM  r  ry  %Invitation link does not exist in db.Invitation link has expired.T)accepted_atrP  is_acceptedrR  r  rn  r  User does not exist in db.rN  r  rt  ru  rv  r  r_  zui/onboardingz/ui/onboardingrz  r{  r|  r}  r  r  z?token={}&user_email={})	login_urlr  rq  r   )*r  rm  r   r  r]  r^  r   r  r   r   r  r  ry  r  litellm_invitationlinkr  r	  r  get_utc_datetimer  
expires_atr  r  r  rq  r   r  r  r   r2  rf  r  r  r   r   r"  r4  r   rH  r   r5  r6   )r  r  rm  
invite_objutc_now_dateexpires_at_datecurrent_timer`  user_objrq  r  r  r  r  r  r  r  s                    r(   
onboardingr  D  s)     A P ++66	
 	
 .EEKKL
 	

 %''>>JJ[! K  J W.U$V
 	

 ==11388:L ++002O%W.L$M
 	

 ==113L55<<[!'&$,,	
 =  	A #%%77CC*,,- D  H W.J$K
 	
 $$J+  "++%;;''*

 H 7
C)#g.>.>*?@$$S)/ 00 	56 -  5  &&$$(!)--%
 2Z-/  

T+,  I 5<<Y
SS)  q&	sK   BK,K!CK,#K$$=K,!K'"AK,?K* C"K,$K,'K,*K,z/onboarding/claim_tokenrn  c                 h  K   t         't        ddt        j                  j                  i      t         j
                  j                  j                  d| j                  i       d{   }|t        dddi      t        j                  j                         j                         }|j                  j                         }||k  rt        ddd	i      |j                  d
u rnt        dddi      |j                  | j                  k7  r3t        dddj!                  | j                  |j                        i      t#        | j$                        }t         j
                  j&                  j)                  d|j                  id|i       d{   }|t        dddi      |S 7 D7 w)a&  
    Special route. Allows UI link share user to update their password.

    - Get the invite link
    - Validate it's still 'valid'
    - Check if user within initial session (prevents abuse)
    - Get user from db
    - Update user password

    This route can only update user password.
    Nr  r  r  rM  r  ry  r  r  TzThe invitation link was never validated. Please file an issue, if this is not intended - https://github.com/BerriAI/litellm/issues.zwInvalid invitation link. The user id submitted does not match the user id this link is attached to. Got={}, Expected={}r  r  r  r  r  )r   r   r  r  ry  r  r  r  invitation_linkr	  r  r  r  r  r  r  r6   r   r  r  r  )rn  r  r  r  r  r  s         r(   claim_onboarding_linkr    s     .EEKKL
 	

 %''>>JJT))* K  J W.U$V
 	

 ==11388:L ++002O%W.L$M
 	
 %  _
 	
 T\\)  S  Z  ZLL*"4"4
 	
 T]]3M"%%77>>*,,-Z4O ?  H W.J$K
 	
 OiVs%   A'F2)F-*D+F2F0F20F2z
/get_imagec                     t         j                  j                  t         j                  j                  t                    } t         j                  j                  | d      }t        j                  d|      }t        j                  d|       |j                  d      rt               }|j                  |      }|j                  dk(  r]t         j                  j                  | d      }t        |d      5 }|j                  |j                         ddd       t!        |d	
      S t!        |d	
      S t!        |d	
      S # 1 sw Y   0xY w)zGet logo to show on admin UIzlogo.jpgUI_LOGO_PATHzReading logo from path: %s)zhttp://r  r  zcached_logo.jpgwbNz
image/jpegrW  )r*  r+  r_  r`  __file__r  r  r=   r  r	  rR   r4  r  r5  r    r  r   )r  default_logo	logo_pathr  r  
cache_pathfs          r(   	get_imager  	  s   
 ''//"''//(";<K77<<Z8L		.,7I;YG 34::i(3&k3DEJj$' *1(()*  
|DD  FF I,??* *s   4D??Ez/invitation/newzInvite Links)rg  r  ru  r  c                   K   	 ddl m} t        't        ddt        j
                  j                  i      |j                  t        j                  k7  rAt        dddj                  t        j                  j                  |j                        i       || |       d{   }|S 7 # t        $ r}t        |      d}~ww xY ww)	%  
    Allow admin to create invite links, to onboard new users to Admin UI.

    ```
    curl -X POST 'http://localhost:4000/invitation/new'         -H 'Content-Type: application/json'         -d '{
            "user_id": "1234" // 👈 id of user in 'LiteLLM_UserTable'
        }'
    ```
    r   )create_invitation_for_userNr  r  r  r,  )rn  r  )0litellm.proxy.management_helpers.user_invitationr  r   r   r  r  ry  r  r  r  r6   r?  r  r   )rn  r  r  r  r  s        r(   new_invitationr  ,  s     *+	
  !2!I!I!O!OP 
 &&*:*F*FF/66)<<BB)33  4/
 
 	

  +'**+s;   CBB+ "B)#B+ (C)B+ +	C4B??CCz/invitation/infoinvitation_idc                   K   t         't        ddt        j                  j                  i      |j
                  t        j                  k7  rAt        dddj                  t        j                  j                  |j
                        i      t         j                  j                  j                  d| i       d{   }|t        dddi      |S 7 w)	r  Nr  r  r  r,  rM  r  -Invitation id does not exist in the database.)r   r   r  r  ry  r  r  r  r6   r?  r  r  r  )r  r  r  s      r(   invitation_infor  b  s     . .EEKKL
 	

 ""&6&B&BB+22%88>>%//
 	
 #%%<<HH]# I  H LM
 	
 Os   B;C=C>Cz/invitation/updatec           	        K   t         't        ddt        j                  j                  i      |j
                  (t        dddj                  |j
                        i      t        j                  j                         }t         j                  j                  j                  d| j                  i| j                  | j                  |||j
                  d	       d{   }|t        ddd
i      |S 7 w)uV  
    Update when invitation is accepted

    ```
    curl -X POST 'http://localhost:4000/invitation/update'         -H 'Content-Type: application/json'         -d '{
            "invitation_id": "1234" // 👈 id of invitation in 'LiteLLM_InvitationTable'
            "is_accepted": True // when invitation is accepted
        }'
    ```
    Nr  r  r  r  z'Unable to identify user id. Received={}rM  )rM  r  r  rP  rR  r  r  )r   r   r  r  ry  r  r6   r	  r  r  r  r  r  r  r  )rn  r  r  r  s       r(   invitation_updater    s    2 .EEKKL
 	

   (BII%--
 	
 ==113L"%%<<CCT''($$++'&+33
 D 	 	H LM
 	
 O!	s   CC: C8!C:z/invitation/deletec                   K   t         't        ddt        j                  j                  i      |j
                  t        j                  k7  rAt        dddj                  t        j                  j                  |j
                        i      t         j                  j                  j                  d| j                  i       d{   }|t        dddi      |S 7 w)	u  
    Delete invitation link

    ```
    curl -X POST 'http://localhost:4000/invitation/delete'         -H 'Content-Type: application/json'         -d '{
            "invitation_id": "1234" // 👈 id of invitation in 'LiteLLM_InvitationTable'
        }'
    ```
    Nr  r  r  r,  rM  r  r  )r   r   r  r  ry  r  r  r  r6   r?  r  r  deleter  )rn  r  r  s      r(   invitation_deleter    s     0 .EEKKL
 	

 ""&6&B&BB+22%88>>%//
 	
 #%%<<CCT''( D  H LM
 	
 Os   CC!CC!z/config/updatezconfig.yamlconfig_infoc                   K   	 ddl }	 t        t        d      t        durt	        dddi      | j                  d	      }t        j                  |      }|j                         D ]H  \  }}|d
k(  st        j                  j                  j                  d|i||dd|id       d{    J t        j                          d{   }t        j                  d|       | j                  |j!                  di        | j                  j#                  d	      }|d   }|j                         D ]G  \  }}|dk(  r8d|vrddgi}n.t%        |d   t&              rd|d   vr|d   j)                  d       |||<   I ||d<   | j*                  l|j!                  di        | j*                  }|j                         D ]  \  }}t-        |      }	|	||<    |d   }
|j                         D ]  \  }}||   |
|<    | j.                  |j!                  di        | j.                  }i ||d   |d<   d|v rZd|d   v rSt%        |d   d   t&              r=t%        |d   t&              r*|d   d   |d   z   }t'        t1        |            }||d   d<   t        j3                  |       d{    t        j5                  t        t6               d{    ddiS 7 ,7 7 57 # t        $ r}t        j8                  dj;                  t=        |                   t        j                  t?        j@                                t%        |t              rYtC        tE        |ddt=        |       d       tF        jH                  tE        |d!d"      tE        |d#tJ        jL                        $      t%        |tB              r|tC        d%t=        |      z   tF        jH                  tE        |d!d"      tJ        jL                  $      d}~ww xY ww)&z
    For Admin UI - allows admin to update config via UI

    Currently supports modifying General Settings + LiteLLM settings
    r   NzNo DB ConnectedTr  r  CSet `'STORE_MODEL_IN_DB='True'` in your env to enable this feature.r  rs  rZ  r  r  r  r  creater  r  zLoaded config: %sr"  r1  r-  r.  r  r  r[  r  rl  rf  r!   zConfig updated successfullyzBlitellm.proxy.proxy_server.update_config(): Exception occured - {}r  rY  rZ  rs  r  r  r  r[  )'rj  r   r  r  r   r'  jsonify_objectrh  r  r  upsertr-  r  r=   r  r"  r  r5  r1  re  rn  r  rj   r[  r  rt  r  r  r  r6   r2  r  r   r  r  r]  r^  r   r  )r  rj  updated_settingsr  r  rM  updated_general_settings_existing_settings_updated_environment_variablesr  _existing_env_variablesupdated_litellm_settingscombined_success_callbackr  s                 r(   update_configr  	  s    
	  -..D(b  '+++>(778HI$**,DAq%%#&&55<<'+121"E#0!"4 =    - $..00""#6? ''30"5'2'C'C'H'H! (I ($ "((:!;06681..!);;.87)-D*#$6z$BDI"*<Z*HH.z:AA'J()"1% 9 *<F%&,,85r:-8-N-N* 7<<>1"6Q"?4C.q1 ? '--D&E#6<<>1-KA-N'* ?
 ''30"5'2'C'C$***+,*F%& #&>>&&1C*DD -./ABD !9:L!MtT123EF23EFG . 15S9R5S0T- 2 -.*
 &&&&999))';L * 
 	
 	
 899g 1D 	:	

  
""PWWA	

 	""9#7#7#9:a' 8/DSVHA-NO$//a&1Qv/J/JK	  >*G,s1v5 ++!Wf-,,	
 	
!
sy   PA/K" 48K" ,K-K" 
KGK" (K)&K" K K" PK" K" K"  K" "
P,DO==PPz/config/field/updatec           
        K   	 t         't        ddt        j                  j                  i      |j
                  t        j                  k7  r't        ddt        j                  j                  i      | j                  t        j                  vr(t        dddj                  | j                        i      	 t        di | j                  | j                  i t         j                   j"                  j%                  ddi	       d{   }||j&                  i }nt)        |j&                        }| j                  || j                  <   t         j                   j"                  j+                  ddidt-        j.                  |      d
dt-        j.                  |      id       d{   }|S # t        $ r2 t        dddj                  t        | j                              i      w xY w7 7 Fw)z=
    Update a specific field in litellm general settings
    Nr  r  r  Invalid field={} passed in.z)Invalid type of field value={} passed in.r  r"  r  r  r  r  r  r   )r   r   r  r  ry  r  r  r  r?  r8  ConfigGeneralSettingsrA  r6   r;  r  rX  r  r  r  r  r5  r  r'  r  rn  r  r  r"  r  s        r(   update_config_general_settingsr    s     .EEKKL
 	

 ""&6&B&BB.AAGGH
 	

 3@@@:AA$//RS
 	



D$2B2B CD !. 0 0 ? ? J J/0 !K ! 
 "&9&E&E&M 3 ? ?@ )-(8(8T__%"%%44;;/0%7

ScHde$djj1A&BC
 <  H OC  
DKK))*
 	

s=   B7G5:!F3 /G5
G1B!G5,G3-G53;G..G53G5z/config/field/infor8  c                   K   	 t         't        ddt        j                  j                  i      |j
                  t        j                  k7  r't        ddt        j                  j                  i      | t        j                  vrt        dddj                  |       i      t         j                  j                  j                  ddi       d {   }||j                  t        dddj                  |       i      t!        |j                        }| |v rt#        | ||    	      S t        dddj                  |       i      7 ww)
Nr  r  r  r  r  r"  r  zField name={} not in DB)r8  r;  )r   r   r  r  ry  r  r  r  r?  r  rA  r6   r  r  r  r  r5  ConfigFieldInfo)r8  r  r  r"  s       r(   get_config_general_settingsr    st    
 .EEKKL
 	

 ""&6&B&BB.AAGGH
 	

 .;;;:AA*MN
 	
 !. 0 0 ? ? J J/0 !K ! 
 "&9&E&E&M6==jIJ
 	

   3 ? ?@))"%3CJ3O   !:!A!A*!MN %s   CEEA8Ez/config/listconfig_typec                   K   	 t         't        ddt        j                  j                  i      |j
                  t        j                  k7  rAt        dddj                  t        j                  j                  |j
                        i      t         j                  j                  j                  ddi       d{   }|"|j                  t        |j                        }ni }d	d
id	d
id	d
id	d
id	did}g }t        j                   j#                         D ]  \  }}||v s||   d	   }|dk(  r/|dk(  rt$        g}	ng }	|	D ]  }
|
j&                  j#                         D cg c]3  \  }}t)        ||j*                  dt,        j/                  |d      d      5 }}}d}|
j                   j#                         D ]6  \  }}t1        |d      r |j2                  |j2                  ||   _        |dz  }8 d}||v rd}n
|t,        v rd}t7        |||   d	   |j2                  xs dt,        j/                  |d      ||j8                  |      }|j;                  |        Id}d}||v rd}n
|t,        v rd}t7        |||   d	   |j2                  xs dt,        j/                  |d      ||j8                  |      }|j;                  |        |S 7 c c}}w w)z
    List the available fields + current values for a given type of setting (currently just 'general_settings'user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),)
    Nr  r  r  r,  r  r"  r  rX  r.  PydanticModel)r  r  max_request_size_mbmax_response_size_mbr  r  r   )r8  r9  r:  r=  r<  r   rN  r  TF)r8  r9  r:  r;  r<  r=  nested_fields)r   r   r  r  ry  r  r  r  r6   r?  r  r  r  r  r5  r  rA  rh  PassThroughGenericEndpoint__annotations__FieldDetailr   r"  r4  rl  rN  r:  r@  r+   rn  )r  r  r  rB  rE  rH  r8  rK  typed_dict_typepydantic_class_listpydantic_class	sub_fieldsub_field_typer  r
  sub_field_inforL  rJ  s                     r(   get_config_listr  -   sZ     
 .EEKKL
 	

 ""&6&B&BB+22%88>>%//
 	
 !. 0 0 ? ? J J/0 !K !  &+>+J+J+V#'(;(G(G#H #%  #))!4)/(; &	2!' 3#)?";L J"7"D"D"J"J"L
J% +:6v>O/1!99+E*F'*,'&9N :H9W9W9]9]9_	% 6I~ $'0'5'>'>.00@0D0DYPT0U)-	%M 	% C (44::<!& $NMB . : : F !/ : : *#.@ q = %)M!%==(,#'77(-$.#-#/
#;F#C*4*@*@*FB$4$8$8T$J%2,6,>,>&3%M %%m4U ':Z !% $!99$(M#33$)M *)+J7?&0&<&<&B 0 4 4Z F!.(2(:(:"/! !!-0U #MX B	%s-   B<K>K?A'K'A K'8K
D5KKz/config/field/deletec                   K   	 t         't        ddt        j                  j                  i      |j
                  t        j                  k7  rAt        dddj                  t        j                  j                  |j
                        i      | j                  t        j                  vr(t        dddj                  | j                        i      t         j                  j                  j                  ddi	       d{   }||j                   (t        ddd
j                  | j                        i      t#        |j                         }|j%                  | j                  d       t         j                  j                  j'                  ddidt)        j*                  |      ddt)        j*                  |      id       d{   }|S 7 7 w)z|
    Delete the db value of this field in litellm general settings. Resets it to it's initial default value on litellm.
    Nr  r  r  r,  r  r  r"  r  zField name={} not in configr  r  r  r  )r   r   r  r  ry  r  r  r  r6   r?  r8  r  rA  r  r  r  r  r5  rq  r  r'  r  r  s        r(   delete_config_general_settingsr     s    
 .EEKKL
 	

 ""&6&B&BB+22%88>>%//
 	
 3@@@:AA$//RS
 	
 !. 0 0 ? ? J J/0 !K ! 
 "&9&E&E&M:AA$//RS
 	

   3 ? ?@ $/"%%44;;/0%7

ScHde$djj1A&BC
 <  H O3"s%   D GGC	GGGGz/config/callback/deletec                   K   t         't        ddt        j                  j                  i      |j
                  t        j                  k7  rAt        dddj                  t        j                  j                  |j
                        i      t        durt        dddi      	 t        j                          d{   }| j                  j                         }|j                  d	i       }|j                  d
g       }||vrt        ddd| di      |j!                  |       ||j#                  d	i       d
<   t        j%                  |       d{    t        j'                  t         t(               d{    d| ||t+        j,                         j/                         dS 7 7 W7 2# t        $ r  t0        $ r}t3        j4                  dt7        |              t3        j8                  t;        j<                                t?        dt7        |      z   t@        jB                  dtD        jF                        d}~ww xY ww)z>
    Delete specific logging callback from configuration.
    Nr  r  r  r,  Tr  r  r[  r  i  z
Callback 'z#' not found in active configurationr  rf  zSuccessfully deleted callback: )r!   removed_callbackremaining_callbacks
deleted_atzClitellm.proxy.proxy_server.delete_callback(): Exception occurred - zError deleting callback: callback_namer  )$r   r   r  r  ry  r  r  r  r6   r?  r  r-  r  r  rR  r4  remover  rt  r  r  r   r~  	isoformatr  r=   r  r2  r  r  r   r  r]  internal_server_errorr   r  )rn  r  rM  r  r[  r  r  s          r(   delete_callbackr     s\     .EEKKL
 	

 ""&6&B&BB+22%88>>%//
 	
 $^
 	
2
#..00**002 "::&8"=,001CRH 11z-8[\  	  /  	,b1	

 &&&&999 ))';L * 
 	
 	

 9H -#4",,.224	
 	
; 1, 	:	
   

""QRUVWRXQYZ	
 	""9#7#7#9:/#a&8 66!66	
 	


sb   B#I&F2 =F,>BF2 F.&F2 =F0>-F2 +I,F2 .F2 0F2 2IA?IIIz/get/config/callbacks)rg  r  r  c                  8  K   	 ddl } t               }t        j                          d{   }|j	                  di       }|j	                  di       }|j	                  di       }|j	                  dg       }g }	 |D ]  }|dk7  r|dk(  rd	g}	n1|d
k(  rdg}	n(|dk(  rdg}	n|dk(  rdg}	n|dk(  rg d}	n|dk(  rg d}	ng }	i }
|	D ].  }|j	                  |d      }|d|
|<   t        ||      }||
|<   0 |j                  ||
d       |dk(  sg d}i }|D ].  }|j	                  |d      }|d||<   t        ||      }|||<   0 |j                  ||d        |j	                  dg       }g }d|v rdg}i }|D ]D  }|j	                  |d      }|t        j                  dd      }|||<   3t        ||      }|||<   F t        j                  j                  }t        j                  j                         }t        j                  j                  }|j                  d|||d       g d}i }|D ].  }|j	                  |d      }|d||<   t        ||      }|||<   0 |j                  d|d       t        i }nt        j                         }d||||dS 7 s# t         $ r}t#        j$                  dj'                  t)        |                   t+        |t,              rYt/        t1        |d d!t)        |       d"      t2        j4                  t1        |d#d$      t1        |d%t6        j8                        &      t+        |t.              r|t/        d't)        |      z   t2        j4                  t1        |d#d$      t6        j8                  &      d}~ww xY ww)(z~
    For Admin UI - allows admin to view config via UI
    # return the callbacks and the env variables for the callback

    r   Nr[  r"  r  r  r  	openmeterOPENMETER_API_KEY
braintrustBRAINTRUST_API_KEY	traceloopTRACELOOP_API_KEYcustom_callback_apiGENERIC_LOGGER_ENDPOINTotel)OTEL_EXPORTEROTEL_ENDPOINTOTEL_HEADERS	langsmith)LANGSMITH_API_KEYLANGSMITH_PROJECTLANGSMITH_DEFAULT_RUN_NAMErf  )rZ  	variables)LANGFUSE_PUBLIC_KEYLANGFUSE_SECRET_KEYLANGFUSE_HOSTr-  r.  SLACK_WEBHOOK_URL)rZ  r  active_alertsalerts_to_webhook)	SMTP_HOST	SMTP_PORTSMTP_USERNAMESMTP_PASSWORDSMTP_SENDER_EMAILTEST_EMAIL_ADDRESSEMAIL_LOGO_URLEMAIL_SUPPORT_CONTACTemailr  )r   r  alertsrZ  available_callbacksz?litellm.proxy.proxy_server.get_config(): Exception occured - {}r  rY  rZ  rs  r  r  r  r[  )rj  AllCallbacksr-  r  r4  ri   rn  r*  r  r  r  r0  _all_possible_alert_typesr1  r   get_settingsr  r=   r  r6   r2  r1  r   r  r  r]  r^  r   r  )rj  all_available_callbacksrz  _litellm_settingsr  r  _success_callbacks_data_to_return	_callbackenv_varsenv_vars_dict_varenv_variablerw  _langfuse_vars_langfuse_env_vars	_alertingalerting_data_slack_vars_slack_env_varsrn  _decrypted_value_alerting_types_all_alert_types_alerts_to_webhook_email_vars_email_env_varsr  r  s                                r(   r  r  [!  sQ    u
"..(3355'OO,>C'OO,>C +0G L /223ErJ	 ,IJ&++ H ,., H +- 34H"77 9:H&(QH+- H  "H "$D#8#<#<T4#HL#+.2d+ +?".D+ />d+ %  &&	'VWj("
 &("*D#8#<#<T4#HL#+37*40 +?".D+ 4C*40 +  &&&5GHq ,z &))*b9	i#K !O#488tD'YY':DAF,2OD) (<*($ -=OD) $ 0GGSSO!99SSU  "99NN    #!0%4);		
 D044T4@L#(,% $8lPT#U (8%   	,	
 !)668  (#/#:
 	
k 6x  
&&MTTA	

 a' 8/DSVHA-NO$//a&1Qv/J/JK	  >*G,s1v5 ++!Wf-,,	
 	

sA   N%J JC"J FJ NJ 	N(C*NNNz/config/yamlc                    K   ddiS w)a  
    This is a mock endpoint, to show what you can set in config.yaml details in the Swagger UI.

    Parameters:

    The config.yaml object has the following attributes:
    - **model_list**: *Optional[List[ModelParams]]* - A list of supported models on the server, along with model-specific configurations. ModelParams includes "model_name" (name of the model), "litellm_params" (litellm-specific parameters for the model), and "model_info" (additional info about the model such as id, mode, cost per token, etc).

    - **litellm_settings**: *Optional[dict]*: Settings for the litellm module. You can specify multiple properties like "drop_params", "set_verbose", "api_base", "cache".

    - **general_settings**: *Optional[ConfigGeneralSettings]*: General settings for the server like "completion_model" (default model for chat completion calls), "use_azure_key_vault" (option to load keys from azure key vault), "master_key" (key required for all calls to proxy), and others.

    Please, refer to each class's description for a better understanding of the specific attributes within them.

    Note: This is a mock endpoint primarily meant for demonstration purposes, and does not actually provide or change any configurations.
    helloworldr   )r  s    r(   config_yaml_endpointr9   "  s     . Ws   z/get/litellm_model_cost_map)r  r  c                     K   	 t         j                  } | S # t        $ r}t        ddt	        |       d      d }~ww xY ww)Nr  zInternal Server Error (rZ  r  )r	  
model_costr  r   r2  )_model_cost_mapr  s     r(   get_litellm_model_cost_mapr=  :"  sK     
!,, 
,SVHA6
 	

s   A A	>9>A)r  c                    K   yw)NzLiteLLM: RUNNINGr   r  s    r(   homer?  J"  s	     s   z/routesc                  &  K   ddl m}  g }t        j                  D ]o  }t	        |dd      }|#|j                  | j                  ||             5t        |d      sBt        |d      sO|j                  | j                  |             q d	|iS w)
zD
    Get a list of available routes in the FastAPI application.
    r   )	GetRoutesr  N)rp  endpoint_routerU   r+  )rp  rS  )	%litellm.proxy.common_utils.get_routesrA  rU   rS  r  ri  get_app_routesrl  get_routes_for_mounted_app)rA  rS  rp  rB  s       r(   
get_routesrF  O"  s     
 @F 
D9%MM((#1 )  UE"wuf'=MM)>>U>KL  fs   ABB*'B)r+  rU   )NNr  )NNNNFFNNr  NFTTNFFN(i  r<  rB  r  r7  r*  r2   r  r7  sysr  r  uuidwarningsr   r   typingr   r   r   r   r	   r
   r   r   r   r   r   r   litellm.constantsr   r   r   r   r   litellm.types.utilsr   r   r   opentelemetry.tracer   _Span"litellm.integrations.opentelemetryr   r)   filterwarningsUserWarningr,   re  r  r+  insertr`  r  backofffastapir  rV  apscheduler.schedulers.asyncior-   ImportErrorr  r4   r8   collectionsr9   
contextlibr:   r	  r;   r  r=   r>   r  r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   litellm.exceptionsrJ   1litellm.integrations.SlackAlerting.slack_alertingrK   'litellm.litellm_core_utils.core_helpersrL   rM   .litellm.litellm_core_utils.credential_accessorrN   r6  rO   LiteLLMLoggingObj0litellm.litellm_core_utils.sensitive_data_maskerrP   &litellm.llms.custom_httpx.http_handlerrQ   rR   5litellm.proxy._experimental.mcp_server.rest_endpointsrT   mcp_rest_endpoints_router-litellm.proxy._experimental.mcp_server.serverrU   mcp_app4litellm.proxy._experimental.mcp_server.tool_registryrV   litellm.proxy._types5litellm.proxy.analytics_endpoints.analytics_endpointsanalytics_router+litellm.proxy.anthropic_endpoints.endpointsanthropic_routerlitellm.proxy.auth.auth_checksrX   rY   rZ   litellm.proxy.auth.auth_utilsr[   litellm.proxy.auth.handle_jwtr\   "litellm.proxy.auth.litellm_licenser]   litellm.proxy.auth.model_checksr^   r_   r`   ra   rb   $litellm.proxy.auth.user_api_key_authrc   rd   )litellm.proxy.batches_endpoints.endpointsbatches_routerlitellm.proxy.caching_routescaching_router'litellm.proxy.common_request_processingre   rf   )litellm.proxy.common_utils.callback_utilsrg   &litellm.proxy.common_utils.debug_utilsrh   debugging_endpoints_router0litellm.proxy.common_utils.encrypt_decrypt_utilsri   rj   .litellm.proxy.common_utils.html_forms.ui_loginrk   -litellm.proxy.common_utils.http_parsing_utilsrl   rm   rn   ,litellm.proxy.common_utils.load_config_utilsro   rp   0litellm.proxy.common_utils.openai_endpoint_utilsrq   &litellm.proxy.common_utils.proxy_staterr   +litellm.proxy.common_utils.reset_budget_jobrs   (litellm.proxy.common_utils.swagger_utilsrt   ,litellm.proxy.credential_endpoints.endpointscredential_router7litellm.proxy.db.db_transaction_queue.spend_log_cleanupru   "litellm.proxy.db.exception_handlerrv   !litellm.proxy.discovery_endpointsrw   -litellm.proxy.fine_tuning_endpoints.endpointsfine_tuning_routerrx   (litellm.proxy.google_endpoints.endpointsgoogle_router,litellm.proxy.guardrails.guardrail_endpointsguardrails_router(litellm.proxy.guardrails.init_guardrailsry   rz   litellm.proxy.health_checkr{   0litellm.proxy.health_endpoints._health_endpointshealth_router,litellm.proxy.hooks.model_max_budget_limiterr|   .litellm.proxy.hooks.prompt_injection_detectionr}   -litellm.proxy.hooks.proxy_track_cost_callbackr~   'litellm.proxy.image_endpoints.endpointsimage_router$litellm.proxy.litellm_pre_call_utilsr   >litellm.proxy.management_endpoints.budget_management_endpointsbudget_management_router@litellm.proxy.management_endpoints.callback_management_endpoints$callback_management_endpoints_router/litellm.proxy.management_endpoints.common_utilsr   5litellm.proxy.management_endpoints.customer_endpointscustomer_router:litellm.proxy.management_endpoints.internal_user_endpointsinternal_user_routerr   ;litellm.proxy.management_endpoints.key_management_endpointsr   r   r   key_management_router;litellm.proxy.management_endpoints.mcp_management_endpointsmcp_management_router=litellm.proxy.management_endpoints.model_management_endpointsr   r   r   model_management_router9litellm.proxy.management_endpoints.organization_endpointsorganization_router/litellm.proxy.management_endpoints.scim.scim_v2r   ;litellm.proxy.management_endpoints.tag_management_endpointstag_management_router:litellm.proxy.management_endpoints.team_callback_endpointsteam_callback_router1litellm.proxy.management_endpoints.team_endpointsteam_routerr   r   )litellm.proxy.management_endpoints.ui_ssor   ui_sso_router+litellm.proxy.management_helpers.audit_logsr   3litellm.proxy.middleware.prometheus_auth_middlewarer   4litellm.proxy.openai_files_endpoints.files_endpointsopenai_files_routerr   >litellm.proxy.pass_through_endpoints.llm_passthrough_endpointsr   llm_passthrough_routerr  r   pass_through_routerlitellm.proxy.public_endpointspublic_endpoints_router(litellm.proxy.rerank_endpoints.endpointsrerank_router.litellm.proxy.response_api_endpoints.endpointsresponse_routerlitellm.proxy.route_llm_requestr   r  cloudzero_router7litellm.proxy.spend_tracking.spend_management_endpointsspend_management_router1litellm.proxy.spend_tracking.spend_tracking_utilsr   litellm.proxy.types_utils.utilsr   r[  ui_crud_endpoints_routerlitellm.proxy.utilsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   .litellm.proxy.vector_store_endpoints.endpointsvector_store_router4litellm.proxy.vertex_ai_endpoints.langfuse_endpointslangfuse_routerlitellm.routerr   r   r   r   litellm.schedulerr   r   *litellm.secret_managers.aws_secret_managerr   "litellm.secret_managers.google_kmsr   litellm.secret_managers.mainr   r   r   r   )litellm.types.integrations.slack_alertingr   litellm.types.llms.anthropicr   r   r   r   litellm.types.llms.openair   Clitellm.types.proxy.management_endpoints.model_management_endpointsr   /litellm.types.proxy.management_endpoints.ui_ssor   r   litellm.types.realtimer   r  r   r   rT  r   r   litellm.types.schedulerr   "litellm.types.secret_managers.mainr   r   r   r   ModelMapInfor   r   r  r   litellm._versionr   r  suppress_debug_infor'  r   r   r   r   r   r   r   r   r   r   r   r   r   fastapi.encodersr   fastapi.middleware.corsr   fastapi.openapi.docsr   fastapi.openapi.utilsr   rg  r   r   r   r   r   fastapi.routingr   fastapi.securityr   fastapi.security.api_keyr   fastapi.staticfilesr   enterprise_routerlitellm.proxy.enterpriseproxy
enterprise*litellm_enterprise.proxy.enterprise_routes_enterprise_router%litellm_enterprise.proxy.proxy_serverr   r   r  r  r(  r)  r   r  airgapped_license_datar   r   r2  proxy_stater~  r   r  r   r   r  rb  model_hub_link
ui_messagecustom_swagger_message_title_descriptionr  r  rJ  rQ  rt  r}  openapienumEnumr  exception_handlerr  r  originsr_  r  r  r  ui_pathlitellm_asset_prefixwalkrootdirsfilesr#   rT  r  r5  r  r6  r  ro  modified_contentr    UnicodeDecodeErrorr  listdirrQ  folder_namefolder_pathmakedirssrcdstrenameadd_middlewarer  r  r   r  r  r  r  r  r  user_configr  r   local_loggingr  r   r0  r"  r5  r  log_filerG  r   r   r   r  ry  r  model_max_budget_limiterr  r  r!  r   r   r   r   r   r	  r   rD  r  r  r#  rC  r  r$  r%  r  r&  r  r  r  r?  r  r  r  async_resultcelery_app_conn	celery_fnr  r  r  r  r  r  r/  r:  r>  rH  rJ  r-  r  r6  r  r]  r&  r0  r3  r:  r=  r@  r8  r4  r<  postr  r  r  r  r1  r<  rb  r=  r>  r@  rS  rY  r\  r  r`  rd  ri  rm  rp  rt  r}  TokenCountRequestrw  r  TransformRequestBodyr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r*  rM  r`  rj  r  r  InvitationClaimr  r  InvitationModelInvitationNewr  r  InvitationUpdater  InvitationDeleter  
ConfigYAMLr  ConfigFieldUpdater  r  r  r@  r  ConfigFieldDeleter  CallbackDeleter  r  r9  r=  r?  rF  include_routerr   r*   r(   <module>r     s4(      	 	    
     (      1@DDM# #    	K 8
 $  rwww	U?	 8 $ *   H 9
 
 
 4 K N S P P I # S 
 F 4 ;  O B T G W E 
 > F D T S G K V P L T < T I J L Q S 
 
 H T N S X R M L T 9 W R Q ; ;        " Y   2 1 C C > >   H G   A @   7 6 4 4 = = H H 5 5  K J 9 K K G G(( #          . - 2 2 4 4 - -    & % 1 1 1 1 + + K 11#WKK*?T?VX&;<V
 299/4 #..0d 0)) 834  :C1: '#  l+- *2/0'0*-.U*V'?Hryy7@ -x}  187;-u;0551- d
#$%%89.wi7TU  T T
 
3N3C  Db  c  c
 N  4@<	/] 	 BII
VWmVnnrs}r~
 AAW@XX\]g\h	i "&> w!7 w! w!t _
  . -0f, 299_g&&0\ CKTYY  ~&G .  '& 
%M	''//"''//(";<Kggll;?G2 ,3!(!1D$!GGLLx8	$$
 iw? +1"#&&(+ (//0+,($ (8'?'?@+,,JK($
 iw? 21 012C " "2R IIbggll7G<=  
 II
 'bggll7G<=   IIe[7>TIJ BJJw'W%(l*B''**84Q7K'',,w<KBKKd3 '',,w1C'',,{L9CBIIc3 ( ggoobggooh78   %%     + ,<*   

  '+ x} +#
HV #!% % $  4  
HSM  (,x% ,0DDJJ  B!       5 56N O 8J'    %) "# 	  DF d3c4S#X+?&? @@A Ft 2 3 7<gn-t34 <$E !$E !; +   lOS )K L S 4 15 x. 5 )  	/3 (+, 3w 84 "
4 
>PuC=uc]u #u c]	u
 E?u tnup
3@	Y 	} }@4 }3 

	#vt34,!/4,?C4,nL,!/L,?CL,^!/?C *, $ Y
&XI XIx
 (9 :;CUBV   W%678@R?S   )00A(B-2!27/4',#'w%w$TNw c]w "*$	w
 'tnw tnw C=wwt +,-
	  
 +,-
	  
 ,+,-
	  
 7+,-
	]$9:NoN	    (/0A(B	_
_
_
 C=_
 &	_
*_
D W->%?$@   '*;"<!=]O   '+,-
  
 2+,-
    (/0A(B	k
k
k
 C=k
 &	k
 k
\ +,-!
	   +,-!
	   &+,-!
	   1+,-!
	    (/0A(B	zzz C=z &	z0zz +,-!
	   +,-!
	   )00A(Bjjj &jjZ +,-
  
 +,-
   )00A(Bjjj &jjZ +,-
  
 +,-
   Cy(/0A(B	JJJ J &	JJd < ; ;   ~{  '--C 9:KIKIKI KI  KIl +,-
  
 +,-
   )00A(BUUU &UUp +,-
  
 +,-
   )00A(BUUU &UUp (+,-
  
 %+,-
   )00A(B	TTT T &	TTn +,-
  
 +,-
   )00A(BTTT &TTn +,-
  
 +,-
   )00A(B	RRR R &	RRj &+,-
  
 #+,-
   )00A(B	VVV V &	VVr &+,-
  
 #+,-
   )00A(B	RRR R &	RRj "+,-
  
 +,-
   )00A(B	aaa a &	aa\ 
+,-%	  7!2 77t $
+,-  

 


2 
+,-&	  W%9 WWJ% L) 
$Z	>$%1B	$Z(*T
** &* L)	*Z, 12,, 
#s3x-,^) d3i-.) )  )  
#tCy.	) X %   
#Y &B%BB B T
	B
 
$ZBJ  ^
	+,-   )00A(B(7=== (5w}}B( +8'--K+ "p %p C=p 
 tnp  "$p  D>p p f C
	+,-   )00A(B+/$("&	z
%z
#C=z
 !z
 h	z
z
z P
	+,-   )00A(B+6$("&!"i
%i
#C=i
 !i
 h	i

 c]i
 smi
i
X #A
	+,-   )00A(B+6$("&!"P%P#C=P !P h	P
 c]P smPPf I
	+,-   )00A(B+/$("&!"NH%NH#C=NH !NH h	NH
 c]NH smNHNHb& &$ &R 
	+,-  
 
	+,-   )00A(B&*B %B smB B J(,S	@H	
> 
	+,-   )00A(B!%\"%\"#\"
\"~ _
	+,-  4 X
+,-   )00A(Bc%ccN 
	+,-	    (/0A(B	k
k
k
 C=k
 &	k
k
\ 	.!1UK@' @ L@8   x
 x
x
v 	 E:u# u u ;up 
#u=Ho H >HV /@ 0@D 
	+,-"   >EEV=W,+
,+,:,+,+^ 
	+,-"   =DDU<V**+9**Z 
	+,-"   )00A(B3
3%33l 
	+,-"   )00A(B+
+%++^ 
+,-	  F
Z F
F
T 
+,-	   )00A(BE
E%EEP 
+,-"   )00A(B44%44n 
+,-	   )00A(B@+,@%@ 
*@@F 
+,-	   )00A(B?
?%??D 
+,-	   )00A(BT

T
%T
T
n 
+,-	  |
|
~ 
+,-	  J ( !+,-  



 Cw'89:;  < IW->%?$@A B`   6    ? #   > "   * +   = !   <     % &   & '   $ %   ) *   ( )   # $   = !   ? #   & '   = !   ( )   ' (   ;    = !   ;    & '   ? #   * +   # $   > "   # $   $ %   7 8   - .   + ,   & '   ' (   + ,   * +   ( )   $ %   0 1 		~7	 +   , -wR  U
+A3.RS
TTUd	  GT   	  #"#j+ +2 2) @  		s'  )A 6	A- 6A= 'B@ &B<BA #BA0B@-ABAB@:"BA*CBA /BA 6B.BA A*A%%A*-	A:9A:=B@@B@@
B@@B@@B@@B@@B@@B@@B@*@)B@*@-B@7@2BA@:BA@?BAABAABA ABAABA ABAABA