Ë
    tPêjûŸ ã                   ó´ƒ  — U d dl Z d dlZd dlZd dlZd dlZd dlZd dl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mZmZmZmZmZ d dlmZmZmZ d dlmZmZ d dl m!Z!m"Z"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/Z/d dl0Z0d dl1Z0d dl2m3Z3m4Z4m5Z5 d dl6m7Z7m8Z8m9Z9 d dl:m;Z; d d	l<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZL d d
lMmNZN d dlOmPZP d dlQmRZR d dlSmTZTmUZUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`maZambZbmcZcmdZdmeZemfZfmgZgmhZhmiZimjZjmkZkmlZlmmZmmnZnmoZompZpmqZqmrZrmsZsmtZtmuZumvZvmwZw d dlxmyZy d dlzm{Z{m|Z|m}Z}m~Z~ d dlm€Z€ d dl�m‚Z‚mƒZƒ d dl„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• d dl–m—Z˜ d dl™mšZ› d dlœm�Z� e˜e"z  Z—ne"Z—e"Z�ddddœZže#eŸe e¡f      e¢d<   dêd„Z£e£e_£         e�jH                  d e¥¬!«       g Z¦e#e§   e¢d"<   e�jP                  �jS                  d e�jP                  �jU                  d#«      «       	 d dl«Z«d dl¬Z¬d dl­Z­d dl®Z®d dl¯Z¯d d$l°m±Z± d d%l²m³Z³ g d(¢Z¶e#e¢d)<   d*„ Z·d dl¸Z¸d d+l¹mºZº d d,l¸m»Z» d d-l¼m½Z½ d dl¾Z¾d dl¿Z¾d d.l¾mÀZÀ d d/lÁmÂZÂmÃZÃmÄZÄ d d0lÅmÆZÆmÇZÇ d d1lÈmÉZÉ d d2l<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ØmÙZÙmÚZÚmÛZÛmÜZÜmÝZÝmÞZÞmßZß d d3làmáZá d d4lâmãZã d d5lämåZå d d6læmçZç d d7lèméZé d d8lêmëZë d d9lìmíZímîZî d d:lïmðZð d d;lMmñZò d d<lómôZômõZõ d d=löm÷Z÷møZø d d>lùmúZúmûZû d d?lümýZý d d@lþmÿZÿ d dAlS­ d dB�l �m�Z d dC�l�m�Z�m�Z�m�Z�m�Z d dD�l�m	�Z	�m
�Z
�m�Z d dE�l�m�Z d dF�l�m�Z d dG�l�m�Z d dH�l�m�Z�m�Z�m�Z�m�Z�m�Z�m�Z d dI�l�m�Z�m�Z�m�Z d dB�l�m�Z d dB�l�m�Z  d dJ�l!�m"�Z"�m#�Z#�m$�Z$�m%�Z%�m&�Z&�m'�Z' d dK�l(�m)�Z) d dLlz�m*�Z* d dM�l+�m,�Z, d dN�l-�m.�Z. d dB�l-�m�Z/ d dO�l0�m1�Z1�m2�Z2 d dP�l3�m4�Z4�m5�Z5 d dQ�l6�m7�Z7 d dR�l8�m9�Z9�m:�Z:�m;�Z;�m<�Z< d dS�l=�m>�Z>�m?�Z? d dT�l@�mA�ZA d dU�lB�mC�ZC d dV�lD�mE�ZE d dW�lF�mG�ZG�mH�ZH�mI�ZI�mJ�ZJ�mK�ZK�mL�ZL�mM�ZM�mN�ZN�mO�ZO d dX�lP�mQ�ZQ d dY�lR�mS�ZS d dZ�lT�mU�ZU�mV�ZV�mW�ZW�mX�ZX d d[�lY�mZ�ZZ d d\�l[�m\�Z\�m]�Z] d d]�l^�m_�Z_�m`�Z`�ma�Za�mb�Zb�mc�Zc�md�Zd d d^�le�mf�Zf d d_�lg�mh�Zh�mi�Zi�mj�Zj d dB�lk�m�Zl d dB�lm�m�Zn d d`�lo�mp�Zp�mq�Zq d da�lr�ms�Zs d db�lt�mu�Zu�mv�Zv d dc�lw�mx�Zx�my�Zy d dd�lz�m{�Z{�m|�Z| d de�l}�m~�Z~ d df�l�m€�Z€ d dB�l��m�Z‚ d dg�l��mƒ�Zƒ d dB�l„�m�Z… d dh�l†�m‡�Z‡�mˆ�Zˆ d di�l‰�mŠ�ZŠ�m‹�Z‹�mŒ�ZŒ�m��Z� d dB�lŽ�m�Z� d dj�l��m‘�Z‘ d dk�l’�m“�Z“ d dl�l”�m•�Z• d dB�l–�m�Z— d dm�l˜�m™�Z™�mš�Zš�m›�Z› d dn�lœ�m��Z� d do�lž�mŸ�ZŸ d dB�l �m�Z¡ d dB�l¢�m�Z£ d dB�l¤�m�Z¥ d dB�l¦�m�Z§ d dp�l¨�m©�Z©�mª�Zª�m«�Z« d dq�l¬�m­�Z­ d dB�l¬�m�Z® d dB�l¯�m�Z° d dB�l±�m�Z² d dB�l³�m�Z´ d dB�lµ�m�Z¶ d dB�l·�m�Z¸ d dr�l·�m¹�Z¹ d ds�lº�m»�Z»�m¼�Z¼�m½�Z½ d dB�lº�m�Z¾ d dB�l¿�m�ZÀ d dt�lÁ�mÂ�ZÂ d dB�lÃ�m�ZÄ d du�lÅ�mÆ�ZÆ�mÇ�ZÇ�mÈ�ZÈ�mÉ�ZÉ d dB�lÅ�m�ZÊ d dB�lË�m�ZÌ d dB�lÍ�m�ZÎ d dB�lÏ�m�ZÐ d dB�lÑ�m�ZÒ d dB�lÓ�m�ZÔ d dv�lÓ�mÕ�ZÕ�mÖ�ZÖ d dw�l×�mØ�ZØ d dB�l×�m�ZÙ d dB�lÚ�m�ZÛ d dB�lÜ�m�ZÝ d dx�lÞ�mß�Zß�mà�Zà d dy�lá�mâ�Zâ�mã�Zã�mä�Zä d dB�lå�m�Zæ d dz�lç�mè�Zè�mé�Zé d d{�lê�më�Zë d dB�lê�m�Zì d d|�lí�mî�Zî 	 d d}�lï�mð�Zñ d d~�lï�mò�Zó �eñ�Zðed�eédz  f   dz  e¢d€<   �eó�Zòeg df   dz  e¢d�<   d d‚�lô�mõ�Zõ d dƒ�lö�m÷�Z÷ d d„�lø�mù�Zù d d…�lú�mû�Zû d dB�lü�m�Zý d dB�lþ�m�Zÿ d d†�lþ�m �Z  d d‡�l�m�Z�m�Z�m�Z d dB�l�m�Z d dˆ�l�m�Z d dB�l�m�Z d dB�l	�m�Z
 d dB�l�m�Z d dB�l�m�Z d dB�l�m�Z d dB�l�m�Z d d‰�l�m�Z d dB�l�m�Z d dŠ�l�m�Z d d‹�l�m�Z d dB�l�m�Z d dŒ�l�m�Z d d��l�m �Z  d dB�l!�m�Z" d dB�l#�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/�m0�Z0�m1�Z1�m2�Z2�m3�Z3�m4�Z4�m5�Z5�m6�Z6�m7�Z7�m8�Z8�m9�Z9�m:�Z:�m;�Z;�m<�Z<�m=�Z= d dB�l>�m�Z? d d��l@�mA�ZA d d��lB�mC�ZC d d‘�lD�mE�ZE d d’�lF�mG�ZG�mH�ZH�mI�ZI�mJ�ZJ d d“�lK�mL�ZL�mM�ZM d d”�lN�mO�ZO d d•�lP�mQ�ZQ d d–�lR�mS�ZS�mT�ZT�mU�ZU�mV�ZV�mW�ZW�mX�ZX d d—�lY�mZ�ZZ�m[�Z[ d d˜�l\�m]�Z]�m^�Z^�m_�Z_�m`�Z` d d™�la�mb�Zb�mc�Zc�md�Zd�me�Ze d dš�lf�mg�Zg d d›�lh�mi�Zi d dœ�lj�mk�Zk�ml�Zl d d��lm�mn�Zn�mo�Zo d dž�lp�mq�Zq d dŸ�lr�ms�Zs�mt�Zt�mu�Zu�mv�Zv�mw�Zw�mx�Zx d d �lr�my�Zz d d¡�l{�m|�Z| d d¢�l}�m~�Z~�m�Z d d£lˆ�m€�Z€�m��Z��m‚�Z‚�mƒ�Zƒ d d lˆ�my�Z„ d d¤lŽ�m…�Z… 	 d d¥�l†�m‡�Z‡ d§e¾�_‰        d d�lŠ�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–�m—�Z—�m˜�Z˜�m™�Z™ d d©�lš�m›�Z› d dª�lœ�m��Z� d d«�lž�mŸ�ZŸ d d¬�l �m¡�Z¡ d d­�l¢�m£�Z£ d d®�l¤�m¥�Z¥�m¦�Z¦�m§�Z§�m¨�Z¨�m©�Z© d d¯l”�mª�Zª d d°�l«�m¬�Z¬ d d±�l­�m®�Z® d d²�l¯�m°�Z°  �eª«       �Z±	 d d³�l²�m³�Z³ 	 d dB�l´�m�Zµ d d´�l¶�m·�Z· �eµ�Z± �e·«       �Z¸�e·dz  e¢dµ<    �e4«       �Z¹e#e¢d¶<    �e«       �aº�tt        �jw                  «       �a¼�e½e¢d·<   �tt        �j|                  �Z¿e&d¸   e¢d¹<    e�j€                  dº«      �ZÁe#e dz     e¢d»<    �eQ«       �ZÂe#e¢d¼<    e÷«       �ZÃe#e¢d½<    �eÄh d¾£«      �ZÅe#e¢d¿<   dÀe eŸe e5f   z  dz  dÁe5fdÂ„�ZÆ�eÁ€
dÃ�ZÇ�eÈe¢dÄ<   n �eÈ�eÁ«      �ZÇ e�j€                  dÅ«      �ZÉe#e dz     e¢dÆ<   �eÉ€
dÇ�ZÊ�eËe¢dÈ<   n �eË�eÉ«      �ZÊ�e¹› dÉ��ZÌe#e¢dÊ<   �e¹› dË��ZÍe#e¢dÌ<   �e¹› dÍ��ZÎe#e¢dÎ<   dÏ�eÌ› dÐ�eÍ› dÑ��ZÏ�eÏdÒz  �ZÏ�eÏdÓ�eÎ› dÔ�z  �ZÏdÕ�ZÐe#e¢dÖ<   �tx        r e�j€                  d×dØ«      ndØ�ZÑe#e¢dÙ<   �tx        r e�j€                  dÚdÛ�eÐ› dÜ�eÏ› �«      n	dÝ�eÐ› dÜ�eÏ› ��ZÒe#e¢dÞ<   dß„ �ZÓ�ddà„�ZÔ�ddá�e|dz  dÁdfdâ„�ZÕ�eÖ�eÈe�j®                  z  �eÈe�j°                  z  �eÈe �eÖe¡df   f   �ZÙe(e¢dã<    G dä„ dåe)dæ¬ç«      �ZÚdè„ �ZÛe»dé�eŒdÁedê   fdë„«       �ZÜdìdídÁe fdî„�ZÝh dï£�ZÞe#e¢dð<   dñdòh�Zße#�eàe       e¢dó<   dôe dÁe fdõ„�Zá	 �ddöeŸe e"f   d÷�eàe    dz  dÁeŸe e"f   fdø„�Zâ �eŒ �e*«        �e-«        �e+«       �eÑ�eÒ�e‡�e¹�eÜ�eÝdæ¬ù«
      �Zãd dú�lä�må�Zå  �eå�eã«        eý«       �Zæe#e¢dû<   d dül”�mç�Zç döeŸdýe§dÁeŸfdþ„�Zèdÿ„ �Zé�d „ �Zê e�j€                  �d�d«      �dk(  r�tx        r�eê�eã�_ë        n
�eé�eã�_ë         G �d„ �de�jØ                  «      �Zí�eã�jÝ                  ep«      �d�e“�depf�d„«       �Zï�d�d�e“�d	�eÈ�d�eˆdz  dÁdf�d
„�Zð�eã�jÝ                  �eš«      �d�e“�d�ešf�d„«       �Zñ G �d„ �de'«      �Zò G �d„ �de'«      �Zó G �d„ �de'«      �Zô G �d„ �de'«      �Zõ G �d„ �de'«      �Zö G �d„ �de'«      �Z÷ G �d„ �de'«      �Zø�d�Zùe(e¢�d<   �d�e&dz  dÁ�eE�eò   f�d„�Zú G �d„ �de)«      �Zû G �d „ �d!e)«      �Zü G �d"„ �d#e)dæ¬ç«      �Zý G �d$„ �d%e)«      �Zþ�eã�jÝ                  �e�«      �d�e“�d�e�f�d&„«       �Zÿ�eã�jÝ                  �eˆ«      �d�e“�d�eˆf�d'„«       �Z  �eª«       �Ze#e¢�d(<   	 	 dê�d)e dz  �d*e dz  f�d+„�Z �e«       \  �Z�Z	 e�jP                  �j	                  e�jP                  �jU                  �e«      «      �Ze�jP                  �j                  �e�d,�d-«      �Ze#e¢�d.<   �e�Z	�d/�Z
e#e¢�d0<   �d1e dÁ�e½f�d2„�Z�d3e dÁ�e½f�d4„�Z�d5e dÁ�e½f�d6„�Z�d7e �d8e dÁ�eÖ�e½e f   f�d9„�Z e�j€                  �d:�d;«      �j                  «       �d<k(  �Ze#e¢�d=<   �er�d>�Zn�e�Z e�j€                  �d?�e«      �Ze#e¢�d@<    �e�e«      s eÃ�j&                  �dA�e«       �e�ek7  �Ze#e¢�dB<   �er¬ �e�e«      �Z �e�e«      �Ze#e¢�dC<   �er�er eÃ�j.                  �dD�e«       �e�Z	n‰�er�es eÃ�j0                  �dE�e«       �e�Z	nh eÃ�j.                  �dF�e«        �e�e�e«      \  �Z�Z�er�e�Z	n9 eÃ�j0                  �dG�e�e�e«       �e�Z	n eÃ�j.                  �dH�e«       �e�Z	 �e�e	«      s eÃ�j&                  �dI�e	«       �e¹�r2�e¹�dJk7  �r* e�j4                  �e	e�j6                  «      �Z�es eÃ�j0                  �dK�e	«       nï e�j:                  �e	«      D ]Ø  \  �Z�Z�Z �e D ]É  �Z!e�jP                  �j                  �e�e!«      �Z"�e!�jG                  �dL«      rŒ:	  �e$�e"�dM�dN�¬O«      5 �Z%�e%�jM                  «       �Z'ddd«       �e'�jQ                  �e
› �e¹› «      �Z)�e)�jQ                  �dP�e¹› �dQ�«      �Z) �e$�e"�dR�dN�¬O«      5 �Z%�e%�jU                  �e)«       ddd«       ŒË ŒÚ �eã�j]                  �dS �e°e�jP                  �j                  �e	�dT«      �¬U«      �dV�¬W«       �eã�j]                  �e
› �dS� �e°e�jP                  �j                  �e	�dT«      �¬U«      �dV�¬W«       �eã�j]                  dÉ �e°�e	d§�¬X«      �dY�¬W«       �dZe dÁdf�d[„�Z/	  �e�e	«      �Z e�j4                  �e	e�j6                  «      �Z�er eÃ�j.                  �d\�e	«       n:�es eÃ�j0                  �d]�e	«       n  �e/�e	«        eÃ�j.                  �d^�e	«       e�jP                  �j	                  e�jP                  �jU                  �e«      «      �Z�eã�jc                  �eŸ�e�e�dag�dageK�¬b«       �eã�jc                  �e÷«       �eã�jc                  �eè�dc„ �dd„ �¬e«       �eã�jc                  �eõ«       �eã�jc                  �eû«       �df„ �Z2 �e2«         �e*«       �Z3e#e¢�dg<    e�j€                  �dh«      �Z4e#e dz     e¢�di<   �e3�dJk7  r"�e4��eã�jk                  �dJdæ�¬j«      �dk„ «       �Z6d�a7d�a8dæ�a9d�a:d�a;d�a<d§�a=d�Z>e#e¢�dl<   d�a?d�a@e dz  e¢�dm<   d§�ZAe#e¢�dn<   dæ�aBd�aCeÀdz  e¢�do<   d�aDe§dz  e¢�dp<    e �jŠ                  «       �ZFe#e¢�dq<   i �aGeŸe¢�dr<   d�aHe§eŸe e"f      dz  e¢�ds<   �dt�ZIe#e¢�du<   d�ZJe#e¢dÀ<   d�aKe dz  e¢�dv<   dæ�aLd�aM�e&dz  e¢�dw<   d�aNe&�dx   e¢�dy<    �e_�eí�jž                  �j                   �¬z«      �aQ�e_e¢�d{<    eÆ�eí�jž                  �j                   �¬z«      �ZRe#e¢�d|<    eÆeÏ�¬z«      �ZSe#e¢�d}<    �e‘�t¢        �¬~«      �ZTe#e¢�d<   e¾�jª                  �j­                  �eT«       d�aWeÇdz  e¢�d€<   dæ�aXe$�d�   e§e    z  �e½z  e¢�d‚<   g �aYe§e    e¢�dƒ<   �d„�aZ�eÈe¢�d…<   d�a[d�a\dæ�a]�e½e¢�d†<   dæ�a^�e½e¢�d‡<   d�a_d�a`d�aad�abd�acdæ�add�aed�afd�agi �aheŸe �eÈe§eŸe e"f      z  f   e¢�dˆ<   dæ�aid �ajg �Zke#e§   e¢�d‰<   eÕ�Zle#e¢�dŠ<   eÔ�am�d��ane$�d‹   eŸz  e¢�dŒ<   eÝ�aoeÜ�apeÚ�aqeÛ�areÞ�asd�atdæ�au �e«       �Zve#e¢�d�<   d�aw�e“dz  e¢�dŽ<   dæ�ax�e½e¢�d�<   d�aye�dz  e¢�d�<    �ex«       �Zze#e¢�d‘<    �e'�t¢        �tx        �¬’«      �a{�e'e¢�d“<   d�Z|e#e¢�d”<   d�Z}e#e¢�d•<   d�Z~e#e¢�d–<   d�ad�a€d�a�eúdz  e¢�d—<   �d˜e¡f�d™„�Z‚�d˜e¡dÁe§f�dš„�Zƒ�d�d›�e½f�dœ„�Z„�d�„ �Z…�dž�Z†e#e¢�dŸ<   dÁ�e½f�d „�Z‡�d¡e dÁdf�d¢„�Zˆ	 	 	 	 	 	 �d�d¡e �d£�eË�d¤�eËdz  �d¥e dz  �d¦e dz  �d§e dz  �d¨edz  �d©�e½dÁ�eËf�dª„�Z‰�d¡e �d«�eËdÁdf�d¬„�ZŠ�d¡e dÁdf�d­„�Z‹	 	 	 	 �d�d¡e �d¥e dz  �d¦e dz  �d§e dz  �d¨edz  dÁ�eËdz  f�d®„�ZŒ�d¡e �d£�eËdÁ�eÖ�eË�e½f   f�d¯„�Z�	 	 	 	 	 	 	 �d�d°e dz  �d±e dz  �d²e dz  �d³�eËdz  �d´e dz  �dµeŸdz  �d¶e dz  �d·e§e    dz  �d¸e dz  �d¹edz  �dºee    dz  f�d»„�ZŽ�dµeŸdz  �d³�eËdz  dÁ�eàe    f�d¼„�Z��d¶e dz  �d·e§e    dz  �d³�eË�d½�eàe    dÁdf
�d¾„�Z��dºee¡   �d³�eË�d½�eàe    dÁdf�d¿„�Z‘�d´e dz  �d³�eË�d½�eàe    dÁdf�dÀ„�Z’�d¡e �dÁe e§e    z  �dÂ�eË�d½�eàe    dÁdf
�dÃ„�Z“�d¡e �dÁe e§e    z  �dÂ�eËf�dÄ„�Z”�dÅeg�dÆe �dÇee z  dz  �d§e �d¨edz  �dÂ�eË�d¸e dz  �d¹edz  dÁdf�dÈ„�Z•�d¡e �dÅe �dÆe �d§e dz  �d¨edz  �dÂ�eËf�dÉ„�Z–�d¡e �dÁe e§e    z  f�dÊ„�Z—�dÁe e§e    z  dÁ�eËf�dË„�Z˜�d¡e �dÅe �dÆe �d§e 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 f�dÐ„�Z�	 �d�d°e dz  �d²e dz  �d¶e dz  �d±e dz  �d³�eËdz  �dÑe—dz  �d·e§e    dz  f�dÒ„�Zž�dÓ„ �ZŸdÁ�eËdz  f�dÔ„�Z dÁe f�dÕ„�Z¡ e�jD                  �dÖ«      �Z£e#e¢�d×<   �dØe§�dÙ�e½dz  �dÚ�eÈdz  �dÛeŸf�dÜ„�Z¤�dØe§�dÝe§�dÞe§f�dß„�Z¥�dàeŸ�dáeŸdÁ�eÈf�dâ„�Z¦	 �d�dÝe§�dÞe§�dãeŸdz  dÁdf�dä„�Z§�då�Z¨e#e¢�dæ<   �dç„ �Z©�dè„ �Zª G �dé„ �dê�eˆ«      �Z«�dë�dì�díœ�Z¬e#eŸe �eÖe df   f      e¢�dî<   �dï�dði�Z­e#eŸe �eÖe df   f      e¢�dñ<   �dòe¡dÁ�e½f�dó„�Z®�dôeŸe e5f   dÁdf�dõ„�Z¯�döe �d÷e5dÁe5f�dø„�Z°�dòe¡dÁ�e½dz  f�dù„�Z±�dúee e¡f   dÁdf�dû„�Z²�düeÇdz  dÁdf�dý„�Z³�dþee e¡f   dÁeŸe e¡f   f�dÿ„�Z´�d ee e¡f   dÁeÇf�d„�ZµdÁ�e½f�d„�Z¶dÁeÇdz  f�d„�Z·�deÇ�d�e½dÁdf�d„�Z¸�de§�de dz  �d	e dÁe§f�d
„�Z¹�de �deŸ�de dz  dÁdf�d„�Zº�dee e¡f   dÁdf�d„�Z»�dee e¡f   dÁdf�d„�Z¼�deŸdÁdf�d„�Z½�de �de dz  �d	e dÁ�esf�d„�Z¾�deŸdÁ�eÈf�d„�Z¿�de esz  dÁ�e½f�d„�ZÀ G �d„ �d«      �ZÁ �eÁ«       �aÂ�d„ �ZÃ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 �d�d„�ZÄ�d„ �ZÅ�dew�deŸf�d„�ZÆ�deŸdÁe f�d „�ZÇ�dòe �eËz  dz  dÁ�e½f�d!„�ZÈ�deŸe e¡f   dÁ�e½f�d"„�ZÉ�d#e¡dÁ�eÖ�e½e dz  e§eŸe e¡f      f   f�d$„�ZÊ�d%e dz  �d&e§eŸe e¡f      dÁe f�d'„�ZËdæd�d(œ�d)e"�d*e �deŸ�d+�e½�d,�e½�d-e dz  dÁ�eÖe"�e½f   f�d.„�ZÌ�d)eŠdÁ�eÍdz  f�d/„�ZÎ�d)e3dÁe �eÍz  f�d0„�ZÏ�d)e¡dÁ�e½f�d1„�ZÐ�d2e‹dÁ�e½f�d3„�ZÑ�d)e"�dew�deŸ�d4e dÁ�eÖe"e f   f
�d5„�ZÒ�d)e �eÍz  dÁe �eÍz  f�d6„�ZÓ�d7�ZÔe#e¢�d8<   �d9�ZÕe#e¢�d:<   �d;e dÁ�eÖe dz  e f   f�d<„�ZÖ e¡«       �Z×e#e¢�d=<   �d>�ZØe#e¢�d?<   �d@�ZÙe#e¢�dA<    ei «      �ZÚe#ee e¡f      e¢�dB<   �dCee"   �dDee¡g�eËf   �dE�eËdÁee"df   f�dF„�ZÛ G �dG„ �dHe%«      �ZÜ�dee e"f   �dIe¡dÁ�eÜdz  f�dJ„�ZÝ�dKe¡dÁ�e½f�dL„�ZÞ�d�dee e¡f   �dIe¡dÁ�eËf�dM„�Zß�dN�Zàe#e¢�dO<   �dee e¡f   dÁee¡g�eËf   f�dP„�Zá	 �d�dew�deŸ�d�e“dz  f�dQ„�Zâ	 �d�dew�deŸ�d�e“dz  f�dR„�Zãi f�deŸf�dS„�Zä�dT„ �Zå�dU„ �Zæ G �dV„ �dW«      �Zç�e�jk                  �dX �e‹�e«      g�dYg�¬Z«      �e�jk                  �d[ �e‹�e«      g�dYg�¬Z«      d �e‹�e«      dæddædædædddæf
�d�e“�dew�d\�e½dz  �d±e dz  �d]�e½dz  �d^�e½dz  �d_�e½dz  �d`e dz  �dae dz  �db�e½dz  f�dc„«       «       �Zè�e�jk                  �dd �e‹�e«      g�dYg�¬Z«      �e�jk                  �de �e‹�e«      g�dYg�¬Z«       �e‹�e«      ddæf�dfe �dew�d±e dz  �db�e½dz  f�dg„«       «       �Zé�dhe¡dz  dÁ�dif�dj„�Zê�e�j×                  �dk �e‹�e«      g�dlg�¬Z«      �e�j×                  �dm �e‹�e«      g�dlg�¬Z«      �e�j×                  �dn �e‹�e«      g�dlg�¬Z«      �e�j×                  �do �e‹�e«      g�dlg�dp�dq�drii�eZ¥�¬s«      d �e‹�e«      f�d�e“�dt�e”�de dz  �dewf�du„«       «       «       «       �Zì�e�j×                  �dv �e‹�e«      g�dwg�¬Z«      �e�j×                  �dx �e‹�e«      g�dwg�¬Z«      �e�j×                  �dy �e‹�e«      g�dwg�¬Z«      �e�j×                  �dz �e‹�e«      g�dwg�¬Z«      d �e‹�e«      f�d�e“�dt�e”�de dz  �dewf�d{„«       «       «       «       �Zí�e�j×                  �d| �e‹�e«      g�e§�d}g�¬~«      �e�j×                  �d �e‹�e«      g�e§�d}g�¬~«      �e�j×                  �d€ �e‹�e«      g�e§�d}g�¬~«      �e�j×                  �d� �e‹�e«      g�e§�d}g�¬~«      d �e‹�e«      f�d�e“�dt�e”�de dz  �dewf�d‚„«       «       «       «       �Zî�e�j×                  �dƒ �e‹�e«      g�e§�d„g�¬~«      �e�j×                  �d… �e‹�e«      g�e§�d„g�¬~«       �e‹�e«      f�d�e“�dt�e”�dewf�d†„«       «       �Zï�d‡�eedÁe�eÍdf   f�dˆ„�Zð�e�j×                  �d‰ �e‹�e«      g�dŠg�¬Z«      �e�j×                  �d‹ �e‹�e«      g�dŠg�¬Z«       �e‹�e«      f�d�e“�dt�e”�dewf�dŒ„«       «       �Zñ�e�j×                  �d� �e‹�e«      g�dŠg�¬Z«      �e�j×                  �dŽ �e‹�e«      g�dŠg�¬Z«       �e�d«       �e‹�e«      f�d�e“�dt�e”�d��e•�dewf�d�„«       «       �Zò�eã�jç                  �d‘«       e­�j$                  d�d’�¬“«       e­�j$                  d�d”�¬“«       e­�j$                  d�d•�¬“«       �e‹�e«      f�d–�e–�de dz  �d—e dz  �d˜e dz  �dewf
�d™„«       �Zô e½eÊ�¬š«      �de dz  �d›e dz  dÁ�eÖ�eÖe e f   df   f�dœ„«       �Zõ�eã�jç                  �d�«      �eã�jç                  d«      �eã�jç                  �dž«       e­�j$                  d�dŸ�¬“«       e­�j$                  d�d �¬“«       e­�j$                  d�d¡�¬“«       �e‹�e«      f�d–�e–�de dz  �d›e dz  �d¢e dz  �dewf
�d£„«       «       «       �Zö�e�jk                  �d¤ �e‹�e«      g�d¥g�¬Z«      �e�jk                  �d¦ �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�dt�e”�dewf�d§„«       «       �Z÷�e�j×                  �d¤ �e‹�e«      g�d¥g�¬Z«      �e�j×                  �d¦ �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�dt�e”�dewf�d¨„«       «       �Zø�e�jó                  �d© �e‹�e«      g�d¥g�¬Z«      �e�jó                  �dª �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�d«e �dt�e”�dewf�d¬„«       «       �Zú�e�j×                  �d­ �e‹�e«      g�d¥g�¬Z«      �e�j×                  �d® �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�dt�e”�dewf�d¯„«       «       �Zû�e�jk                  �d° �e‹�e«      g�d¥g�¬Z«      �e�jk                  �d± �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�d²e �dt�e”�dewf�d³„«       «       �Zü�e�j×                  �d´ �e‹�e«      g�d¥g�¬Z«      �e�j×                  �dµ �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�d²e �dt�e”�dewf�d¶„«       «       �Zý�e�jk                  �d´ �e‹�e«      g�d¥g�¬Z«      �e�jk                  �dµ �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�d²e �dt�e”�dewf�d·„«       «       �Zþ�e�j×                  �d¸ �e‹�e«      g�d¥g�¬Z«      �e�j×                  �d¹ �e‹�e«      g�d¥g�¬Z«       �e‹�e«      f�d�e“�d²e �dt�e”�dewf�dº„«       «       �Zÿd �d»�l �m�Z d �d¼�l�m�Z d �d½�l�m�Z d �d¾�l�m�Z d �d¿�l�m	�Z	�m
�Z
�m�Z�m�Z�m�Z�m�Z d �dÀ�l�m�Z d �dÁ�l�m�Z �dÂeŸ�dÃe dÁ�eÖ�edz  e dz  e dz  f   f�dÄ„�Z	 	 dê�dÅ�dÆ�dÇe dz  �dÃe d"e§dz  �dÈe§dz  �dÂeŸe e"f   dz  �dÉe �dÊe§dz  �dËe dz  dÁe&�dÌ   f�dÍ„�Z�dËe¡dÁ�ecdz  f�dÎ„�Z�e�j×                  �dÏ�dÐg �e‹�e«      ge��¬Ñ«      �d�deu�dÒ�e½f�dÓ„«       �Z�e�jk                  �dÔ�dÐg �e‹�e«      g�¬Õ«      �de f�dÖ„«       �Z�e�j×                  �d×�dÐg �e‹�e«      g�e‚�¬Ñ«      �devf�dØ„«       �Z�dÙe§eŸ   �dew�dw�e&dz  dÁe§eŸ   f�dÚ„�Z�dÙe§�et   �dÛ�eødÁe§eŸ   f�dÜ„�Z�dÝe§eŸ   �doeÀ�dew�dw�e&dz  f�dÞ„�Z�dße§ej   �doeÀdÁeŸe �eàe    f   f�dà„�Z�dße§ej   �doeÀ�dw�e&�dáeŸe �eàe    f   dÁeŸe �eàe    f   f
�dâ„�Z�dãe§e    e$�da   z  �dw�e&�doeÀdÁeŸe e§e    f   f�dä„�Z�dÙee    �doeÀdÁ�eÖe df   f�då„�Z	 �d�dæel�doeÀ�dçee    dÁ�eÖe df   f�dè„�Z �dÝe§eŸ   dÁe§eŸ   f�dé„�Z!�dew�dw�e&�doeÀ�dÝe§eŸ   dÁe§eŸ   f
�dê„�Z"�dew�dw�e&�doeÀ�dÝe§eŸ   dÁe§eŸ   f
�dë„�Z#	 �d�deŸe e"f   �dì�e½�doeÀdz  dÁeŸe e"f   f�dí„�Z$�dewdz  �dw�e&dz  dÁ�eàe    dz  f�dî„�Z%�dïeŸe e5f   �dð�eàe    dz  dÁ�e½f�dñ„�Z&�dò�Z'e#e¢�dó<   	 �d�dw�e&�dô�eÁ�dõe �dö�eàe    �d÷�eÈ�dø�eÈ�dù�eÈ�dúe dz  �dûeeŸe e5f   g�e½f   �de dz  dÁ�eÖe§eŸe e"f      �eÈf   f�dü„�Z(	 	 	 	 	 �d�dÝe§eŸe e"f      �dÿe �dw�e&dz  �dô�eÁ�dewdz  �dø�eÈ�dù�eÈ�dúe dz  �de dz  dÁ�eÖe§eŸe e"f      �eÈdz  f   f�d „�Z)�de¡dÁedz  f�d„�Z*	 �d�dÝe§eŸe e"f      �dúe dz  �de dÁe§eŸe e"f      f�d„�Z+�dee e¡f   dÁ�e½f�d„�Z,�dÝe§eŸe e"f      �dø�eÈ�dù�eÈ�d�eÈdz  �dÿe dz  dÁeŸe e¡f   f�d„�Z-�dáe§e    �d	ee ee    f   dÁe§e    f�d
„�Z.�d±e �dw�e&dÁejdz  f�d„�Z/�dej�d±e �dw�e&�doeÀdÁ�eàe    f
�d„�Z0�d±e �dew�dw�e&dÁdf�d„�Z1	 �d�dÝe§eŸe e"f      �d±e �dw�e&�doeÀ�dewdz  dÁe§eŸe e"f      f�d„�Z2�dfe �dÿe dz  �doeÀdz  �dw�e&dz  �dô�ddÁ�eÖe§�eÈdz  f   f�d„�Z3�e�jk                  �d�dYg �e‹�e«      g�¬Õ«       �e‹�e«       e­�j$                  d�d�¬“«       e­�j$                  dæ�d�¬“«       e­�j$                  dæ�d�¬“«      dæ �e’�dý�d�dý�¬«       �e’�dþ�d�dý�¬«       e­�j$                  d�d�¬“«       e­�j$                  d�d�¬“«       e­�j$                  d�d�¬“«       e­�j$                  d�d�¬“«       e­�j$                  �d�d�¬“«       e­�j$                  dæ�d�¬“«      f�dew�de dz  �d�e½dz  �d�e½dz  �dì�e½dz  �dø�eÈ�dù�eÈ�dÿe dz  �d e dz  �d!e dz  �d"e dz  �d#e dz  �d$�e½dz  f�d%„«       �Z4�e�jk                  �d&�d'�dYgdæ �e‹�e«      g�¬(«       �e‹�e«      dddf�dew�d)e dz  �d*edz  �d+edz  f�d,„«       �Z5�e�jk                  �d-�d.�dYgdæ �e‹�e«      g�¬(«       �e‹�e«      �d/ddddf�dew�d)e dz  �d*edz  �d+edz  �d0e dz  �d1e dz  f�d2„«       �Z6�e�jk                  �d3�d4�dYgdæ �e‹�e«      g�¬(«       �e‹�e«      �d/ddddf�dew�d)e dz  �d*edz  �d+edz  �d0e dz  �d1e dz  f�d5„«       �Z7�e�jk                  �d6�d7�dYgdæ �e‹�e«      g�¬(«       �e‹�e«      dddddf�dew�d)e dz  �d*edz  �d+edz  �d0e dz  �d1e dz  f�d8„«       �Z8�deŸe e5f   �d9ee    dÁ�e½f�d:„�Z9�dew�doeÀdÁ�eàe    dz  f�d;„�Z:�dÝe§eŸ   �d9�eàe    dz  dÁe§eŸ   f�d<„�Z;�deŸdÁeŸf�d=„�Z<�deŸdÁeŸf�d>„�Z=�e�jk                  �d?�dYg �e‹�e«      g�¬Õ«      �e�jk                  �d@�dYg �e‹�e«      g�¬Õ«       �e‹�e«      d e­�j$                  dæ�dA�¬“«       e­�j$                  d�d�¬“«      dæf�dew�dBe dz  �d�e½dz  �d!e dz  �db�e½dz  f
�dC„«       «       �Z>�e�jk                  �dD�dE �e‹�e«      f�eo�¬Ñ«      �e�jk                  �dF�dE �e‹�e«      f�eo�¬Ñ«      �enf�dG�eÈdÁ�eof�dH„«       «       �Z?�doeÀ�dIe§e    �dJe dz  dÁe§�ei   f�dK„�Z@�e�jk                  �dL�dYg �e‹�e«      g�¬Õ«       �e‹�e«      df�dew�dJe dz  f�dM„«       �ZA�e�jk                  �dN�dO�dYg �e‹�e«      gdæ�¬P«      �dQ„ «       �ZB�e�jk                  �dR�dS�dTg �e‹�e«      gdæ�¬P«       �e‹�e«      f�dewf�dU„«       �ZC�e�j×                  �dV�dWg �e‹�e«      gdæ�¬X«      d �e‹�e«      f�d�e“�dt�e”�de dz  �dewf�dY„«       �ZD�eã�jk                  dË�dWgdæ�¬Z«      �d�e“f�d[„«       �ZE�e�j×                  �d\dæ�¬j«      �d�e“f�d]„«       �ZF�e�j×                  �d^dæ�¬j«      �d�e“f�d_„«       �ZG�e�j×                  �d`dæ�¬j«      �d�e“f�da„«       �ZH�e�j×                  �dbdæ�¬j«      �d�e“f�dc„«       �ZI�eã�jk                  �dddæ�¬j«      �dee �d�e“f�df„«       �ZJ�d�e“dÁeŸf�dg„�ZK�dhe �d²e dÁdf�di„�ZL�dj�e÷dÁe f�dk„�ZM�eã�j×                  �dldæ�¬j«      �dmea�d�e“f�dn„«       �ZN�eã�jk                  �dodæ�¬j«      �dp„ «       �ZO�dqe dÁ�e”dz  f�dr„�ZP�eã�jk                  �dsdæ�¬j«      �d�dte$�du   dz  f�dv„«       �ZQ�eã�jk                  �dwdæ�¬j«      �dx„ «       �ZR�e�j×                  �dy�dzg �e‹�e«      gecdæ�¬{«       �e‹�e«      f�dmed�dewf�d|„«       �ZS�e�jk                  �d}�dzg �e‹�e«      gecdæ�¬{«       �e‹�e«      f�d~e �dewf�d„«       �ZT�e�j×                  �d€�dzg �e‹�e«      gecdæ�¬{«       �e‹�e«      f�dmee�dewf�d�„«       �ZU�e�j×                  �d‚�dzg �e‹�e«      gecdæ�¬{«       �e‹�e«      f�dmeb�dewf�dƒ„«       �ZV�e�j×                  �d„�d…g �e‹�e«      gdæ�¬X«       �e‹�e«      f�d†e]�dewf�d‡„«       �ZW	 �dˆ�ZXe#e¢�d‰<    ei �dŠ�d‹“�dŒ�d‹“�d��d‹“�dŽ�d‹“�d��d‹“�d��d‹“�d‘�d’“�d��d““�d”�d““�d•�d–“�d—�d–“�d˜�d‹“�d™�d‹“�dš�d–“�d›�d–“�dœ�d�“�dž�d�“�d‹�d“�d“�d��d“�d“�d“�dŸœ¥«      �ZYe#ee e f      e¢�d <   �d¡e¡�d¢e¡dÁe¡f�d£„�ZZ�e�j×                  �d¤�d…g �e‹�e«      gdæ�¬X«       �e‹�e«      f�dmeZ�dewf�d¥„«       �Z[�d¦e dÁ�e½f�d§„�Z\�då�Z]e#e¢�d¨<   �d�dòe5�d©�eÈdÁe5f�dª„�Z^�d«e dz  �d¬e5dÁe5f�d­„�Z_�d¦e �dòe5�d®�e½dÁe5f�d¯„�Z`dæ�d°œ�dòe5dz  �d±�e½dÁe dz  f�d²„�Za�eb�jÆ                  f�d«e �d³�ed�d´e5dz  �dµe5dz  �dew�d¶�ebdÁdf�d·„�Ze �eÄh �d¸£«      �Zfe#e¢�d¹<   �dºeŸe e dz  f   dÁeŸe e dz  f   f�d»„�Zg�d¼e§�d®�e½dÁe§f�d½„�Zh G �d¾„ �d¿e)«      �Zi�dºeŸ�d®�e½dÁeŸf�dÀ„�Zj�d®�e½f�dÁ„�Zk�e�jk                  �dÂ�d…g �e‹�e«      geYdæ�¬{«       �e‹�e«      f�d¦e �dewf�dÃ„«       �Zl�eË�e½z  e z  dz  �Zm G �dÄ„ �dÅe)«      �Zn�dÆ�dÇ�dÈœ�d“�dÉ�dÊ�dËœ�dÌ�dÍ�dÉ�dÎ�dÏœ�d“�dÐ�dÈœ�dÑ�d>�dÒ�dÓœ�dÔœ�Zoe#eŸe �enf      e¢�dÕ<   �dÖ�endÁ�emf�d×„�Zp�d¦e �dòe¡dÁ�emf�dØ„�Zq�d¦e �dòe¡�dewdÁeŸf�dÙ„�Zr�d¦e �dewdÁeŸf�dÚ„�Zs�e�jk                  �dÛ�d…g �e‹�e«      gdæ�¬X«       �e‹�e«      f�dÜe$�dr   �dewdÁe§e\   f�dÝ„«       �Zt�e�j×                  �dÞ�d…g �e‹�e«      gdæ�¬X«       �e‹�e«      f�dmeX�dewf�dß„«       �Zu�e�j×                  �dà�d…g �e‹�e«      gdæ�¬X«       �e‹�e«      f�dmeU�dewf�dá„«       �Zv�e�jk                  �dâ�d…gdæ �e‹�e«      g�¬ã«       �e‹�e«      f�dewf�dä„«       �Zw�e�jk                  �då�d…g �e‹�e«      gdæ�¬X«      �d†e]f�dæ„«       �Zx�e�j×                  �dç�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dewf�dè„«       �Zy�e�j×                  �dé�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dê�eÈ�dewf�dë„«       �Zz�e�jó                  �dé�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dewf�dì„«       �Z{�e�jk                  �dí�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dewf�dî„«       �Z|�e�jk                  �dï�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dewf�dð„«       �Z}�e�j×                  �dñ�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dewf�dò„«       �Z~�e�j×                  �dó�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dê�eÈ�dewf�dô„«       �Z�e�jó                  �dó�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dewf�dõ„«       �Z€�e�jk                  �dö�dYg �e‹�e«      gdæ�¬X«       �e‹�e«      f�dewf�d÷„«       �Z��e�jk                  �dJ �e‹�e«      g�¬ø«      �d�e“f�dù„«       �Z‚�e�jk                  �dú�dûg �e‹�e«      g�¬Õ«       �e‹�e«      f�dewf�dü„«       �Zƒ�e�jk                  �dý �e‹�e«      g�¬ø«      �dþ„ «       �Z„�eã�	j                  �e«       �eã�	j                  �e«       �eã�	j                  �e
«       �eã�	j                  �e«       �eã�	j                  �e«       �eã�	j                  �eý«       �eã�	j                  �e«       �eã�	j                  �e?«       �eã�	j                  �el«       �eã�	j                  �e«       �eã�	j                  �e—«       �eã�	j                  �e‚«       �eã�	j                  �en«       �eã�	j                  �e«       �eã�	j                  �e«       �eã�	j                  �eÿ«       �eã�	j                  �e«       �eã�	j                  �e«       �eã�	j                  �e�«       �eã�	j                  �e¾«       �eã�	j                  �e¸«       �eã�	j                  �eÔ«       �eã�	j                  �eÙ«       �eã�	j                  �eÌ«       �eã�	j                  �e²«       �eã�	j                  �eÀ«       �eã�	j                  �e«       �eã�	j                  �e «       �eã�	j                  �e«       �eã�	j                  �e§«       �eã�	j                  �e/«       �eã�	j                  �eŸ«       �eã�	j                  �e"«       �eã�	j                  �e$«       �eã�	j                  �eÒ«       �eã�	j                  �e£«       �eã�	j                  �eÊ«       �eã�	j                  �eÄ«       �eã�	j                  �e¡«       �eã�	j                  �eÐ«       �eã�	j                  �eÝ«       �eã�	j                  �eæ«       �eã�	j                  �eì«       �eã�	j                  �e°«       �eã�	j                  �eÎ«       �eã�	j                  �e´«       �eã�	j                  �e¥«       �eã�	j                  �e®«       �eã�	j                  �eÛ«       �eã�	j                  �e¶«       �eã�	j                  �e±«       �eã�	j                  �e€«       �eã�	j                  �e…«        eÿ�eã«       �eã�jc                  �eù�dÿ„ �d „ �¬«       �daeŸdÁ�df�d„�Z†�eã�	j                  eCg �d¢�¬«      �d�e“f�d„«       �Zˆ�eã�	j                  �dg �d¢�¬«      �de �d�e“f�d	„«       �Z‰�d
e �d�e“f�d„�ZŠ�de �de dz  dÁe§e    f�d„�Z‹�de dÁ�e½f�d„�ZŒ�eã�	j                  �dg �d¢�¬«      �de �d�e“f�d„«       �Z�y# e´$ rZµ e´d&eµ› d'�«      ‚dZµ[µww xY w# e´$ r
 d�Zðd�ZòY �9Œ†w xY w# �eˆ$ r d¦�Z‡Y �6Œýw xY w# �eˆ$ r 	 d d�l³�Z³n# �eˆ$ r Y nw xY wY �6ŒTw xY w# e´$ r d�Z¸Y �6Œ:w xY w# 1 sw Y   �.Œ³xY w# 1 sw Y   �.Œ^xY w# �e+�e,�e-f$ r Y �/Œ9w xY w# �e,$ r"Zµ eÃ�j`                  �d_�e	eµ«       Y dZµ[µ�-Œ_dZµ[µw�eˆ$ r"Zµ eÃ�j`                  �d`�e	eµ«       Y dZµ[µ�-Œ…dZµ[µww xY w# �eˆ$ r Y �-Œ–w xY w(   é    N)ÚAsyncGeneratorÚAsyncIteratorÚCallableÚ
CollectionÚMappingÚMutableMappingÚSequence)ÚdatetimeÚ	timedeltaÚtimezone)ÚMappingProxyTypeÚ	UnionType)ÚTYPE_CHECKINGÚAnyÚFinalÚLiteralÚ
NamedTupleÚOptionalÚProtocolÚ	TypeAliasÚ	TypedDictÚUnionÚcastÚget_argsÚ
get_originÚget_type_hints)Ú	BaseModelÚJsonÚ	JsonValue)ÚNotRequiredÚReadOnlyÚassert_never)Úuuid)ÚAIOHTTP_CONNECTOR_LIMITÚ AIOHTTP_CONNECTOR_LIMIT_PER_HOSTÚAIOHTTP_KEEPALIVE_TIMEOUTÚAIOHTTP_NEEDS_CLEANUP_CLOSEDÚAIOHTTP_TTL_DNS_CACHEÚAUDIO_SPEECH_CHUNK_SIZEÚBASE_MCP_ROUTEÚ DAILY_TAG_SPEND_BATCH_MULTIPLIERÚDEFAULT_MAX_RECURSE_DEPTHÚ$DEFAULT_SHARED_HEALTH_CHECK_LOCK_TTLÚDEFAULT_SHARED_HEALTH_CHECK_TTLÚ DEFAULT_SLACK_ALERTING_THRESHOLDÚ<LITELLM_EMBEDDING_PROVIDERS_SUPPORTING_INPUT_ARRAY_OF_TOKENSÚ"LITELLM_SETTINGS_SAFE_DB_OVERRIDESÚLITELLM_UI_ALLOW_HEADERSÚLITELLM_UI_SESSION_DURATION)Ú$_init_custom_logger_compatible_class)Ú
safe_dumps)Úsafe_json_loads)$Ú
UI_TEAM_IDÚCallbackDeleteÚCallInfoÚCommonProxyErrorsÚConfigFieldDeleteÚConfigFieldInfoÚConfigFieldUpdateÚConfigGeneralSettingsÚ
ConfigListÚ
ConfigYAMLÚCoordinationRedisParamsÚEnterpriseLicenseDataÚFieldDetailÚInvitationClaimÚInvitationDeleteÚInvitationModelÚInvitationNewÚInvitationUpdateÚLiteLLM_EndUserTableÚLitellm_EntityTypeÚLiteLLM_JWTAuthÚLiteLLM_TagTableÚLiteLLM_TeamTableÚLiteLLM_TeamTableCachedObjÚLiteLLM_UserTableÚLitellmUserRolesÚPassThroughGenericEndpointÚProxyErrorTypesÚProxyExceptionÚRoleBasedPermissionsÚSpecialModelNamesÚSupportedDBObjectTypeÚTeamDefaultSettingsÚTokenCountRequestÚTransformRequestBodyÚUserAPIKeyAuth)Ú
CacheCodec)Úis_sensitive_callback_keyÚnormalize_callback_namesÚprocess_callbackÚstrip_callback_config©Ú_realtime_request_body)Ú get_fallback_errors_from_headersÚget_hidden_params_dict)ÚSTRATEGY_ROUTER_PARAM_FIELDSÚ"carries_complexity_router_settingsÚ+validate_complexity_router_config_placement)ÚModelResponseÚModelResponseStreamÚStreamingChoicesÚTextCompletionResponseÚTokenCountResponse)Ú$_invalidate_model_cost_lowercase_mapÚload_credentials_from_listÚ(reapply_runtime_model_cost_registrations)ÚClientSession)ÚAPIRoute)ÚSpan©Úmodels)ÚOpenTelemetryÚhttpÚPOSTz/v1/realtime)ÚtypeÚmethodÚpathÚREALTIME_REQUEST_SCOPE_TEMPLATEc                 ó\   — |› d|› d|j                   › d| › d�}|�|j                  |«       y y )Nú:ú: ú
)Ú__name__Úwrite)ÚmessageÚcategoryÚfilenameÚlinenoÚfileÚlineÚtraceback_infos          ú_/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/proxy_server.pyÚshowwarningr‰   �   s?   € Ø'˜j¨¨&¨°°H×4EÑ4EÐ3FÀbÈÈ	ÐQSÐT€NØÐØ�
‰
�>Õ"ð ó    Údefault)r‚   Úmessagesz../..)ÚAsyncIOScheduler)ÚIntervalTriggerz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...'Úlist_of_messagesc                  óò  — d} t        j                  t        «      }t        «        t        dd| z  z   dz   «       t        dd| z  z   dz   «       t        dd|d›d	�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# z^59z #[0mz# {:^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Úchoicer�   ÚprintÚformat)Ú	box_widthr�   s     rˆ   Úgenerate_feedback_boxr™   Ä   sä   € Ø€Iô —]‘]Ô#3Ó4€Gä	„GÜ	Ð
˜s Y™Ñ
.°Ñ
;Ô<Ü	Ð
˜s Y™Ñ
.°Ñ
;Ô<Ü	ˆ,˜2˜g c˜]¨)Ð4Ñ
4Ô5Ü	ØÐ*×1Ñ1Ð2aÓbÑbôô 
Ð
˜s Y™Ñ
.°Ñ
;Ô<Ü	Ð
˜s Y™Ñ
.°Ñ
;Ô<Ü	„GÜ	Ð
;Ô<Ü	„GÜ	„GÜ	„GÜ	Øbôô 
„GÜ	…GrŠ   )Údefaultdict)Úasynccontextmanager)Ú	lru_cache)ÚRouter)Ú_redact_stringÚverbose_proxy_loggerÚverbose_router_logger)Ú	DualCacheÚ
RedisCache)ÚRedisClusterCache)Ú_REALTIME_BODY_CACHE_SIZEÚAPSCHEDULER_COALESCEÚAPSCHEDULER_MAX_INSTANCESÚAPSCHEDULER_MISFIRE_GRACE_TIMEÚAPSCHEDULER_REPLACE_EXISTINGÚCLI_SSO_SESSION_TTL_SECONDSÚDAYS_IN_A_MONTHÚDEFAULT_HEALTH_CHECK_INTERVALÚDEFAULT_MODEL_CREATED_AT_TIMEÚGLOBAL_PROXY_SPEND_CACHE_KEYÚLITELLM_PROXY_ADMIN_NAMEÚLITELLM_PROXY_BUDGET_NAMEÚMONTHLY_SPEND_REPORT_JOB_IDÚ PROMETHEUS_FALLBACK_STATS_JOB_IDÚ)PROMETHEUS_FALLBACK_STATS_SEND_TIME_HOURSÚPROXY_BATCH_POLLING_ENABLEDÚPROXY_BATCH_POLLING_INTERVALÚPROXY_BATCH_WRITE_ATÚ!PROXY_BUDGET_RESCHEDULER_MAX_TIMEÚ!PROXY_BUDGET_RESCHEDULER_MIN_TIMEÚ$PROXY_CONFIG_RELOAD_INTERVAL_SECONDSÚWEEKLY_SPEND_REPORT_JOB_ID)ÚRejectedRequestError)ÚModifyResponseException)ÚCustomLogger)ÚSlackAlerting)Úvalidated_max_agentic_loops)Úasyncify)Ú!_get_parent_otel_span_from_kwargsÚ get_litellm_metadata_from_kwargs)ÚCredentialAccessor)ÚLogging)Úrealtime_error_eventÚwebsocket_close_reason)ÚSensitiveDataMaskerÚmask_sensitive_keys)ÚAsyncHTTPHandlerÚHTTPHandler)Ú
VertexBase)Úattach_lazy_features)Ú*©Úrouter)ÚExperimentalUIJWTTokenÚcan_key_call_resolved_modelÚget_team_objectÚlog_db_metrics)Úcheck_response_size_is_safeÚis_request_body_safeÚ,warn_once_if_custom_auth_skips_common_checks)Úrouter_fallback_access_check)Ú
JWTHandler)ÚLicenseCheck)Ú*expand_wildcard_deployments_for_model_infoÚget_all_fallbacksÚget_complete_model_listÚget_key_modelsÚget_mcp_server_idsÚget_team_models)Ú+_fetch_global_spend_with_event_coordinationÚuser_api_key_authÚuser_api_key_auth_websocket)ÚProxyBaseLLMRequestProcessingÚ_is_azure_model_router_requestÚ_should_return_raw_model_nameÚcreate_responseÚopen_sse_before_first_byteÚttft_keepalive_interval)ÚAuthCacheInvalidationSubscriber)Úinitialize_callbacks_on_proxy)ÚConfigSyncSubscriber)Úinit_verbose_loggers)Údecrypt_value_helperÚencrypt_value_helper)Ú get_hidden_unhealthy_model_namesÚis_healthy_only_listing_default)Úbuild_ui_login_form)Ú_read_request_bodyÚ_safe_get_request_headersÚcheck_file_size_under_limitÚget_form_data)Ú!get_config_file_contents_from_gcsÚget_file_contents_from_s3)Úcollect_model_deprecations)ÚTeamModelNameTranslator)Ú%remove_sensitive_info_from_deployment)	Ú MODEL_COST_MAP_RELOAD_PARAM_NAMEÚclear_reload_intervalÚpod_reload_is_dueÚread_reload_scheduleÚrecord_manual_reloadÚrecord_reload_runÚreload_schedule_statusÚutc_nowÚwrite_reload_interval)Ú
ProxyState)ÚResetBudgetJob)Úapply_scheduled_job_staggerÚattach_job_timing_loggerÚparse_stagger_settingsÚstagger_trigger)ÚERROR_RESPONSES)Úget_budget_reset_settingsÚget_budget_reset_time)ÚUserApiKeyCacheÚend_user_cache_keyÚget_management_object_ttlÚmodel_access_group_cache_keyÚ$model_access_group_spend_counter_keyÚtag_cache_key)Úresolve_fields)ÚEMAIL_DESCRIPTORSÚMS_TEAMS_DESCRIPTORSÚSLACK_DESCRIPTORS)Ú SPEND_LOG_CLEANUP_BOUND_SETTINGSÚSpendLogCleanup)Úbuild_window_spend_transaction)ÚPrismaDBExceptionHandlerÚcall_with_db_reconnect_retry)ÚGatewayRequestAccumulatorÚflush_gateway_requests)Ú'PROXY_WORKER_HEARTBEAT_INTERVAL_SECONDSÚProxyWorkerHeartbeat)ÚSpendCounterReseed)Úui_discovery_endpoints_router)Úset_fine_tuning_config)Úinit_guardrails_v2Úinitialize_guardrails)Ú"filter_deployments_to_model_groupsÚ0health_check_filter_kwargs_from_general_settingsÚ*parse_background_health_check_model_groupsÚperform_health_check)Ú&_PROXY_VirtualKeyModelMaxBudgetLimiter)Ú"_OPTIONAL_PromptInjectionDetection)Ú_ProxyDBLogger)ÚPROBLEM_TYPE_BASEÚManagementProblemÚproblem_response)Úadd_litellm_data_to_request)Úrust_control_plane_router)Ú_user_has_admin_privilegesÚ_user_has_admin_viewÚadmin_can_invite_user)Ú)get_persisted_coordination_redis_settings)Úuser_update)Údelete_verification_tokensÚduration_in_secondsÚgenerate_key_helper_fn)ÚMANAGEMENT_V1_PREFIX)Ú_add_model_to_dbÚ_add_team_model_to_dbÚ"_deduplicate_litellm_router_modelsÚlive_model_ids_snapshot)Úupdate_teamÚvalidate_membership)Ú,get_disabled_non_admin_personal_key_creation)Úcreate_audit_log_for_updateÚcreate_object_audit_log)ÚTEAM_METADATA_SCHEMA_REGISTRYÚ TEAM_METADATA_VALIDATOR_REGISTRYÚparse_team_metadata_schema)Ú BillableRequestMetricsMiddlewareÚBillingRecorder)Úregister_plugins_from_config)ÚProblemDetail)Úbuild_billing_metrics_recorder)Ú!shutdown_billing_metrics_recorder.rI  rJ  )ÚInFlightRequestsMiddleware)ÚPrometheusAuthMiddleware)ÚRequestSizeLimitMiddleware)ÚSecurityHeadersMiddleware)Úset_files_config)Úopenai_passthrough_routerÚpassthrough_endpoint_routerÚ$vertex_ai_live_websocket_passthrough)Ú!initialize_pass_through_endpoints)Úroute_request)ÚGracefulShutdownManager)Úget_budget_window_start)Úget_logging_payload)Úget_instance_fn)ÚPrismaClientÚProxyLoggingÚProxyUpdateSpendÚ_cache_user_rowÚ_get_docs_urlÚ_get_openapi_urlÚ_get_projected_spend_over_limitÚ_get_redoc_urlÚ_is_projected_spend_over_limitÚ_is_valid_team_configsÚevict_config_paramÚget_config_paramÚget_custom_urlÚget_error_message_strÚget_server_root_pathÚhandle_exception_on_proxyÚhash_passwordÚ
hash_tokenÚinvalidate_config_paramÚlitellm_config_cacheÚ!migrate_passwords_to_scrypt_asyncÚ model_dump_with_preserved_fieldsÚprefetch_config_paramsÚupdate_spend)ÚSupportsModelDump)ÚCredentialsRepository)ÚTableActions)ÚAssistantsTypedDictÚ
DeploymentÚLiteLLM_ParamsÚModelGroupInfo)ÚFlowItemÚ	Scheduler)Úload_aws_kms)Úload_google_kms)Ú
get_secretÚget_secret_boolÚget_secret_strÚnormalize_nonempty_secret_strÚ!secret_manager_would_be_consultedÚstr_to_bool)Ú	AlertTypeÚSlackAlertingArgs)ÚAnthropicMessagesRequestÚAnthropicResponseÚ!AnthropicResponseContentBlockTextÚAnthropicResponseUsageBlock)ÚAllMessageValuesÚChatCompletionSystemMessageÚChatCompletionToolParamÚHttpxBinaryResponseContent)ÚWorkerRegistryEntry)ÚModelGroupInfoProxy)ÚDefaultTeamSSOParamsÚ#LiteLLM_UpperboundKeyGenerateParams)ÚDEFAULT_DEPRECATION_WARN_DAYSÚModelDeprecationResponse)ÚRealtimeQueryParams)ÚClassifierPluginÚDeploymentTypedDictÚRouterGeneralSettingsÚRoutingPluginÚSearchToolTypedDictÚupdateDeployment)Ú	ModelInfo)ÚDefaultPriorities)ÚKeyManagementSettingsÚKeyManagementSystem)ÚCredentialItemÚCustomHuggingfaceTokenizerÚRawRequestTypedDictÚStandardLoggingPayload)Ú-_add_custom_logger_callback_to_specific_event)Úversionz0.0.0T)ÚDependsÚFastAPIÚFileÚFormÚHeaderÚHTTPExceptionÚPathÚQueryÚRequestÚResponseÚ
UploadFileÚ	WebSocketÚWebSocketDisconnectÚapplicationsÚstatus)Újsonable_encoder)ÚRequestValidationError)ÚCORSMiddleware)Úget_swagger_ui_html)Úget_openapi)ÚFileResponseÚJSONResponseÚORJSONResponseÚRedirectResponseÚStreamingResponse)Ú	APIRouter)ÚOAuth2PasswordBearer)ÚAPIKeyHeader)ÚStaticFiles)Ú
enterprise)ÚEnterpriseProxyConfigÚenterprise_proxy_configÚserver_root_pathÚpremium_userrB   Úpremium_user_dataÚ+LITELLM_GLOBAL_MAX_PARALLEL_REQUEST_RETRIESÚ'global_max_parallel_request_retries_envÚproxy_stateÚSENSITIVE_DATA_MASKER>   Údatabase_urlÚalert_to_webhook_urlÚpass_through_endpointsÚ database_extra_connection_paramsÚ%_EXTRA_SECRET_GENERAL_SETTINGS_FIELDSÚworker_configÚreturnc                 ó¤   — | €yt        | t        «      rt        | «      S t        | d¬«      }t        |t        «      rt	        t        |«      «      S | S )aW  Mask sensitive fields in the worker config before it enters a log record.

    `worker_config` reaches `proxy_startup_event` as either the JSON blob
    persisted by `save_worker_config` (a string) or the dict passed directly
    to `initialize`. Both shapes can carry `master_key`, `database_url`,
    provider API keys, etc.; passing the raw value to `verbose_proxy_logger`
    leaks them whenever the last-line-of-defense regex filter is bypassed
    (`LITELLM_DISABLE_REDACT_SECRETS=true`, an older log sink, a downstream
    handler that captures records pre-filter). Redact at the source.
    N©r‹   )Ú
isinstanceÚdictÚ_redact_secret_values_in_objr6   r5   )rÏ  Úparseds     rˆ   Ú!_redact_worker_config_for_loggingr×  &  sO   € ð ÐØÜ�-¤Ô&Ü+¨MÓ:Ð:Ü# M¸4Ô@€FÜ�&œ$ÔÜÔ6°vÓ>Ó?Ð?ØÐrŠ   é   Ú#global_max_parallel_request_retriesÚ1LITELLM_GLOBAL_MAX_PARALLEL_REQUEST_RETRY_TIMEOUTÚ-global_max_parallel_request_retry_timeout_envg      N@Ú)global_max_parallel_request_retry_timeoutz/uiÚui_linkz/fallback/loginÚfallback_login_linkz/ui/model_hub_tableÚmodel_hub_linku(   ðŸ‘‰ [```LiteLLM Admin Panel on /ui```](zI). Create, Edit Keys with SSO. Having issues? Try [```Fallback Login```](ú)uB   

ðŸ’¸ [```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/ai_hub)zr[**Customize Swagger Docs**](https://docs.litellm.ai/docs/proxy/enterprise#swagger-docs---custom-routes--branding)Úcustom_swagger_messageÚ
DOCS_TITLEzLiteLLM APIÚ_titleÚDOCS_DESCRIPTIONzJEnterprise Edition 

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

z5Proxy Server to call 100+ LLMs in the OpenAI format. Ú_descriptionc                  ó�   — d a d ad ad ad ad ad at        j                  d «       t        j                  d«       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_key_updaterC  ÚsetrB  Úuser_custom_ssoÚ"user_custom_ui_sso_sign_in_handlerÚuse_background_health_checksÚuse_shared_health_checkÚhealth_check_intervalÚhealth_check_concurrencyÚprisma_clientrè  rŠ   rˆ   Úcleanup_router_config_variablesrø  `  sp   € ð$ €JØ ÐØ€LØÐØ ÐØ#ÐØ!ÐÜ$×(Ñ(¨Ô.Ü!×%Ñ% bÔ)Ø€OØ)-Ð&Ø#'Ð Ø"ÐØ ÐØ#ÐØ�MrŠ   c               ƒ   óÂ   K  — t         €y 	 ddlm}   | t         t        t        ¬«      ƒ d {  –—†  y 7 Œ# t
        $ r }t        j                  d|«       Y d }~y d }~ww xY w­w)Nr   )Údrain_spend_logs_queue©r÷  Údb_writer_clientÚproxy_logging_objz/Error flushing spend logs queue on shutdown: %s)r÷  Úlitellm.proxy.utilsrú  rü  rý  Ú	ExceptionrŸ   Ú	exception)rú  Úes     rˆ   Ú#_flush_spend_logs_queue_on_shutdownr  „  s[   è ø€ ÜÐØð	]Ý>á$Ü'Ü-Ü/ô
÷ 	
ò 	
ùô
 ò ]Ü×&Ñ&Ð'XÐZ[×\Ñ\ûð]üs6   ‚A‹ 3 «1¬3 °A±3 ³	A¼AÁAÁAÁAÚworker_heartbeatc              ƒ   ó  K  — t        j                  d«       | �t        r| j                  «       ƒ d {  –—†  t        rMt	        t        t
        «      ƒ d {  –—†  t        j                  d«       t        j                  «       ƒ d {  –—†  t        j                  �&t        j                  j                  «       ƒ d {  –—†  t        j                  «       ƒ d {  –—†  t        �t        j                  «       ƒ d {  –—†  t        �
t        «        dt        j                  v r.	 ddlm} |�|j"                  j%                  «        t)        «        y t)        «        y 7 �Œ'7 �Œ7 ŒÙ7 Œ¥7 Œ‹7 Œk# t&        $ r Y t)        «        y w xY w­w)Nz"Shutting down LiteLLM Proxy ServerzDisconnecting from PrismaÚlangfuser   )ÚlangFuseLogger)rŸ   Úinfor÷  Ú
deregisterr  Úgateway_request_accumulatorÚdebugÚ
disconnectÚlitellmÚcacheÚjwt_handlerÚcloserü  rJ  Úsuccess_callbackÚlitellm.utilsr  ÚLangfuseÚflushrÿ  rø  )r  r  s     rˆ   Úproxy_shutdown_eventr  ”  s8  è ø€ ä×ÑÐBÔCØÐ#­Ø×)Ñ)Ó+×+Ð+Ýô
 %¤]Ô4OÓP×PÐPÜ×"Ñ"Ð#>Ô?Ü×&Ñ&Ó(×(Ð(ä‡}�}Ð Ü�m‰m×&Ñ&Ó(×(Ð(ä
×
Ñ
Ó
×ÐäÐ#Ü×$Ñ$Ó&×&Ð&ô )Ð4Ü)Ô+ð ”W×-Ñ-Ñ-ð	å4àÐ)Ø×'Ñ'×-Ñ-Ô/ô $Õ%Ô#Õ%ðI 	,ùð 	Qùà(øð 	)øàøð 	'ùô ò 	àô $Õ%ð	üs�   ‚1F³E´!FÁEÁ0FÂE Â5FÂ<E"Â=FÃE$Ã!FÃ:E&Ã;&FÄ""E( ÅFÅFÅ FÅ"FÅ$FÅ&FÅ(	E>Å1FÅ=E>Å>FÚ_AiohttpAddrInfoc                   ój   — e Zd ZU eed<   eed<   eed<   eed<   eed<   eege	j                  f   ed<   y)Ú_AiohttpConnectorKwargsÚkeepalive_timeoutÚttl_dns_cacheÚenable_cleanup_closedÚlimitÚlimit_per_hostÚsocket_factoryN)
r   Ú
__module__Ú__qualname__ÚfloatÚ__annotations__ÚintÚboolr   r  Úsocketrè  rŠ   rˆ   r  r  Â  s7   … ØÓØÓØÓØƒJØÓØÐ.Ð/°·±Ð>Ñ?Ô?rŠ   r  F)Útotalc               ƒ   óœ  K  — 	 ddl m} m}m} ddlm} t        t        dœ}t        rd|d<   t        dkD  r	t        |d<   t        dkD  r	t        |d<    |«       }|�||d
<    |di |¤Ž} | | |«       ¬«      }t        j                  dt        |«      t        t        «       |S # t        $ r }t        j                  d|«       Y d	}~y	d	}~ww xY w­w)zNInitialize shared aiohttp session for connection reuse with connection limits.r   )ro   ÚDummyCookieJarÚTCPConnector)Ú'_build_aiohttp_keepalive_socket_factory)r  r  Tr  r  r  Nr  )Ú	connectorÚ
cookie_jarzjSESSION REUSE: Created shared aiohttp session for connection pooling (ID: %s, limit=%s, limit_per_host=%s)zNFailed to create shared aiohttp session: %s. Continuing without session reuse.rè  )Úaiohttpro   r'  r(  Ú&litellm.llms.custom_httpx.http_handlerr)  r&   r(   r'   r$   r%   rŸ   r  Úidrÿ  Úwarning)	ro   r'  r(  r)  Úconnector_kwargsr  r*  Úsessionr  s	            rˆ   Ú"_initialize_shared_aiohttp_sessionr2  Ë  sâ   è ø€ ð#ßGÑGõ	
ô
 ";Ü2ñ<
Ðõ (Ø8<ÐÐ4Ñ5Ü" QÒ&Ü(?Ð˜WÑ%Ü+¨aÒ/Ü1QÐÐ-Ñ.Ù GÓ IˆØÐ%Ø1?ÐÐ-Ñ.á'Ñ;Ð*:Ñ;ˆ	Ù&°Á~ÓGWÔXˆä×!Ñ!ØxÜˆw‹KÜ#Ü,ô		
ð ˆøÜò Ü×$Ñ$Ø\Ð^_ô	
ô ûð	üs/   ‚C„BB  ÂCÂ 	C	Â)CÂ?CÃC	Ã	CÚapp)NNc                óÔ  K  — dd l }t        «        t        j                  j	                  dd«      }|rµ|j                  d«      D ]¡  }|j                  «       }|sŒ	 d|vrt        d|› d�«      ‚|j                  dd«      \  }}t        j                  |«      }t        ||«      }t        j                  |«      r |«       ƒ d {  –—†  n |«        t        j                  d	|«       Œ£ t        j$                  dt&        «       t&        du rt(        j+                  «       at-        d«      at1        d«      }	t-        d«      }
t        j$                  dt3        |	«      «       |
�_t        j4                  j7                  |
«      �r6t8        j;                  |
¬«      �rt8        j=                  t>        |
¬«      ƒ d {  –—† \  aa a!n÷|	�õtE        |	tF        «      r5t        j4                  j7                  |	«      rt8        j;                  |	¬«      s/t        j                  j	                  d«      �8tE        |	tF        «      r(t8        j=                  t>        |	¬«      ƒ d {  –—† \  aa a!nYtE        |	tH        «      rtK        d9i |	¤Žƒ d {  –—†  n5 |jL                  |	«      }	tE        |	tH        «      rtK        d9i |	¤Žƒ d {  –—†  tN        €4t1        dd «      }tP        jS                  |tT        tV        ¬«      ƒ d {  –—† a'tN        �;d„ }tY        jZ                   |«       «       d:d„}tY        jZ                   |«       «       tP        j]                  t8        j_                  «       j	                  d«      xs i t>        ¬«      ƒ d {  –—† }|�ta        |«       tb        }|€tP        je                  tB        ¬«      }tP        jg                  t>        tT        |¬«       	 ddl4m5}  |«       rAddl6m7} ddl8m9}m:} ddl;m<} tE        tz        |«      rtz        nd } |||j|                  |¬ «       tP        j                  tB        |¬"«       tP        j�                  tB        ¬«       	 t        j$                  d#«       t8        j_                  «       }|j	                  di «      }t        j$                  d$tƒ        |j…                  «       «      «       tP        j‡                  t>        |¬%«      ƒ d {  –—†  t        j$                  d&«       tP        j‰                  tB        tN        tV        ¬*«       tŠ        �tŠ        j�                  t>        ¬+«       t        j$                  d,tN        «       tN        �YtŽ        j�                  dkD  rFtP        j“                  «        tY        jZ                  tP        j•                  tV        tN        ¬-«      «       tP        j—                  tŽ        j�                  tN        ¬.«       tN        �;tP        j™                  tB        tN        tš        tœ        tž        tT        ¬/«      ƒ d {  –—† nd }tN        �8tP        j¡                  «       ƒ d {  –—†  tP        j£                  «       ƒ d {  –—†  t¤        rtY        jZ                  t§        «       «       t>        �st        t>        d0d «      rbt>        j¨                  j«                  «       D ]A  }|D ]:  }|j¬                  j¯                  tN        «      ƒ d {  –—†  d(|j¬                  _X        Œ< ŒC tY        jZ                  t³        «       «       tP        jµ                  «        tP        j·                  «        t¹        «       ƒ d {  –—† a]d ­–— t½        j¾                  «        t½        jÀ                  «       ƒ d {  –—†  tº        �2	 tº        jÃ                  «       ƒ d {  –—†  t        j                  d1«       tN        �QtÅ        tN        d3«      rAtÅ        tN        jÆ                  d4«      r'	 tN        jÆ                  jÉ                  «       ƒ d {  –—†  tN        �-tÅ        tN        d6«      r	 tN        jË                  «       ƒ d {  –—†  tÍ        «       ƒ d {  –—†  t8        jÏ                  «       ƒ d {  –—†  t8        jÑ                  «       ƒ d {  –—†  tÓ        |¬8«      ƒ d {  –—†  y 7 �ŒÚ# t         $ r}t        j"                  d
||«       ‚ d }~ww xY w7 �Œ7 �Œy7 �ŒT7 �Œ!7 �Œê7 �Œd# t         $ r!}t        j$                  d!|«       Y d }~�Œéd }~ww xY w7 �Œ5# t         $ r#}t        j"                  d'|d(¬)«       Y d }~�ŒEd }~ww xY w7 �Œ+7 �Œ
7 �Œñ7 �Œm7 �Œ7 �ŒÒ7 �Œ²# t         $ r!}t        j"                  d2|«       Y d }~�ŒÀd }~ww xY w7 �Œv# t         $ r!}t        j"                  d5|«       Y d }~�Œ™d }~ww xY w7 �Œs# t         $ r!}t        j"                  d7|«       Y d }~�Œ–d }~ww xY w7 �Œ‘7 �Œx7 �Œ_7 �ŒN­w);Nr   ÚLITELLM_WORKER_STARTUP_HOOKSÚ ú,r|   zInvalid hook spec 'z1': expected format is 'module.path:function_name'é   z.Worker startup hook '%s' executed successfullyz#Worker startup hook '%s' failed: %szElitellm.proxy.proxy_server.py::startup() - CHECKING PREMIUM USER - %sFÚLITELLM_MASTER_KEYÚWORKER_CONFIGÚCONFIG_FILE_PATHzworker_config: %s©Úconfig_file_path©rÎ   r=  ÚLITELLM_CONFIG_BUCKET_NAMEÚDATABASE_URL)rÊ  rý  Úuser_api_key_cachec               “   óÄ   K  — 	 t        t        «      ƒ d {  –—† } t        j                  d| «       y 7 Œ# t        $ r }t        j
                  d|«       Y d }~y d }~ww xY w­w)NzPassword migration: %szPassword migration skipped: %s)rm  r÷  rŸ   r  rÿ  r/  )Úresultr  s     rˆ   Ú_run_pw_migrationz.proxy_startup_event.<locals>._run_pw_migrationV  sU   è ø€ ðRÜ&GÌÓ&V× V�Ü$×)Ñ)Ð*BÀFÕKð !Wùäò RÜ$×,Ñ,Ð-MÈq×QÑQûðRüs6   ‚A „4 –2—4 ±A ²4 ´	A½AÁA ÁAÁA c               “   óö  K  — ddl m} m} t        d«      D ]«  }	 | j	                   |t
        «      ¬«      ƒ d {  –—† }|j                  r t        j                  d|j                  «       |j                  dk(  r y t        j                  d|dz   |j                  «       |d	k  sŒ�t        j                  d
«      ƒ d {  –—†  Œ­ y 7 Œ‹# t        $ r$}t        j                  d|dz   |«       Y d }~ŒPd }~ww xY w7 Œ9­w)Nr   )Úglobal_agent_registryÚobject_permission_tablerØ  )Útablez>Rewrote %s object_permission rows from legacy config agent idszDLegacy agent grant id migration attempt %s/3 left %s rows unmigratedr8  z7Legacy agent grant id migration attempt %s/3 failed: %sé   é   )Ú,litellm.proxy.agent_endpoints.agent_registryrF  rG  ÚrangeÚmigrate_legacy_grant_idsr÷  Ú	rewrittenrŸ   r  Úmissedr/  rÿ  ÚasyncioÚsleep)rF  rG  ÚattemptrC  r  s        rˆ   Ú_run_agent_grant_id_migrationz:proxy_startup_event.<locals>._run_agent_grant_id_migration_  sö   è ø€ ÷ô
 ! ›8ò +�ðØ#8×#QÑ#QÙ5´mÓDð $Ró $÷ �Fð ×'Ò'Ü,×1Ñ1Ø\Ð^d×^nÑ^nôð —}‘}¨Ò)ÙÜ(×0Ñ0Ø^Ø !™ØŸ™ôð ˜Q“;Ü!Ÿ-™-¨Ó*×*Ñ*ñ++ðùô !ò Ü(×0Ñ0ØQÐSZÐ]^ÑS^Ð`a÷ñ ûðúð
 +ús\   ‚C9šC¹Cº?CÁ9C9Á;$CÂC9Â%C9Â=C7Â>C9ÃCÃ	C4ÃC/Ã*C9Ã/C4Ã4C9Úlitellm_settings)rT  Ú
llm_router©Úgeneral_settings)rU  rý  Úredis_usage_cache©Úis_otel_v2_enabled)Útrace)ÚOpenTelemetryV2Úpublish_global_otel_v2_provider©Ú_in_memory_loggers)Ú
registeredz#Skipping OTel V2 provider setup: %s)rW  rX  z(About to initialize semantic tool filterzlitellm_settings keys = %s)rU  rT  z)After semantic tool filter initializationzSemantic filter init failed: %sT©Úexc_info)rW  r÷  rA  rÍ   zprisma_client: %s)rA  r÷  ©Ú
max_budgetr÷  )rW  r÷  Ú!proxy_budget_rescheduler_min_timeÚ!proxy_budget_rescheduler_max_timeÚproxy_batch_write_atrý  Úadaptive_routersz,SESSION REUSE: Closed shared aiohttp sessionz(Error closing shared aiohttp session: %sÚdbÚstop_token_refresh_taskz%Error stopping token refresh task: %sÚstop_db_health_watchdog_taskz*Error stopping DB health watchdog task: %s)r  rè  ©rÐ  N)jÚjsonrë   ÚosÚenvironÚgetÚsplitÚstripÚ
ValueErrorÚrsplitÚ	importlibÚimport_moduleÚgetattrÚinspectÚiscoroutinefunctionrŸ   r  rÿ  Úerrorr
  rÄ  Ú_license_checkÚ
is_premiumr~  ré  r|  r×  ry   ÚisfileÚproxy_configÚis_yamlÚload_configrU  Úllm_model_listrW  rÓ  ÚstrrÔ  Ú
initializeÚloadsr÷  ÚProxyStartupEventÚ_setup_prisma_clientrý  rA  rP  Úcreate_taskÚ _init_coordination_redis_from_dbÚget_config_stateÚ_set_redis_usage_cacherX  Ú#_get_transaction_buffer_redis_cacheÚ_initialize_startup_loggingÚ&litellm.integrations.otel.model.configrZ  Úopentelemetryr[  Ú litellm.integrations.otel.loggerr\  r]  Ú*litellm.litellm_core_utils.litellm_loggingr_  Úopen_telemetry_loggerÚset_tracer_providerÚ)_validate_redis_transaction_buffer_configÚ$_warn_if_mock_testing_params_enabledÚlistÚkeysÚ _initialize_semantic_tool_filterÚ_initialize_jwt_authÚprompt_injection_detection_objÚupdate_environmentr  rd  Ú_add_proxy_budget_to_dbÚ_warm_global_spend_cacheÚ_warn_budget_without_dbÚ$initialize_scheduled_background_jobsre  rf  rg  Ú"_update_default_team_member_budgetÚ%_sync_ui_settings_to_general_settingsró  Ú_run_background_health_checkrh  ÚvaluesÚstrategyÚload_state_from_dbÚ_state_loadedÚ_adaptive_router_flusher_loopÚ_init_dd_tracerÚ_init_pyroscoper2  Úshared_aiohttp_sessionrU  Ústart_shutdownÚwait_for_drainr  Úhasattrri  rj  rk  r  Ústop_config_sync_subscriberÚ'stop_auth_cache_invalidation_subscriberr  )r3  rm  Ú_startup_hooks_envÚ
_hook_specÚ_module_pathÚ
_func_nameÚ_moduleÚ_hook_fnr  rÏ  Úenv_config_yamlÚ_db_urlrD  rS  Údb_coordination_redis_cacheÚtransaction_buffer_redis_cacherZ  Ú_otel_tracer\  r]  r_  r`  Ú_configÚ_litellm_settingsr  Ú_tagged_routersÚ_taggeds                              rˆ   Úproxy_startup_eventr¾  ó  s®  è ø€ ó$ äÔô !#§
¡
§¡Ð/MÈrÓ RÐÙØ,×2Ñ2°3Ó7ò 	ˆJØ#×)Ñ)Ó+ˆJÙØðØ˜jÑ(Ü$Ø-¨j¨\Ð9jÐkóð ð ,6×+<Ñ+<¸SÀ!Ó+DÑ(�˜jÜ#×1Ñ1°,Ó?�Ü" 7¨JÓ7�Ü×.Ñ.¨xÔ8Ù"›*×$Ñ$á”JÜ$×)Ñ)Ð*ZÐ\fÕgð!	ô, ×ÑÐfÔhtÔuÜ�uÑÜ%×0Ñ0Ó2ˆô  Ð 4Ó5€Jä'1°/Ó'B€MÜ)7Ð8JÓ)K€OÜ×ÑÐ2Ô4UÐVcÓ4dÔeàÐ"Ü�7‰7�>‰>˜/Õ*¬|×/CÑ/CÐUdÐ/CÕ/eô
 #×.Ñ.´jÐSbÐ.Óc×cñ	ØØÙ à	Ð	"ô ˜=¬#Ô.Ü—G‘G—N‘N =Ô1Ü ×(Ñ(¸-Ð(ÔHä�z‰z�~‰~Ð:Ó;ÐGÜ˜=¬#Ô.ô #×.Ñ.´jÐS`Ð.Óa×añ	ØØÙ ä˜¤tÔ,ÜÑ-˜}Ñ-×-Ñ-ð '˜DŸJ™J }Ó5ˆMÜ˜-¬Ô.Ü Ñ1 =Ñ1×1Ð1ô ÐÜ%/°ÀÓ%EˆÜ/×DÑDØ Ü/Ü1ð Eó 
÷ 
ˆô Ð ò	Rô 	×ÑÑ-Ó/Ô0ó	+ô: 	×ÑÑ9Ó;Ô<ô
 0A×/aÑ/aÜ%×6Ñ6Ó8×<Ñ<Ð=OÓPÒVÐTVÜð 0bó 0÷ *Ðð #Ð.ÜÐ:Ô;ô &7Ð"Ø%Ð-Ü):×)^Ñ)^Ü-ð *_ó *
Ð&ô ×1Ñ1ÜÜ+Ø8ð 2ô ð"MÝMáÔÝ:÷õ Vä9CÔDYÐ[jÔ9kÕ 5ÐquˆJÙ+Ø"Ø×/Ñ/Ø%õô ×?Ñ?Ü)Ø8ð @ô ô
 ×:Ñ:ÔL\Ð:Ô]ðXÜ×"Ñ"Ð#MÔNÜ%×6Ñ6Ó8ˆØ#*§;¡;Ð/AÀ2Ó#FÐÜ×"Ñ"Ð#?ÄÐFW×F\ÑF\ÓF^ÓA_Ô`Ü×@Ñ@Ü!Ø.ð Aó 
÷ 	
ð 	
ô 	×"Ñ"Ð#NÔOô
 ×*Ñ*Ü)Ü#Ü-ð +ô ô &Ð1Ü&×9Ñ9ÄÐ9ÔLä×ÑÐ2´MÔBÜÐ ¤W×%7Ñ%7¸!Ò%;Ü×1Ñ1Ô3Ü×ÑÜ×6Ñ6Ü#5Ü+ð 7ó ô	
ô ×-Ñ-Ü×%Ñ%Ü#ð .ô ô Ð$ô  ×DÑDÜ-Ü'Ü.OÜ.OÜ!5Ü/ð Eó 
÷ 	
ð 	
ð ð ô Ð Ü×BÑBÓD×DÐDô  ×EÑEÓG×GÐGõ $Ü×ÑÔ8Ó:Ô;ô Ð¤'¬*Ð6HÈ$Ô"OÜ)×:Ñ:×AÑAÓCò 	6ˆOØ*ò 6�Ø×&Ñ&×9Ñ9¼-ÓH×HÐHØ15�× Ñ Õ.ñ6ð	6ô ×ÑÔ5Ó7Ô8ô ×%Ñ%Ô'ô ×%Ñ%Ô'ô $FÓ#G×GÐô 
ô ×*Ñ*Ô,Ü
!×
0Ñ
0Ó
2×2Ð2ô Ð)ð	VÜ(×.Ñ.Ó0×0Ð0Ü ×%Ñ%Ð&TÔUô 	Ð!Ü”M 4Ô(Ü”M×$Ñ$Ð&?Ô@ð	SÜ×"Ñ"×:Ñ:Ó<×<Ð<ô
 Ð ¤W¬]Ð<ZÔ%[ð	XÜ×<Ñ<Ó>×>Ð>ô .Ó
/×/Ð/ä
×
2Ñ
2Ó
4×4Ð4ä
×
>Ñ
>Ó
@×@Ð@ä
Ð0@Ô
A×AÑAðA	 %úô ò Ü$×*Ñ*Ð+PÐR\Ð^_Ô`Øûðúð, dùð bùà-ùð
 2ùð

ùðf*úôd ò MÜ×"Ñ"Ð#HÈ!×LÒLûðMúð$	
úô
 ò XÜ×"Ñ"Ð#DÀaÐRV×WÓWûðXúð:	
ùð 	Eùð 	Hùð Iùð Hùð 3ùð
 1úäò 	VÜ ×&Ñ&Ð'QÐST×UÒUûð	Vúð =úÜò 	SÜ ×&Ñ&Ð'NÐPQ×RÒRûð	Súð ?úÜò 	XÜ ×&Ñ&Ð'SÐUV×WÒWûð	Xúð 0ùà4ùà@ùàAûsn  ‚Ag(ÁA(b ÃbÃ"b Ã&Cg(Æ5c	Æ6Bg(ÉcÉ'g(É;cÉ<5g(Ê1cÊ29g(Ë+cË,Bg(Í4cÍ5Ag(Ï	Ac Ð5g(ÑBd ÓdÓd Ó-D"g(Ød:Ø#g(Ø3d=Ø4g(Ùe ÙBg(ÛeÛA+g(ÝeÝ4g(Ý7e	Ý8
g(Þe ÞeÞe Þ40g(ß%!e? àe<àe? àg(à"f/ à9f,à:f/ à>g(ágág(á'gá(g(âg"âg(âg%âg(âb â 	câ)cãcãg(ãg(ãg(ãg(ãg(ãg(ã	dã$d ã:g(ä däg(äd ä	d7äd2ä,g(ä2d7ä7g(ä=g(å g(åg(åg(å	g(åe å	e9åe4å.g(å4e9å9g(å<e? å?	f)æf$æg(æ$f)æ)g(æ,f/ æ/	gæ8gçg(çgçg(çg(ç"g(ç%g(Úrouterp   c                 óâ   — t        j                  dd| j                  › | j                  › �«      }t	        | j
                  xs g «      }t        |«      dk(  r|› d|d   j                  «       › �}|S )Nz\WÚ_r8  r   )ÚreÚsubÚnameÚpath_formatÚsortedÚmethodsÚlenÚlower)r¿  Úoperation_idÚroute_methodss      rˆ   Ú_generate_stable_operation_idrÌ  <  sm   € Ü—6‘6˜% ¨¯©¨°U×5FÑ5FÐ4GÐ&HÓI€LÜ! %§-¡-Ò"5°2Ó6€MÜ
ˆ=Ó˜QÒØ&˜ q¨°qÑ)9×)?Ñ)?Ó)AÐ(BÐCˆØÐrŠ   >   rp  ÚputÚheadÚpostÚpatchr[  ÚdeleteÚoptionsÚ_OPENAPI_HTTP_METHODSÚSLACK_WEBHOOK_URLÚSMTP_PASSWORDÚ_ALERTING_SENSITIVE_VARSrÊ  c                 óH   — | j                  d«      \  }}}|r
|t        v r|S | S )NrÁ  )Ú
rpartitionrÓ  )rÊ  ÚbaseÚ	separatorÚsuffixs       rˆ   Ú!_strip_operation_id_method_suffixrÜ  Y  s/   € Ø*×5Ñ5°cÓ:Ñ€Dˆ)�VÙ�VÔ4Ñ4ØˆØÐrŠ   Úopenapi_schemaÚreserved_operation_idsc                 ó   — g }i }| j                  di «      j                  «       D ]’  }t        |t        «      sŒ|j	                  «       D ]l  \  }}|t
        vst        |t        «      sŒ|j                  d«      }t        |t        «      sŒA|j                  |||f«       |j                  |d«      dz   ||<   Œn Œ” t        |xs
 t        «       «      }t        «       }	|D ]›  \  }}}||   dkD  xs
 ||v xs ||	v }
|
s#|	j                  |«       |j                  |«       Œ@t        |«      }|› d|› �}d}||v s||	v r|› d|› d|› �}|dz  }||v rŒ||	v rŒ||d<   |	j                  |«       |j                  |«       Œ� |�|j                  |«       | S )NÚpathsÚoperationIdr   r8  rÁ  rI  )rp  r¢  rÓ  rÔ  ÚitemsrÓ  r‚  Úappendrð  ÚaddrÜ  Úupdate)rÝ  rÞ  Úoperation_entriesÚoperation_id_countsÚ	path_itemrx   Ú	operationrÊ  Úused_operation_idsÚseen_operation_idsÚshould_rewriteÚbase_operation_idÚnew_operation_idrÛ  s                 rˆ   Ú#ensure_unique_openapi_operation_idsrï  `  sû  € ð  "ÐØ13ÐØ#×'Ñ'¨°Ó4×;Ñ;Ó=ò 
]ˆ	Ü˜)¤TÔ*ØØ!*§¡Ó!2ò 	]ÑˆF�IØÔ2Ñ2¼*ÀYÔPTÔ:UØØ$Ÿ=™=¨Ó7ˆLÜ˜l¬CÔ0ØØ×$Ñ$ f¨i¸Ð%FÔGØ0C×0GÑ0GÈÐVWÓ0XÐ[\Ñ0\Ð Ò-ñ	]ð
]ô !$Ð$:Ò$C¼c»eÓ DÐÜ*-«%ÐØ+<ò 1Ñ'ˆ�	˜<à Ñ-°Ñ1ò 2ØÐ1Ð1ò2àÐ1Ð1ð 	ñ
 Ø×"Ñ" <Ô0Ø×"Ñ" <Ô0Øä=¸lÓKÐØ/Ð0°°&°Ð:ÐØˆØÐ"4Ñ4Ð8HÐL^Ñ8^Ø"3Ð!4°A°f°X¸Q¸v¸hÐGÐØ�a‰KˆFð Ð"4Ò4Ð8HÐL^Ò8^ð $4ˆ	�-Ñ Ø×ÑÐ/Ô0Ø×ÑÐ/Õ0ð'1ð* Ð)Ø×%Ñ%Ð&8Ô9àÐrŠ   )
Údocs_urlÚ	redoc_urlÚopenapi_urlÚtitleÚdescriptionr¢  Ú	root_pathÚlifespanÚgenerate_unique_id_functionÚstrict_content_type)Úinstrument_fastapi_appÚ#vertex_live_passthrough_vertex_base)ÚAPIWebSocketRouteÚwebsocket_routesc           	      ó   — |D ]ó  }|j                   j                  d«      d   j                  d«      }g }	 t        |d«      rX|j                  �Lt        |j                  dg «      }|r3|D ].  }|j                  |j                  d|j                  ddid	œ«       Œ0 | d
   j                  |i «      }d|vsŒ±d|j                  xs |› �dd|j                  xs |j                  dd«      › �|dddiidgdœ|d<   Œõ | S # t        t        f$ r Y Œrw xY w)uw  
    Add a synthetic GET stub for each WebSocket route so it appears in Swagger UI.

    Merges into any existing path entry rather than replacing it â€” a WebSocket route
    that shares its path with an HTTP route must not erase the HTTP operation. If
    a "get" operation is already documented on the path, the WebSocket stub is
    skipped to preserve the real GET.
    ú{r   ú?Ú	dependantÚquery_paramsÚqueryrw   Ústring)rÄ  ÚinÚrequiredÚschemarà  rp  zWebSocket: zWebSocket connection endpointÚ
websocket_ú/rÁ  Ú101rô  zWebSocket Protocol Switchedr®  )Úsummaryrô  rá  Ú
parametersÚ	responsesÚtags)ry   rq  Úrstripr¬  r   rw  rã  rÄ  r  ÚAttributeErrorÚ	TypeErrorÚ
setdefaultÚreplace)rÝ  rü  r¿  Ú	base_pathr  r  ÚparamÚ
path_entrys           rˆ   Ú+_inject_websocket_stubs_into_openapi_schemar  ®  sB  € ð "ò ˆØ—J‘J×$Ñ$ SÓ)¨!Ñ,×3Ñ3°CÓ8ˆ	àˆ
ð	Ü�u˜kÔ*¨u¯©Ð/Jä& u§¡¸ÈÓK�ÙØ!-ò ˜Ø"×)Ñ)à(-¯
©
Ø&-Ø,1¯N©NØ+1°8Ð*<ñ	õðð $ GÑ,×7Ñ7¸	À2ÓFˆ
Ø˜
Ò"à(¨¯©Ò)@°yÐ(AÐBØ>Ø!+¨E¯J©JÒ,U¸)×:KÑ:KÈCÐQTÓ:UÐ+VÐWØ(Ø# mÐ5RÐ%SÐTØ$˜ñ!ˆJ�uÒð/ð@ Ðøô ¤	Ð*ò 	Ùð	ús   ¶A$C;Ã;DÄDc                  óV  — t         j                  rt         j                  S ddlm}   | t        t         j
                  t         j                  t         j                  t         j                  ¬«      }t         j                  D �cg c]  }t        |t        «      sŒ|‘Œ }}t        ||«      }ddlm} |j                  |«      }ddlm}m}  || |t         «      «      }t%        |«      }t&        rddt&        j)                  d«      z   ig|d<   |t         _        t         j                  S c c}w )	Nr   )Úget_openapi_schema_with_compat)Úget_openapi_funcró  r¢  rô  Úroutes©ÚCustomOpenAPISpec©Úinject_lazy_stubsÚloaded_lazy_modulesÚurlr  Úservers)r3  rÝ  Ú0litellm.proxy.common_utils.openapi_schema_compatr  r¶  ró  r¢  rô  r  rÓ  rû  r  Ú.litellm.proxy.common_utils.custom_openapi_specr  Úadd_llm_api_request_schema_bodyÚlitellm.proxy._lazy_featuresr  r  rï  rÃ  rr  )r  rÝ  r¿  rü  r  r  r  s          rˆ   Úget_openapi_schemar&  Ú  sõ   € Ü
×ÒÜ×!Ñ!Ð!õñ 4Ü$Ü�i‰iÜ—‘Ü—O‘OÜ�z‰zô€Nô 36·*±*Öe¨Ä
È5ÔRcÕ@dšuÐeÐÐeô AÀÐQaÓb€Nõ Qà&×FÑFÀ~ÓV€N÷ Tá& ~Ñ7JÌ3Ó7OÓP€NÜ8¸ÓH€Nõ Ø&+¨SÔ3C×3IÑ3IÈ#Ó3NÑ-NÐ%OÐ$Pˆ�yÑ!à'„CÔÜ×ÑÐùò- fs   ÂD&ÂD&c                  óÄ  — t         j                  rt         j                  S t        «       } t        j                  j
                  }i }|D ]  }|| d   v sŒ| d   |   ||<   Œ || d<   ddlm} |j                  | «      } ddl	m
}m}  ||  |t         «      «      } t        | «      } t        rddt        j                  d«      z   ig| d<   | t         _        t         j                  S )Nrà  r   r  r  r   r  r!  )r3  rÝ  r&  ÚLiteLLMRoutesÚopenai_routesÚvaluer#  r  r$  r%  r  r  rï  rÃ  rr  )rÝ  r)  Úpaths_to_includer¿  r  r  r  s          rˆ   Úcustom_openapir,    së   € Ü
×ÒÜ×!Ñ!Ð!Ü'Ó)€Nô )×6Ñ6×<Ñ<€MØ$&ÐØò EˆØ�N 7Ñ+Ò+Ø&4°WÑ&=¸eÑ&DÐ˜UÒ#ðEð /€N�7Ñõ Qà&×FÑFÀ~ÓV€N÷ Tá& ~Ñ7JÌ3Ó7OÓP€NÜ8¸ÓH€Nõ Ø&+¨SÔ3C×3IÑ3IÈ#Ó3NÑ-NÐ%OÐ$Pˆ�yÑ!à'„CÔÜ×ÑÐrŠ   ÚDOCS_FILTEREDÚFalseÚTruec                   ó   — e Zd ZdZy)ÚUserAPIKeyCacheTTLEnumr‘   N)r   r  r  Úin_memory_cache_ttlrè  rŠ   rˆ   r1  r1  ,  s   „ ØÑrŠ   r1  ÚrequestÚexcc              ƒ   óà   K  — |j                   }|j                  «       }|j                  rt        |j                  «      nt        j
                  }t        | ||¬«       t        |d|i|¬«      S ­w)N©r4  rz  )Ústatus_codeÚcontentÚheaders)r9  Úto_dictÚcoder"  r±  ÚHTTP_500_INTERNAL_SERVER_ERRORÚ _close_dangling_otel_server_spanr¸  )r3  r4  r9  Ú
error_dictr7  s        rˆ   Úopenai_exception_handlerr?  0  s^   è ø€ ð —[‘[€GØŸ™›€JØ*-¯(ª(œ˜SŸX™Xœ¼×8]Ñ8]€KÜ$ W¨k¸sÕCÜØØ˜*Ð%Øôð ùs   ‚A,A.r7  c                 óª  — t        | j                  dd «      }|€y t        €y 	 ddlm}  |«       }	 ddlm}m} |r2|dk\  rt        j                  |||«       	 |sd | j                  _
        y y t        j                  ||«       |dk\  rt        j                  |||«       |j                   ||dk\  r|j                  n|j                  «      «       |j                  «        |sd | j                  _
        y y # t
        $ r d}Y ŒÓw xY w# t
        $ r)}t!        j"                  dt%        |«      «       Y d }~ŒSd }~ww xY w# |sd | j                  _
        w w xY w)NÚparent_otel_spanr   rY  F)ÚStatusÚ
StatusCodeé�  z+Error closing dangling OTEL SERVER span: %s)rw  Ústater‘  r�  rZ  rÿ  Úopentelemetry.tracerB  rC  Úrecord_error_attributes_on_spanrA  Ú"set_response_status_code_attributeÚ
set_statusÚERRORÚOKÚendrŸ   r
  r‚  )	r3  r7  r4  rA  rZ  Ú
v2_enabledrB  rC  r  s	            rˆ   r=  r=  >  sQ  € Ü,3°G·M±MÐCUÐW[Ó,\ÐØÐØÜÐ$ØðÝMá'Ó)ˆ
ð2ß:áØ˜cÒ!Ü%×EÑEÐFVÐX[Ð]hÔiØñ Ø-1ˆG�M‰MÕ*ð ô 	×@Ñ@ÐAQÐS^Ô_Ø˜#ÒÜ!×AÑAÐBRÐTWÐYdÔeØ×#Ñ#¡F¸{ÈcÒ?Q¨:×+;Ò+;ÐWa×WdÑWdÓ$eÔfØ×ÑÔñ Ø-1ˆG�M‰MÕ*ð øô# ò ØŠ
ðûô ò ZÜ×"Ñ"Ð#PÔRUÐVWÓRX×YÑYûðZûñ Ø-1ˆG�M‰MÕ*ð úsA   £C6 ±&D Á-A4D Ã6DÄDÄ	D9ÄD4Ä/D< Ä4D9Ä9D< Ä<Ec              ƒ   óx   K  — t        | |j                  j                  |¬«       t        |j                  «      S ­w)Nr6  )r=  Úproblemr±  r-  ©r3  r4  s     rˆ   Ú$management_problem_exception_handlerrQ  d  s+   è ø€ ä$ W¨c¯k©k×.@Ñ.@ÀcÕJÜ˜CŸK™KÓ(Ð(ùs   ‚8:c                   ó2   — e Zd ZU eed<   eeef   dz  ed<   y)Ú_ConfigParamRowÚ
param_nameNÚparam_value)r   r  r  r‚  r!  r   r   rè  rŠ   rˆ   rS  rS  j  s   … ØƒOØ˜˜i˜Ñ(¨4Ñ/Ô/rŠ   rS  c                   ó(   — e Zd ZU eeef   dz  ed<   y)Ú_ConfigOverridesRowNÚconfig_value)r   r  r  r   r‚  r   r!  rè  rŠ   rˆ   rW  rW  o  s   … Ø˜#˜y˜.Ñ)¨DÑ0Ô0rŠ   rW  c                   ó"   — e Zd ZU eeef   ed<   y)Ú_SSOConfigRowÚsso_settingsN)r   r  r  r   r‚  Úobjectr!  rè  rŠ   rˆ   rZ  rZ  s  s   … Ø   f Ñ-Ô-rŠ   rZ  c                   ó.   — e Zd ZU eeef   ez  dz  ed<   y)Ú_UISettingsRowNÚui_settings)r   r  r  r   r‚  r\  r!  rè  rŠ   rˆ   r^  r^  w  s   … Ø˜˜f˜Ñ%¨Ñ+¨dÑ2Ô2rŠ   r^  c                   óF   — e Zd ZU eed<   eed<   eed<   edz  ed<   eed<   y)Ú_InvitationLinkRowÚuser_idÚ
expires_atÚis_acceptedNÚaccepted_atÚ
created_by)r   r  r  r‚  r!  r
   r#  rè  rŠ   rˆ   ra  ra  {  s"   … ØƒLØÓØÓØ˜D‘Ó Ø„OrŠ   ra  c                   ó8   — e Zd ZU eed<   edz  ed<   edz  ed<   y)Ú_UserTableRowrb  NÚ
user_emailÚ	user_role)r   r  r  r‚  r!  rè  rŠ   rˆ   rh  rh  ƒ  s   … ØƒLØ�d‘
ÓØ�T‰zÔrŠ   rh  c                   ó(   — e Zd Zedee   fd„«       Zy)Ú_UserTeamsRowrÐ  c                  ó   — y ©Nrè  ©Úselfs    rˆ   Úteamsz_UserTeamsRow.teamsŠ  s   € Ø&)rŠ   N)r   r  r  Úpropertyr	   r‚  rq  rè  rŠ   rˆ   rl  rl  ‰  s   „ ØØ)�x ‘}Ò)ó Ù)rŠ   rl  z%prisma_models.LiteLLM_ProxyModelTableÚ_ProxyModelRowÚclientc                 ó@   — t        dt        | «      j                  «      S )NzTableActions[_ConfigParamRow])r   ÚConfigRepositoryrH  )rt  s    rˆ   Ú_config_param_tablerw  ‘  s    € ÜØ'Ô)9¸&Ó)A×)GÑ)Góð rŠ   c                   ó@   — e Zd ZU eed<   eed<   eed<   eed<   eed<   y)Ú_TTFTRowÚapi_baseÚmodelÚtime_to_first_tokenÚ
request_idÚdayN©r   r  r  r‚  r!  r   rè  rŠ   rˆ   ry  ry  —  s   … ØƒMØƒJØÓØƒOØ	„HrŠ   ry  c                   ó<   — e Zd ZU edz  ed<   eed<   eed<   eed<   y)Ú_LatencyRowNrz  r{  r~  Úavg_latency_per_tokenr  rè  rŠ   rˆ   r�  r�  Ÿ  s   … Ø�D‰jÓØƒJØ	ƒHØ Ô rŠ   r�  c                   ó6   — e Zd ZU eed<   eed<   eeef   ed<   y)Ú_ExceptionRowÚcombined_model_api_baseÚtotal_exceptionsÚexception_countsN)r   r  r  r‚  r!  r"  r   rè  rŠ   rˆ   r„  r„  ¦  s   … Ø Ó ØÓØ˜c 3˜hÑ'Ô'rŠ   r„  c                   ó2   — e Zd ZU eeez  df   ed<   eed<   y)Ú_ValidationErrorDetail.ÚlocÚmsgN)r   r  r  Útupler"  r‚  r!  rè  rŠ   rˆ   r‰  r‰  ¬  s   … Ø	ˆs�S‰y˜#ˆ~Ñ	ÓØ	„HrŠ   r‰  c              ƒ   ór  K  — | j                   j                  j                  t        «      rWt	        | d|¬«       |j                  «       }t        t        t        › d�dddj                  d„ |D «       «      xs d¬«      «      S t	        | d	|¬«       t        d	d
t        |j                  «       «      i¬«      S ­w)NrD  r6  zinvalid-query-parameterzInvalid query parameterz; c              3   óh   K  — | ]*  }d j                  d„ |d   dd D «       «      › d|d   › �–— Œ, y­w)ú.c              3   ó2   K  — | ]  }t        |«      –— Œ y ­wrn  ©r‚  )Ú.0Úparts     rˆ   ú	<genexpr>zFotel_request_validation_exception_handler.<locals>.<genexpr>.<genexpr>¼  s   è ø€ ÒG¨d¤ D§	ÑGùó   ‚rŠ  r8  Nr}   r‹  )Újoin)r’  rz  s     rˆ   r”  z<otel_request_validation_exception_handler.<locals>.<genexpr>»  s@   è ø€ ò !Ø^c�s—x‘xÑG°e¸E±lÀ1À2Ð6FÔGÓGÐHÈÈ5ÐQVÉ<È.ÔYñ!ùs   ‚02z)The request query parameters are invalid.)rw   ró  r±  Údetaili¦  r—  ©r7  r8  )r   ry   Ú
startswithr8  r=  Úerrorsr-  rH  r+  r–  r¸  r²  )r3  r4  Úvalidation_errorss      rˆ   Ú)otel_request_validation_exception_handlerrœ  ±  s³   è ø€ à‡{�{×Ñ×"Ñ"Ô#7Ô8Ü(¨°#¸3Õ?ØEHÇZÁZÃ\ÐÜÜÜ)Ð*Ð*AÐBØ/ØØ—y‘yñ !Øgxô!ó ò ?ð ?ôó

ð 
	
ô % W¨c°sÕ;ÜØØÔ+¨C¯J©J«LÓ9Ð:ôð ùs   ‚B5B7c              ƒ   óÖ   K  — t        |t        t        t        f«      r|‚t	        j
                  dt        |«      j                  «       t        | d|¬«       t        dddddœi¬«      S ­w)	Nz"Unhandled exception in request: %séô  r6  rz  úInternal server errorÚinternal_server_error)r�   rw   r˜  )
rÓ  rS   r¨  r³  rŸ   r   rw   r   r=  r¸  rP  s     rˆ   Ú otel_unhandled_exception_handlerr¡  È  sg   è ø€ ä�#œ¬Ô7MÐNÔOØˆ	Ü×"Ñ"Ð#GÌÈcË×I[ÑI[Ô\Ü$ W¨c°sÕ;ÜØàØ2Ø/ñð
ôð ùs   ‚A'A)rÎ   Úcors_origins_envÚcors_credentials_envc                 óz  — | �| nt        j                  d«      }|�|j                  «       dk(  rdg}n=|j                  d«      D �cg c]#  }|j                  «       sŒ|j                  «       ‘Œ% }}|�|nt        j                  d«      }|�%|j                  «       j	                  «       dk(  }||fS d|v}||fS c c}w )a³  
    Compute CORS allowed origins and credentials flag from environment variables.

    Extracted into a function so it can be unit-tested without reloading the module.

    Args:
        cors_origins_env: Value of LITELLM_CORS_ORIGINS (defaults to os.getenv).
        cors_credentials_env: Value of LITELLM_CORS_ALLOW_CREDENTIALS (defaults to os.getenv).

    Returns:
        Tuple[List[str], bool]: (origins, allow_credentials)
    ÚLITELLM_CORS_ORIGINSr6  rÌ   r7  ÚLITELLM_CORS_ALLOW_CREDENTIALSÚtrue)rn  Úgetenvrr  rq  rÉ  )r¢  r£  Ú_origins_rawÚcomputed_originsÚoÚ_credentials_rawÚcomputed_credentialss          rˆ   Ú_get_cors_configr®  Ü  sØ   € ð  /?Ð.JÑ*ÔPR×PYÑPYÐZpÓPq€LØÐ˜|×1Ñ1Ó3°rÒ9Ø˜5Ñà/;×/AÑ/AÀ#Ó/FÖT¨!È!Ï'É'Í)˜AŸG™G�IÐTÐÐTð !5Ð @ÑÄbÇiÁiÐPpÓFqð ð Ð#Ø/×5Ñ5Ó7×=Ñ=Ó?À6ÑIÐð Ð1Ð1Ð1ð  #Ð*:Ð:ÐàÐ1Ð1Ð1ùò! Us   ÁB8ÁB8Ú_experimentalÚoutÚpackaged_ui_pathz/litellm-asset-prefixÚlitellm_asset_prefixry   c                 ó    — 	 t         j                  j                  | «      xr t        t        j                  | «      «      S # t
        $ r Y yw xY w)NF)rn  ry   ÚisdirÚanyÚscandirÚFileNotFoundError)ry   s    rˆ   Ú_dir_has_contentr¸    s?   € ð	Ü—7‘7—=‘= Ó&Ò@¬3¬r¯z©z¸$Ó/?Ó+@Ð@øÜ ò 	Ùð	ús   ‚>A Á	AÁAÚui_pathc                 ó@  — t         j                  j                  | «      syt         j                  j                  t         j                  j	                  | d«      «      syt         j                  j	                  | d«      }t         j                  j                  |«      syy)a  
        Verify UI directory has minimum required structure.

        Checks for:
        - Directory exists
        - Has index.html (main entry point)
        - Has _next directory (Next.js assets)

        Returns True if UI directory appears valid and servable.
        Fú
index.htmlÚ_nextT)rn  ry   r´  Úexistsr–  )r¹  Únext_dirs     rˆ   Ú_validate_ui_directoryr¿    sg   € ô �w‰w�}‰}˜WÔ%Øô �w‰w�~‰~œbŸg™gŸl™l¨7°LÓAÔBØô Ÿ'™'Ÿ,™, w°Ó8ˆÜ�w‰w�}‰}˜XÔ&ØàrŠ   Úui_dirc                 ó:  — t         j                  j                  | «      syt         j                  j                  | d«      }t         j                  j	                  |«      rt        j                  d|«       yt         j                  j	                  t         j                  j                  | d«      «      sy	 t        j                  | «      D ]š  }|j                  «       sŒ|j                  j                  d«      rŒ0t         j                  j                  |j                  d«      }t         j                  j	                  |«      sŒzt        j                  d|j                  «        y 	 y# t        t        f$ r!}t        j                  d| |«       Y d	}~yd	}~ww xY w)
ad  
        Detect if UI directory is already pre-restructured and ready to serve.

        Returns True if:
        1. Marker file .litellm_ui_ready exists (created by Dockerfile), OR
        2. Restructuring pattern detected (subdirectories with index.html inside)

        This allows skipping copy/restructure operations on read-only filesystems.
        Fz.litellm_ui_readyzFound UI ready marker: %sTr»  rÁ  z9Detected restructured UI via pattern: found %s/index.htmlz1Could not scan %s for restructuring detection: %sN)rn  ry   r´  r–  r½  rŸ   r
  r¶  Úis_dirrÄ  r™  ÚPermissionErrorÚOSError)rÀ  Úmarker_fileÚentryÚ
index_pathr  s        rˆ   Ú_is_ui_pre_restructuredrÈ  ,  s(  € ô �w‰w�}‰}˜VÔ$Øô  ŸW™WŸ\™\¨&Ð2EÓFˆÜ�7‰7�>‰>˜+Ô&Ü ×&Ñ&Ð'BÀKÔPØô �w‰w�~‰~œbŸg™gŸl™l¨6°<Ó@ÔAØð	ÜŸ™ FÓ+ò $�Ø—<‘<•>¨%¯*©*×*?Ñ*?ÀÕ*DÜ!#§¡§¡¨e¯j©j¸,Ó!G�JÜ—w‘w—~‘~ jÕ1ä,×2Ñ2ØWÐY^×YcÑYcôñ  $ñ$ð øô  ¤Ð)ò 	Ü ×&Ñ&Ð'ZÐ\bÐdeÔfÜûð	ús1   Â6(E* ÃE* Ã;A	E* Å!E* Å'E* Å*FÅ9FÆFÚsource_pathÚtarget_pathc                 ó  — 	 t        j                  |d¬«       t        |«      s:t        | «      r/t        j                  | |d¬«       t        j                  d|«       yy# t        t        f$ r}dt        |«      fcY d}~S d}~ww xY w)	z|
        Attempt to populate target UI directory from source.

        Returns: (success: bool, error_message: str)
        T©Úexist_ok)Údirs_exist_okzSuccessfully populated UI at %s)Tr6  )Fz(Source or target directory state invalidFN)
rn  Úmakedirsr¸  ÚshutilÚcopytreerŸ   r  rÃ  rÄ  r‚  )rÉ  rÊ  r  s      rˆ   Ú_try_populate_ui_directoryrÒ  Y  sv   € ð	!Ü�K‰K˜¨dÕ3Ü# KÔ0Ô5EÀkÔ5RÜ—‘ØØØ"&õô
 %×)Ñ)Ð*KÈ[ÔYØàHøÜ¤Ð)ò 	!Øœ#˜a›&�=Õ ûð	!ús   ‚AA ÁBÁ.B Á:BÂ BÚLITELLM_NON_ROOTr6  r§  Úis_non_rootz/var/lib/litellm/uiÚLITELLM_UI_PATHÚruntime_ui_pathzJPackaged UI at %s is invalid or incomplete. UI may not function correctly.Úshould_use_runtime_pathÚhas_contentzUsing pre-restructured UI at %sz\UI at %s has content but is not properly restructured. Will attempt to restructure in place.z<UI not found at %s. Attempting to populate from packaged UI.z¯Failed to populate UI at %s: %s. Falling back to packaged UI at %s. For read-only deployments, pre-build UI in Dockerfile or set LITELLM_UI_PATH to a writable emptyDir volume.zUsing packaged UI directory: %szHSelected UI path %s is invalid or incomplete. UI may not work correctly.r  z°Cannot apply server_root_path replacements to UI at %s: path is not writable. Ensure server_root_path is '/' or pre-process UI files in Dockerfile with custom server_root_path.)	z.pngz.jpgz.jpegz.gifz.icoz.woffz.woff2z.ttfz.eotÚrúutf-8)Úencodingz&/litellm/.well-known/litellm-ui-configz/.well-known/litellm-ui-configÚwz/_nextr¼  ©Ú	directoryÚnext_static©rÄ  )rÞ  ÚhtmlÚuiÚui_rootc                 óZ  — t        j                  | «      D �]  \  }}}t         j                  j                  || «      }|dk(  rdn!|j	                  t         j
                  «      d   }|dv rŒV|D ]©  }|j                  d«      r|dk(  rŒt         j                  j                  ||«      }t         j                  j                  |«      d   }t         j                  j                  |d«      }	t        j                  |d¬«       	 t        j                  ||	«       Œ« �Œ y	# t        $ r Y Œ»w xY w)
zCEnsure each exported HTML route is available as <route>/index.html.r�  r6  r   >   úlitellm-asset-prefixr¼  z.htmlr»  TrÌ  N)rn  Úwalkry   Úrelpathrq  ÚsepÚendswithr–  ÚsplitextrÏ  r  r·  )
rã  Úcurrent_rootrÁ  ÚfilesÚrel_rootÚfirst_segmentrƒ   Ú	file_pathÚ
target_dirrÊ  s
             rˆ   Ú_restructure_ui_html_filesrñ  û  s  € ô ')§g¡g¨gÓ&6ó 	Ñ"ˆL˜!˜UÜ—w‘w—‘ |°WÓ=ˆHØ"*¨c¢/™B°x·~±~ÄbÇfÁfÓ7MÈaÑ7PˆMð Ð AÑAØà!ò �Ø×(Ñ(¨Ô1°XÀÒ5MØäŸG™GŸL™L¨°xÓ@�	ÜŸW™W×-Ñ-¨iÓ8¸Ñ;�
Ü Ÿg™gŸl™l¨:°|ÓD�ä—‘˜J°Õ6ðÜ—J‘J˜y¨+Õ6òñ	øô& )ò áðús   ÄDÄ	D*Ä)D*z9Skipping UI restructuring: %s is already pre-restructuredz¬Cannot restructure UI at %s: path is not writable. UI may not work correctly for extensionless routes. Pre-build and restructure UI in Dockerfile for read-only deployments.zRestructured UI directory: %sz8Permission error while restructuring UI directory %s: %sz-Error while restructuring UI directory %s: %srÌ   )Úallow_originsÚallow_credentialsÚallow_methodsÚallow_headersÚexpose_headersc                  óZ   — t         �$t        t        t        j                  t        ¬«      S d S )N)ÚpremiumÚlicense_dataÚlitellm_version)rI  rÄ  r{  Úairgapped_license_datar¢  rè  rŠ   rˆ   ú<lambda>rü  J  s4   € ô *Ð5ô 	'Ü ô (×>Ñ>Ü#ô	
ð ð ð rŠ   c                  ó   — t         �t        S d S rn  )r÷  r	  rè  rŠ   rˆ   rü  rü  Z  s   € ¼Ð8QÔ4€ ÐW[€ rŠ   )Úrecorder_factoryÚsink_factoryc                  ód  ‡‡‡— t         j                  j                  t        d«      } t        €dnt        }|j                  d«      s|dz   }|dz   Št        j                  dt        | ¬«      d¬«       ddl	m
Š ddlm} d	t        j                   |«       «      z   d
z   Šˆˆˆfd„}|t        _        y )NÚswaggerr  z/swaggerrÝ  rà  r   ©ÚHTMLResponse)Úlazy_tag_to_prefixzconst TAG_TO_PREFIX = a  ;const warmedTags = new Set();const LAZY_TAGS = new Set(Object.keys(TAG_TO_PREFIX));const hideStubRows = () => {document.querySelectorAll('.opblock').forEach(op => {const d = op.querySelector('.opblock-summary-description');if (d && LAZY_TAGS.has(d.textContent.trim())) op.style.display = 'none';});};const annotateLazyHeaders = () => {document.querySelectorAll('.opblock-tag').forEach(tagEl => {const m = (tagEl.id || '').match(/^operations-tag-(.+)$/);if (!m || !LAZY_TAGS.has(m[1])) return;const existing = tagEl.querySelector('.lazy-load-hint');if (warmedTags.has(m[1])) { if (existing) existing.remove(); return; }if (existing) return;const hint = document.createElement('small');hint.className = 'lazy-load-hint';hint.textContent = ' (expand to load routes)';hint.style.opacity = '0.6';hint.style.marginLeft = '6px';const target = tagEl.querySelector('a span') || tagEl.querySelector('span') || tagEl;target.appendChild(hint);});};setInterval(() => { hideStubRows(); annotateLazyHeaders(); }, 200);const LazyLoadPlugin = () => ({afterLoad:function(system){setTimeout(()=>{for(const tag of LAZY_TAGS)system.layoutActions.show(['operations-tag',tag],false);},200);},statePlugins:{layout:{wrapActions:{show:(ori,sys)=>(...args)=>{const thing=args[0];const shown=args[1];let tag=null;if(Array.isArray(thing)){for(const t of thing)if(TAG_TO_PREFIX[t])tag=t;}if(shown!==false&&tag&&!warmedTags.has(tag)){warmedTags.add(tag);fetch('/lazy/warm/'+tag,{method:'POST',credentials:'include'}).then(r=>r.json()).then(d=>{if(!d.paths||Object.keys(d.paths).length===0)return;const cur=sys.specSelectors.specJson().toJS();const merged={};let inserted=false;for(const k in (cur.paths||{})){if(k===d.stub_path){for(const nk in d.paths)merged[nk]=d.paths[nk];inserted=true;}else{merged[k]=cur.paths[k];}}if(!inserted)Object.assign(merged,d.paths);cur.paths=merged;cur.components=cur.components||{};cur.components.schemas=Object.assign(cur.components.schemas||{},(d.components||{}).schemas||{});sys.specActions.updateSpec(JSON.stringify(cur));}).catch(()=>{});}return ori(...args);}}}}});c                  ó¬   •— t        | i |¤‰› d�‰› d�‰› d�dœ¤Ž}|j                  j                  d«      }|j                  d‰dz   d«      } ‰|¬	«      S )
Nz/swagger-ui-bundle.jsz/swagger-ui.cssz/favicon.png)Úswagger_js_urlÚswagger_css_urlÚswagger_favicon_urlrÚ  zconst ui = SwaggerUIBundle({zHconst ui = SwaggerUIBundle({plugins:[LazyLoadPlugin],tagsSorter:"alpha",r8  )r8  )rµ  ÚbodyÚdecoder  )ÚargsÚkwargsÚresponser	  r  Ú_lazy_plugin_jsÚcustom_root_path_swagger_paths       €€€rˆ   Úswagger_monkey_patchz.mount_swagger_ui.<locals>.swagger_monkey_patch¡  s�   ø€ Ü-Øð
àð
ð <Ð<Ð<QÐRØ<Ð=¸_ÐMØ#@Ð"AÀÐ Nó
ˆð �}‰}×#Ñ# GÓ,ˆØ�|‰|Ø*ØÐhÑhØó
ˆñ
  DÔ)Ð)rŠ   )rn  ry   r–  Úcurrent_dirrÃ  ré  r3  Úmountr¿  Úfastapi.responsesr  r%  r  rm  Údumpsr°  rµ  )Úswagger_directoryÚswagger_pathr  r  r  r  r  s       @@@rˆ   Úmount_swagger_uir  `  sŸ   ú€ Ü!Ÿw™wŸ|™|¬K¸ÓCÐÜ*Ð2‘3Ô8H€LØ× Ñ  Ô%Ø# cÑ)ˆØ+7¸)Ñ+CÐ!ä‡I�Iˆjœ+Ð0AÔBÈ€IÔSõ
 /å?ð 	!¤4§:¡:Ñ.@Ó.BÓ#CÑCð -G&ñ -	&ð öb*ð  (<„LÕ$rŠ   rð  ÚROOT_REDIRECT_URLÚroot_redirect_url)Úinclude_in_schemac               ƒ   ó*   K  — t        t        ¬«      S ­w)N©r   )rº  r  rè  rŠ   rˆ   Úroot_redirectr  º  s   è ø€ äÔ$5Ô6Ð6ùs   ‚Úuser_configrê  Úlocal_loggingrU  r�  ÚMODEL_RECONCILE_LOCKrW  Úconfig_passthrough_endpointszapi_log.jsonÚlog_fileré  r÷  ro   r©  )Údefault_in_memory_ttlrA  Úspend_counter_cacheÚcli_sso_session_cache)Ú
dual_cacheÚmodel_max_budget_limiterrX  ÚallÚpolling_via_cache_enabledÚnative_background_modeé  Úpolling_cache_ttlÚ_pkce_no_redis_warning_emittedÚ_cp_no_redis_warning_emittedÚhealth_check_resultsÚqueueÚlitellm_proxy_budget_name)Úadminr(  Úui_access_moder  r™  Ústore_model_in_dbr‘  r	  )rA  rÄ  rý  Úasync_resultÚcelery_app_connÚ	celery_fnrü  Útypc                 óÐ   — ddl m} t        | «      }|t        u s|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   r   rÓ  rw   rÔ  )r8  r;  ÚoriginÚ
union_argsÚargs        rˆ   Ú_resolve_typed_dict_typer@  !	  se   € å0ä& s›O€FØ”�˜&¤IÑ-Ü08¸³ˆ
Øò 	ˆCÜ˜#˜~Õ.Ø’
ð	ð
 ô 
�CœÔ	¤:¨c´4Ô#8Øˆ
ØrŠ   c                 óò   — t        | «      }g }|t        u s|t        u r6t        | «      }|D ]$  }|€Œdt	        |«      vsŒ|j                  |«       Œ& |S t        | t        «      rt        | t        «      r| gS |S )r:  ÚNoneType)	r   r   r   r   r‚  rã  rÓ  rw   r   )r8  r=  Útypsr>  r?  s        rˆ   Ú_resolve_pydantic_typerD  0	  sz   € ä& s›O€FØ€DØ”�˜&¤IÑ-Ü08¸³ˆ
Øò 	!ˆCØ‰ :´S¸³XÒ#=Ø—‘˜CÕ ð	!ð
 €Kô 
�CœÔ	¤:¨c´9Ô#=Øˆ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.identityrG  Úazure.keyvault.secretsrH  rn  r¨  rÿ  r  Úsecret_manager_clientrœ  ÚAZURE_KEY_VAULTÚ_key_management_systemr‚  rŸ   r   )rE  rG  rH  ÚKVUrirK  rt  r  Ú
_error_strs           rˆ   Úload_from_azure_key_vaultrS  >	  s�   € Ø˜eÑ#Øð
Ý9Ý7ô —y‘yÐ!6¸Ó=ˆàˆ=ÜÐkÓlÐlá2Ó4ˆ
ñ %¨uÀÔLˆà(.ŒÔ%Ü)<×)LÑ)LŒÕ&øÜò 
Ü ›Fˆ
Ü×&Ñ&ð CØ÷	
ñ 	
ûð
ús   ‡A$A, Á,	B Á5!BÂB c                  ó  — t         �yddlm}  t        j                  j                  t        «       «       t        j                  j                  t        «       «       t        j                  j                   | «       «       y y )Nr   ©ÚShadowEvalLogger)r÷  Ú'litellm.integrations.shadow_eval_loggerrV  r  Úlogging_callback_managerÚadd_litellm_callbackr*  Ú"add_litellm_async_success_callbackrU  s    rˆ   Úcost_trackingr[  [	  sV   € äÐ ÝLä×(Ñ(×=Ñ=¼nÓ>NÔOÜ×(Ñ(×KÑKÌNÓL\Ô]Ü×(Ñ(×=Ñ=Ñ>NÓ>PÕQð !rŠ   rJ  Ú SPEND_DB_FLOOR_CACHE_TTL_SECONDSc                  ó0   — t         j                  d«      du S )NÚfail_closed_budget_enforcementT©rW  rp  rè  rŠ   rˆ   Ú_fail_closed_budget_enforcementr`  j	  s   € Ü×ÑÐ @ÓAÀTÐIÐIrŠ   Úcounter_keyc                 óh   — t        j                  d| «       t        t        j                  ddi¬«      ‚)Nuv   fail_closed_budget_enforcement: rejecting request â€” spend for %s could not be verified against Redis or the databaserz  zæBudget enforcement unavailable: current spend could not be verified against Redis or the database, and fail_closed_budget_enforcement is enabled, so the request was rejected to avoid exceeding the configured budget. Retry shortly.©r7  r—  )rŸ   r/  r¨  r±  ÚHTTP_503_SERVICE_UNAVAILABLE©ra  s    rˆ   Ú_raise_budget_unverifiablerf  n	  s>   € Ü× Ñ ð	8àôô
 Ü×7Ñ7àðTð
ô
ð 
rŠ   Úfallback_spendrd  Úwindow_entity_typeÚwindow_entity_idÚwindow_durationÚwindow_startÚfallback_authoritativec              ƒ   ó:  K  — t        | |¬«      ƒ d{  –—† \  }}	|rd}	|�||k\  r|S |du}
||kD  s|
s
t        «       r?t        | ||||¬«      ƒ d{  –—† }|�d}	||kD  rt        | |¬«      ƒ d{  –—†  |S ||kD  r|S |	st        «       rt	        | «       |S 7 Œ�7 ŒF7 Œ*­w)a]  
    Read current spend from the cross-pod spend counter.

    Reads Redis FIRST (authoritative cross-pod value), not DualCache's
    async_get_cache which returns in-memory first. This is critical:
    DualCache.async_get_cache returns stale per-pod values because each
    pod's in-memory cache is only updated by that pod's own increments.

    Fallback chain:
    1. Redis counter (cross-pod, authoritative)
    2. In-memory counter (single-instance or Redis failure)
    3. Reseed from authoritative DB spend (counter expired, cross-pod stale)
    4. Caller-supplied fallback (DB unavailable, cold start)

    When ``max_budget`` is supplied, the counter is re-checked against the
    authoritative recorded spend before a request is admitted. A Redis counter
    that survived a Redis restart can return a stale-low value loaded from an
    older RDB snapshot; that read is a hit (not a clean miss), so step 3 never
    runs and a key can leak spend past ``max_budget`` indefinitely. The
    authoritative source depends on the counter: primary key/team/user/org
    counters read the DB row; per-window counters (``window_start`` supplied)
    read the maintained window-spend row and only aggregate spend logs when
    that row is missing or stale; end-user/tag counters have no DB row, so the caller's
    ``fallback_spend`` (loaded fresh in auth) is authoritative. The DB read is
    skipped for healthy primary counters (counter at or above recorded spend)
    and cached in-process for a few seconds, so a persistently stale counter
    drives at most one read per counter per window rather than one per request.
    )ra  rg  NT)ra  rh  ri  rj  rk  ©ra  Údb_spend)Ú_read_spend_counter_estimater`  Ú_authoritative_floor_spendÚ_repair_stale_spend_counterrf  )ra  rg  rd  rh  ri  rj  rk  rl  ÚcurrentÚverifiedÚ	is_windowÚauthoritatives               rˆ   Úget_current_spendrw  �	  sÚ   è ø€ ôL ;À{ÐcqÔr×rÑ€GˆXÙØˆàÐ˜W¨
Ò2Øˆð $¨4Ð/€IØ˜Ò¡9Ô0OÔ0QÜ%?Ø#Ø1Ø-Ø+Ø%ô&
÷  
ˆð Ð$ØˆHØ˜wÒ&Ü1¸kÐTaÔb×bÐbØ$Ð$Ø˜gÒ%ð "Ð!ñ Ô7Ô9Ü" ;Ô/à€NðO søð 
øð cús3   ‚B“B”<BÁBÁBÁ.BÁ/'BÂBÂBro  c              ƒ   ó®  K  — t         j                  j                  | ¬«      }d}|�	 t        |«      |k  }|r!t         j                  j                  | |¬«       t         j                  �+	 t         j                  j                  | |¬«      ƒ d{  –—†  yy# t        t
        f$ r d}Y Œrw xY w7 Œ# t        $ r t        j                  d| d¬«       Y yw xY w­w)a×  Raise a counter that has fallen below the authoritative DB spend (e.g.
    Redis restarted and reloaded an older snapshot) so every worker reads the
    corrected value directly instead of re-deriving it per request, and so a
    worker whose own cached spend is also stale still sees the true total.

    The write is monotonic: it only ever raises the counter, so a repair that
    carries a slightly-stale DB total cannot clobber a concurrent increment that
    already pushed the counter higher (which would let racing requests
    under-count). Redis enforces this atomically via async_set_max; the
    in-memory copy is guarded by a read-compare-write with no await in between,
    so it is atomic within the worker.
    ©ÚkeyTN©rz  r*  z0Unable to repair stale spend counter %s in Redisra  )r$  Úin_memory_cacheÚ	get_cacher   r  rs  Ú	set_cacheÚredis_cacheÚasync_set_maxrÿ  rŸ   r
  )ra  ro  ÚcachedÚneeds_updates       rˆ   rr  rr  Ñ	  sÙ   è ø€ ô (×7Ñ7×AÑAÀkÐAÓR€FØ€LØÐð	 Ü  ›=¨8Ñ3ˆLñ Ü×+Ñ+×5Ñ5¸+ÈXÐ5ÔVÜ×&Ñ&Ð2ð	Ü%×1Ñ1×?Ñ?ÀKÐW_Ð?Ó`×`Ñ`ð 3øô	 œ:Ð&ò 	 ØŠLð	 úð aùÜò 	Ü ×&Ñ&ØBØØ÷ð	üs]   ‚%C¨B ¶3CÁ*$B. ÂB,ÂB. ÂCÂB)Â&CÂ(B)Â)CÂ,B. Â.!CÃCÃCÃCc              ƒ   óŠ   K  — t        j                  t        | ¬«      ƒ d{  –—† }|€yt        | |¬«      ƒ d{  –—†  y7 Œ7 Œ­w)aë  Recover a counter that the reservation reconcile found in an inconsistent
    state (missing, or where applying the reconcile delta would drive it
    negative) by reseeding it from the DB instead of deleting it.

    The DB row is a LAGGING authoritative floor, not post-request truth: the
    entity .spend column is flushed in batches (every PROXY_BATCH_WRITE_AT), so
    it can exclude this request's just-recorded cost and other buffered spend.
    That is fine here: the monotonic set-max can only RAISE a stale-low counter
    toward that floor (never lowers it or clobbers a concurrent increment), and
    the read-time floor (_authoritative_floor_spend) converges to the true total
    as the buffer flushes. The point is to restore enforcement to a real floor
    rather than leave the counter deleted and unenforced (the prior fail-open).
    Counters with no DB row (window/end-user/tag) are left untouched rather than
    deleted, so enforcement keeps reading whatever value they hold.
    ©r÷  ra  Nrn  )r  Úfrom_dbr÷  rr  rn  s     rˆ   Úreseed_spend_counter_from_dbr†  ò	  sD   è ø€ ô  /×6Ñ6Ä]Ð`kÔl×l€HØÐØÜ
%°+ÈÔ
Q×QÑQð møð Rús   ‚A¡?¢A¹AºAÁAc              ƒ   óÈ  K  — d| › �}t         j                  j                  |¬«      }|�t        |«      S t	        j
                  t        | ¬«      ƒ d {  –—† }|€,|�*|�(|�&t	        j                  t        ||||¬«      ƒ d {  –—† }|€y t         j                  j                  |¬«      }|�t        |«      S t         j                  j                  ||t        ¬«       |S 7 ŒŠ7 Œ^­w)Nzspend_db_floor:ry  r„  )r÷  Úentity_typeÚ	entity_idrj  rk  ©rz  r*  Úttl)
r$  r|  r}  r   r  r…  r÷  Úwindow_from_dbr~  r\  )	ra  rh  ri  rj  rk  Ú
marker_keyr�  ro  Ú	recheckeds	            rˆ   rq  rq  
  sû   è ø€ ð *¨+¨Ð7€JÜ'×7Ñ7×AÑAÀjÐAÓQ€FØÐÜ�V‹}Ðä'×/Ñ/¼mÐYdÔe×e€HàÐØÐ*ØÐ(ØÐ$ä+×:Ñ:Ü'Ø*Ø&Ø+Ø%ô
÷ 
ˆð ÐØô +×:Ñ:×DÑDÈÐDÓT€IØÐÜ�YÓÐä×'Ñ'×1Ñ1ØØÜ,ð 2ô ð
 €Oð9 føð
ús%   ‚AC"ÁCÁ-C"ÂC ÂAC"Ã C"c              ƒ   óÊ  K  — d}t         j                  �:	 t         j                  j                  | ¬«      ƒ d{  –—† }|�t        |«      dfS d}|s/t         j                  j                  | ¬«      }|�t        |«      dfS t        j                  t        t         | ¬«      ƒ d{  –—† }|�|dfS |dfS 7 Œx# t        $ r!}t        j                  d| |«       Y d}~ŒŠd}~ww xY w7 Œ=­w)a  Return (spend, authoritative). ``authoritative`` is True when the value
    came from Redis or a fresh DB read (cross-pod truth), False when it came
    from the per-pod in-memory copy or the caller's fallback. Only the
    fail-closed path reads the flag; normal callers ignore it.FNry  TzJget_current_spend: Redis read failed for %s, falling back to in-memory: %s)r÷  r$  ra  )r$  r  Úasync_get_cacher   rÿ  rŸ   r
  r|  r}  r  Ú	coalescedr÷  )ra  rg  Úredis_clean_missÚvalr  ro  s         rˆ   rp  rp  3
  sÿ   è ø€ ð ÐÜ×&Ñ&Ð2ð
	Ü+×7Ñ7×GÑGÈKÐGÓX×XˆCØˆÜ˜S“z 4Ð'Ð'Ø#Ðñ Ü!×1Ñ1×;Ñ;ÀÐ;ÓLˆØˆ?Ü˜“:˜uÐ$Ð$ô /×8Ñ8Ü#Ü/Øô÷ €Hð
 ÐØ˜ˆ~Ðð ˜5Ð Ð ð7 Yùô ò 	Ü ×&Ñ&Ø\ØØ÷ñ ûð	úðúsW   ‚C#–#B4 ¹B2ºB4 ÁC#ÁB4 ÁAC#Â#C!Â$C#Â2B4 Â4	CÂ=CÃC#ÃCÃC#ÚtokenÚteam_idrb  Úresponse_costÚorg_idÚbudget_reservationÚend_user_idr  r}  Úrequest_started_atÚmodel_access_groupsc              ƒ   ó†  ‡‡	‡‡K  — t        ||¬«      ƒ d{  –—† Š|�|dk(  r|�d|d<   y|Šdt        ddfˆˆˆ	ˆfd„}d	t        ddfˆˆˆ	ˆfd
„}dt        d	t        ddfˆˆfd„}dt        ddfˆˆfd„}t        d„ | � || «      nd|� ||«      nd|�|�	 |||«      nd|� ||«      nd|€|�t        ||‰‰¬«      nd|
rt	        |
‰‰¬«      nd|�t        |‰‰¬«      ndfD «       «      }t        j                  |ddiŽƒ d{  –—† }|D �cg c]  }t        |t        «      sŒ|‘Œ }}|r|d   ‚|�d|d<   yy7 �Œ 7 Œ7c c}w ­w)a–  
    Atomically increment spend counters for budget enforcement.

    Uses spend_counter_cache (DualCache with Redis backend when available)
    so counters are shared across all pods. Budget check functions read
    from these counters via get_current_spend() (Redis-first).

    Awaited (not create_task) in the cost callback, so the counter is
    updated before the next request's auth check runs.
    )r˜  r–  Nr   TÚ	finalizedÚ	key_tokenrÐ  c              “   ó,  •K  — t        | t        «      r| j                  d«      rt        | ¬«      n| }d|› �}|‰vrt	        ||‰
¬«      ƒ d {  –—†  t
        j                  |¬«      ƒ d {  –—† }|€y t        |dd «      xs# t        |t        «      r|j                  d«      nd }t        |t        «      rt        j                  |«      }t        |t        «      sy |D ]©  }t        |t        «      r|d   n|j                  }t        |t        «      r|j                  d«      n|j                  }d|› d	|› �}t        |«      }	|‰vrt!        |d
|||	‰
¬«      ƒ d {  –—†  t#        t$        j&                  ||||	‰
‰‰¬«      ƒ d {  –—†  Œ« y 7 �Œ=7 �Œ"7 Œ67 Œ­w)Núsk-©r”  z
spend:key:©ra  Úsource_cache_keyÚ	incrementry  Úbudget_limitsÚbudget_durationÚreset_atú:window:ÚKey©ra  rˆ  r‰  rj  rk  r¤  ©rˆ  r‰  r§  rj  rk  r¤  r}  rš  )rÓ  r‚  r™  rj  Ú!_init_and_increment_spend_counterrA  r�  rw  rÔ  rp  rm  r„  r•  r¦  r§  rV  Ú(_init_and_increment_window_spend_counterÚ _enqueue_window_spend_row_updaterJ   ÚKEY)rž  Úhashed_tokenÚkey_counter_keyÚkey_objÚkey_budget_limitsÚwindowÚdurationÚkey_window_reset_atÚkey_window_counterÚkey_window_startÚcostr}  rš  Úreserved_counter_keyss             €€€€rˆ   Ú
_key_scopez,increment_spend_counters.<locals>._key_scope
  s¼  øè ø€ ô ,6°iÄÔ+EÈ)×J^ÑJ^Ð_dÔJeŒJ˜YÕ'Ðktð 	ð $.¨l¨^Ð!<ˆØÐ"7Ñ7Ü3Ø+Ø!-Øô÷ ð ô (:×'IÑ'IÈlÐ'IÓ'[×![ˆØˆ?ØÜ# G¨_¸dÓCò 
Ü,6°wÄÔ,EˆG�K‰K˜Ô(È4ð 	ô Ð'¬Ô-Ü $§
¡
Ð+<Ó =ÐÜÐ+¬TÔ2ØØ'ò 	ˆFÜ4>¸vÄtÔ4L�vÐ/Ò0ÐRX×RhÑRhˆHÜ<FÀvÌtÔ<T &§*¡*¨ZÔ"8ÐZ`×ZiÑZiÐØ#-¨l¨^¸8ÀHÀ:Ð!NÐÜ6°vÓ>ÐØ!Ð)>Ñ>Ü>Ø 2Ø %Ø*Ø$,Ø!1Ø"ô÷ ð ô 3Ü.×2Ñ2Ø&Ø,Ø (Ø-ØØ%Ø#5ô	÷ 	ñ 	ñ	ð!ùð "\ùð øð	úsI   ƒA
FÁF
ÁFÁ+FÁ,C-FÅFÅ(FÆFÆFÆFÆFÆFÚscope_team_idc              “   óÚ  •K  — d| › �}|‰vrt        |d| › �‰	¬«      ƒ d {  –—†  t        j                  d| › �¬«      ƒ d {  –—† }|€y t        |dd «      xs# t	        |t
        «      r|j                  d«      nd }t	        |t        «      rt        j                  |«      }t	        |t        «      sy |D ]©  }t	        |t
        «      r|d   n|j                  }t	        |t
        «      r|j                  d«      n|j                  }d| › d|› �}t        |«      }|‰vrt        |d	| ||‰	¬
«      ƒ d {  –—†  t        t         j"                  | |||‰	‰
‰¬«      ƒ d {  –—†  Œ« y 7 �Œ@7 �Œ"7 Œ67 Œ­w)Nzspend:team:úteam_id:r¢  ry  r¥  r¦  r§  r¨  ÚTeamrª  r«  )r¬  rA  r�  rw  rÓ  rÔ  rp  r‚  rm  r„  r•  r¦  r§  rV  r­  r®  rJ   ÚTEAM)r¼  Úteam_counter_keyÚteam_objÚteam_budget_limitsr´  rµ  Úteam_window_reset_atÚteam_window_counterÚteam_window_startr¹  r}  rš  rº  s            €€€€rˆ   Ú_team_scopez-increment_spend_counters.<locals>._team_scope´
  s¥  øè ø€ Ø$/°¨Ð"?ÐØÐ#8Ñ8Ü3Ø,Ø#+¨M¨?Ð!;Øô÷ ð ô );×(JÑ(JÐQYÐZgÐYhÐOiÐ(JÓ(j×"jˆØÐØÜ$ X¨ÀÓEò 
Ü-7¸Ä$Ô-GˆH�L‰L˜Ô)ÈTð 	ô Ð(¬#Ô.Ü!%§¡Ð,>Ó!?ÐÜÐ,¬dÔ3ØØ(ò 	ˆFÜ4>¸vÄtÔ4L�vÐ/Ò0ÐRX×RhÑRhˆHÜ=GÈÔPTÔ=U 6§:¡:¨jÔ#9Ð[a×[jÑ[jÐ Ø$/°¨¸hÀxÀjÐ"QÐÜ 7¸Ó ?ÐØ"Ð*?Ñ?Ü>Ø 3Ø &Ø+Ø$,Ø!2Ø"ô÷ ð ô 3Ü.×3Ñ3Ø'Ø-Ø (Ø.ØØ%Ø#5ô	÷ 	ñ 	ñ	ð!ùð #kùð øð	úsF   ƒE+¡E!¢ E+ÁE$ÁC-E+Ä0E'Ä1(E+ÅE)ÅE+Å$E+Å'E+Å)E+Úscope_user_idc              “   ód   •K  — d| › d|› �}|‰v ry t        |d| › d|› �‰¬«      ƒ d {  –—†  y 7 Œ­w)Nzspend:team_member:r|   zteam_membership:r¢  ©r¬  )rÈ  r¼  Úteam_member_counter_keyr¹  rº  s      €€rˆ   Ú_team_member_scopez4increment_spend_counters.<locals>._team_member_scopeà
  sN   øè ø€ Ø+=¸m¸_ÈAÈmÈ_Ð)]ÐØ"Ð&;Ñ;ØÜ/Ø/Ø/°¨¸aÀ¸ÐOØô
÷ 	
ò 	
ús   ƒ%0¨.©0c              “   óR   •K  — d| › �}|‰v ry t        || ‰¬«      ƒ d {  –—†  y 7 Œ­w)Nzspend:user:r¢  rÊ  )rÈ  Úuser_counter_keyr¹  rº  s     €€rˆ   Ú_user_scopez-increment_spend_counters.<locals>._user_scopeê
  s;   øè ø€ Ø$/°¨Ð"?ÐØÐ4Ñ4ØÜ/Ø(Ø*Øô
÷ 	
ò 	
ús   ƒ'Ÿ% 'c              3   ó$   K  — | ]  }|�|–— Œ
 y ­wrn  rè  )r’  Úcoros     rˆ   r”  z+increment_spend_counters.<locals>.<genexpr>ô
  s    è ø€ ò àð8 Ðô; 	ñùó   ‚)r™  r  r–  rº  )r›  r–  rº  ©r—  r–  rº  Úreturn_exceptions)
Ú0_reconcile_budget_reservation_for_counter_updater‚  rŒ  Ú*_increment_end_user_and_tag_spend_countersÚ,_increment_model_access_group_spend_countersÚ_increment_org_spend_counterrP  ÚgatherrÓ  ÚBaseException)r”  r•  rb  r–  r—  r˜  r™  r  r}  rš  r›  r»  rÇ  rÌ  rÏ  Úscope_corosÚscope_resultsrÙ  Úscope_errorsr¹  rº  s           ``         @@rˆ   Úincrement_spend_countersrÞ  \
  sØ  ûè ø€ ô. *ZØ-Ø#ô*÷ $Ðð
 Ð °Ò 2ØÐ)Ø.2Ð˜{Ñ+Øà&€Dð3¤Cð 3¨D÷ 3ð 3ðj*¬ð *°÷ *ð *ðX
´ð 
ÄCð 
ÈDö 
ð
¬ð 
°ö 
ô ñ ð "'Ð!2‰J�uÔ¸Ø$+Ð$7‰K˜Ô ¸TØ4;Ð4GÈGÐL_Ñ˜w¨Ô0ÐeiØ$+Ð$7‰K˜Ô ¸Tð Ð&¨$Ð*:ô 7Ø'ØØ"Ø&;õ	ð ñ #ô 9Ø$7Ø"Ø&;õð ð Ð!ô )ØØ"Ø&;õð ð5
ôó €KôH ")§¡°Ð!UÐPTÑ!U×U€MØ&3ÖT ´zÀ!Ä]Õ7Sš1ÐT€LÐTÙØ˜1‰oÐàÐ%Ø*.Ð˜;Ò'ð &ðU$ùðJ VúÚTùs:   †E—D7˜C*EÄD:ÄEÄD<Ä!D<Ä%EÄ:EÄ<Ec              ƒ   óP  K  — | €
t        «       S ddlm}m}m}  || ¬«      }	  || |xs dd¬«      ƒ d {  –—†  |S 7 Œ# t
        $ r\ t        j                  dd¬	«       	  || ¬«      ƒ d {  –—†7   n$# t
        $ r t        j                  d
«       Y nw xY wt        «       cY S w xY w­w)Nr   )Úget_reserved_counter_keysÚ&invalidate_budget_reservation_countersÚreconcile_budget_reservation)r˜  ç        F)r˜  Úactual_costÚfinalizez�Failed to reconcile budget reservation after persisted spend; invalidating reserved counters and falling back to direct incrementTra  zNFailed to invalidate reserved counters after reservation reconciliation failed)	rð  Ú/litellm.proxy.spend_tracking.budget_reservationrà  rá  râ  rÿ  rŸ   r/  r   )r˜  r–  rà  rá  râ  rº  s         rˆ   rÕ  rÕ  !  sÃ   è ø€ ð Ð!Ü‹uˆ÷ñ ñ $=ÐPbÔ#cÐðÙ*Ø1Ø%Ò,¨Øô
÷ 	
ð 	
ð" !Ð ð#	
ùô
 ò Ü×$Ñ$ð PØõ	
ð	Ù8ÐL^Ô_×_Ò_øÜò 	Ü ×*Ñ*Ø`öð	úô ‹uŠðüsa   ‚ B&£> µ<¶> ºB&¼> ¾ B#ÁA2Á+A.Á,A2Á1B#Á2BÂB#ÂBÂB#Â B&Â"B#Â#B&rº  c              ƒ   ó  K  — | �#t        d| › �t        | «      ||¬«      ƒ d {  –—†  |€y t        «       }|D ]M  }|rt        |t        «      r||v rŒ|j                  |«       t        d|› �t        |«      ||¬«      ƒ d {  –—†  ŒO y 7 Œd7 Œ	­w)Nzspend:end_user:©ra  r£  r¤  rº  z
spend:tag:)Ú,_init_and_increment_unreserved_spend_counterr  rð  rÓ  r‚  rä  r  )r™  r  r–  rº  Ú	seen_tagsÚtag_names         rˆ   rÖ  rÖ  D  s¯   è ø€ ð ÐÜ:Ø)¨+¨Ð7Ü/°Ó<Ø#Ø"7ô	
÷ 	
ð 	
ð €|Øä!$£€IØò 	
ˆÙœz¨(´CÔ8¸HÈ	Ñ<QØØ�‰�hÔÜ:Ø$ X JÐ/Ü*¨8Ó4Ø#Ø"7ô	
÷ 	
ñ 	
ñ		
ð	
øð	
ús"   ‚!B£B¤ABÂ B
ÂBÂ
Bc              ƒ   óº   K  — t        t        j                  d„ | D «       «      «      }|D ]+  }t        t	        |«      t        |«      ||¬«      ƒ d{  –—†  Œ- y7 Œ­w)aG  Charge the model access groups that authorized this request.

    Without this the counter auth reads is written only by the reservation path, so
    ``disable_budget_reservation`` would leave ``_model_access_group_max_budget_check`` enforcing
    against the DB row's spend, which lags by up to the cache TTL.

    Typed ``object`` rather than ``str`` because the names reach the cost callback out of request
    metadata, which the coercion upstream filters to a list but not to strings. A non-string that
    slipped through would build a counter key nothing else ever reads.
    c              3   óH   K  — | ]  }|sŒt        |t        «      sŒ|–— Œ y ­wrn  ©rÓ  r‚  )r’  Úgroups     rˆ   r”  z?_increment_model_access_group_spend_counters.<locals>.<genexpr>r  s   è ø€ Òa ÂÌ*ÐUZÔ\_ÕJ`”eÑaùs   ‚"Š"›"rè  N)rŒ  rÔ  Úfromkeysré  r  r  )r›  r–  rº  Úunique_groupsrï  s        rˆ   r×  r×  b  sc   è ø€ ô !Ü�‰ÑaÐ)<ÔaÓaó€Mð ò 
ˆÜ:Ü<¸UÓCÜ9¸%Ó@Ø#Ø"7ô	
÷ 	
ñ 	
ñ
ð	
ús   ‚AAÁAÁAc              ƒ   ó\   K  — | €y t        d| › �d| › d�d| › �g||¬«      ƒ d {  –—†  y 7 Œ­w)Nz
spend:org:zorg_id:z:with_budgetrè  )ré  rÓ  s      rˆ   rØ  rØ  }  sJ   è ø€ ð
 €~Øä
6Ø   Ð)Ø# F 8¨<Ð8¸GÀFÀ8Ð:LÐMØØ3ô	÷ ò ús   ‚",¤*¥,r£  r¤  c              ƒ   óF   K  — | |v ry t        | ||¬«      ƒ d {  –—†  y 7 Œ­w)Nr¢  rÊ  rè  s       rˆ   ré  ré  �  s/   è ø€ ð Ð+Ñ+Øä
+ØØ)Øô÷ ò ús   ‚!™š!c              ƒ   óh   K  — t        | |¬«      ƒ d{  –—†  t        | |¬«      ƒ d{  –—†  y7 Œ7 Œ­w)al  
    Initialize counter from the authoritative DB spend value if not yet
    set, then atomically increment in both in-memory and Redis.

    On first access per pod:
    1. Check spend_counter_cache (in-memory -> Redis via DualCache)
    2. If not found, reseed from the DB via `SpendCounterReseed.coalesced`.
       Falls back to the cached object's `.spend` via user_api_key_cache
       only if prisma is unavailable, since that value can lag the flusher.
    3. Seed counter via async_increment_cache (not async_set_cache) to avoid a
       check-then-set race: if two pods cold-start simultaneously, both may see
       the counter as absent and seed it. Using increment means the worst case
       is over-counting (conservative, blocks slightly early) rather than
       under-counting (would allow overspend).
    4. Increment atomically (both in-memory + Redis)
    )ra  r£  N©ra  r¤  )Ú!_ensure_spend_counter_initializedÚ_increment_spend_counter_cacher¢  s      rˆ   r¬  r¬  �  s>   è ø€ ô* ,ØØ)ô÷ ð ô )°[ÈIÔ
V×VÑVð	øð Wús   ‚2“.”2¨0©2°2rˆ  r‰  r§  c              ƒ   ó$  K  — |�|sy	 t         j                  j                  j                  t	        | j
                  ||||||¬«      «      ƒ d{  –—†  y7 Œ# t        $ r-}t        j                  d| j
                  |||«       Y d}~yd}~ww xY w­w)a7  Queue this request's cost against the LiteLLM_BudgetWindowSpend row for
    the window, so enforcement can read a maintained total instead of
    aggregating LiteLLM_SpendLogs.

    request_id is the LiteLLM_SpendLogs id this cost was recorded under and
    request_started_at its startTime; the flush uses them to keep the one-time
    seed from counting a request that its increment already covers.

    Enqueued even when the cache increment was skipped for a reserved counter:
    the reservation only pre-charged the counter, and the row still owes the
    actual cost.

    Windows with no reset_at slide with wall clock, so their window_start moves
    on every request and no single row can represent them. Those are left to
    the read path's LiteLLM_SpendLogs fallback rather than rewritten per
    request.
    N)rˆ  r‰  rj  rk  Úspendr}  Ú
started_atzDUnable to enqueue budget window spend update for %s=%s window=%s: %s)	rý  Údb_spend_update_writerÚwindow_spend_update_queueÚ
add_updater  r*  rÿ  rŸ   r
  )	rˆ  r‰  r§  rj  rk  r¤  r}  rš  r  s	            rˆ   r®  r®  ¹  s˜   è ø€ ð6 Ð¡8Øð
Ü×6Ñ6×PÑP×[Ñ[Ü*Ø'×-Ñ-Ø#Ø /Ø)ØØ%Ø-ôó

÷ 
	
ò 
	
ùô ò 
Ü×"Ñ"ØRØ×ÑØØØ÷	
ñ 	
ûð
üsA   ‚B‰AA ÁAÁA ÁBÁA Á	BÁ #BÂBÂBÂBc              ƒ   óª   K  — |€t        j                  d| «       y t        | ||||¬«      ƒ d {  –—† }|du ry t        | |¬«      ƒ d {  –—†  y 7 Œ7 Œ­w)Nz=Skipping spend counter increment for invalid budget window %s)ra  rˆ  r‰  rj  rk  Frõ  )rŸ   r/  Ú(_ensure_window_spend_counter_initializedr÷  )ra  rˆ  r‰  rj  rk  r¤  Úinitializeds          rˆ   r­  r­  ì  sn   è ø€ ð ÐÜ×$Ñ$ØKØô	
ð 	äGØØØØ'Ø!ô ÷ €Kð �eÑØÜ
(°[ÈIÔ
V×VÑVðøð Wús!   ‚-A¯A°AÁ	AÁ
AÁAc              ƒ   ó  K  — t        | ¬«      ƒ d {  –—† }|du r\t        j                  t        t        | d¬«      ƒ d {  –—† }|€0t        |¬«      ƒ d {  –—† }|dkD  rt        | |¬«      ƒ d {  –—†  y y y y 7 Œe7 Œ:7 Œ&7 Œ­w)Nre  FT)r÷  r$  ra  Úrequire_cache_warm)r£  r   rõ  )Ú_is_spend_counter_cache_warmr  r‘  r÷  r$  Ú_get_source_cache_base_spendr÷  )ra  r£  Úis_warmro  Ú
base_spends        rˆ   rö  rö    s’   è ø€ ô 8ÀKÔP×P€GØ�%Ñä 2× <Ñ <Ü'Ü 3Ø#Ø#ô	!
÷ 
ˆð Ðä&BÐTdÔ&e× eˆJØ˜AŠ~Ü4ÀÐXbÔc×cÑcð ð ð ð Qøð
øð !føàcúsD   ‚B ’A8“,B ¿A:Á B ÁA<ÁB Á/A>Á0	B Á:B Á<B Á>B c              ƒ   ó"  K  — t        | t        «      r| gn| }|D ]o  }t        j                  |¬«      ƒ d {  –—† }|€Œ$t        |t        «      r!t        |j                  dd«      xs d«      c S t        t        |dd«      xs d«      c S  y7 ŒV­w)Nry  rù  rã  )rÓ  r‚  rA  r�  rÔ  r   rp  rw  )r£  Úsource_cache_keysÚ	cache_keyÚsources       rˆ   r  r    s—   è ø€ ô 6@Ð@PÔRUÔ5VÐ 0Ñ1Ð\lÐØ&ò ;ˆ	Ü)×9Ñ9¸iÐ9ÓH×HˆØˆ>ØÜ�fœdÔ#Ü˜Ÿ™ G¨SÓ1Ò8°SÓ9Ò9Ü”W˜V W¨cÓ2Ò9°cÓ:Ò:ð;ð ð Iús   ‚4B¶B·ABc           	   ƒ   óÐ   K  — t        | ¬«      ƒ d {  –—† }|du ryt        j                  t        t        | ||||¬«      ƒ d {  –—† }|€t        j                  d| «       yy7 ŒO7 Œ ­w)Nre  T)r÷  r$  ra  rˆ  r‰  rj  rk  zPSkipping cold spend counter seed for %s because window spend could not be loadedF)r  r  Úcoalesced_windowr÷  r$  rŸ   r/  )ra  rˆ  r‰  rj  rk  r  Úwindow_spends          rˆ   rÿ  rÿ  )  sy   è ø€ ô 8ÀKÔP×P€GØ�$�Øä 2× CÑ CÜ#Ü/ØØØØ'Ø!ô!÷ €Lð ÐÜ×$Ñ$Ø^Øô	
ð Øð' Qøðús!   ‚A&’A"“0A&ÁA$ÁA&Á$A&c              ƒ   óh  K  — t         j                  �N	 t         j                  j                  | ¬«      ƒ d {  –—† }|€yt         j                  j	                  | |¬«       yt         j                  j                  | ¬«      d uS 7 ŒK# t
        $ r!}t        j                  d| |«       Y d }~ŒId }~ww xY w­w)Nry  Fr{  TzZUnable to read Redis spend counter %s before initialization, falling back to in-memory: %s)	r$  r  r�  r|  r~  rÿ  rŸ   r
  r}  )ra  Úcurrent_valuer  s      rˆ   r  r  F  s¾   è ø€ Ü×&Ñ&Ð2ð	Ü1D×1PÑ1P×1`Ñ1`Øð 2aó 2÷ ,ˆMð Ð$ØÜ×/Ñ/×9Ñ9ØØ#ð :ô ð ô ×.Ñ.×8Ñ8¸[Ð8ÓIÐQUÐUÐUð#,ùô ò 	Ü ×&Ñ&ØlØØ÷ñ ûð	üsH   ‚B2”#B ·B¸B ¾B2¿!B Á #B2ÂB Â	B/ÂB*Â%B2Â*B/Â/B2c              ƒ   ó8   K  — t        | |¬«      ƒ d{  –—† S 7 Œ­w)z×Public raw-counter increment for budget domains outside the entity scopes (e.g.
    shadow eval's per-leg spend), sharing the primitive the entity counters use so
    invalidation and read semantics can never drift.rõ  N)r÷  rõ  s     rˆ   Úincrement_spend_counterr  ]  s   è ø€ ô 0¸KÐS\Ô]×]Ð]Ð]ús   ‚“”c              ƒ   óT  K  — t         j                  �N	 t         j                  j                  | |d¬«      ƒ d {  –—† }t         j
                  j                  | |¬«       |S t         j                  | |d¬«      ƒ d {  –—† S 7 ŒG# t        $ r t	        | ¬«      ƒ d {  –—†7   ‚ w xY w7 Œ)­w)NT)rz  r*  Úrefresh_ttlre  r{  )r$  r  Úasync_incrementrÿ  Ú_invalidate_spend_counterr|  r~  Úasync_increment_cache)ra  r¤  r  s      rˆ   r÷  r÷  d  s¼   è ø€ Ü×&Ñ&Ð2ð	Ü)<×)HÑ)H×)XÑ)XØØØ ð *Yó *÷ $ˆMô 	×+Ñ+×5Ñ5ØØð 	6ô 	
ð Ðä$×:Ñ:ØØØð ;ó ÷ ð ð$ùô
 ò 	Ü+¸ÔD×DÑDØð	úðúsC   ‚B(”%B ¹BºB ¾>B(Á<B&Á=B(ÂB ÂB#ÂBÂB#Â#B(c              ƒ   ó  K  — t         j                  j                  | ¬«       t         j                  �*	 t         j                  j	                  | ¬«      ƒ d {  –—†  y y 7 Œ# t
        $ r t        j                  d| d¬«       Y y w xY w­w)Nry  z?Unable to delete stale spend counter %s after increment failureTra  )r$  r|  Údelete_cacher  Úasync_delete_cacherÿ  rŸ   r
  re  s    rˆ   r  r  |  sx   è ø€ Ü×'Ñ'×4Ñ4¸Ð4ÔEÜ×&Ñ&Ð2ð	Ü%×1Ñ1×DÑDÈÐDÓU×UÑUð 3àUùÜò 	Ü ×&Ñ&ØQØØ÷ð	üs:   ‚1B´#A  ÁAÁA  ÁBÁA  Á !BÂBÂBÂBrA  c              ƒ   óª  ‡‡‡‡‡‡‡K  — g Šdt         dt        fd„}ˆˆˆfd„}ˆˆˆfd„}	ˆˆˆfd„}
ˆˆˆfd„}| �‰� || ‰¬	«      ƒ d{  –—†  ‰� |«       ƒ d{  –—†  ‰� |	«       ƒ d{  –—†  ‰� |
«       ƒ d{  –—†  ‰� |«       ƒ d{  –—†  t        Št        ˆfd
„‰D «       «      }t        ˆfd„‰D «       «      }|rBt	        j
                  t        j                  t        |«      t        t        «      |d¬«      «       |rBt	        j
                  t        j                  t        |«      t        t        «      |¬«      «       yy7 Œÿ7 Œð7 Œá7 ŒÒ7 ŒÃ­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                  |t        ¬«      ƒ d {  –—† }t	        j
                  d|«       |€y |j                  xs d}||z   }|j                  du rÄ|j                  �·t        ||j                  ¬«      d	u r�t        ||j                  ¬«      \  }}|j                  }t        |j                  xs d
||j                   ||j"                  |t        |«      t$        j&                  ¬«      }	t)        j*                  t,        j/                  d|	¬«      «       y y y y 7 �Œ­w)Nr   r¡  z"_update_key_cache: hashed_token=%s)rz  Ú
model_typez(_update_key_cache: existing_spend_obj=%srã  F)Úcurrent_spendÚsoft_budget_limitTr6  )r”  rù  Ú	key_aliasrd  rb  Úprojected_spendÚprojected_exceeded_dateÚevent_groupÚprojected_limit_exceeded)rw   Ú	user_info)rÓ  r‚  r™  rj  rŸ   r
  rA  r�  rZ   rù  Úsoft_budget_cooldownÚsoft_budgetra  r_  r9   r”  r  rb  rJ   r¯  rP  r‡  rý  Úbudget_alerts)
r”  r–  r°  Úexisting_spend_objÚexisting_spendÚ	new_spendr   r!  Ú
soft_limitÚ	call_infos
             rˆ   Ú_update_key_cachez'update_cache.<locals>._update_key_cache›  su  è ø€ ä�eœSÔ! e×&6Ñ&6°uÔ&=Ü%¨EÔ2‰Là ˆLÜ×"Ñ"Ð#GÈÔVÜ#5×#EÑ#EÈ,ÔcqÐ#EÓ#r×rÐÜ×"Ñ"Ð#MÐOaÔbØÐ%Øà 2× 8Ñ 8Ò ?¸Cˆà)¨MÑ9ˆ	ð ×3Ñ3°uÑ<Ø"×.Ñ.Ð:ä.Ø"+Ø&8×&DÑ&Dôð ñ	ô 8WØ'Ø"4×"@Ñ"@ô8Ñ4ˆOÐ4ð !3× >Ñ >ˆJÜ'Ø(×.Ñ.Ò4°"ØØ,×6Ñ6Ø%Ø*×2Ñ2Ø /Ü(+Ð,CÓ(DÜ.×2Ñ2ô	 ˆIô ×ÑÜ!×/Ñ/Ø3Ø'ð 0ó õð/ð ;ð =ð sûs   ‚A%E0Á'E-Á(DE0c            	   “   ó˜  •K  — ‰	€y ‰
g} 	 | D ]¤  }|€Œt         j                  |¬«      ƒ d {  –—† }|€ y t        j                  |t        «      }|€ y t        j                  d|‰	«       |j                  xs d}|‰	z   }||_        ‰j                  |t        j                  |t        ¬«      f«       Œ¦ t         j                  t        ¬«      ƒ d {  –—† }|€y ‰	� |�|‰	z   }‰j                  t        |f«       y y y 7 ŒÏ7 Œ,# t        $ r>}t        j                  d‰
‰	t        |«      t        j                  «       «       Y d }~y d }~ww xY w­w)Nry  z6_update_user_db: existing spend: %s; response_cost: %srã  ©r  zŠSpend tracking - failed to update user spend in cache. Budget enforcement may use stale spend values. user_id=%s, response_cost=%s - %s
%s)rA  r�  r[   ÚdeserializerO   rŸ   r
  rù  rã  Ú	serializer­   rÿ  r/  r‚  Ú	tracebackÚ
format_exc)Úuser_idsÚ_idÚcached_userr(  r)  r*  Úglobal_proxy_spendr¤  r  r–  rb  Úvalues_to_update_in_caches            €€€rˆ   Ú_update_user_cachez(update_cache.<locals>._update_user_cacheÐ  s|  øè ø€ àÐ ØØ"˜)ˆð,	Øò �à�;ØÜ$6×$FÑ$FÈ3Ð$FÓ$O×O�ØÐ&áÜ%/×%;Ñ%;¸KÔIZÓ%[Ð"Ø%Ð-ÙÜ$×*Ñ*ØLÐN`Ðboôð "4×!9Ñ!9Ò!@¸S�à*¨]Ñ:�	à+4Ð"Ô(Ø)×0Ñ0àÜ"×,Ñ,Ð-?ÔL]Ô^ðõð)ô6 /A×.PÑ.PÔUqÐ.PÓ.r×(rÐØ!Ð)àØÐ*Ð/AÐ/MØ#5¸Ñ#E�	Ø)×0Ñ0Ô2NÐPYÐ1ZÕ[ð 0NÐ*ð7 Pøð. )sùô ò 		Ü ×(Ñ(ð8ð ØÜ�A“Ü×$Ñ$Ó&÷ñ ûð		üss   ƒE
‹!D  ¬C<­D  ´E
µD  ÁE
ÁA>D  ÃC>ÃD  ÃE
Ã D  Ã9E
Ã<D  Ã>D  Ä 	EÄ	4EÄ=E
ÅEÅE
c            	   “   ó  •K  — ‰�‰€y t        ‰«      } 	 t        j                  | ¬«      ƒ d {  –—† }|€y t        j                  |t
        «      }|€y t        j                  d|‰«       |j                  xs d}|‰z   }||_        ‰j                  | t        j                  |t
        ¬«      f«       y 7 Œ„# t        $ r>}t        j                  d‰‰t        |«      t        j                  «       «       Y d }~y d }~ww xY w­w)Nry  z:_update_end_user_db: existing spend: %s; response_cost: %srã  r/  z’Spend tracking - failed to update end user spend in cache. Budget enforcement may use stale spend values. end_user_id=%s, response_cost=%s - %s
%s)r  rA  r�  r[   r0  rI   rŸ   r
  rù  rã  r1  rÿ  r/  r‚  r2  r3  )	r5  Úcached_end_userr(  r)  r*  r  r™  r–  r8  s	         €€€rˆ   Ú_update_end_user_cachez,update_cache.<locals>._update_end_user_cache  s  øè ø€ ØÐ -Ð"7Øä'¨Ó4ˆð"	ä+=×+MÑ+MÐRUÐ+MÓ+V×%VˆOØÐ&ð Ü(2×(>Ñ(>¸ÔPdÓ(eÐØ!Ð)ØÜ ×&Ñ&ØLÐN`Ðboôð %7×$<Ñ$<Ò$CÀˆNà-°Ñ=ˆIà'0ÐÔ$Ø%×,Ñ,àÜ×(Ñ(Ð);ÔH\Ô]ðõð# &Wùô. ò 		Ü ×(Ñ(ð<ð ØÜ�A“Ü×$Ñ$Ó&÷ñ ûð		üsU   ƒC?•B5 ®B3¯B5 µC?¶B5 ÁC?ÁAB5 Â2C?Â3B5 Â5	C<Â>4C7Ã2C?Ã7C<Ã<C?c            	   “   óö  •K  — ‰�‰€y d‰› �} 	 t         j                  | ¬«      ƒ d {  –—† }|€y t        j                  |t        «      }|€y t        j                  d|‰«       |j                  xs d}|‰z   }||_        ‰j                  | t        j                  |t        ¬«      f«       y 7 Œ„# t        $ r>}t        j                  d‰‰t        |«      t        j                  «       «       Y d }~y d }~ww xY w­w)Nr¾  ry  z6_update_team_db: existing spend: %s; response_cost: %srã  r/  zŠSpend tracking - failed to update team spend in cache. Budget enforcement may use stale spend values. team_id=%s, response_cost=%s - %s
%s)rA  r�  r[   r0  rN   rŸ   r
  rù  rã  r1  rÿ  r/  r‚  r2  r3  )	r5  Úcached_teamr(  r)  r*  r  r–  r•  r8  s	         €€€rˆ   Ú_update_team_cachez(update_cache.<locals>._update_team_cache.  s  øè ø€ Øˆ?˜mÐ3Øà ˜yÐ)ˆð"	Ü'9×'IÑ'IÈcÐ'IÓ'R×!RˆKØÐ"àÜKU×KaÑKaØÔ7óLÐð "Ð)ØÜ ×&Ñ&ØHÐJ\Ð^kôð ,>×+CÑ+CÒ+JÀsˆNà-°Ñ=ˆIà'0ÐÔ$Ø%×,Ñ,àÜ×(Ñ(Ð);ÔHbÔcðõð% "Sùô0 ò 		Ü ×(Ñ(ð8ð ØÜ�A“Ü×$Ñ$Ó&÷ñ ûð		üsU   ƒC9�B/ ¨B-©B/ ¯C9°B/ ÁC9ÁAB/ Â,C9Â-B/ Â/	C6Â84C1Ã,C9Ã1C6Ã6C9c            	   “   ó8  •K  — ‰�‰€y	 ‰D ]¾  } | rt        | t        «      sŒt        | «      }t        j	                  |¬«      ƒ d{  –—† }|€ŒBt        j                  |t        «      }|€Œ_t        j                  d| |‰«       |j                  xs d}|‰z   }||_
        ‰	j                  |t        j                  |t        ¬«      f«       ŒÀ y7 Œ‡# t        $ r>}t        j                  d‰‰t        |«      t        j                   «       «       Y d}~yd}~ww xY w­w)z:
        Update the tag cache with the new spend.
        Nry  zC_update_tag_cache: existing spend for tag=%s: %s; response_cost: %srã  r/  z†Spend tracking - failed to update tag spend in cache. Budget enforcement may use stale spend values. tags=%s, response_cost=%s - %s
%s)rÓ  r‚  r  rA  r�  r[   r0  rL   rŸ   r
  rù  rã  r1  rÿ  r/  r2  r3  )
rë  r	  Ú
cached_tagÚexisting_tag_objr)  r*  r  r–  r  r8  s
          €€€rˆ   Ú_update_tag_cachez'update_cache.<locals>._update_tag_cacheX  s0  øè ø€ ð ˆ<˜=Ð0Øð+	Ø ò  �Ù¤z°(¼CÔ'@Øä)¨(Ó3�	ä#5×#EÑ#EÈ)Ð#EÓ#T×T�
ØÐ%àä#-×#9Ñ#9¸*ÔFVÓ#WÐ Ø#Ð+Øä$×*Ñ*ØYØØ$Ø!ô	ð "2×!7Ñ!7Ò!>¸3�à*¨]Ñ:�	à)2Ð Ô&Ø)×0Ñ0à!Ü"×,Ñ,Ð-=ÔJZÔ[ðõñ7 ð Uùô6 ò 		Ü ×(Ñ(ð5ð ØÜ�A“Ü×$Ñ$Ó&÷ñ ûð		üsA   ƒDŠ<C ÁCÁBC ÃDÃC Ã	DÃ4DÄDÄDÄDN)r”  r–  c              3   ó8   •K  — | ]  \  }}|‰k7  sŒ||f–— Œ y ­wrn  rè  ©r’  ÚkÚvÚglobal_proxy_spend_keys      €rˆ   r”  zupdate_cache.<locals>.<genexpr>œ  s"   øè ø€ Ò't±4°1°aÐXYÐ]sÓXs¨¨A¬Ñ'tùó   ƒ‘	c              3   ó8   •K  — | ]  \  }}|‰k(  sŒ||f–— Œ y ­wrn  rè  rE  s      €rˆ   r”  zupdate_cache.<locals>.<genexpr>�  s"   øè ø€ Ò(u±D°A°qÐYZÐ^tÓYt¨!¨Q¬Ñ(uùrI  T)Ú
cache_listr‹  Úlitellm_parent_otel_spanÚ
local_only)rK  r‹  rL  )
r‚  r   r­   rŒ  rP  r‡  rA  Úasync_set_cache_pipeliner•  r  )r”  rb  r™  r•  r–  rA  r  r-  r9  r<  r?  rC  Úlocal_object_updatesÚshared_scalar_updatesrH  r8  s    ```` `       @@rˆ   Úupdate_cacherQ  ‰  sf  þè ø€ ð BDÐð1¤sð 1¼5ó 1öj1öh'öT'öT2ðh Ð˜]Ð6Ù e¸=ÔI×IÐIàÐÙ Ó"×"Ð"àÐÙ$Ó&×&Ð&àÐÙ Ó"×"Ð"àÐÙÓ!×!Ð!ä$@ÐÜ"'Ó'tÐ;TÔ'tÓ"tÐÜ#(Ó(uÐ<UÔ(uÓ#uÐáÜ×ÑÜ×7Ñ7ÜÐ 4Ó5Ü-Ô.@ÓAØ)9Øð	 8ó ô	
ñ Ü×ÑÜ×7Ñ7ÜÐ 5Ó6Ü-Ô.@ÓAØ)9ð 8ó õ	
ð ð7 	Jøð 	#øð 	'øð 	#øð 	"ús[   ‰A EÁ	E	Á
EÁEÁEÁ+EÁ,EÁ<EÁ=EÂEÂB<EÅEÅEÅEÅE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|«       Y d }~y d }~ww xY w)NÚollamaÚserverÜ  )ÚstdoutÚstderrz�
            LiteLLM Warning: proxy started with `ollama` model
`ollama serve` failed with Exception%s. 
Ensure you run `ollama serve`
        )Úopenrn  ÚdevnullÚ
subprocessÚPopenrÿ  rŸ   r
  )ÚcommandrX  r  s      rˆ   Úrun_ollama_server\  ²  sw   € ð	
Ø" GÐ,ˆä”"—*‘*˜cÓ"ð 	F gÜ×Ñ˜W¨W¸WÕE÷	F÷ 	Fñ 	Fûäò 
Ü×"Ñ"ð bØ÷	
ñ 	
ûð
ús3   ‚A  A¹A ÁAÁA ÁA Á	A7ÁA2Á2A7c                  óÒ   — 	 ddl } | j                  | j                  «      j                  }t        j
                  dk(  rt        |«      dz  S t        |«      dz  S # t        $ r Y yw xY w)zj
    Get process RSS memory in MB.
    On Linux, ru_maxrss is in KB. On macOS, ru_maxrss is in bytes.
    r   NÚdarwini   é   )ÚresourceÚ	getrusageÚRUSAGE_SELFÚ	ru_maxrssÚsysÚplatformr   rÿ  )r`  rc  s     rˆ   Ú_get_process_rss_mbrf  ¿  sd   € ð
Ûà#×-Ñ-¨h×.BÑ.BÓC×MÑMˆ	Ü�<‰<˜8Ò#Ü˜Ó# {Ñ3Ð3Ü�YÓ $Ñ&Ð&øÜò Ùðús   ‚A	A ÁA Á	A&Á%A&c                  ó$   — t        «       } | €y| d›S )NÚunknownú.2f)rf  )Úrss_mbs    rˆ   Ú_rss_mb_for_logrk  Ï  s   € Ü'Ó)€FØ€~ØØ�Sˆ\ÐrŠ   z-unexpected keyword argument '(?P<name>[^']+)'Ú_UNEXPECTED_KWARGÚ
model_listÚdetailsÚmax_concurrencyÚinstrumentation_contextc              ƒ   óÆ  K  — t        t        |dœt        t        «      ¥«      }t	        t        |«      dz   «      D ]  }	 t        d| ||dœ|¤Žƒ d{  –—† c S  t        d«      ‚7 Œ# t        $ ro}t        j                  t        |«      «      }|�|d   |vr‚ t        |j                  «       D ��	ci c]  \  }}	||d   k7  sŒ||	“Œ nc c}	}w c}	}«      }Y d}~Œžd}~ww xY w­w)aH  Call ``perform_health_check``, dropping exactly the optional kwarg each TypeError names.

    A callee that predates an argument rejects it by name, so only that one is dropped. A
    hand-written ladder of combinations would drop working options alongside it, and would
    need a new rung every time an argument is added.
    )rÎ   rp  r8  )rm  rn  ro  NrÄ  z5perform_health_check rejected every optional argumentrè  )r   rU  r%  rW  rL  rÈ  r'  r  rl  Úsearchr‚  râ  ÚAssertionError)
rm  rn  ro  rp  ÚoptionalrÁ  r  ÚrejectedrF  rG  s
             rˆ   Ú-_run_direct_health_check_with_instrumentationrv  Ù  s  è ø€ ô &6ä Ø'>ñ	
ô ?Ô?OÓPð	
ó&€Hô ”3�x“= 1Ñ$Ó%ò fˆð	fÜ-ð Ø%ØØ /ñð ñ	÷ ò ðfô ÐPÓ
QÐQðùô ò 	fÜ(×/Ñ/´°A³Ó7ˆHØÐ 8¨FÑ#3¸8Ñ#CØÜ'¸(¿.¹.Ó:J×(d±$°!°QÈaÐS[Ð\bÑScÓNc¨¨A©Ñ(dùÖ(dÓe�Hûð		füsS   ‚<C!¿A&ÁA$ÁA&ÁC!Á$A&Á&	CÁ/A CÂ/CÃ CÃCÃC!ÃCÃC!Úhealthy_endpointsÚunhealthy_endpointsc           
      ó    — | €yddl }ddlm} |�|j                  nd}|j                  «       }t	        j
                   || |||||¬«      «       y)zKFire-and-forget: persist health check results to DB if prisma is available.Nr   )Ú$_save_background_health_checks_to_dbÚbackground_health_check)Ú
checked_by)ÚtimeÚ0litellm.proxy.health_endpoints._health_endpointsrz  Úpod_idrP  r‡  )	r÷  Úshared_health_managerrm  rw  rx  Útime_modulerz  r|  Ú
start_times	            rˆ   Ú)_schedule_background_health_check_db_saverƒ  ü  sb   € ð ÐØÛõð 9NÐ8YÐ-×4Ò4Ð_x€JØ#×(Ñ(Ó*€JÜ×ÑÙ,ØØØØØØ!ô	
õ	rŠ   ÚendpointÚ
exceptionsc                 ó�   — | j                  d«      }|r|j                  |«      nd}|�t        |dd«      S | j                  dd«      S )a  Return the HTTP status code for an unhealthy endpoint.

    Prefers the live exception object in `exceptions` (direct health check path).
    Falls back to the `exception_status` integer stored on the endpoint dict
    (shared-cache path, where exception objects are not available).
    Úmodel_idNr7  rž  Úexception_status)rp  rw  )r„  r…  r‡  r4  s       rˆ   Ú_get_endpoint_exception_statusr‰    sJ   € ð —l‘l :Ó.€HÙ-5�—‘ Ô)¸4€CØ
€Ü�s˜M¨3Ó/Ð/Ø�<‰<Ð*¨CÓ0Ð0rŠ   Úexceptions_by_model_idc           	      óZ  — ddl m} ddlm} ddlm} |xs i }	 t        €yt        j                  }|st        t        «      sy|}t        j                  r|D �	cg c]  }	t        |	|«      dvsŒ|	‘Œ }}	 || |¬«      }
|
rrt        j                  j                  |
«       t        j                  dt!        d	„ |
j#                  «       D «       «      t!        d
„ |
j#                  «       D «       «      «       |sy|D ]y  }|j%                  d«      }|sŒ|j%                  |«      }|€Œ+t'        |dd«      }t        j                  r|dv rŒM |t        |¬«        |t        |||t        j(                  ¬«       Œ{ yc c}	w # t*        $ r)}t        j,                  dt/        |«      «       Y d}~yd}~ww xY w)a  
    Write deployment health states to the router's health state cache
    for health-check-driven routing. No-op if the feature is disabled.

    `model_list_healthy_only` reads the same cache to hide unhealthy models from
    the listing endpoints, so it also keeps the cache populated. That is a pure
    write: every routing-time reader is itself gated on
    `enable_health_check_routing`, and the cooldown/failure bookkeeping below
    stays behind that flag, so routing is untouched when only the listing filter
    is on.
    r   )Úbuild_deployment_health_states)Ú_set_cooldown_deployments)Ú0increment_deployment_failures_for_current_minuteN)i­  i˜  )rw  rx  z:health_check_routing_state_updated healthy=%d unhealthy=%dc              3   óD   K  — | ]  }|j                  d «      sŒd–— Œ y­w©Ú
is_healthyr8  N©rp  ©r’  Úss     rˆ   r”  z6_write_health_state_to_router_cache.<locals>.<genexpr>W  s   è ø€ ÒF˜!°!·%±%¸Õ2E”AÑFùó   ‚ ™ c              3   óD   K  — | ]  }|j                  d «      rŒd–— Œ y­wr�  r’  r“  s     rˆ   r”  z6_write_health_state_to_router_cache.<locals>.<genexpr>X  s   è ø€ ÒJ˜!°a·e±e¸LÕ6I”AÑJùr•  r‡  r7  rž  )Úlitellm_router_instanceÚdeployment_id)r—  Úoriginal_exceptionrˆ  Ú
deploymentÚtime_to_cooldownz0Failed to write health state to router cache: %s)Úlitellm.proxy.health_checkrŒ  Ú&litellm.router_utils.cooldown_handlersr�  Ú>litellm.router_utils.router_callbacks.track_deployment_metricsrŽ  rU  Úenable_health_check_routingrï   rW  Ú$health_check_ignore_transient_errorsr‰  Úhealth_state_cacheÚset_deployment_health_statesrŸ   r
  Úsumr¢  rp  rw  Úcooldown_timerÿ  r/  r‚  )rw  rx  rŠ  rŒ  r�  rŽ  Ú_exceptionsÚhealth_check_routing_enabledÚ_effective_unhealthyÚepÚstatesr„  r‡  r™  rˆ  r  s                   rˆ   Ú#_write_health_state_to_router_cacherª  (  sº  € õ  JÝPõð  6Ò;¸€Kð=aÜÐØÜ.8×.TÑ.TÐ$Ù+Ô4SÔTdÔ4eØð  3ÐÜ×:Ò:à0ö$ØÔ4RÐSUÐWbÓ4cÐkuÒ4u’ð$Ð ð $ñ 7Ø/Ø 4ô
ˆñ Ü×)Ñ)×FÑFÀvÔNÜ ×&Ñ&ØLÜÑF˜vŸ}™}›ÔFÓFÜÑJ˜vŸ}™}›ÔJÓJôñ ,Øà+ò 	ˆHØ—|‘| JÓ/ˆHÙØà!,§¡°Ó!:ÐØ!Ð)Øä&Ð'9¸=È#ÓNÐä×>Ò>ÐCSð Xñ Dð á<Ü(2Ø&õñ
 &Ü(2Ø#5Ø!1Ø#Ü!+×!9Ñ!9öñ-	ùò'$øôb ò aÜ×$Ñ$Ð%WÔY\Ð]^ÓY_×`Ñ`ûðaúsB   šE8 ¡!E8 ÁE8 ÁE3Á-E3Á1BE8 Ã4A>E8 Å3E8 Å8	F*ÆF%Æ%F*é
   Ú'_ADAPTIVE_ROUTER_FLUSH_INTERVAL_SECONDSc               ƒ   óv  K  — 	 	 t        j                  t        «      ƒ d{  –—†  t        t        dd«      xs i } | rt
        €ŒA| j                  «       D ]•  }|D ]Ž  }|j                  }t        |dd«      s%	 |j                  t
        «      ƒ d{  –—†  d|_	        |j                  j                  t
        «      ƒ d{  –—†  |j                  j                  t
        «      ƒ d{  –—†  Œ� Œ— 	 Œê7 ŒÌ7 Œa# d|_	        w xY w7 ŒA7 Œ# t         j                  $ r ‚ t        $ r t        j                   d«       Y ŒHw xY w­w)zÓ
    Drain every AdaptiveRouter's in-memory state + session aggregators into
    Postgres on a fixed cadence. Hot-path writes go to memory; this loop is
    the only writer to the adaptive router DB tables.
    TNrh  r¥  Fz(adaptive_router flusher iteration failed)rP  rQ  r¬  rw  rU  r÷  r¢  r£  r¤  r¥  r0  Úflush_state_to_dbÚflush_session_to_dbÚCancelledErrorrÿ  rŸ   r   )rh  Útagged_routersÚtaggedÚars       rˆ   r¦  r¦  ƒ  s(  è ø€ ð ð	WÜ—-‘-Ô GÓH×HÐHÜ&¤zÐ3EÀtÓLÒRÐPRÐÙ#¤}Ð'<ØØ"2×"9Ñ"9Ó";ò F�Ø,ò 
F�FØŸ™�Bô # 2 ¸Ô>ð4Ø"$×"7Ñ"7¼Ó"F×FÐFà/3˜BÔ,ØŸ(™(×4Ñ4´]ÓC×CÐCØŸ(™(×6Ñ6´}ÓE×EÑEñ
FñFð àHøð Gùà/3˜BÕ,úØCøØEùÜ×%Ñ%ò 	ØÜò 	WÜ ×*Ñ*Ð+UÖVð	WüsŒ   ‚D9…D ¡C.¢!D ÁD9Á1D Á6C2ÂC0ÂC2Â)D Â<C>Â=&D Ã#D Ã$D Ã,D9Ã.D Ã0C2Ã2	C;Ã;D Ä D Ä1D6Ä3D9Ä5D6Ä6D9c               ƒ   ó  K  — t         �t        t         t        «      r	t         dk  ryt        r$t	        j
                  dt         t        t        «       dat	        j                  dt         t        t        t        t        j                  «       t        «       «       d} t        r8t        �2ddlm}  |t        t         t"        ¬«      } t	        j                  d«       	 t$        d	z  ad
t$        › �}t'        j(                  «       }t+        j,                  t.        «      xs g }t1        |«      }|D �cg c]'  }|j3                  di «      j3                  dd«      rŒ&|‘Œ) }}t4        �t4        j6                  nd}t9        t;        ||«      «      }|�!|st	        j
                  dt=        |«      «       t1        |«      }|}	t        t        t        «      rt        dkD  r|dkD  rt?        |t        «      }	t	        j@                  d|||t         t        |	| dut        j                  «       t        «       «
       dd|dœ}
t        �t        nd}tC        tD        «      }| �-	  | jF                  d||t        t4        dœ|¤Žƒ d{  –—† \  }}}ntO        ||t        |
«      ƒ d{  –—† \  }}}|tP        d<   |tP        d<   t1        |«      tP        d<   t1        |«      tP        d<   t'        j(                  «       |z
  dz  }t	        j@                  d||t1        |«      t1        |«      |t         t        j                  «       t        «       «	       |t         dz  kD  rt	        j
                  d||t         «       tS        tT        | |||«       tW        |||«       tY        jZ                  t         «      ƒ d{  –—†  �ŒÉc c}w 7 �Œ5# tH        $ rI}t	        jJ                  dtM        |«      «       tO        ||t        |
«      ƒ d{  –—†7  \  }}}Y d}~�Œ]d}~ww xY w7 �Œn7 Œf­w)zÓ
    Periodically run health checks in the background on the endpoints.

    Update health_check_results, based on this.
    Uses shared health check state when Redis is available to coordinate across pods.
    Nr   zxbackground_health_check_loop_overlap_detected existing_loop_active=true interval_seconds=%s max_concurrency=%s shared=%sTzzbackground_health_check_loop_started interval_seconds=%s max_concurrency=%s shared=%s details=%s thread_count=%d rss_mb=%s)ÚSharedHealthCheckManager)r  Úhealth_check_ttlÚlock_ttlz'Initialized shared health check managerr8  zbg-Ú
model_infoÚdisable_background_health_checkFzFbackground_health_check_model_groups matched no deployments; groups=%szÁbackground_health_check_cycle_start cycle_id=%s model_count_total=%d model_count_enabled=%d interval_seconds=%s max_concurrency=%s expected_peak_in_flight=%d shared=%s thread_count=%d rss_mb=%sÚproxy_background_loop)Úenabledr
  Úcycle_id)rm  rn  ro  rÎ   zEError in shared health check, falling back to direct health check: %srw  rx  Úhealthy_countÚunhealthy_countiè  z¬background_health_check_cycle_complete cycle_id=%s model_count_enabled=%d healthy_count=%d unhealthy_count=%d duration_ms=%.2f interval_seconds=%s thread_count=%d rss_mb=%szibackground_health_check_cycle_duration_exceeded_interval cycle_id=%s duration_ms=%.2f interval_seconds=%srè  ).rõ  rÓ  r"  Ú#background_health_check_loop_activerŸ   r/  rö  rô  r  Úhealth_check_detailsÚ	threadingÚactive_countrk  rX  Ú<litellm.proxy.health_check_utils.shared_health_check_managerrµ  r.   r-   Ú!background_health_check_cycle_seqr}  Ú	monotonicÚcopyÚdeepcopyr�  rÈ  rp  rU  Ú$background_health_check_model_groupsr•  r$  rÆ  Úminr
  r%  rW  Úperform_shared_health_checkrÿ  rz  r‚  rv  r/  rƒ  r÷  rª  rP  rQ  )r€  rµ  r¼  Úcycle_start_timeÚ_llm_model_listÚmodel_count_totalÚmÚscoped_model_groupsÚmodel_count_enabledÚexpected_peak_in_flightrp  Údetails_boolÚ
_hc_filterrw  rx  Ú_exceptions_by_model_idr  Úcycle_duration_mss                     rˆ   r¡  r¡  ¢  s%  è ø€ ô Ð$¬JÔ7LÌcÔ,RÔVkÐopÒVpØå*Ü×$Ñ$ð GÜ!Ü$Ü#ô		
ð +/Ð'Ü×Ñð 	EÜÜ ÜÜÜ×ÑÓ ÜÓôð !ÐÝÔ#4Ð#@õ	
ñ !9Ü)Ü<Ü9ô!
Ðô
 	×!Ñ!Ð"KÔLà
Ü)¨QÑ.Ð)ØÔ:Ð;Ð<ˆÜŸ>™>Ó+Ðô Ÿ-™-¬Ó7Ò=¸2ˆÜ Ó0Ðð 'ö
Ø¨a¯e©e°LÀ"Ó.E×.IÑ.IÐJkÐmrÕ.sŠAð
ˆð 
ô R\ÐQgœj×MÒMÐmqÐÜÔAÀ/ÐSfÓgÓhˆØÐ*±?Ü ×(Ñ(ØXÜÐ*Ó+ôô " /Ó2ÐØ"5ÐÜÔ.´Ô4Ô9QÐTUÒ9UÐZmÐpqÒZqÜ&)Ð*=Ô?WÓ&XÐ#ä×"Ñ"ð PØØØÜ!Ü$Ø#Ø!¨Ð-Ü×"Ñ"Ó$ÜÓô	
ð Ø-Ø ñ#
Ðô 0DÐ/OÕ+ÐUYˆÜEÔFVÓWˆ
à Ð,ðð
 LÐ/×KÑKð Ø.Ø(Ü$<Ü%ñ	ð
 !ñ÷ ñ	Ø%Ø'Ù+ô8 DØØÜ(Ø'ó	÷ ñ	Ø!Ø#Ø'ð 5FÔÐ0Ñ1Ø6IÔÐ2Ñ3Ü03Ð4EÓ0FÔ˜_Ñ-Ü25Ð6IÓ2JÔÐ.Ñ/Ü!Ÿ^™^Ó-Ð0@Ñ@ÀDÑHÐÜ×"Ñ"ð {ØØÜÐ!Ó"ÜÐ#Ó$ØÜ!Ü×"Ñ"Ó$ÜÓô
	
ð Ô 5¸Ñ <Ò=Ü ×(Ñ(Ø{ØØ!Ü%ô	ô 	2ÜØ!ØØØô	
ô 	,Ð,=Ð?RÐTkÔlä�m‰mÔ1Ó2×2Ð2ñ} ùò
ðZúô ò Ü$×*Ñ*Ø[Ü˜“Fôô HØ#Ø Ü,Ø+ó	÷ ð ñ	Ø%Ø'Þ+ûðúð(ùðX 	3ús€   ‚D)PÄ+'N"ÅN"ÅC8PÉ"N* É2N'É3N* É;PÊO?ÊD	PÎPÎPÎ'N* Î*	O<Î34O7Ï'O*Ï(	O7Ï1PÏ7O<Ï<PÐPc                   ó   — e Zd Zy)ÚStreamingCallbackErrorN)r   r  r  rè  rŠ   rˆ   r×  r×  R  s   „ ØrŠ   r×  )Úpost_call_rules)Úcustom_authÚcustom_key_generateÚcustom_key_updateÚcustom_team_metadata_validateÚ
custom_ssoÚcustom_ui_sso_sign_in_handler)rT  rW  Ú$_DB_OVERLAY_REMOTE_MODULE_STR_FIELDSrT  )Ú	callbacksr  Úfailure_callbackÚaudit_log_callbacksÚ%_DB_OVERLAY_REMOTE_MODULE_LIST_FIELDSr*  c                 ón   — t        | t        «      xr$ | j                  d«      xs | j                  d«      S )Nzs3://zgcs://)rÓ  r‚  r™  ©r*  s    rˆ   Ú_is_remote_module_urlræ  s  s0   € Ü�eœSÓ!Ò_ u×'7Ñ'7¸Ó'@Ò'^ÀE×DTÑDTÐU]ÓD^Ð_rŠ   Úinnerc                 óž  — | j                  d«      }t        |t        «      rb|D �cg c]  }t        |«      rŒ|‘Œ }}t	        |«      t	        |«      k7  r0t        j                  dt	        |«      t	        |«      z
  «       || d<   t        | j                  d«      «      r+t        j                  d| j                  d«      «       d| d<   yyc c}w )z~Strip remote-URL entries from a guardrail's ``callbacks`` list
    and ``guardrail`` (v2 module-path) field. Mutates in place.rà  zXRefused %d remote-URL entries from DB-overlay litellm_settings.guardrails[...].callbacksÚ	guardrailzbRefused remote-URL guardrail module from DB-overlay litellm_settings.guardrails[...].guardrail: %rN)rp  rÓ  r•  ræ  rÈ  rŸ   r/  )rç  ÚcbsÚcÚcleaneds       rˆ   Ú_scrub_guardrail_innerrí  w  s¹   € ð —‘˜;Ó'€CÜ�#”tÔØ%(ÖI Ô0EÀaÕ0Hš!ÐIˆÐIÜˆw‹<œ3˜s›8Ò#Ü ×(Ñ(ØjÜ�C“œ3˜w›<Ñ'ôð ")ˆE�+ÑÜ˜UŸY™Y {Ó3Ô4Ü×$Ñ$ØpØ�I‰I�kÓ"ô	
ð "ˆˆkÒð 5ùò Js
   ¦C
·C
ÚsectionÚdb_valuec                 ó˜  — t        |t        «      s|S t        j                  | d«      }t        j                  | d«      }|s	|s| dk7  r|S t        j                  |«      }|D ]<  }|j                  |«      }t        |«      sŒ t        j                  d| ||«       d||<   Œ> |D ]‰  }|j                  |«      }t        |t        «      sŒ%|D �cg c]  }t        |«      rŒ|‘Œ }}t        |«      t        |«      k7  sŒXt        j                  dt        |«      t        |«      z
  | |«       |||<   Œ‹ | dk(  r~|j                  d«      }	t        |	t        «      r]|	D ]X  }t        |t        «      sŒt        |j                  d«      «      sŒ/t        j                  d	|j                  d«      «       d|d<   ŒZ | dk(  r—|j                  d
«      }
t        |
t        «      rv|
D ]q  }t        |t        «      sŒ|j                  «       D ]  }t        |t        «      sŒt        |«       Œ  |j                  d«      }t        |t        «      sŒgt        |«       Œs | dk(  ró|j                  d«      }t        |t        «      rDt        |j                  d«      «      r*t        j                  d|j                  d«      «       d|d<   |j                  d«      }t        |t        «      rm|D ]h  }t        |t        «      sŒt        |j                  d«      «      sŒ/t        j                  d|j                  d«      |j                  d«      «       d|d<   Œj |S c c}w )a^  Strip ``s3://`` / ``gcs://`` entries from the DB-overlay value for
    fields whose contents reach ``get_instance_fn``. The same scheme is
    allowed from a YAML config (the documented operator flow) but a
    DB-overlay write would otherwise smuggle the same payload through
    the YAML-load chain and reach ``_load_instance_from_remote_storage``.rè  rW  zpRefused remote-URL value for DB-overlay %s.%s=%r; only config.yaml entries may reference s3:// / gcs:// modules.NzsRefused %d remote-URL entries from DB-overlay %s.%s; only config.yaml entries may reference s3:// / gcs:// modules.rT  Úcustom_provider_mapÚcustom_handlerzZRefused remote-URL custom_handler from DB-overlay litellm_settings.custom_provider_map: %rÚ
guardrailsÚlitellm_paramsÚlitellm_jwtauthÚcustom_validatezWRefused remote-URL custom_validate from DB-overlay general_settings.litellm_jwtauth: %rrÌ  Útargetz_Refused remote-URL target from DB-overlay general_settings.pass_through_endpoints (path=%r): %rry   )rÓ  rÔ  rß  rp  rã  rÆ  rÇ  ræ  rŸ   r/  r•  rÈ  r¢  rí  )rî  rï  Ú
str_fieldsÚlist_fieldsÚ	sanitizedÚfieldrG  Úitemrì  Úcpmró  rÆ  rç  ÚlpÚjwtÚptes                   rˆ   Ú%_scrub_db_overlay_remote_module_loadsr  ‹  s#  € ô �h¤Ô%ØˆÜ<×@Ñ@ÀÈ"ÓM€JÜ>×BÑBÀ7ÈBÓO€KÙ™k¨gÐ9KÒ.KØˆÜ—}‘} XÓ.€IØò 
$ˆØ�M‰M˜%Ó ˆÜ  Õ#Ü ×(Ñ(ðLàØØôð  $ˆI�eÒð
$ð ò +ˆØ�M‰M˜%Ó ˆÜ�aœÕØ()ÖM Ô1FÀtÕ1L’tÐMˆGÐMÜ�7‹|œs 1›vÓ%Ü$×,Ñ,ðô ˜“FœS ›\Ñ)ØØôð $+�	˜%Ò ð+ð  Ð$Ò$Ø—]‘]Ð#8Ó9ˆÜ�cœ4Ô Øò 2�Ü˜d¤DÕ)Ô.CÀDÇHÁHÐM]ÓD^Õ._Ü(×0Ñ0ØtØŸ™Ð!1Ó2ôð .2�DÐ)Ò*ð2ð Ð$Ò$Ø%ŸM™M¨,Ó7ˆ
Ü�j¤$Ô'Ø#ò 	/�Ü! %¬Ô.ØØ"Ÿ\™\›^ò 2�EÜ% e¬TÔ2Ø Ü*¨5Õ1ð2ð —Y‘YÐ/Ó0�Ü˜b¤$Õ'Ü*¨2Õ.ð	/ð Ð$Ò$Ø—]‘]Ð#4Ó5ˆÜ�cœ4Ô Ô%:¸3¿7¹7ÐCTÓ;UÔ%VÜ ×(Ñ(ØiØ—‘Ð)Ó*ôð &*ˆCÐ!Ñ"ð —]‘]Ð#;Ó<ˆÜ�cœ4Ô Øò 	+�Ü˜e¤TÕ*Ô/DÀUÇYÁYÈxÓEXÕ/YÜ(×0Ñ0ð(ð Ÿ	™	 &Ó)ØŸ	™	 (Ó+ôð '+�E˜(’Oð	+ð ÐùòM Ns   ÃMÃMc                 óT   — | €y t        | t        «      rt        | «      S t        | «      S rn  )rÓ  r‚  r�  r#  rå  s    rˆ   Ú_normalize_user_url_validationr  ï  s)   € Ø€}ØÜ�%œÔÜ˜5Ó!Ð!Ü�‹;ÐrŠ   Úsettingsc                 óð   — d| v r#t        t        t           | d   «      t        _        t        | j                  d«      «      }|�|t        _        d| v r$t        t        t           | d   «      t        _        y y )NÚuser_url_allowed_hostsÚuser_url_validationÚ&provider_url_destination_allowed_hosts)	r   r•  r‚  r  r  r  rp  r  r  )r  r  s     rˆ   Ú_apply_ssrf_general_settingsr	  ÷  so   € Ø 8Ñ+Ü)-¬d´3©i¸ÐBZÑ9[Ó)\ŒÔ&ä!?ÀÇÁÐMbÓ@cÓ!dÐØÐ&Ø&9ŒÔ#à/°8Ñ;Ü9=Ü”‰I�xÐ HÑIó:
ŒÕ6ð <rŠ   Úcoordination_redis_cachec                 ó   — | a y)zOPublish the resolved coordination Redis to the consumers that read it directly.N)rX  )r
  s    rˆ   rŠ  rŠ    s
   € ð 1ÑrŠ   Ú
raw_paramsc           	      ó®   — | j                  «       D ��ci c]4  \  }}|t        |t        «      r|j                  d«      rt	        |«      n|“Œ6 c}}S c c}}w )zBResolve `os.environ/VAR` references in a coordination_redis block.úos.environ/)râ  rÓ  r‚  r™  r|  )r  rz  r*  s      rˆ   Ú$_resolve_coordination_redis_env_refsr    sT   € ð %×*Ñ*Ó,÷áˆC�ð 	¤:¨e´SÔ#9¸e×>NÑ>NÈ}Ô>]Œj˜ÔÐchÑhóð ùó s   ”9AÚredis_paramsc                 óþ   — | j                  d«      }|€"t        d«      }|�t        j                  |«      }| j	                  «       D ��ci c]  \  }}|dk7  sŒ||“Œ }}}|rt        dd|i|¤ŽS t        di |¤ŽS c c}}w )ao  
    Builds the proxy's coordination Redis client from resolved connection
    params. Cluster-mode targets (explicit `startup_nodes` or the
    REDIS_CLUSTER_NODES env var) get a `RedisClusterCache`, so consumers that
    branch on cluster mode (e.g. the v3 rate limiter) take the cluster path;
    everything else (host/url/sentinel) gets a plain `RedisCache`.
    Ústartup_nodesÚREDIS_CLUSTER_NODESrè  )rp  r~  rm  r„  râ  r£   r¢   )r  r  Úenv_cluster_nodesrz  r*  Únon_node_paramss         rˆ   Ú_build_redis_usage_cacher    s’   € ð !×$Ñ$ _Ó5€MØÐÜ#1Ð2GÓ#HÐØÐ(Ü ŸJ™JÐ'8Ó9ˆMØ;G×;MÑ;MÓ;O×j©Z¨S°%ÐSVÐZiÓSi˜c 5™jÐj€OÑjÙÜ ÑP¨}ÐPÀÑPÐPÜÑ(˜Ñ(Ð(ùó ks   Á	A9ÁA9c                  óŽ   — t         j                  j                  «       } d| v xs" d| v xs t        d«      duxs t        d«      duS )zÿ
    Whether the REDIS_* environment variables name a Redis to connect to (host,
    url, cluster nodes, or sentinel nodes). Read-only: callers that only need to
    know whether the env fallback would apply use this instead of building a
    client.
    Úhostr   r  NÚREDIS_SENTINEL_NODES)r  Ú_redisÚ_redis_kwargs_from_environmentr~  )Úredis_env_kwargss    rˆ   Ú(_environment_has_redis_connection_targetr  &  s[   € ô &Ÿn™n×KÑKÓMÐàÐ"Ð"ò 	>ØÐ$Ð$ò	>äÐ/Ó0¸Ð<ò	>ô Ð0Ó1¸Ð=ð	rŠ   c                  óf   — t        «       syt        t        j                  j	                  «       «      S )a¦  
    Builds a standalone coordination Redis from REDIS_* environment variables.

    Lets the proxy's coordination Redis (cross-pod tpm/rpm rate limits, spend
    tracking, pod lock manager) run when the response-cache backend is not a
    plain Redis KV cache (e.g. a semantic cache, disk, or s3).

    Returns None when the environment carries no connection target (host, url,
    cluster nodes, or sentinel nodes).
    N)r  r  r  r  r  rè  rŠ   rˆ   Ú)_build_redis_usage_cache_from_environmentr  6  s%   € ô 4Ô5ØÜ#¤G§N¡N×$QÑ$QÓ$SÓTÐTrŠ   r  Úenable_redis_auth_cachec                 óX  — t         j                  | t        j                  ¬«       t        j                  | t
        ¬«       |du rFt        j                  | t        j                  ¬«       t        j                  d«       | t        _
        yt        j                  d«       | t        _
        y)aä  
    Wires an established coordination Redis into the proxy-level caches that
    consume it directly: the spend counter cache, the CLI SSO login-session
    cache, the cluster-wide config cache, and (only when opted in) the
    virtual-key auth cache.

    The CLI SSO login-session cache is always backed by Redis when available so
    that the browser SSO flow behind `lite login` survives landing on different
    workers; it must not be gated behind enable_redis_auth_cache.
    )Údefault_redis_ttlTuƒ   enable_redis_auth_cache=True: attached Redis to user_api_key_cache â€” virtual-key lookups are now shared across all proxy workers.zÉenable_redis_auth_cache is not set: user_api_key_cache remains in-memory only (per-worker). Set litellm_settings.enable_redis_auth_cache: true to share the auth cache across workers and reduce DB load.N)r$  Úattach_redis_cacher  r"  r%  r©   rA  rŸ   r  rl  r  )r  r   s     rˆ   Ú_attach_redis_usage_cacher$  F  s¨   € ô ×*Ñ*ØÜ!×3Ñ3ð +ô ô ×,Ñ,ØÜ5ð -ô ð  $Ñ&Ü×-Ñ-ØÜ%×7Ñ7ð 	.ô 	
ô 	×!Ñ!ð/ô	
ð (3ÔÕ$ô 	×!Ñ!ð@ô	
ð (3ÔÕ$rŠ   Úplugin_pathsr=  Úsource_labelc           	      ó  — | D �cg c]!  }t        |t        «      rt        ||¬«      n|‘Œ# }}t        | |«      D ]I  \  }}t        |t        «      r!t        j                  t        |dd«      «      rŒ7t        |› d|›d|›d�«      ‚ |S c c}w )aÝ  
    Resolves a list of routing-plugin entries to live `RoutingPlugin` instances.
    Each string entry is resolved through `get_instance_fn` (the same dotted-path
    convention `litellm_settings.callbacks` uses, which resolves both local module
    files next to the config and modules installed as Python packages); non-string
    entries are assumed to already be instances and passed through. Raises at
    config-load time if any entry resolves to something that doesn't implement
    `RoutingPlugin`, rather than deferring to a confusing `AttributeError` on the
    first request that reaches the plugin pipeline. `source_label` names the config
    key being resolved so the error points the operator at the right place.
    ©r*  r=  ÚrunNú entry ú resolved to z�, which does not implement the RoutingPlugin interface (an async `run(context)` method). Fix the referenced module before starting the proxy.)	rÓ  r‚  rX  Úzipr–  rx  ry  rw  rs  )r%  r=  r&  Úplugin_pathÚresolved_pluginsÚresolved_plugins         rˆ   Úresolve_routing_pluginsr0  m  s½   € ð( (ö	ð ô �k¤3Ô'ô 	˜kÐ<LÕMàñ	ðÐð ô ),¨LÐ:JÓ(Kò Ñ$ˆ�_ô
 ˜/¬=Ô9Ä×A\ÑA\Ü�O U¨DÓ1õB
ô Ø�. ¨ °mÀOÐCVð W?ð ?óð ðð Ðùò's   …&BÚ
model_nameÚcomplexity_router_configc                 óÞ   — |j                  d«      }t        |t        «      rt        ||d| ›�¬«      |d<   |j                  d«      }t        |t        «      rt        ||d| ›�¬«      }||d<   yy)zä
    Resolves `complexity_router_config["plugins"]` dotted-path strings to live
    instances in place, via `resolve_routing_plugins`, and
    `complexity_router_config["classifier_plugin"]` via `resolve_classifier_plugin`.
    Úpluginsz*complexity_router_config.plugins on model ©r%  r=  r&  Úclassifier_pluginz4complexity_router_config.classifier_plugin on model )r-  r=  r&  N)rp  rÓ  r•  r0  r‚  Úresolve_classifier_plugin)r1  r2  r=  r%  Úclassifier_plugin_pathÚresolved_classifiers         rˆ   Ú!resolve_complexity_router_pluginsr:  “  s�   € ð 3×6Ñ6°yÓA€LÜ�,¤Ô%Ü.EØ%Ø-ØEÀjÀ^ÐTô/
Ð  Ñ+ð %=×$@Ñ$@ÐATÓ$UÐÜÐ(¬#Ô.Ü%>Ø.Ø-ØOÐPZÈ~Ð^ô&
Ðð
 9LÐ Ð!4Ò5ð /rŠ   r{  c                 óœ   — | j                  d«      }t        |t        «      syd|vry| j                  dd«      }t        |d   d|›�¬«       y)aÑ  
    Reject a per-deployment `max_agentic_loops` the agentic loop cannot honor.

    Checked here rather than on `LiteLLM_Params` because the proxy builds its
    router with `ignore_invalid_deployments=True`, so a validator down there
    turns a bad value into a silently missing model instead of a refusal to
    start. Left unchecked entirely, a `0` used to read as the default ceiling
    of 3 and a non-integer failed every request to that model instead.
    rô  NÚmax_agentic_loopsr1  r6  z*litellm_params.max_agentic_loops on model )rû  )rp  rÓ  r   r¾   )r{  rô  r1  s      rˆ   Ú%validate_deployment_max_agentic_loopsr=  ¯  sV   € ð "ŸI™IÐ&6Ó7€NÜ�n¤gÔ.ØØ .Ñ0ØàŸ	™	 ,°Ó3€JÜØÐ*Ñ+Ø:¸:¸.ÐIörŠ   c                 ó(  ‡— | j                  d«      Št        ‰t        «      syt        ˆfd„t        D «       «      }t        t        ‰j                  d«      xs d«      |«      syt        ‰«      }|�!t        d| j                  dd«      ›d|› �«      ‚y)	a~  
    Reject a complexity-router setting written one level above `complexity_router_config`.

    Checked here rather than on `LiteLLM_Params` for the same reason as
    `max_agentic_loops`: the proxy builds its router with
    `ignore_invalid_deployments=True`, so a rejection further down turns a bad
    deployment into a silently missing model instead of a refusal to start.
    rô  Nc              3   óF   •K  — | ]  }‰j                  |«      €Œ|–— Œ y ­wrn  r’  )r’  rû  rô  s     €rˆ   r”  zBvalidate_deployment_complexity_router_placement.<locals>.<genexpr>Ò  s&   øè ø€ ò &Ø¸>×;MÑ;MÈeÓ;TÑ;`Œñ&ùs   ƒ!š!r{  r6  zmodel r1  r}   )	rp  rÓ  r   Ú	frozensetrd   re   r‚  rf   rs  )r{  Úpresent_fieldsÚ	violationrô  s      @rˆ   Ú/validate_deployment_complexity_router_placementrC  Æ  s—   ø€ ð "ŸI™IÐ&6Ó7€NÜ�n¤gÔ.ØÜ%ó &Ü7ô&ó €Nô .¬c°.×2DÑ2DÀWÓ2MÒ2SÐQSÓ.TÐVdÔeØÜBÀ>ÓR€IØÐÜ˜6 %§)¡)¨L¸"Ó"=Ð!@ÀÀ9À+ÐNÓOÐOð rŠ   c                 ób  — | j                  d«      }t        |t        «      rt        |j                  d«      t        «      sy| j                  d«      }t        |t        «      si }|| d<   |j                  d«      €5t        j                  j                  | j                  dd«      |¬«      |d<   yy)	a¬  
    Stamps `model_info.id` from the raw litellm_params before plugin resolution swaps
    dotted-path strings for live instances. `_delete_deployment` re-reads the raw config
    and re-hashes these params to decide which ids the config wants served; an id the
    Router derived from the resolved params would never match that hash, so the reconcile
    would evict every plugin-bearing deployment one sync after startup.
    rô  r2  Nr¸  r.  r1  r6  ©Úmodel_grouprô  )rp  rÓ  rÔ  r  r�   Úgenerate_model_id)r{  rô  r¸  s      rˆ   Úpin_complexity_router_model_idrH  Ü  s    € ð "ŸI™IÐ&6Ó7€NÜ�n¤dÔ+´:¸n×>PÑ>PÐQkÓ>lÔnrÔ3sØØ—‘˜<Ó(€JÜ�j¤$Ô'Øˆ
Ø(ˆˆlÑØ‡~�~�dÓÐ#Ü"Ÿ>™>×;Ñ;ØŸ	™	 ,°Ó3Ø)ð <ó 
ˆ
�4Òð $rŠ   r-  c                 ó¨   — t        | |¬«      }t        |t        «      r t        j                  t        |dd«      «      st        |› d| ›d|›d�«      ‚|S )an  
    Resolves a classifier-plugin dotted path to a live `ClassifierPlugin` instance, with the
    same load-time interface check `resolve_routing_plugins` applies to routing plugins: a
    sync `def classify` passes the runtime_checkable isinstance and would only fail on the
    first classified request, so reject it here where the error names the config key.
    r(  ÚclassifyNr*  r+  z•, which does not implement the ClassifierPlugin interface (an async `classify(context)` method). Fix the referenced module before starting the proxy.)rX  rÓ  r“  rx  ry  rw  rs  )r-  r=  r&  Úresolveds       rˆ   r7  r7  ò  sg   € ô &¨KÐJZÔ[€HÜ�hÔ 0Ô1¼×9TÑ9TÜ�˜* dÓ+ô:ô Øˆn˜G K ?°-À¸|ð L?ð ?ó
ð 	
ð
 €OrŠ   Únew_model_cost_mapc                 óŽ   — | t         _        t        «        t        j                  | ¬«       | rt	        | «      nd}t        «        |S )zZAdopt a freshly fetched cost map into this process's litellm state, return the model count)Úmodel_cost_mapr   )r  Ú
model_costrl   Úadd_known_modelsrÈ  rn   )rL  Úfetched_model_counts     rˆ   Ú_swap_in_model_cost_maprR  	  sC   € à+„GÔä(Ô*ô ×ÑÐ,>Õ?ñ =O¤Ð%7Ô!8ÐTUÐô -Ô.ØÐrŠ   Úobject_typec                 óÔ   ‡— t         j                  dd«      }|€yt        |t        «      s t	        j
                  dt        |«      «       yt        | «      Št        ˆfd„|D «       «      S )a,  
    Check if an object type should be loaded from the database based on general_settings.supported_db_objects.

    Args:
        object_type: Type of object to check (e.g., SupportedDBObjectType.MODELS, "models", etc.)

    Returns:
        True if the object should be loaded, False otherwise
    Úsupported_db_objectsNTz@supported_db_objects is not a list, got %s. Loading all objects.c              3   ó:   •K  — | ]  }t        |«      ‰k(  –— Œ y ­wrn  r‘  )r’  ÚobjÚobject_type_strs     €rˆ   r”  z(should_load_db_object.<locals>.<genexpr>0  s   øè ø€ ÒK¨sŒs�3‹x˜?Õ*ÑKùs   ƒ)	rW  rp  rÓ  r•  rŸ   r/  rw   r‚  rµ  )rS  rU  rX  s     @rˆ   Úshould_load_db_objectrY    sh   ø€ ô #3×"6Ñ"6Ð7MÈtÓ"TÐàÐ#ØäÐ*¬DÔ1Ü×$Ñ$ØNÔPTÐUiÓPjô	
ð ä  Ó-€OÜÓKÐ6JÔKÓKÐKrŠ   c            
       óx  — e Zd ZU dZd‹d„Zdedefd„Zdedefd„Z	dŒdedz  defd	„Z
d
ededefd„Zd�dedefd„Zdeeedz  f   ddfd„Zdefd
edededefd„Zd
eeef   dedz  ddfd„Zdedee   defd„Zdefd„Zd
ededz  fd„Z	 d�dedededz  fd„Zd„ ZdŒdedz  defd „Zd
efd!„Zd"„ Zd
edee   fd#„Zd
edee    dz  fd$„Z!h d%£Z"e#e   e$d&<   d
efd'„Z%d
ede&ed(f   fd)„Z'd*e(jR                  dz  defd+„Z*dŒd
ededz  fd,„Z+d
edz  d-e,d.   d/e,d0   fd1„Z-d2efd3„Z.	 dŒd4edz  dedz  fd5„Z/d�de0fd6„Z1d7ede2e   dz  fd8„Z3d9ed:edefd;„Z4d7edefd<„Z5d=edefd>„Z6d=e7dz  d?e8de2e   dz  fd@„Z9dAedBee:dC      dDeddfdE„Z;dFeddfdG„Z<dŒdHedIedz  defdJ„Z=	 d�dHedKedefdL„Z>dMedefdN„Z?dŒdHedIedz  defdO„Z@eAd:ededz  fdP„«       ZB	 dŒdQe,dR   d-eCdz  d?e,dS   dedz  fdT„ZDdFed/e)dz  d-eCdz  ddfdU„ZEdFed2ed?e8ddfdV„ZFdW„ ZGdXe7dz  fdY„ZHdZed[e:d\   d]eIdefd^„ZJd-eCd
ed_edz  fd`„ZKdaeeLz  defdb„ZMd-eCdeNeO   dz  fdc„ZPd-eCd?e8deQfdd„ZRd-eCd?e8deQfde„ZSd-eCd?e8dfedz  ddfdg„ZTd‹dh„ZUdfedz  dieVddfdj„ZWd‹dk„ZXd-eCfdl„ZYd-eCddfdm„ZZd-eCfdn„Z[d-eCfdo„Z\d-eCfdp„Z]d-eCddfdq„Z^d-eCfdr„Z_d-eCfds„Z`d-eCfdt„Zadu„ Zbd-eCfdv„Zcd-eCfdw„Zdd-eCfdx„Zed-eCfdy„Zfd-eCfdz„Zgd-eCfd{„Zhd|„ Zid‹d}„Zjd‹d~„Zkd-eCfd„Zld-eCfd€„Zmd‹d�„ZneAd‚ee    dƒeeeeIf      deeeeIf      fd„„«       Zod…„ Zpd†eeqz  defd‡„Zrdˆee   fd‰„Zsd-eCfdŠ„Zty)ŽÚProxyConfigz}
    Abstraction class on top of config loading/updating logic. Gives us one place to control all config updating logic.
    rÐ  Nc                 óê   — i | _         d | _        d | _        d | _        d | _        g | _        d | _        d | _        ddlm	}  |«       xs
 t        «       | _        d| _        t        «       | _        i | _        y )Nr   )Úget_model_cost_map_loaded_at)ÚconfigÚ_last_semantic_filter_configÚ_last_hashicorp_vault_configÚ_last_cyberark_configÚ_cyberark_boot_envÚworker_registryÚconfig_sync_subscriberÚ"auth_cache_invalidation_subscriberÚ-litellm.litellm_core_utils.get_model_cost_mapr]  r  Úmodel_cost_map_loaded_atÚmodel_cost_map_applied_revisionrð  Ú_yaml_general_settings_keysÚ_yaml_spend_log_cleanup_bounds)rp  r]  s     rˆ   Ú__init__zProxyConfig.__init__8  s{   € Ø&(ˆŒØFJˆÔ)ØFJˆÔ)Ø?CˆÔ"Ø@DˆÔØ:<ˆÔØCGˆÔ#ØZ^ˆÔ/õ	
ñ 3OÓ2PÒ2]ÔT[ÓT]ˆÔ%ð 56ˆÔ,ô 69³UˆÔ(ØACˆÕ+rŠ   r=  c                 óÖ   — t         j                  j                  |«      syt         j                  j                  |«      \  }}|j	                  «       dk(  xs |j	                  «       dk(  S )NFz.yamlz.yml)rn  ry   r}  rê  rÉ  )rp  r=  rÁ  Úfile_extensions       rˆ   r  zProxyConfig.is_yamlP  sW   € Ü�w‰w�~‰~Ð.Ô/ØäŸG™G×,Ñ,Ð-=Ó>Ñˆˆ>Ø×#Ñ#Ó%¨Ñ0ÒT°N×4HÑ4HÓ4JÈfÑ4TÐTrŠ   rï  c                 ó¾   — 	 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|› �«      ‚d}~ww xY w)z,
        Load and parse a YAML file
        rÙ  NzError loading yaml file r}   )rW  ÚyamlÚ	safe_loadrÿ  )rp  rï  r…   r  s       rˆ   Ú_load_yaml_filezProxyConfig._load_yaml_fileW  sd   € ð	IÜ�i Ó%ð 2¨Ü—~‘~ dÓ+Ò1¨r÷2÷ 2ò 2ûäò 	IÜÐ6°y°kÀÀAÀ3ÐGÓHÐHûð	Iú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: )rm  rW  Úrouter_settingsrT  zConfig cannot be None or Empty.r6  )r^  Úbase_dir)rê  rn  ry   r½  rW  ro  rp  rÿ  Ú_process_includesÚdirnameÚabspath)rp  r=  rï  Úconfig_filer^  s        rˆ   Ú_get_config_from_filez!ProxyConfig._get_config_from_filea  së   è ø€ ð ,ÒDÔ/Dˆ	ØÐ'Ø$4Ð!ô �7‰7�>‰>˜Y˜KÔ)Ü˜˜ cÓ*ð 5¨kÜŸ™¨Ó4�÷5ð 5àÐ"ÜÐ5°i°[ÐAÓBÐBð !Ø$&Ø#%Ø$&ñ	ˆFð ˆ>ÜÐ=Ó>Ð>à×'Ñ'¨vÄÇÁÇÁÔPR×PWÑPW×P_ÑP_Ð`iÒ`oÐmoÓPpÓ@qÐ'Órˆð ˆ÷%5ð 5üs   ‚<C ¾CÁB C ÃCÃC r^  rt  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: )rÓ  r•  rs  rn  ry   r–  r½  r·  rq  râ  Úextend)rp  r^  rt  Úinclude_filerï  Úincluded_configrz  r*  s           rˆ   ru  zProxyConfig._process_includes…  sß   € ð ˜FÑ"ØˆMä˜& Ñ+¬TÔ2ÜÐEÓFÐFð # 9Ñ-ò 	(ˆLÜŸ™Ÿ™ X¨|Ó<ˆIÜ—7‘7—>‘> )Ô,Ü'Ð*CÀIÀ;Ð(OÓPÐPà"×2Ñ2°9Ó=ˆOà-×3Ñ3Ó5ò (‘
��UÜ˜e¤TÔ*¨s°f©}Ø˜3‘K×&Ñ& uÕ-à"'�F˜3’Kñ	(ð	(ð �9ÐØˆrŠ   Ú
new_configÚinclude_env_varsc              ƒ   óÄ  K  — 	 t         �•t        j                  dd«      du st        rw|j	                  «       }|s|j                  dd «       d|v r|d   r| j                  |d   ¬«      |d<   |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)Nr4  FTÚenvironment_variables©r‚  rm  r^  )ÚdataÚ
table_namerÜ  )Údefault_flow_style)r÷  rW  rp  r4  rÆ  ÚpopÚ_encrypt_env_variables_for_dbÚinsert_datarW  rê  ro  Údump)rp  r  r€  Úconfig_to_saverx  s        rˆ   Úsave_configzProxyConfig.save_config¬  sù   è ø€ ð	ô
 Ð$Ü× Ñ Ð!4°eÓ<ÀÑDÕHYð
 %/§O¡OÓ$5ˆNñ $Ø×"Ñ"Ð#:¸DÔAð '¨.Ñ8¸^ÐLcÒ=dØ:>×:\Ñ:\Ø*8Ð9PÑ*Qð ;]ó ;�Ð6Ñ7ð ×Ñ˜|¨TÔ2Ü×+Ñ+°ÈHÐ+ÓU×UÑUô Ô.Ð/°#Ó6ð M¸+Ü—	‘	˜* kÀeÕL÷Mð Mð	 Vø÷Mð Müs*   ‚BC ÂCÂC Â0CÃ	
C ÃCÃC Úupdatesc              ƒ   ó  K  — t         �t        j                  dd«      du st        syt	        t         «      j                  ddi¬«      ƒ d{  –—† }|�!|j                  �t        |j                  «      ni }|j                  «       D ��ci c]  \  }}|€Œ	||“Œ }}}|r| j                  |¬«      ni }|j                  «       D ��ch c]
  \  }}|�Œ	|’Œ }}}i |j                  «       D ��ci c]  \  }}||vsŒ||“Œ c}}¥|¥}	t        j                  |	«      }
t        t         «      j                  j                  ddid|
d	œd
|
idœ¬«      ƒ d{  –—†  t        d«      ƒ d{  –—†  y7 �Œc c}}w c c}}w c c}}w 7 Œ-7 Œ­w)aß  Persist specific environment variables to the DB config row.

        Each key in ``updates`` is written to the ``environment_variables``
        config row; a ``None`` value deletes that key. Env vars the caller does
        not name are preserved, so a caller that owns a couple of keys can
        update just those without snapshotting unrelated (YAML/OS-sourced)
        values the way a full ``save_config`` write would. No-op when config is
        not DB-backed.
        Nr4  FTrT  r‚  ©Úwhererƒ  ©rT  rU  rU  ©Úcreaterå  ©r�  r„  )r÷  rW  rp  r4  rw  Ú
find_firstrU  rÔ  râ  rˆ  rm  r  rv  rH  Úupsertrk  )rp  r�  ÚrowÚexistingrF  rG  Úto_setÚ	encryptedÚdeleted_keysÚmergedÚ
serializeds              rˆ   Úsave_environment_variablesz&ProxyConfig.save_environment_variablesÙ  s‡  è ø€ ô Ð Ô)9×)=Ñ)=Ð>QÐSXÓ)YÐ]aÑ)aÕevØä3FÄ}Ó3U×3`Ñ3`ØÐ!8Ð9ð 4aó 4
÷ .
ˆð :=¸ÈSÏ_É_ÐMh¤ S§_¡_Ô 5Ðnpˆà*1¯-©-«/×K¡$ ! Q¸Q¹]˜˜A™ÐKˆÑKÙ_e˜4×=Ñ=ÐTZÐ=Ô[Ðkmˆ	Ø-4¯]©]«_×J¡T Q¨ÀÁ	šqÐJˆÑJØe¨X¯^©^Ó-=×W¡T Q¨ÀÈ,ÒAV˜A˜q™DÓWÐeÐ[dÐeˆä ŸJ™J vÓ.ˆ
Üœ}Ó-×3Ñ3×:Ñ:ØÐ!8Ð9à)@ÐQ[Ñ\Ø(¨*Ð5ñð ;ó 
÷ 	
ð 	
ô &Ð&=Ó>×>Ñ>ð%.
ûó
 LùãJùÛWð	
øð 	?úsm   ‚A
FÁE)Á<FÂ	
E,ÂE,Â,FÃ
E2ÃE2ÃFÃ+E8Ã8E8Ã=AFÅE>ÅFÅ#F Å$FÅ,FÆ Fr   ÚdepthÚ	max_depthc                 óò  — ||kD  rt        j                  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        |«      }|€!t        |«      rt        j                  d|«       |||<   ŒÈ |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 (%s) reached while processing config.r8  )r^  rŸ  r   r  z/%s is absent from the configured secret manager)rŸ   r/  râ  rÓ  rÔ  Ú_check_for_os_environ_varsr•  r‚  r™  r|  r€  )rp  r^  rŸ  r   rz  r*  rü  rK  s           rˆ   r¢  z&ProxyConfig._check_for_os_environ_varsû  s   € ð �9ÒÜ ×(Ñ(Ð)hÐjsÔtØˆMà Ÿ,™,›.ò 	'‰JˆC�Ü˜%¤Ô&Ø"×=Ñ=ÀUÐRWÐZ[ÑR[ÐgpÐ=Óq��s’Ü˜E¤4Ô(Ø!ò r�DÜ! $¬Õ-Ø#×>Ñ>ÀdÐRWÐZ[ÑR[ÐgpÐ>Óq™ñrô ˜E¤3Õ'¨E×,<Ñ,<¸]Õ,KÜ% eÓ,�ØÐ#Ô(IÈ%Ô(PÜ(×0Ñ0Ð1bÐdiÔjØ&��s’ð	'ð ˆrŠ   c           	      óà  — t         j                  �y|j                  d«      }t        |t        «      sy|j                  d«      }t        |t
        «      r|j                  d«      rt        |«      n|}t        |t
        «      sy|j                  d«      }t        |t        «      r7t        di | j                  t        j                  |«      ¬«      ¤Žt         _        | j                  ||¬«       y)	aÌ  
        Bring the secret manager up before `os.environ/<KEY>` references are resolved.

        `_check_for_os_environ_vars` writes whatever it resolves back into the config, so a key
        held only by the secret manager would otherwise become a permanent `None` that the later
        fallbacks in `load_config` can no longer recover from.

        `get_config` also runs on management-endpoint request paths, so this returns early once a
        manager exists rather than rebuilding the client on every request.

        The manager's own settings can only come from real environment variables, so they are
        resolved against a throwaway copy and the config is left untouched for the main pass.
        NrW  Úkey_management_systemr  Úkey_management_settings©r^  )r¤  r=  rè  )r  rN  rp  rÓ  rÔ  r‚  r™  r|  r›  r¢  rÆ  rÇ  Ú_key_management_settingsÚinitialize_secret_manager)rp  r^  r=  rW  Ú
raw_systemr¤  Úraw_settingss          rˆ   Ú*_initialize_secret_manager_from_raw_configz6ProxyConfig._initialize_secret_manager_from_raw_config  sß   € ô  ×(Ñ(Ð4Øà"(§*¡*Ð-?Ó"@ÐÜÐ*¬DÔ1Øà,×0Ñ0Ð1HÓIˆ
ô ˜*¤cÔ*¨z×/DÑ/DÀ]Ô/Sô �zÔ"àð 	ô
 Ð/´Ô5Øà.×2Ñ2Ð3LÓMˆÜ�l¤DÔ)Ü/Dñ 0Ø×1Ñ1¼¿¹À|Ó9TÐ1ÓUñ0ŒGÔ,ð 	×&Ñ&Ø"7Ø-ð 	'õ 	
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: r  )rÿ  rÉ  Ú	mask_dictrâ  rÓ  r‚  r™  r|  )rp  r•  r¬  Úteam_configÚteamrF  rG  s          rˆ   Ú_get_team_configzProxyConfig._get_team_configH  s›   € ØˆØ$ò 	ˆDØ Ñ$ÜÐ"=Ô>S×>]Ñ>]Ð^bÓ>cÐ=dÐ eÓfÐfØ˜$˜y™/Ó)Ø"�Ùð	ð  ×%Ñ%Ó'ò 	/‰DˆAˆqÜ˜!œSÕ! a§l¡l°=Õ&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
        rT  Údefault_team_settingsN)r•  r¬  )r‰  rp  r±  )rp  r•  r^  rT  r¬  r¯  s         rˆ   Úload_team_configzProxyConfig.load_team_configU  sb   € ð ×-Ñ-Ó/ˆð #)§*¡*Ð-?ÀÓ"DÐØ"2×"6Ñ"6Ð7NÐPTÓ"UÐØÐ#ØˆIØ!×2Ñ2¸7ÐUeÐ2ÓfˆØÐrŠ   c                 ó´  — |j                  d«      xs i }|j                  d«      xs i }|j                  d«      }|€yt        |t        «      st        d«      ‚t	        di t        |«      ¤Ž}|j                  «       st        d«      ‚t        |j                  d¬«      «      }t        ||j                  d	d
«      du ¬«       t        j                  d«       |S )a�  
        Builds the coordination Redis from `general_settings.coordination_redis`
        when present, attaching it to the proxy-level caches. Runs before cache
        init, so an explicit block takes precedence over borrowing the
        response-cache Redis and over the REDIS_* env fallback. Returns the
        built client (None when the block is absent) for the caller to publish.
        rW  rT  Úcoordination_redisNzPgeneral_settings.coordination_redis must be a mapping of Redis connection paramszugeneral_settings.coordination_redis needs a connection target: set one of host, url, startup_nodes, or sentinel_nodesT©Úexclude_noner   F©r   z�coordination_redis: using a standalone Redis from general_settings for usage tracking, rate limiting, and cross-pod coordination.rè  )rp  rÓ  rÔ  rs  rA   r  Úhas_connection_targetr  Ú
model_dumpr$  rŸ   r  )rp  r^  r  rT  r  Úcoordination_paramsr
  s          rˆ   Ú_init_coordination_redisz$ProxyConfig._init_coordination_redisf  sî   € ð !Ÿ*™*Ð%7Ó8Ò>¸BˆØ"(§*¡*Ð-?Ó"@Ò"FÀBÐØ$ŸL™LÐ)=Ó>ˆ
ØÐØÜ˜*¤dÔ+ÜÐoÓpÐpä%<Ñ%pÔ?cÐdnÓ?oÑ%pÐØ"×8Ñ8Ô:ÜðIóð ô
 +CÐCV×CaÑCaÐosÐCaÓCtÓ*uÐ Ü!Ø$Ø$4×$8Ñ$8Ð9RÐTYÓ$ZÐ^bÐ$bõ	
ô 	×!Ñ!ðMô	
ð (Ð'rŠ   Úcache_paramsr   c                 óê  — ddl m} d|v r|d   t         _        d|v r|d   t         _         |di |¤Žt         _        t
        }t         j                  �t         j                  j                  nd}|€Nt        |t        t        f«      r|}n5t        «       }|�)t        j                  dt        |«      j                  «       |�t        ||«       |S t        j                   €t        j                  d«       |S )	aE  
        Initializes the response cache and resolves the coordination Redis.

        Returns the coordination Redis for the caller to publish: an explicit
        coordination_redis block already set wins, else a plain-Redis response
        cache backend is borrowed, else the REDIS_* environment fallback applies.
        r   ©ÚCacher#  r"  Nz¤Cache backend %s is not a Redis KV cache; built a standalone Redis from REDIS_* environment variables for usage tracking, rate limiting, and cross-pod coordination.zOlitellm_config_cache: no Redis configured; cluster-wide cache sharing disabled.rè  )r  rÁ  r#  r"  r  rX  rÓ  r¢   r£   r  rŸ   r  rw   r   r$  rl  r  )rp  r¾  r   rÁ  Úresolved_usage_cacheÚcache_backends         rˆ   Ú_init_cachezProxyConfig._init_cacheˆ  só   € õ 	"à" lÑ2Ø,8Ð9PÑ,QŒGÔ)à ,Ñ.Ø(4Ð5HÑ(IŒGÔ%áÑ- Ñ-ŒŒä0ÐÜ6=·m±mÐ6OœwŸ}™}×2Ò2ÐUYˆØÐ'Ü˜-¬*Ô6GÐ)HÔIà'4Ñ$ä'PÓ'RÐ$Ø'Ð3Ü(×-Ñ-ðEô ˜]Ó+×4Ñ4ô	ð  Ð+ô &Ð&:Ð<SÔTð $Ð#ô "×-Ñ-Ð5Ü ×%Ñ%Ð&wÔxØ#Ð#rŠ   c                 óš   — ddl }t        �A|j                  �4t        j                  dur!dt        _        t	        j
                  d«       yyyy)zë
        Enable caching on the router by setting cache_responses=True.
        This ensures caching works without needing caching=True in request body.
        Router passes caching=self.cache_responses to litellm.completion()
        r   NTz8Set router.cache_responses=True after initializing cache)r  rU  r  Úcache_responsesrŸ   r
  )rp  r  s     rˆ   Úswitch_on_llm_response_cachingz*ProxyConfig.switch_on_llm_response_caching¶  sH   € ó 	äÐ! g§m¡mÐ&?ÄJ×D^ÑD^ÐfjÑDjØ)-ŒJÔ&Ü ×&Ñ&Ð'aÕbð EkÐ&?Ð!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!                  |¬«      }| j#                  |¬«       |S 7 ŒË7 Œ˜7 Œh­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)r^  r÷  r4  r‚  ©r^  r=  r¦  )rn  ro  rp  rŸ   r
  rõ   rö   rÿ  ry  r÷  r4  Ú_update_config_from_dbrÆ  rÇ  r‡  r«  r¢  Úupdate_config_state)rp  r=  rÌ  rÍ  Úbucket_typer^  Úprinted_yamls          rˆ   Ú
get_configzProxyConfig.get_configÃ  s\  è ø€ ô$ �:‰:�>‰>Ð6Ó7ÐCÜ!#§¡§¡Ð0LÓ!MˆKÜ "§
¡
§¡Ð/QÓ RˆJÜ!#§¡§¡Ð0LÓ!MˆKÜ ×&Ñ&Ð'HÈ+ÐWaÔbØ˜eÒ#Ü@È[ÐeoÔp×p‘ä2¸{ÐWaÔb�àˆ~ÜÐ JÓKÐKð  ×5Ñ5ÐGWÐ5ÓX×XˆFô Ð$Ô):¸dÑ)BØ×6Ñ6ØÜ+Ü"3ð 7ó ÷ ˆFô #Ÿm™m¨FÓ3ˆØ×ÑÐ0°$Ô7à×7Ñ7¸vÐXhÐ7Ôià×0Ñ0¸Ð0Ó?ˆà× Ñ ¨Ð Ô/àˆð; qøð Yøðús7   ‚B)E=Â+E7Â,4E=Ã E9Ã!1E=ÄE;ÄA%E=Å9E=Å;E=c                 ó   — || _         y rn  r¦  )rp  r^  s     rˆ   rÐ  zProxyConfig.update_config_stateú  s	   € Øˆ�rŠ   c                 ó´   — 	 t        j                  | j                  «      S # t        $ r-}t	        j
                  d| 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=%s
Error: %sN)rÆ  rÇ  r^  rÿ  rŸ   r
  )rp  r  s     rˆ   r‰  zProxyConfig.get_config_stateý  sL   € ð	Ü—=‘= §¡Ó-Ð-øÜò 	Ü ×&Ñ&ØqØ—‘Øôð
 �Iûð	ús   ‚! ¡	Aª"AÁ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è  )rp  r�  )rp  r^  Úcredential_list_dictr×  Úcreds        rˆ   Úload_credential_listz ProxyConfig.load_credential_list  sC   € ð '-§j¡jÐ1BÓ&CÐØˆÙØBVÖW¸$œ~Ñ5°Ó5ÐWˆOÐWØÐùò Xs   š0c                 ó¾  — |j                  dd«      }|s&|j                  di «      }|r|j                  dd«      }|syg }t        d«       |D ]Û  }|j                  dd«      }|j                  di «      j                  dd«      }t        d	|› d
|› d�«       |j                  di «      }|rb|j                  «       D ]J  \  }	}
t        |
t        «      sŒ|
j                  d«      sŒ)|
j                  dd«      }t        |«      }
|
||	<   ŒL ||d<   	 t        di |¤Ž}|j                  |«       ŒÝ |r|S dS # t        $ r"}t        j                  d||«       Y d}~�Œ
d}~ww xY w)a/  
        Parse and validate search tools from config.
        Loads environment variables and casts to SearchToolTypedDict.

        Args:
            config: Config dictionary containing search_tools

        Returns:
            List of validated SearchToolTypedDict or None if not configured
        Úsearch_toolsNrW  z6[32mLiteLLM: Proxy initialized with Search Tools:[0mÚsearch_tool_namer6  rô  Úsearch_providerú	[32m    z (z)[0mr  z Error parsing search tool %s: %srè  )rp  r–   râ  rÓ  r‚  r™  r  r|  r—  rã  rÿ  rŸ   rz  )rp  r^  Úsearch_tools_rawrW  Úsearch_tools_parsedÚsearch_toolrÝ  rÞ  rô  rF  rG  Ú_vÚsearch_tool_typedr  s                 rˆ   Úparse_search_toolszProxyConfig.parse_search_tools  sŠ  € ð "Ÿ:™: n°dÓ;ÐÙà%Ÿz™zÐ*<¸bÓAÐÙØ#3×#7Ñ#7¸ÈÓ#MÐ áØà@BÐäØJô	
ð ,ò 	ˆKà*Ÿ™Ð/AÀ2ÓFÐØ)Ÿo™oÐ.>ÀÓC×GÑGÐHYÐ[]Ó^ˆOÜØÐ/Ð0°°?Ð2CÀ8ÐLôð
 )Ÿ_™_Ð-=¸rÓBˆNÙØ*×0Ñ0Ó2ò .‘D�A�qÜ! !¤SÕ)¨a¯l©l¸=Õ.IØŸY™Y }°bÓ9˜Ü& r›N˜Ø,-˜ qÒ)ð	.ð
 1?�Ð,Ñ-ðÜ9LÑ9[È{Ñ9[Ð!Ø#×*Ñ*Ð+<Õ=ð+	ñ4 ':Ð"ÐC¸tÐCøô	 ò Ü$×*Ñ*Ð+MÐO_ÐabÔcÝûðús   ÄD1Ä1	EÄ:EÅE>   ÚHOMEÚPATHÚUSERÚSHELLÚLOGNAMEÚNO_PROXYÚno_proxyÚ
LD_PRELOADÚ
PYTHONHOMEÚ
PYTHONPATHÚPYTHONSTARTUPÚLD_LIBRARY_PATHÚDYLD_LIBRARY_PATHÚDYLD_INSERT_LIBRARIESÚ_BLOCKED_ENV_KEYSc                 óØ  — |j                  dd «      }|rÖ|j                  «       D ]Š  \  }}|| j                  v rt        j                  d|«       Œ+t        |t        «      r4|j                  d«      r#t        |¬«      }|€Œ[|t        j                  |<   Œot        |«      t        j                  |<   ŒŒ d|v r4t        j                  dd «      t        _        t        j                  «       ay y y )Nr‚  z-Skipping blocked environment variable key: %sr  )Úsecret_nameÚLITELLM_LICENSE)rp  râ  rô  rŸ   r/  rÓ  r‚  r™  r~  rn  ro  r¨  r{  Úlicense_strr|  rÄ  )rp  r^  r‚  rz  r*  Úresolved_secret_strings         rˆ   Ú_load_environment_variablesz'ProxyConfig._load_environment_variablesa  sÚ   € ð (.§z¡zÐ2IÈ4Ó'PÐÙ Ø3×9Ñ9Ó;ò 1‘
��UØ˜$×0Ñ0Ñ0Ü(×0Ñ0Ð1`ÐbeÔfØô ˜e¤SÔ)¨e×.>Ñ.>¸}Ô.MÜ9GÐTYÔ9ZÐ*Ø-Ñ9Ø*@œŸ
™
 3šô '*¨%£j”B—J‘J˜s’Oð/1ð4 !Ð$9Ñ9Ü-/¯Y©YÐ7HÈ$Ó-O”Ô*Ü-×8Ñ8Ó:‘ð :ð7 !rŠ   .c                 ó‚   ‡— t        ˆfd„dD «       «      }|s|S t        j                  ddj                  |«      «       |S )Nc              3   ó,   •K  — | ]  }|‰v sŒ|–— Œ y ­wrn  rè  )r’  rz  r^  s     €rˆ   r”  z:ProxyConfig._warn_on_misplaced_jwt_keys.<locals>.<genexpr>…  s   øè ø€ Ò"j¨3Ð\_ÐciÒ\i¤3Ñ"jùó   ƒ	�)Úenable_jwt_authrõ  a  Ignoring top-level config key(s) %s. JWT auth settings must live under 'general_settings' (e.g. general_settings.enable_jwt_auth, general_settings.litellm_jwtauth); placed at the top level they are silently dropped and JWT auth (and JWT-to-virtual-key mapping) will not engage.ú, )rŒ  rŸ   r/  r–  )rp  r^  Úmisplaced_jwt_keyss    ` rˆ   Ú_warn_on_misplaced_jwt_keysz'ProxyConfig._warn_on_misplaced_jwt_keys„  sI   ø€ Ü"Ó"jÐ2XÔ"jÓjÐÙ!Ø%Ð%Ü×$Ñ$ðUð �I‰IÐ(Ó)ô	
ð "Ð!rŠ   rÎ   c              ƒ   ó,+  K  — | j                  |¬«      ƒ d{  –—† }| j                  |¬«       | j                  |¬«       | j                  |¬«      }|�t	        |«       |j                  di «      }|r|t        _        |j                  dd«      }|€i }|�	r<ddlm	}  ||«       d}d	}	|j                  «       D �	]  \  }
}|
d
k(  �rß|du �rÚt        |› d�«       ddlm} i }d|v r|d   }|j                  |«       |j                  dd«      }t        j                   d|«       |dk(  s|dk(  rÖt#        |j%                  «       «      dk(  rºt'        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 t	        | j/                  ||j                  dd«      du ¬«      «       t        j0                  €�ŒÓt        j                   d ||	«       �Œì|
d
k(  r|du r�Œ÷|
d!k(  r t3        |t4        ||¬"«      }|t        _        �Œ|
d#k(  r'dd$lm}  ||«       t        j<                  d%||	«       �ŒH|
d&k(  r'dd'lm }  ||«       t        j<                  d(||	«       �Œt|
d)k(  r'dd*l!m"}  ||«       t        j<                  d+||	«       �Œ |
d,k(  rdd-l#m$}  |dÄi |¤Žt        _%        �Œ¾|
d.k(  rtM        |t4        |||¬/«       �ŒÙ|
d0k(  rdd1l'm(}  |dÄi |¤Žt        _)        �Œ÷|
d2k(  r=tU        ||¬3«      gt        _+        t        j                   d4t        jV                  «       �Œ9|
d5k(  rtY        |«      t        _-        �ŒT|
d6k(  rtY        |«      t        _.        �Œo|
d7k(  rAtY        |«      t        _/        t        j\                  ��Œšt        j^                  t        _.        �Œµ|
d8k(  rut)        |t`        «      re|j                  d5«      �i |¥d5tY        |d5   «      i¥n|t        _1        t        j                   d9||
te        |
t        jb                  d¬:«      |	«       �Œ/|
d;k(  r<dd<l3m4} |D �cg c]  }|d=   tU        |d>   |¬3«      d?œ‘Œ c}t        _5         |«        �Œp|
d@k(  r¶g t        _6        |D ]ƒ  }dA|v r+t        jn                  jq                  tU        ||¬3«      «       Œ2t        jn                  jq                  |«       dB|v sŒVddCl9m:} |€Œ_t        j                   dD«       |jw                  «        Œ… t        |› dEt        jl                  › dF|	› �«       �Œ+|
dGk(  rƒg t        _<        |D ]P  }dA|v r+t        jn                  j{                  tU        ||¬3«      «       Œ2t        jn                  j{                  |«       ŒR t        |› dHt        jx                  › dF|	› �«       �Œ³|
dIk(  rÒddJl>m?}m@}  |«        g t        _A        |D ]P  }dA|v r+t        j‚                  j…                  tU        ||¬3«      «       Œ2t        j‚                  j…                  |«       ŒR |j                  dKt        j†                  «      } ||¬L«      r#t        |› dMt        j‚                  › dF|	› �«       �Œst        jˆ                  dN«       �ŒŠ|
dk(  r�Œ‘|
dOk(  rp|j                  dPi «      } | j                  dQd«      aE| j                  dRg «      aF| j                  dSdT«      aGt        j                   dU|tŠ        tŒ        tŽ        |	«       �Œ|
dVk(  r@|�tY        |«      ndt        _H        t        j                   dW|t        j�                  |	«       �ŒK|
dXk(  rWt“        |«      D ]  \  }!}"	 t•        dÄi |"¤Ž Œ t        j                   d9||
te        |
|d¬:«      |	«       t›        t        |
|«       �Œ§|
d[k(  r|�ot)        |t`        «      r_|j                  «       D ]6  \  }#}$t)        |$t*        «      sŒ|$j-                  d«      sŒ)t'        |$«      ||#<   Œ8 t�        dÄi |¤Žt        _O        �Œt—        d\|› �«      ‚|
d]k(  r<|du r8dt        _P        t        j¢                  «        t        j                   d^||	«       �Œl|
d_k(  r!dd`lRmS}%  |%|«       t›        t        |
|«       �Œ’t        j                   d9||
te        |
|d¬:«      |	«       t›        t        |
|«       |
dak(  rdt        _T        |
dbv s�ŒÞddclUmV}& dddlWmX}' ddel>m@}  |«        |'D �(cg c]  }(t)        |(|&«      rŒ|(‘Œ c}(|'dd �	Œ |j                  dfi «      })|)€i })t³        |)«      }*d}+d},d}-|)�r–tµ        |)j%                  «       «      | _[        t¸        D �
ci c]  }
|
|)v sŒ|
|)|
   “Œ c}
| _]        |)j                  dgd«      }.|.�t½        dÄi |.¤Žt        __        |)j                  dhd«      }/tÁ        |/¬i«       |)j                  djd«      }0tÃ        |0¬k«       | jÅ                  |)¬l«       tÇ        |)«       |)j                  dmd«      }1|1rF|1j-                  d«      r5t        j                   dn«       t'        |1«      }1t        j                   do«       |)j                  dpt'        dqd«      «      adtÈ        r$tÈ        j-                  d«      rt'        tÈ        «      adtÈ        �$t)        tÈ        t*        «      rtË        tÈ        «      afnt        jÎ                  dr«       |)j                  dsd«      }2|2�"tY        |2«      }3tÐ        jÓ                  |3|3¬t«       tÕ        jÖ                  dudv«      jÙ                  «       dwk(  }4|4r#tÚ        €tÜ        sdant        jˆ                  dx«       |)j                  dy«      }5|5r#tÚ        €tÞ        sdaot        jˆ                  dz«       |)j                  d{d«      aptà        €daptà        |)d{<   |)j                  d|d«      }6|6�tU        |6|¬3«      aqtå        |6dutç        |)j                  d}d«      «      ¬~«       |)j                  dd«      }7|7�tU        |7|¬3«      at|)j                  d€d«      }8|8�tU        |8|¬3«      au|)j                  d�d«      }9tí        j´                  |9�tU        |9|¬3«      nd«       tï        j´                  tñ        |)j                  d‚«      «      «       |)j                  dƒd«      }:|:�tU        |:|¬3«      ay|)j                  d„d«      };|;�tU        |;|¬3«      aztö        �tö        jù                  |)«      ƒ d{  –—†  |)j                  d…d«      �|)d…   a}tý        |)d…   |¬†«      ƒ d{  –—†  |)j                  d‡dˆ«      a|)j                  d‰d«      }<|<�t4        du r�t        dŠ«      ‚|)j                  d‹�t        «      a�|)j                  dŒ�t        «      a‚|)j                  d��t        «      aƒ|)j                  dŽ�t        «      a„|)j                  d��t
        «      a…|)j                  d��t        «      a†|)j                  d‘d«      a‡|)j                  d’d«      aˆ|)j                  d“�t        «      aŠ|)j                  d”d«      a‹|)j                  d•d«      aŒ|)j                  d–«      }=|=�At)        |=t*        «      r|=jÙ                  «       dwk(  t        _�        ntç        |=«      t        _�        |)j                  d—d«      }+|)j                  d˜d«      },|)j                  d™d«      }-t        j<                  dš�t        �t        �t        �t        �t        |+|*��t        |*«      nd«       |)j                  d›d«      }>|>�|>D �?cg c]  }?�t        dÄi |?¤Ž‘Œ c}?|)d›<   �t!        |)«       |)j                  dœ«      �2t4        dur*�t        d��t"        �j$                  �j&                  z   «      ‚dž|)v r%|)dž   �t(        _•        �t(        �j-                  «       adŸt        j0                  dui}@|+rd@d—<   |,�|,@d˜<   |-rd@d™<   |*��t        |*«      @d <   |j                  d¡d«      }A|A�rA@d¡<   t        d¢«       |AD �]  }B|Bd£   j                  «       D ]9  \  }C}Dt)        |Dt*        «      sŒDj-                  d«      sŒ)t'        D«      Bd£   C<   Œ; �t/        B«       �t1        |B«       �t3        |B«       |Bd£   j                  d¤«      }Et)        |Et`        «      r�t5        Bj                  d¥d¦«      E|¬§«       t        d¨Bj                  d¥d¦«      › d	�«       |Bd£   d©   }F|Bd£   j                  dªd«      }Gd«|Fv sŒûG�Œþ�t7        «        �Œ d}H|j                  d¬d«      }I|IrzId£   j                  «       D ]X  \  }C}Dt)        |Dt*        «      sŒDj-                  d«      sŒ)D�j9                  dd¦«      }$tÕ        jÖ                  |$«      }D|DId£   C<   ŒZ �t;        dÄi I¤Ž}H| �j=                  |«      }Jdd­lŸm }K  |K|j                  d®«      xs g «       |j                  d¯d«      }L�tC        |L¬«       |j                  d°d«      }M�tE        |M¬«       |j                  d±d«      }N�tG        �jH                  |N¬«       |j                  d²d«      }O|Or·t)        Ot`        «      r§d¡d³h}Pt        �jJ                  �jM                  «       D �Qcg c]	  }Q|QPvsŒQ‘Œ }R}QOj                  «       D ]^  \  }C}D|CRv r+Cd´k(  r t)        D�tN        «      r�tQ        D|dµ¬¶«      }DD@C<   Œ5Cd·v r�t        d¸C› d¹�«      ‚t        jˆ                  dºC«       Œ` t        �jJ                  dÄi @¤HJ�tS        d¬»«      d�tT        d¼œ¤Ž}tÚ        �.|j0                  �jV                  €|�jY                  tÚ        ¬½«       d}S|�|j                  d!d«      }SSr�t[        S||¬¾«       | �j]                  |�t^        |¬¿«      ƒ d{  –—†  d}T|�|j                  dÀd«      }TTrddÁl°m±}U  |UT|¬Â«       | �je                  |¬«      }V|Vt        _³        | �ji                  ||¬Ã«      ƒ d{  –—†  ||�jk                  «       |)fS 7 �Œ c c}w # t–        $ rJ t)        |"t`        «      rt—        dY|!› dZ|"j%                  «       › �«      ‚t—        dY|!› dZt™        |"«      › �«      ‚w xY wc c}(w c c}
w 7 �Œ¹7 �Œ�c c}?w c c}Qw 7 Œò7 Œ’­w)Åz<
        Load config values into proxy global state
        r<  Nr¦  Úcallback_settingsrT  r   )Ú!validate_caller_identity_settingsz[94mz[0mr  Tz
Setting Cache on ProxyrÀ  r¾  rw   Úrediszpassed cache type=%szredis-semanticÚ
REDIS_HOSTÚ
REDIS_PORT)rw   r  ÚportÚREDIS_PASSWORDÚpasswordz%sCache Type:%s %sz%sCache Host:%s %sz%sCache Port:%s %sz%sCache Password:%s %sr  r   F)r¾  r   z%sSet Cache on LiteLLM Proxy%sró  )Úguardrails_configrÄ  r=  rT  Úglobal_prompt_directory)Úset_global_prompt_directoryz0%sSet Global Prompt Directory on LiteLLM Proxy%sÚglobal_bitbucket_config)Úset_global_bitbucket_configz0%sSet Global BitBucket Config on LiteLLM Proxy%sÚglobal_gitlab_config)Úset_global_gitlab_configz-%sSet Global Gitlab Config on LiteLLM Proxy%sÚpriority_reservation_settings)ÚPriorityReservationSettingsrà  )r*  rÄ  r=  rT  Úcallback_specific_paramsÚmodel_group_settings)ÚModelGroupSettingsrØ  r(  zlitellm.post_call_rules: %srd  Úmax_internal_user_budgetÚ default_max_internal_user_budgetÚdefault_internal_user_paramsz%s setting litellm.%s=%s%s)Úis_full_adminrñ  )Úcustom_llm_setupÚproviderrò  )r  rò  r  r�  Ú
prometheus©ÚPrometheusLoggerzmounting metrics endpointz! Initialized Success Callbacks - r“   rá  z! Initialized Failure Callbacks - râ  )Úis_audit_logging_enabledÚreset_audit_log_callback_cacheÚstore_audit_logs)r"  z# Initialized Audit Log Callbacks - zh'audit_log_callbacks' is configured but audit logging is not enabled. Audit log callbacks will not fire.r  Úbackground_modeÚpolling_via_cacher*  r‹  r+  zQ%s Initialized polling via cache: enabled=%s, native_background_mode=%s, ttl=%s%sÚmax_ui_session_budgetz-%s setting litellm.max_ui_session_budget=%s%sr³  z4team_id missing from default_team_settings at index=z
passed in value=Úupperbound_key_generate_paramsz=Invalid value set for upperbound_key_generate_params - value=Ú	json_logsz$%s Enabled JSON logging via config%sÚbudget_reset_time)Úparse_budget_reset_timeÚrequest_timeout>   Ús3_callback_paramsÚs3_audit_callback_params)ÚS3Loggerr^  )r!  rW  r¥  Úuse_google_kms©r.  rE  ©rE  rV  rÊ  z)Resolving database_url via secret managerz)Resolved database_url from secret managerré  r9  z�LITELLM_MASTER_KEY is not set! All requests will be treated as INTERNAL_USER with no admin access. Set LITELLM_MASTER_KEY for production use.Úuser_api_key_cache_ttl)r#  r"  ÚGENERIC_CLIENT_USE_PKCEÚfalser§  uÄ  GENERIC_CLIENT_USE_PKCE=true but Redis is not configured for LiteLLM caching. PKCE verifiers will not be shared across instances â€” callbacks may land on a different pod than the login request and fail silently. Configure Redis via the 'cache' section in your proxy config, or enable sticky sessions for single-instance deployments. Set PKCE_STRICT_CACHE_MISS=true to fail fast with a 401 on cache misses instead of continuing without a code_verifier.Úcontrol_plane_urlu\  control_plane_url is configured but Redis is not configured for LiteLLM caching. Login codes (SSO and /v3/login) will not be shared across instances â€” the /v3/login/exchange call may land on a different pod and fail with 401. Configure Redis via the 'cache' section in your proxy config, or ensure sticky sessions for single-instance deployments.r4  rÙ  Úcustom_auth_run_common_checks)Úcustom_auth_configuredÚrun_common_checksrÚ  rÛ  rÜ  Úteam_metadata_schemarÝ  rÞ  rÌ  )rÌ  r=  r3  r(  Úallowed_ipsz\allowed_ips is an Enterprise Feature. Please add a valid LITELLM_LICENSE to your envionment.re  rf  Úproxy_batch_polling_intervalrg  Ú$proxy_config_reload_interval_secondsÚdisable_spend_logsÚbackground_health_checksrô  rõ  rö  rÀ  Úuse_legacy_interactions_schemarŸ  Ú health_check_staleness_thresholdr   z�background_health_check_config enabled=%s shared=%s interval_seconds=%s max_concurrency=%s details=%s health_check_routing=%s model_groups=%sÚrole_permissionsÚenforced_paramszTrying to use `enforced_params`Úlitellm_licenserÆ  rÈ  rm  z<[32mLiteLLM: Proxy initialized with Config, Set models:[0mrô  r2  r1  r6  )r1  r2  r=  rß  r{  rz  rS  Úassistant_settings)Úregister_sandbox_toolsÚsandbox_toolsÚfinetune_settingsÚfiles_settingsÚdefault_vertex_configrs  rÜ  r4  zrouter_settings.pluginsr5  >   rõ  rö  ú'zQ' is NOT a valid router_settings parameter. Please move it to 'general_settings'.zJKey '%s' is not a valid argument for Router.__init__(). Ignoring this key.©Úasync_only_mode)Úassistants_configrÜ  Úrouter_general_settingsÚignore_invalid_deploymentsÚfallback_access_check©r  )Úall_guardrailsr=  rU  )r^  r÷  rU  Úprompts)Úinit_prompts)Úall_promptsr=  rÎ  rè  )¶rÓ  r  rú  r½  rŠ  rp  r  r  Ú%litellm.types.integrations.prometheusr  râ  r–   Úlitellm.caching.cachingrÁ  rå  rŸ   r
  rÈ  r–  r|  rÓ  r‚  r™  rÄ  r  r#  rÄ  Úguardrail_name_config_mapÚlitellm.integrations.dotpromptr  r  Úlitellm.integrations.bitbucketr  Úlitellm.integrations.gitlabr  Úlitellm.types.utilsr  r  ré   Úlitellm.types.routerr  r  rX  rØ  r   rd  r  r  rÔ  r  Ú_redact_general_setting_valuer  r  rñ  r  rX  Úadd_litellm_success_callbackÚlitellm.integrations.prometheusr  Ú_mount_metrics_endpointrá  Úadd_litellm_failure_callbackÚ+litellm.proxy.management_helpers.audit_logsr   r!  râ  rã  r"  r/  r)  r*  r,  r%  Ú	enumeraterW   rÿ  rw   Úsetattrr�  r&  r'  Ú_turn_on_jsonÚ)litellm.proxy.common_utils.timezone_utilsr)  Úrequest_timeout_explicitly_setÚlitellm.integrations.s3_v2r-  r�  r_  r&  rð  ri  r  rj  r›  r§  r{  rS  Ú_load_alerting_settingsrG  ré  rj  Úlitellm_master_key_hashÚcriticalrA  Úupdate_cache_ttlrn  r¨  rÉ  rX  r-  r.  r4  rì  rÕ   r#  rî  rï  rC  rB  rD  rñ  rò  rÂ  Úload_enterprise_configr!  rS  r3  rs  re  rf  r:  rg  r;  r<  ró  rô  r«   rõ  rö  rÀ  r>  rÆ  rT   r	  r:   Únot_premium_userr*  r{  rø  r|  r=  rC  rH  r:  r\  r  rt  rå  Úlitellm.sandbox.sandbox_toolsrD  r!  rO  rQ  Úset_default_vertex_configr�   Úget_valid_argsr•  r0  r•  rÖ   r  Ú_update_redis_cacher"  Ú_init_policy_enginer÷  Ú"litellm.proxy.prompts.init_promptsrS  rÚ  r×  Ú_init_non_llm_configsÚget_model_list)Wrp  rÎ   r=  r^  r
  r  rT  r  Úblue_color_codeÚreset_color_coderz  r*  rÁ  r¾  Úcache_params_in_configÚ
cache_typeÚ
cache_hostÚ
cache_portÚcache_passwordrW  r  r  r  r  r  r  rü  Úcallbackr  r   r!  Ú_store_audit_logsr#  ÚidxÚteam_settingÚ_krã  r)  Ú
S3V2Loggerr_  ÚcbrW  Ú_bg_hc_model_groupsÚ_enable_hc_routingÚ_hc_stalenessÚ_hc_ignore_transientr¥  r.  rE  rÊ  r1  r‹  Úuse_pkceÚcp_urlrÙ  rÚ  rÛ  rÜ  rÝ  rÞ  r9  Ú_use_legacy_interactions_schemaÚrbac_role_permissionsÚrole_permissionÚrouter_paramsrm  r{  rF  rG  r2  Úlitellm_model_nameÚlitellm_model_api_baserL  rC  rÜ  rD  Úfinetuning_configÚfiles_configrH  rs  Úexclude_argsÚxÚavailable_argsÚguardrails_v2rR  rS  rØ  sW                                                                                          rˆ   r€  zProxyConfig.load_config‘  sÛ  è ø€ ðF %)§O¡OÐEU OÓ$V×Vˆà×(Ñ(°Ð(Ô7à×(Ñ(°Ð(Ô7ð +/×*GÑ*GÈvÐ*GÓ*VÐ Ø#Ð/Ü"Ð#;Ô<ð $*§:¡:Ð.AÀ2Ó#FÐÙØ(9ŒGÔ%ð "Ÿ:™:Ð&8¸$Ó?ÐØÐ#Ø!ÐÚõ
 `á-Ð.>Ô?ð &0ˆOØ&/ÐØ.×4Ñ4Ó6ó Nt‘
��UØ˜'“> e¨t¢mÜ˜_Ð-Ð-EÐFÔGÝ=à#%�LØ%Ð)9Ñ9Ø1AÀ.Ñ1QÐ.à$×+Ñ+Ð,BÔCà!-×!1Ñ!1°&¸'Ó!B�Jä(×.Ñ.Ð/EÀzÔRà" gÒ-°Ð?OÒ1OÔUXÐYe×YjÑYjÓYlÓUmÐqrÒUrÜ%/°¸dÓ%C˜
Ü%/°¸dÓ%C˜
Ø)-˜Ø$×+Ñ+à(2Ø(2Ø(2ñôô &Ð&6¸Ó=ÐIÜ-7Ð8HÈ$Ó-O˜NØ(×/Ñ/à$.°ð!"ôô -×2Ñ2Ø0Ø+Ø,Ø&ô	ô -×2Ñ2Ø0Ø+Ø,Ø&ô	ô -×2Ñ2Ø0Ø+Ø,Ø&ô	ô -×2Ñ2Ø4Ø+Ø,Ø*ô	ð '3×&8Ñ&8Ó&:ò B™
˜˜UÜ% e¬SÕ1°e×6FÑ6FÀ}Õ6UÜ0:¸5Ó0A˜L¨Ò-ðBô
 +Ø×(Ñ(Ø)5Ø4D×4HÑ4HÐIbÐdiÓ4jÐnrÐ4rð )ó ôô —}‘}Ò0Ü,×2Ñ2Ð3SÐUdÐfvÖwØ˜G’^¨°©ÙØ˜LÒ(Ü0EØ*/Ü%1Ø)9Ø)9ô	1Ð-ð 9R”GÖ5àÐ5Ò5õñ 0°Ô6Ü(×-Ñ-ØJÈOÐ]möð Ð5Ò5õñ 0°Ô6Ü(×-Ñ-ØJÈOÐ]möð Ð2Ò2ÝTá,¨UÔ3Ü(×-Ñ-ØGÈÐZjöð Ð;Ò;ÝOá<WÑ<`ÐZ_Ñ<`”GÖ9Ø˜KÒ'Ü1Ø#Ü%1Ø)9Ø)9Ø1B÷ð Ð2Ò2ÝGá3EÑ3NÈÑ3N”GÖ0àÐ-Ò-Ü/>ÀUÐ]mÔ/nÐ.o”GÔ+Ü(×.Ñ.Ð/LÌg×NeÑNeÖfØ˜LÒ(Ü).¨u«”GÖ&ØÐ6Ò6Ü7<¸U³|”GÖ4ØÐ>Ò>Ü?DÀU»|”GÔ<Ü×7Ñ7Ò?Ü;B×;cÑ;cœÖ8ØÐ:Ò:¼zÈ%ÔQUÔ?Vð !Ÿ9™9 \Ó2Ð>ð L˜5ÐK ,´°e¸LÑ6IÓ0JÒKà"ô Ô8ô
 )×.Ñ.Ø4Ø'ØÜ5°c¼7×;_Ñ;_ÐotÔuØ(öð Ð1Ò1Ý>ð %*ö	3ð !ð )-¨ZÑ(8Ü.=Ø&*Ð+;Ñ&<Ø1Aô/óò	3”GÔ/ñ %Ö&ØÐ.Ò.Ø/1”GÔ,ð %*ò O˜à (™?Ü#×<Ñ<×YÑYÜ /Ø*2Ø5Eô!"õô $×<Ñ<×YÑYÐZbÔcØ+¨xÒ7õ!"ð $4Ñ#?Ü$8×$>Ñ$>Ð?ZÔ$[Ø$4×$LÑ$LÕ$Nð'Oô( Ø*Ð+Ð+LÌW×MeÑMeÐLfÐfgÐhxÐgyÐzöð Ð.Ò.Ø/1”GÔ,ð %*ò d˜à (™?Ü#×<Ñ<×YÑYÜ /Ø*2Ø5Eô!"õô $×<Ñ<×YÑYÐZbÕcðdô Ø*Ð+Ð+LÌW×MeÑMeÐLfÐfgÐhxÐgyÐzöð Ð1Ò1÷ñ
 3Ô4Ø24”GÔ/à$)ò 	I˜Ø (™?Ü#×7Ñ7×>Ñ>Ü /Ø*2Ø5Eô!"õô $×7Ñ7×>Ñ>¸xÕHð	Ið )9×(<Ñ(<Ð=OÔQX×QiÑQiÓ(jÐ%Ù/ÐARÕSÜØ.Ð/Ð/RÔSZ×SnÑSnÐRoÐopð  rBð  qCð  Döô -×4Ñ4ðAöð ˜NÒ*ñ Ø˜KÒ'ð ',§i¡iÐ0AÀ2Ó&F�OØ0?×0CÑ0CÐDWÐY^Ó0_Ð-Ø-<×-@Ñ-@ÐAYÐ[]Ó-^Ð*Ø(7×(;Ñ(;¸EÀ4Ó(HÐ%Ü(×.Ñ.ØkØ'Ü1Ü.Ü)Ø(öð Ð3Ò3ØDIÐDU´E¸%´LÐ[_”GÔ1Ü(×.Ñ.ØGØ'Ü×5Ñ5Ø(ö	ð Ð3Ò3Ü-6°uÓ-=ò 
Ñ)˜˜\ð	Ü/Ñ?°,Ó?ð
ô )×.Ñ.Ø4Ø'ØÜ5°c¸5ÐPUÔVØ(ôô œG S¨%Ö0ØÐ<Ò<ØÐ(¬Z¸¼tÔ-DØ&+§k¡k£mò ;™F˜B Ü)¨"¬cÕ2°r·}±}À]Õ7SÜ,6°r«N  b¢	ð;ô BeÑAmÐglÑAmœÖ>ä'Ð*gÐhmÐgnÐ(oÓpÐpØ˜KÒ'¨E°T©MØ(,”GÔ%Ü×)Ñ)Ô+Ü(×.Ñ.Ø>ÀÐQaöð Ð/Ò/õñ ,¨EÔ2ÜœG S¨%Ö0ä(×.Ñ.Ø4Ø'ØÜ5°c¸5ÐPUÔVØ(ôô œG S¨%Ô0ØÐ/Ò/ØAEœÔ>ØÐPÓPÝUõõñ 7Ô8Ø>PÖ0s¸ÔXbÐceÐgqÕXr²Ò0sÐ*©1Ò-ð]
Ntðb
 "Ÿ:™:Ð&8¸"Ó=ÐØÐ#Ø!ÐÜ%OÐP`Ó%aÐØ"ÐØˆØ$ÐÚô 03Ð3C×3HÑ3HÓ3JÓ/KˆDÔ,ô
 7Wö3Ø/2ÐZ]ÐaqÒZq�Ð% cÑ*Ñ*ò3ˆDÔ/ð .>×-AÑ-AÐB[Ð]aÓ-bÐ#Ø&Ð2Ü3HÑ3cÐKbÑ3c”Ô0ð %5×$8Ñ$8Ð9IÈ5Ó$QˆNÜ¨>Õ:à)9×)=Ñ)=Ð>SÐUZÓ)[ÐÜ%Ð:MÕNà×(Ñ(Ð:JÐ(ÔKä(Ð)9Ô:à+×/Ñ/°ÀÓEˆLÙ × 7Ñ 7¸Ô FÜ$×*Ñ*Ð+VÔWÜ)¨,Ó7�Ü$×*Ñ*Ð+VÔWà)×-Ñ-¨l¼JÐG[Ð]aÓ<bÓcˆJåœj×3Ñ3°MÔBÜ'¬
Ó3�
äÐ%¬*´ZÄÔ*EÜ*4´ZÓ*@Ñ'ä$×-Ñ-ð dôð -=×,@Ñ,@ÐAYÐ[_Ó,`Ð"Ø%Ð1Ü"Ð#9Ó:�ô #×3Ñ3Ø*-Ø&)ð 4ô ô !Ÿi™iÐ(AÀ7ÓK×QÑQÓSÐW]Ñ]ˆHÙÔ-Ð5å5Ø59Ð2Ü(×0Ñ0ðIôð -×0Ñ0Ð1DÓEˆFÙÔ+Ð3å3Ø37Ð0Ü(×0Ñ0ðUôð !1× 4Ñ 4Ð5HÈ%Ó PÐÜ Ð(Ø$)Ð!Ü4EÐÐ0Ñ1ð "2×!5Ñ!5°mÀTÓ!JˆKØÐ&Ü#2¸ÐWgÔ#hÐ Ü8Ø'2¸$Ð'>Ü"&Ð'7×';Ñ';Ð<[Ð]bÓ'cÓ"dõð
 *:×)=Ñ)=Ð>SÐUYÓ)ZÐØ"Ð.Ü+:ÐATÐgwÔ+xÐ(à'7×';Ñ';Ð<OÐQUÓ'VÐØ Ð,Ü)8Ð?PÐcsÔ)tÐ&à3C×3GÑ3GÐHgÐimÓ3nÐ)Ü,×0Ñ0à0Ð<ô  Ð&CÐVfÕgàôô
 *×-Ñ-Ô.HÐIY×I]ÑI]Ð^tÓIuÓ.vÔwà 0× 4Ñ 4°\À4Ó HˆJØÐ%Ü"1¸
ÐUeÔ"f�à3C×3GÑ3GÐHgÐimÓ3nÐ)Ø,Ð8Ü5DØ7Ø%5ô6Ð2ô
 'Ð2Ü-×DÑDÐEUÓV×VÐVð  ×#Ñ#Ð$<¸dÓCÐOØ/?Ð@XÑ/YÐ,Ü7Ø+;Ð<TÑ+UØ%5ô÷ ð ð .×1Ñ1Ð2BÀEÓJˆNà!1×!5Ñ!5°mÀTÓ!JˆKØÐ&¬<¸5Ñ+@Ý Øróð ð 1A×0DÑ0DØ3Õ5Vó1Ð-ð 1A×0DÑ0DØ3Õ5Vó1Ð-ð ,<×+?Ñ+?Ø.Õ0Ló,Ð(ð $4×#7Ñ#7Ð8NÕPdÓ#eÐ à3C×3GÑ3GØ6Õ8\ó4Ð0ð "2×!5Ñ!5Ð6JÕL^Ó!_Ðð ,<×+?Ñ+?Ð@ZÐ\aÓ+bÐ(à&6×&:Ñ&:Ð;TÐV[Ó&\Ð#Ø$4×$8Ñ$8Ð9PÕRoÓ$pÐ!Ø'7×';Ñ';Ð<VÐX\Ó']Ð$Ø#3×#7Ñ#7Ð8NÐPTÓ#UÐ à5E×5IÑ5IÐJjÓ5kÐ+Ø.Ð:ÜÐ=¼sÔCØ=\×=bÑ=bÓ=dÐhnÑ=n”GÕ:ä=AÐBaÓ=b”GÔ:à!1×!5Ñ!5Ð6SÐUZÓ![ÐØ,×0Ñ0Ð1SÐUYÓZˆMØ#3×#7Ñ#7Ð8^Ð`eÓ#fÐ Ü ×%Ñ%ð `Ý,Ý'Ý%Ý(Ý$Ø"Ø/BÐ/N•Ð*Ô+ÐTXô	ð ,<×+?Ñ+?Ð@RÐTXÓ+YÐ!Ø$Ð0àShö8Ø@OÕ(Ñ;¨?Ó;ò8Ð Ð!3Ñ4õ
 )Ð)9Ô:ð  ×#Ñ#Ð$5Ó6ÐBÄ|Ð[_ÑG_Ý Ð!BÕEV×EgÒEg×EmÒEmÑ!mÓnÐnð !Ð$4Ñ4Ø-=Ð>OÑ-P•Ô*Ý-×8Ò8Ó:�ð œwŸ}™}°DÐ8ð&
ˆñ Ø;?ˆMÐ7Ñ8ØÐ$Ø@MˆMÐ<Ñ=ÙØDHˆMÐ@ÑAØÐ*ÝDJÐK^ÓD_ˆMÐ@ÑAà"ŸJ™J |°TÓ:ˆ
ÚØ*4ˆM˜,Ñ'ÜØTôð $ó '�à!Ð"2Ñ3×9Ñ9Ó;ò C‘D�A�qÜ! !¤SÕ)¨a¯l©l¸=Õ.IÜ5?À³]˜Ð.Ñ/°Ò2ðCõ 6°eÔ<Ý?ÀÔFÝ.¨uÔ5Ø+0Ð1AÑ+B×+FÑ+FÐGaÓ+bÐ(ÜÐ6¼Ô=Ý5Ø#(§9¡9¨\¸2Ó#>Ø1IØ)9õô
 ˜ U§Y¡Y¨|¸RÓ%@Ð$AÀÐIÔJØ%*Ð+;Ñ%<¸WÑ%EÐ"Ø).Ð/?Ñ)@×)DÑ)DÀZÐQUÓ)VÐ&ØÐ1Ò1Ð6LÑ6TÝ$Ö&ð''ð, 9=ÐØ$*§J¡JÐ/CÀTÓ$JÐÙØ*Ð+;Ñ<×BÑBÓDò @‘��1Ü˜a¤Õ%¨!¯,©,°}Õ*EØŸš =°"Ó5�BÜŸ	™	 "›�AØ>?Ð&Ð'7Ñ8¸Ò;ð	@õ
 !4Ñ IÐ6HÑ IÐð AE×@WÒ@WÐX^Ó@_ˆõ 	Iá˜vŸz™z¨/Ó:Ò@¸bÔAð $*§:¡:Ð.AÀ4Ó#HÐÝÐ&7Õ8ð %Ÿj™jÐ)9¸4Ó@ˆÝ Õ-ð (.§z¡zÐ2IÈ4Ó'PÐÝ#×=Ò=ÐEZÕ[ð "(§¡Ð,=¸tÓ!Dˆáœz¨/¼4Ô@ð Øð#ˆLô
 18·²×0MÒ0MÓ0OÖ$i¨1ÐSTÐ\hÒSh¢QÐ$iˆNÐ$ià'×-Ñ-Ó/ò ‘��1Ø˜Ñ&Ø˜I’~¬*°Q½Ô*=Ý3Ø)*Ø-=Ø)Bô˜ð
 ()�M !Ò$ØÐOÑOÝ$Ø˜A˜3ÐoÐpóð ô )×0Ñ0ØdÐfgõðô" —’ñ 	
Øð	
à/Ø%Ý$9Ø $ô%ð (,Ý">ó	
ˆô Ð(¨V¯\©\×-EÒ-EÐ-MØ×&Ò&Ô->Ð&Ô?ð ,0ˆàÐØ"ŸJ™J |°TÓ:ˆMÙÝØ,Ø!1Ø!õð ×&Ò&ØÝ'Øð 'ó 
÷ 	
ð 	
ð &*ˆØÐØ—j‘j ¨DÓ1ˆGÙÝGá WÐ?OÕPð '+×&?Ò&?ÀvÐ&?Ó&NÐØ"6ŒÔð ×(Ò(°ÐIYÐ(ÓZ×ZÐZà�v×,Ò,Ó.Ð0@Ð@Ð@ðU Wûòz	3øôn  )ò Ü)¨,¼Ô=Ü&/Ø&ZÐ[^ÐZ_Ð_qÐr~÷  sDñ  sDó  sFð  rGð  %Hó'"ð !"ô #,Ø"VÐWZÐV[Ð[mÔnrÐsó  oAð  nBð  !Có#ð ðüòt 1tùò$3ð~ Wùð
ûòB8ùòB %jð\	
øð( 	[úsm  ‚AV˜AT™HAVÈ+AVÈ=AAVÊGAVÑB$AVÓ8ATÔA<AVÖAVÖJ AVàAT à'A7AVâAVâ1C%AVæAVæ5AU6çAU6çAAVè$	AU;è.AU;è6NAV÷AV ÷.AV÷6AV÷7HAVÁ@AVÁ@DAVÁD#AVÁD5B:AVÁG0AVÁG3AAVÁIAVÁID#AVÁM6	AVÁN AVÁNDAVÁRAVÁRA!AVÁS?AVÁT AVÁTAVÁT AAU3ÁU3AVÁVAVÁVAVÁVAVc              ƒ   ó  K  — |j                  dd«      }|rddlm} |j                  ||¬«       |j                  d|j                  dd«      «      }|�ddlm} |j                  |«       |j                  d	d«      }|rDdd
lm} |j                  di «      }	|	j                  dd«      }
|j                  ||
«      ƒ d{  –—†  |j                  dd«      }|rEddl
m} t        j                  € |«       t        _        t        j                  j                  |«       |j                  dd«      }|rMt        dur&t!        dt"        j$                  j&                  z   «      ‚|D �cg c]  }t)        di |¤Ž‘Œ c}| _        yg | _        y7 ŒÆc c}w ­w)zO
        Initialize non-LLM configs eg. MCP tools, vector stores, etc.
        Ú	mcp_toolsNr   )Úglobal_mcp_tool_registryr<  ÚagentsÚ
agent_list©rF  Úmcp_servers©Úglobal_mcp_server_managerrT  Úmcp_aliasesÚvector_store_registry©ÚVectorStoreRegistryrc  TzTrying to use `worker_registry`rè  )rp  Ú4litellm.proxy._experimental.mcp_server.tool_registryr™  Úload_tools_from_configrK  rF  Úload_agents_from_configÚ9litellm.proxy._experimental.mcp_server.mcp_server_managerrŸ  Úload_servers_from_configÚ+litellm.vector_stores.vector_store_registryr£  r  r¡  Úload_vector_stores_from_configrÄ  rs  r:   rn  r*  rŒ  rc  )rp  r^  r=  Úmcp_tools_configr™  Úagent_configrF  Úmcp_servers_configrŸ  rT  r   Úvector_store_registry_configr£  Úworker_registry_configr  s                  rˆ   ru  z!ProxyConfig._init_non_llm_configs   s}  è ø€ ð
 #)§*¡*¨[¸$Ó"?ÐÙõð %×;Ñ;Ð<LÐ_oÐ;Ôpð %Ÿj™j¨°6·:±:¸lÈDÓ3QÓRˆØÐ#õð "×9Ñ9¸,ÔGà$*§J¡J¨}¸dÓ$CÐÙõð
 '-§j¡jÐ1CÀRÓ&HÐØ!1×!5Ñ!5°mÀTÓ!JˆKà+×DÑDÐEWÐYdÓe×eÐeð /5¯j©jÐ9PÐRVÓ.WÐ$Ù'ÝWä×,Ñ,Ð4Ù0CÓ0E”Ô-ô ×)Ñ)×HÑHÐIeÔfð )/¯
©
Ð3DÀdÓ(KÐÙ!Ü 4Ñ'Ü Ð!BÔEV×EgÑEg×EmÑEmÑ!mÓnÐnØF\Ö#]ÀÔ$7Ñ$<¸!Ó$<Ò#]ˆDÕ à#%ˆDÕ ð) fúò$ $^ùs%   ‚B<FÂ>FÂ?B#FÅ"FÅ4FÆFr÷  rY  rU  r�   c              ƒ   ó<  K  — ddl m} ddlm} |€t	        j
                  d«       y|j                  dd«      }|st	        j
                  d«       y|j                  dd«      }t	        j                  d	t        |«      «        |||||dud
¬«      ƒ d{  –—†  y7 Œ­w)a  
        Initialize the policy engine from config.

        Args:
            config: The proxy configuration dictionary
            prisma_client: Optional Prisma client for DB validation
            llm_router: Optional LLM router for model validation
        r   )Úinit_policies)ÚPolicyValidatorNz'Policy engine: config is None, skippingÚpoliciesz.Policy engine: no policies in config, skippingÚpolicy_attachmentsz*Policy engine: found %s policies in configT)Úpolicies_configÚpolicy_attachments_configr÷  Úvalidate_dbÚfail_on_error)	Ú)litellm.proxy.policy_engine.init_policiesr±  Ú,litellm.proxy.policy_engine.policy_validatorr²  rŸ   r
  rp  r  rÈ  )rp  r^  r÷  rU  r±  r²  rµ  r¶  s           rˆ   rs  zProxyConfig._init_policy_engineÖ  s�   è ø€ õ 	LÝPàˆ>Ü ×&Ñ&Ð'PÔQØà!'§¡¨J¸Ó!=ˆÙÜ ×&Ñ&Ð'WÔXØà+1¯:©:Ð6JÈDÓ+QÐ!ä×!Ñ!Ð"NÔPSÐTcÓPdÔeñ Ø+Ø&?Ø'Ø%¨TÐ1Øô
÷ 	
ò 	
ús   ‚BBÂBÂBrW  c                 óP  — |j                  dd«      }t        j                  d|«       |€y|j                  dd«      }t        j                  d|«       t        j	                  ||j                  dd«      |j                  dd«      |j                  dd«      |j                  d	d«      |j                  d
d«      t
        ¬«       |D ]^  }|dk(  rŒ	|t        j                  v sŒt        |ddd	|j                  d	d«      i¬«      }|€Œ@t        j                  j                  |«       Œ` y)z.
        Initialize alerting settings
        ÚalertingNz_alerting_callbacks: %sz?_load_alerting_settings: Calling update_values with alerting=%sÚalerting_thresholdéX  Úalert_typesrË  Úalerting_argsÚalert_type_config)r¼  r½  r¿  rË  rÀ  rÁ  r  Úslack)Úlogging_integrationÚinternal_usage_cacherU  Úcustom_logger_init_args)rp  rŸ   r
  rý  Úupdate_valuesrX  r  Ú)_known_custom_logger_compatible_callbacksr4   rX  rY  )rp  rW  Ú_alerting_callbacksÚ_alerting_valueÚ_alertÚ_loggers         rˆ   ri  z#ProxyConfig._load_alerting_settingsþ  s9  € ð
 &6×%9Ñ%9¸*ÀdÓ%KÐÜ×"Ñ"Ð#<Ð>QÔRØÐ&Øð "2×!5Ñ!5°jÀ$Ó!GˆÜ×"Ñ"Ð#dÐfuÔvÜ×'Ñ'Ø$Ø/×3Ñ3Ð4HÈ#ÓNØ(×,Ñ,¨]¸DÓAØ!1×!5Ñ!5Ð6LÈdÓ!SØ*×.Ñ.¨ÀÓEØ.×2Ñ2Ð3FÈÓMÜ)ð 	(ô 	
ð *ò 	WˆFØ˜Ò àð œW×NÑNÒNÜBØ,2Ø-1Ø#'Ø1@ÐBR×BVÑBVÐWfÐhlÓBmÐ0nô	�Gð Ñ*Ü×8Ñ8×MÑMÈgÕVñ	WrŠ   r¤  c                 ó  — |��||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t        j                  ¬«       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         j(                  j                  k(  rddlm}  |«        y|t         j.                  j                  k(  rddlm}  ||¬«       yt5        d«      ‚y)z_
        Initialize the relevant secret manager if `key_management_system` is provided
        NTr0  r/  r   )ÚAWSSecretsManagerV2)Úuse_aws_secret_managerr¥  )Úuse_aws_kms)ÚGoogleSecretManager)ÚHashicorpSecretManager)ÚCyberArkSecretManager)Úload_custom_secret_managerr<  z&Invalid Key Management System selected)rœ  rO  r*  rS  Ú
GOOGLE_KMSr{  ÚAWS_SECRET_MANAGERÚ-litellm.secret_managers.aws_secret_manager_v2rÍ  Úload_aws_secret_managerr  r§  ÚAWS_KMSrz  ÚGOOGLE_SECRET_MANAGERÚ-litellm.secret_managers.google_secret_managerrÐ  ÚHASHICORP_VAULTÚ0litellm.secret_managers.hashicorp_secret_managerrÑ  ÚCYBERARKÚ/litellm.secret_managers.cyberark_secret_managerrÒ  ÚCUSTOMÚ4litellm.secret_managers.custom_secret_manager_loaderrÓ  rs  )rp  r¤  r=  rÍ  rÐ  rÑ  rÒ  rÓ  s           rˆ   r¨  z%ProxyConfig.initialize_secret_manager%  s;  € ð !Ñ,Ø$Ô(;×(KÑ(K×(QÑ(QÒQä)¸dÖCØ&Ô*=×*HÑ*H×*NÑ*NÒNä¨tÖ4à%Ô)<×)OÑ)O×)UÑ)UÒUõð $×;Ñ;Ø+/Ü,3×,LÑ,Lð <õ ð 'Ô*=×*EÑ*E×*KÑ*KÒKÜ¨Ö.Ø&Ô*=×*SÑ*S×*YÑ*YÒYõñ $Õ%Ø&Ô*=×*MÑ*M×*SÑ*SÒSõñ 'Õ(Ø&Ô*=×*FÑ*F×*LÑ*LÒLõñ &Õ'Ø&Ô*=×*DÑ*D×*JÑ*JÒJõñ +Ð<LÖMä Ð!IÓJÐJð] -rŠ   c                 óØ  — t        |dd«      }|�A||j                  d<   d|j                  d<   t        t        |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
        r‡  Nr.  TÚdb_modelÚblockedFÚ
created_atÚ
updated_atrf  Ú
updated_by)r.  râ  rè  )rw  r¸  r#  rÄ  rÓ  rÔ  r‡  ÚRouterModelInfo)rp  r{  râ  r5  Ú_model_infos        rˆ   Úget_model_info_with_idz"ProxyConfig.get_model_info_with_id]  sb  € ô ")¨°
¸DÓ!AˆØˆ?Ø%(ˆE×Ñ˜TÑ"Ø+/ˆE×Ñ˜ZÑ(Ü*.¬w°u¸iÈÓ/OÓ*PˆE×Ñ˜YÑ'ä˜4Ñä-4°U¸LÈ$Ó-OˆE×Ñ˜\Ñ*Ü-4°U¸LÈ$Ó-OˆE×Ñ˜\Ñ*Ü-4°U¸LÈ$Ó-OˆE×Ñ˜\Ñ*Ü-4°U¸LÈ$Ó-OˆE×Ñ˜\Ñ*à×ÑÐ'¬J°u×7GÑ7GÌÔ,NØ˜5×+Ñ+Ñ+Ø).¯©�× Ñ  Ñ&Ø˜U×-Ñ-Ñ-°%×2BÑ2BÀ:Ñ2NÐRWÑ2WØ/7�× Ñ  Ñ,Ü)Ñ=¨E×,<Ñ,<Ñ=ˆKð Ðô *¨U¯^©^ÀhÔOˆKØÐrŠ   Ú	db_modelsc              ƒ   ó^  K  — g }t         €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 ]  }||vsŒt         j#                  |¬«       Œ t%        |«      S 7 �Œ# t        $ r)}t        j                  dt        |«      «       Y d}~yd}~ww xY w­w)aþ  
        (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:
        - frozenset[str] - the ids the db + config say should be served after this
          reconcile, so a caller can tell an id this evicted on purpose from one that
          went missing. None when no reconcile ran and that set is therefore unknown.
        N©r{  r<  zlFailed to load config in _delete_deployment: %s. Skipping deployment cleanup to avoid removing valid models.rm  rô  r  r¸  r.  r1  rE  ©r.  )rU  ré  r.  rã  rÓ  rê  rÿ  rŸ   r/  r‚  rp  râ  rÓ  r™  r|  rG  Úget_model_idsÚdelete_deploymentr@  )rp  rê  Úcombined_id_listrÎ  r¸  r^  r  rm  r{  rF  rG  r‡  Úrouter_model_idss                rˆ   Ú_delete_deploymentzProxyConfig._delete_deployment~  sÇ  è ø€ ð #%Ðô ÐØð ò 	7ˆAØ×4Ñ4¸1Ð4Ó=ˆJØ�}‰}Ñ(Ø ×'Ñ'¨
¯©Õ6ð	7ð	Ø"&§/¡/ÔCX /Ó"Y×YˆFð #ŸJ™J |°TÓ:ˆ
ÙØ#ò 2�à!Ð"2Ñ3×9Ñ9Ó;ò C‘D�A�qÜ! !¤SÕ)¨a¯l©l¸=Õ.IÜ5?À³]˜Ð.Ñ/°Ò2ðCð
 !Ÿ9™9 \°2Ó6×:Ñ:¸4ÀÓF�ØÐ#ä)×;Ñ;Ø$)¨,Ñ$7Ø',Ð-=Ñ'>ð  <ó  ‘Hô
  # 8›}�HØ ×'Ñ'¨Õ1ð!2ô$ #-×":Ñ":Ó"<Ðð )ò 	:ˆHØÐ/Ò/Ü×,Ñ,°Ð,Õ9ð	:ô Ð)Ó*Ð*ðE ZúÜò 	Ü ×(Ñ(ðNä�A“ôô
 ûð	üsZ   ‚-F-°F-ÁE8 Á'E5Á(E8 Á,AF-Â/F-ÃBF-Å#F-Å5E8 Å8	F*ÆF%Æ F-Æ%F*Æ*F-rz  r*  c                 óž   — t        |t        «      s|S t        ||d¬«      }t        |t        «      r|j                  d«      rt	        |«      S |S )NT©r*  rz  Úreturn_original_valuer  )rÓ  r‚  rì   r™  r|  )rp  rz  r*  Údecrypted_values       rˆ   Ú_resolve_db_litellm_paramz%ProxyConfig._resolve_db_litellm_paramÂ  sH   € Ü˜%¤Ô%ØˆLä!5¸EÀsÐbfÔ!gˆÜ�o¤sÔ+°×0JÑ0JÈ=Ô0YÜ˜oÓ.Ð.ØÐrŠ   c                 óª  — ddl }t        €yd}|D ]À  }|j                  }t        |t        «      rD|j                  «       D ]  \  }}| j                  ||¬«      ||<   Œ t        j                  |«      }nt        j                  d|«       Œz| 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   Nr{  úJInvalid model added to proxy db. Invalid litellm params. litellm_params=%sT)r{  râ  ©r1  rô  r¸  )rš  r8  )Úbase64rU  rô  rÓ  rÔ  râ  r÷  rv  Úmodel_validaterŸ   rz  ré  Úupsert_deploymentru  r1  )
rp  rê  rû  Úadded_modelsrÎ  Ú_litellm_paramsrF  rG  rè  Úaddeds
             rˆ   Ú_add_deploymentzProxyConfig._add_deploymentË  sö   € ó 	äÐØàˆàò 	"ˆAØ×.Ñ.ˆOÜ˜/¬4Ô0à+×1Ñ1Ó3ò X‘D�A�qØ)-×)GÑ)GÈAÐUVÐ)GÓ)W�O AÒ&ðXä"0×"?Ñ"?ÀÓ"P‘ô %×*Ñ*Ø`Ðbqôð Ø×5Ñ5¸AÈÐ5ÓMˆKä×0Ñ0Ü%Ø Ÿ|™|Ø#2Ø*ôð 1ó ˆEð Ñ Ø Ñ!‘ð1	"ð2 ÐrŠ   Ú
new_modelsc                 óØ  — g }|D ]â  }|j                   }t        |t        «      r|j                  «       }t        |t        «      rD|j                  «       D ]  \  }}| j                  ||¬«      ||<   Œ t        j                  |«      }nt        j                  d|«       Œš| j                  |¬«      }|j                  t        |j                  ||¬«      j                  d¬«      «       Œä |S )Nr{  rù  rì  rú  Tr·  )rô  rÓ  r   r»  rÔ  râ  r÷  rv  rü  rŸ   rz  ré  rã  ru  r1  Úto_json)rp  r  Ú_model_listrÎ  rÿ  rF  rG  rè  s           rˆ   Údecrypt_model_list_from_dbz&ProxyConfig.decrypt_model_list_from_dbõ  sñ   € Ø#%ˆØò 	ˆAØ×.Ñ.ˆOÜ˜/¬9Ô5Ø"1×"<Ñ"<Ó">�Ü˜/¬4Ô0à+×1Ñ1Ó3ò X‘D�A�qØ)-×)GÑ)GÈAÐUVÐ)GÓ)W�O AÒ&ðXä"0×"?Ñ"?ÀÓ"P‘ä$×*Ñ*Ø`Ðbqôð à×5Ñ5¸AÐ5Ó>ˆKØ×ÑÜØ Ÿ|™|Ø#2Ø*ô÷ ‘' t�'Ó,õð!	ð0 ÐrŠ   rý  c              ƒ   óx  K  — d }i }d }	 t         j                  «       ƒ d {  –—† }| j                  |«      }	 |€t	        j
                  d«       y t        |t        «      r|ng }t        € t        �št	        j                  dt        |«      «       | j                  |¬«      }t        |«      dkD  s|r·t	        j                  d|«       t        j                  |t!        d¬«      |dt"        ¬	«      a	t	        j                  d
t        «       n^t	        j                  dt        |«      «       |�t        �|t        _        | j'                  |¬«      ƒ d {  –—† }| j)                  |¬«       t        �t        j-                  «       a| j1                  |«       | j3                  |t        t4        ¬«      ƒ d {  –—†  | j7                  |t8        |¬«       |S 7 �Œ°# t        $ r*}t	        j
                  dt        |«      «       Y d }~�ŒËd }~ww xY w7 Œ¸# t        $ r }t	        j*                  d|«       Y d }~ŒÈd }~ww xY w7 Œ…­w)NziFailed to load config in _update_llm_router: %s. Proceeding with model loading using cached/empty config.z~_update_llm_router: DB model fetch returned None (transient failure). Skipping router update to preserve existing deployments.zlen new_models: %s)r  r   z_model_list: %sTrJ  )rm  rM  rÜ  rN  rO  zupdated llm_router: %s)rê  z-Error adding/deleting model to llm_router: %s)Úconfig_datarU  r÷  )r  rW  rý  )r~  rÓ  rå  rÿ  rŸ   r/  r‚  rÓ  r•  rU  ré  r
  rÈ  r  r  r�   r•  rÖ   rÜ  rò  r  r   rv  r�  Ú_add_callbacks_from_db_configÚ#_add_router_settings_from_db_configr÷  Ú$_add_general_settings_from_db_configrW  )	rp  r  rý  Ústill_desired_idsr  rÜ  r  Úmodels_listr  s	            rˆ   Ú_update_llm_routerzProxyConfig._update_llm_router  s9  è ø€ ð 48Ðð ˆØˆð	Ü ,× 7Ñ 7Ó 9×9ˆKØ×2Ñ2°;Ó?ˆLð(	_ð Ð!Ü$×,Ñ,ðOôð ä5?À
ÌDÔ5Q¡zÐWYˆKÜÐ!¤jÐ&<Ü$×*Ñ*Ð+?ÄÀ[ÓAQÔRà+/×+JÑ+JÐVaÐ+JÓ+b�ô �{Ó# aÒ'©<Ü(×.Ñ.Ð/@À+ÔNÜ!(§¡Ø#.Ü0EØ,0ô1ð &2Ø37Ü.Jô"�Jô )×.Ñ.Ð/GÌÕTä$×*Ñ*Ð+?ÄÀ[ÓAQÔRØÐ+´
Ð0FØ.:”JÔ+à*.×*AÑ*AÈKÐ*AÓ*X×$XÐ!ð ×$Ñ$¨{Ð$Ô;ô
 Ð!Ü'×6Ñ6Ó8ˆNð 	×*Ñ*¨;Ô7ð ×6Ñ6Ø#´
Ì-ð 7ó 
÷ 	
ð 	
ð
 	×1Ñ1Ø#Ü-Ø/ð 	2ô 	
ð !Ð ðK :úäò 	Ü ×(Ñ(ðKä�A“÷ò ûð	úðR %Yùô
 ò 	_Ü ×*Ñ*Ð+ZÐ\]×^Ñ^ûð	_úð	
ús�   ‚H:ŠG ¡G¢G ¸H ÁH:ÁDH ÅH
ÅH Å(A
H:Æ2H8Æ3H:ÇG Ç	HÇHÇ<H:ÈHÈH:È
H È	H5ÈH0È+H:È0H5È5H:r~  Úevent_types)ÚsuccessÚfailureÚexisting_callbacksc                 ó0  — |t         j                  v r|D ]  }t        ||«       Œ y||vrl|dgk(  r t         j                  j	                  |«       y|dgk(  r t         j                  j                  |«       yt         j                  j                  |«       yy)aQ  
        Helper method to add a single callback to litellm for specified event types.

        Args:
            callback: The callback name to add
            event_types: List of event types (e.g., ["success"], ["failure"], or ["success", "failure"])
            existing_callbacks: The existing callback list to check against
        r  r  N)r  rÇ  r¡  rX  r^  ra  rY  )rp  r~  r  r  Ú
event_types        rˆ   Ú4_add_callback_from_db_to_in_memory_litellm_callbacksz@ProxyConfig._add_callback_from_db_to_in_memory_litellm_callbackse  s‹   € ð ”w×HÑHÑHØ)ò T�
Ü=¸hÈ
ÕSñTàÐ/Ñ/Ø˜y˜kÒ)Ü×0Ñ0×MÑMÈhÕWØ  Ò+Ü×0Ñ0×MÑMÈhÕWä×0Ñ0×EÑEÀhÕOð 0rŠ   r  c                 ó
  — |j                  di «      xs i }|j                  dd«      }|j                  dd«      }|j                  dd«      }|�:t        |t        «      r*|D ]%  }| j                  |dgt        j
                  ¬«       Œ' |�:t        |t        «      r*|D ]%  }| j                  |dgt        j                  ¬«       Œ' |�=t        |t        «      r,|D ]&  }| j                  |ddgt        j                  ¬«       Œ( yyy)	z:
        Adds callbacks from DB config to litellm
        rT  r  Nrá  rà  r  )r~  r  r  r  )rp  rÓ  r•  r  r  r  rá  rà  )	rp  r  rT  Úsuccess_callbacksÚfailure_callbacksrà  r  rá  r~  s	            rˆ   r	  z)ProxyConfig._add_callbacks_from_db_config~  s2  € ð #.§/¡/Ð2DÀbÓ"IÒ"OÈRÐØ#3×#7Ñ#7Ð8JÈDÓ#QÐØ#3×#7Ñ#7Ð8JÈDÓ#QÐØ+×/Ñ/°¸TÓBˆ	àÐ(¬ZÐ8IÌ4Ô-PØ$5ò Ð Ø×IÑIØ-Ø!* Ü'.×'?Ñ'?ð Jõ ðð Ð(¬ZÐ8IÌ4Ô-PØ$5ò Ð Ø×IÑIØ-Ø!* Ü'.×'?Ñ'?ð Jõ ðð Ð ¤Z°	¼4Ô%@Ø%ò �Ø×IÑIØ%Ø!*¨IÐ 6Ü'.×'8Ñ'8ð Jõ ñð &AÐ rŠ   r‚  Únew_encryption_keyc                 ó^   — i }|j                  «       D ]  \  }}t        ||¬«      }|||<   Œ |S )zR
        Encrypts a dictionary of environment variables and returns them.
        )r*  r  )râ  rí   )rp  r‚  r  Úencrypted_env_varsrF  rG  Úencrypted_values          rˆ   Ú_encrypt_env_variablesz"ProxyConfig._encrypt_env_variablesŸ  sF   € ð %'ÐØ)×/Ñ/Ó1ò 	4‰DˆAˆqÜ2¸ÐOaÔbˆOØ$3Ð˜qÒ!ð	4ð "Ð!rŠ   rõ  c           	      óø   — i }|j                  «       D ].  \  }}	 t        |||¬«      }|�|t        j                  |<   |||<   Œ0 |S # t        $ r*}t        j                  d|t        |«      «       Y d}~Œad}~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......."}`
        rô  Nz#Error setting env variable: %s - %s)râ  rì   rn  ro  rÿ  rŸ   rz  r‚  )rp  r‚  rõ  Údecrypted_env_varsrF  rG  rö  r  s           rˆ   Ú!_decrypt_and_set_db_env_variablesz-ProxyConfig._decrypt_and_set_db_env_variables©  s–   € ð %'ÐØ)×/Ñ/Ó1ò 	]‰DˆAˆqð]Ü"6¸QÀAÐ]rÔ"s�Ø"Ð.Ø$3”B—J‘J˜q‘MØ,;Ð& qÑ)øð	]ð "Ð!øô ò ]Ü$×*Ñ*Ð+PÐRSÔUXÐYZÓU[×\Ñ\ûð]ús   š(AÁ	A9Á A4Á4A9Úvariables_dictc                 ó`   — i }|j                  «       D ]  \  }}t        ||d¬«      }|||<   Œ |S )zF
        Decrypts a dictionary of variables and returns them.
        Trô  )râ  rì   )rp  r!  Údecrypted_variablesrF  rG  rö  s         rˆ   Ú_decrypt_db_variablesz!ProxyConfig._decrypt_db_variables¾  sH   € ð &(ÐØ"×(Ñ(Ó*ò 	5‰DˆAˆqÜ2¸ÀÐY]Ô^ˆOØ%4Ð Ò"ð	5ð #Ð"rŠ   c                 óJ   — | j                  |«      }| j                  ||¬«      S )u¼  
        Idempotently encrypt environment variables for a DB write.

        Config writers may pass either plaintext (first write) or values that
        are already ciphertext â€” e.g. the Admin UI reads config back via
        /get/config/callbacks (which returns the stored, still-encrypted
        value) and re-POSTs it on the next save. Decrypt first so an
        already-encrypted value is not stacked with a second encryption
        layer, then encrypt exactly once.

        Decryption here deliberately uses _decrypt_db_variables (not
        _decrypt_and_set_db_env_variables): this is a write path, and
        loading values into os.environ is the read path's responsibility.
        )r‚  r  )r$  r  )rp  r‚  r  r  s       rˆ   rˆ  z)ProxyConfig._encrypt_env_variables_for_dbÈ  s4   € ð %)×$>Ñ$>Ð?TÓ$UÐØ×*Ñ*Ø"4Ø1ð +ó 
ð 	
rŠ   c                 óL  — | €yd}t        | t        «      r| }n*t        | t        «      rddl}	 t	        j
                  | «      }t        |t        «      r|r|S y# t        j                  |j                  f$ r, 	  |j                  | «      }n# |j                  $ r Y nw xY wY Œ_w xY w)z•
        Parse a router_settings value that may be a dict or a JSON/YAML string.

        Returns a non-empty dict if valid, otherwise None.
        Nr   )	rÓ  rÔ  r‚  rm  ro  rp  Ú	YAMLErrorÚJSONDecodeErrorr„  )r*  rÖ  rm  s      rˆ   Ú_parse_router_settings_valuez(ProxyConfig._parse_router_settings_valueÝ  s£   € ð ˆ=Øà"ˆÜ�eœTÔ"Ø‰FÜ˜œsÔ#ÛðÜŸ™¨Ó.�ô �fœdÔ#©ØˆMØøô —N‘N D×$8Ñ$8Ð9ò ðØ'˜TŸZ™Z¨Ó.‘FøØ×+Ñ+ò Ùðüðús5   ®A ÁB#Á8BÂ
B#ÂBÂB#ÂBÂB#Â"B#Úuser_api_key_dictrZ   rZ  c              ƒ   ó  K  — |� | j                  t        |dd«      «      }|�|S |�T|j                  �H	 t        |j                  |t        |¬«      ƒ d{  –—† }| j                  t        |dd«      «      }|�|S 	 yy7 Œ'# t
        $ r Y yw xY w­w)u²  
        Get router_settings in priority order: Key > Team

        Uses the already-cached key object and the cached team lookup
        (get_team_object) to avoid direct DB queries on the hot path.

        Global router_settings are NOT looked up here â€” they are already
        applied to the Router object at config-load / DB-sync time.

        Returns:
            dict: router_settings, or None if no settings found
        Nrs  )r•  r÷  rA  rý  )r)  rw  r•  rÑ   rA  rÿ  )rp  r*  r÷  rý  Úkey_settingsrÂ  Úteam_settingss          rˆ   Ú!_get_hierarchical_router_settingsz-ProxyConfig._get_hierarchical_router_settingsù  s¿   è ø€ ð* Ð(Ø"&×"CÑ"CÄGÐL]Ð_pÐrvÓDwÓ"xˆLØÐ'Ø#Ð#ð
 Ð(Ð->×-FÑ-FÐ-RðÜ(7Ø-×5Ñ5Ø"/Ü'9Ø&7ô	)÷ #�ð (,×'HÑ'HÌÐQYÐ[lÐnrÓIsÓ't�Ø Ð,Ø(Ð(ð -ñ ð#ùô ò ààð	üs@   ‚1B´ A> ÁA<Á#A> Á8BÁ:BÁ<A> Á>	B
ÂBÂ	B
Â
Bc              ƒ   ó\  K  — |��|��t        |«      j                  ddi¬«      ƒ d{  –—† }|j                  di «      }i }|�‹t        |t        «      r{|�yt        |j
                  t        «      r_ddlm} |j
                  j                  «       D ��	ci c]*  \  }}	||v rt        |	t        «      rt        |	«      dk(  s||	“Œ, }
}}	 |||
«      }n=|�t        |t        «      r|}n(|�&t        |j
                  t        «      r|j
                  }|r |j                  di |¤Ž yyyy7 Œúc c}	}w ­w)zÓ
        Adds router settings from DB config to litellm proxy

        1. Get router settings from DB
        2. Get router settings from config
        3. Combine both
        4. Update router settings
        NrT  rs  r�  r   )Ú_update_dictionaryrè  )rw  r•  rp  rÓ  rÔ  rU  r  r0  râ  r•  rÈ  Úupdate_settings)rp  r  rU  r÷  Údb_router_settingsÚconfig_router_settingsÚcombined_router_settingsr0  rF  rG  Ú*db_overlay_deferring_empty_lists_to_configs              rˆ   r
  z/ProxyConfig._add_router_settings_from_db_config'  sa  è ø€ ð Ñ! mÑ&?ÜFYÐZgÓFh×FsÑFsØ#Ð%6Ð7ð Gtó G÷ AÐð -8¯O©OÐ<MÈrÓ,RÐ"à')Ð$à&Ð2ÜÐ5´tÔ<Ø&Ð2ÜÐ1×=Ñ=¼tÔDå<ð !3× >Ñ >× DÑ DÓ F÷Eá˜˜1ØÐ!7Ñ7¼JÀqÌ$Ô<OÔTWÐXYÓTZÐ^_ÒT_ð �q‘DðEÐ:ñ Eñ
 ,>Ø*Ð,Vó,Ñ(ð (Ð3¼
ÐCYÔ[_Ô8`Ø+AÑ(Ø#Ð/´JÐ?Q×?]Ñ?]Ô_cÔ4dØ+=×+IÑ+IÐ(á'Ø*�
×*Ñ*ÑFÐ-EÓFð (ð; '@Ð!ðAúóEùs#   ‚'D,©D$ªA)D,Â/D&ÃA#D,Ä&D,c                 ó¼  — |j                  di «      }|��9d|v �r4|�ã|j                  dd«      �Ñt        |d   t        «      r¾|j                  dd«      �¬t        |d   t        «      r™t        |d   «      }t        |d   «      }t        |j	                  |«      «      }t        |d   «      |d   D �cg c]  }||d   vsŒ|‘Œ c}z   }t        j                  d|d   |d   |«       ||d<   |j                  |d   ¬«       nO|€ i }|d   |d<   |j                  |d   ¬«       n-t        |t        «      r|d   |d<   |j                  |d   ¬«       |�:d|v r6|d   |d<   |d   |_	        |j                  j                  |d   t        ¬«       |�0d|v r,|d   |d<   |j                  j                  |d   t        ¬	«       |�d
|v r|d
   |d
<   t        |«       yyyc c}w )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
        rW  Nr¼  z2Merging alerting values: YAML=%s, DB=%s, Merged=%s)r¼  r¿  )r¿  rU  rË  )rË  rU  r4  )rp  rÓ  r•  rð  ÚunionrŸ   r
  rÆ  rÔ  r¿  Úslack_alerting_instancerU  rG  )	rp  r  rW  rý  Ú_general_settingsÚ_yaml_alertingÚ_db_alertingÚ_merged_alertingrü  s	            rˆ   r  z0ProxyConfig._add_general_settings_from_db_configU  sz  € ð $/§?¡?Ð3EÀrÓ#JÐàÑ(¨ZÐ;LÒ-Là Ð,Ø$×(Ñ(¨°TÓ:ÐFÜÐ/°
Ñ;¼TÔBØ%×)Ñ)¨*°dÓ;ÐGÜÐ0°Ñ<¼dÔCô ),Ð,<¸ZÑ,HÓ(I�Ü&)Ð*;¸JÑ*GÓ&H�Ü#'¨×(<Ñ(<¸\Ó(JÓ#KÐ ä#'Ð(8¸Ñ(DÓ#EØ%6°zÑ%BöIØ!ÀdÐRbÐcmÑRnÒFn’DòIñ $Ð ô %×*Ñ*ØHØ$ ZÑ0Ø% jÑ1Ø$ô	ð 0@Ð  Ñ,à!×/Ñ/Ø-¨jÑ9ð 0õ ð "Ð)Ø#%Ð Ø/@ÀÑ/LÐ  Ñ,à!×/Ñ/Ø-¨jÑ9ð 0õ ô Ð,¬dÔ3Ø/@ÀÑ/LÐ  Ñ,à!×/Ñ/Ø-¨jÑ9ð 0ô ð Ð(¨]Ð>OÑ-OØ.?ÀÑ.NÐ˜]Ñ+Ø,<¸]Ñ,KÐÔ)Ø×5Ñ5×CÑCØ,¨]Ñ;Ì
ð Dô ð Ð(Ð-CÐGXÑ-XØ7HÐI_Ñ7`ÐÐ3Ñ4Ø×5Ñ5×CÑCØ%5Ð6LÑ%MÜ%ð Dô ð
 Ð(¨YÐ:KÑ-KØ*;¸IÑ*FÐ˜YÑ'Ü(Ð)9Õ:ð .LÐ(ùòUIs   Â1GÂ>Gc              ƒ   óÌ  K  — t         €y	 t         j                  d«       t        j                  d«       t
        j                  d«      }t
        j                  d«      }t
        j                  d«      }|€|€|��ddlm}  |«       }t
        j                  d	«      }|r]dd
l	m
} 	 |j                  |«      }t         j                  |j                  |t        gddt        ¬«       t        j                  d|«       yddlm}	 t
        j                  dd«      }
	  |	|
«      }t         j                  |j                  t)        dt+        |¬«      |t-        t
        «      ¬«      t        gddt        ¬«       t        j                  d|
«       yy# t        $ r Y �Œbw xY w# t         $ r t        j"                  d|«       Y yw xY w# t         $ r t        j"                  d«       Y yw xY w­w)zó
        Reschedule the spend log cleanup job based on current general_settings.
        This is called when maximum_spend_logs_retention_period is updated dynamically.
        If the retention period is None, the job will be removed.
        NÚspend_log_cleanup_jobz&Removed existing spend log cleanup jobÚ#maximum_spend_logs_retention_periodÚ+maximum_autorouter_session_retention_periodÚ%maximum_health_check_retention_periodr   )r  Úmaximum_spend_logs_cleanup_cron©ÚCronTriggerT©r  r.  Úreplace_existingÚmisfire_grace_timez+Spend log cleanup rescheduled with cron: %sú1Invalid maximum_spend_logs_cleanup_cron value: %s)r6  Ú%maximum_spend_logs_retention_intervalÚ1d©Úseconds)Újob_idÚtriggerÚperiod_secondsr  z/Spend log cleanup rescheduled with interval: %sú3Invalid maximum_spend_logs_retention_interval value)Ú	schedulerÚ
remove_jobrŸ   r  rÿ  rW  rp  Ú7litellm.proxy.db.db_transaction_queue.spend_log_cleanupr  Úapscheduler.triggers.cronrD  Úfrom_crontabÚadd_jobÚcleanup_old_spend_logsr÷  r§   rs  rz  Ú*litellm.litellm_core_utils.duration_parserr6  r  rŽ   r  )rp  Úretention_periodÚautorouter_retentionÚhealth_check_retentionr  Úspend_log_cleanupÚcleanup_cronrD  Úcron_triggerr6  Úretention_intervalÚinterval_secondss               rˆ   Ú!_reschedule_spend_log_cleanup_jobz-ProxyConfig._reschedule_spend_log_cleanup_job�  sì  è ø€ ô ÐØð	Ü× Ñ Ð!8Ô9Ü ×%Ñ%Ð&NÔOô
 #3×"6Ñ"6Ð7\Ó"]ÐÜ&6×&:Ñ&:Ð;hÓ&iÐÜ(8×(<Ñ(<Ð=dÓ(eÐØÐ'Ð+?Ð+KÐOeÑOqõñ (7Ó'8ÐÜ"2×"6Ñ"6Ð7XÓ"YˆLáÝAðrØ*5×*BÑ*BÀ<Ó*P�LÜ×%Ñ%Ø)×@Ñ@Ø$Ü+˜_Ø2Ø)-Ü+Ið &ô ô )×-Ñ-Ð.[Ð]iÕjõ
ô -=×,@Ñ,@ÐAhÐjnÓ,oÐ"ðfÙ.AÐBTÓ.UÐ$ô ×%Ñ%Ø)×@Ñ@Ü'Ø#:Ü$3Ð<LÔ$MØ+;Ü%;Ô<LÓ%Mô	ô ,˜_Ø2Ø)-Ü+Ið &ô ô )×-Ñ-Ð._ÐasÕtðc Prøô ò 	Úð	ûô: "ò rÜ(×.Ñ.Ð/bÐdpÖqðrûô8 "ò fÜ(×.Ñ.Ð/dÖeðfüsr   ‚G$‹*F µA0G$Â&AF Ã;G$ÄA0G  Æ	G$Æ	FÆG$ÆFÆG$ÆF=Æ:G$Æ<F=Æ=G$Ç G!ÇG$Ç G!Ç!G$Údb_general_settingsc              ƒ   ó  K  — |€yt        |«      }d|v r|d   t        d<   d|v r|d   t        d<   d| j                  vr|j                  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	<   d
|v rŒd
| j                  v rt        j                  d
«      }n|d
   }|€
dt        d
<   nWt        |t        «      r
|t        d
<   n=t        |t        «      r|j                  «       dk(  t        d
<   nt        |«      t        d
<   d|v rF|d   }t        |t        «      r|j                  «       dk(  t        d<   n|€|n
t        |«      t        d<   d|v rTd| j                  vrF|d   }t        |t        «      r|j                  «       dk(  t        d<   n|€|n
t        |«      t        d<   d|v rW|d   }|€nBt        |t        «      r|an/t        |t        «      r|j                  «       dk(  ant        |«      at        t        d<   d|v r@t        j                  d«      }|d   }|t        d<   ||k7  r| j                  «       ƒ d{  –—†  d|v r@t        j                  d«      }|d   }|t        d<   ||k7  r| j                  «       ƒ d{  –—†  d|v r@t        j                  d«      }	|d   }
|
t        d<   |	|
k7  r| j                  «       ƒ d{  –—†  t        D ]4  }|j                  || j                  j                  |«      «      t        |<   Œ6 dD ]  }||v sŒ||   t        |<   Œ t!        |«       y7 �ŒÏ7 Œð7 Œ®7 Œl­w)z;
        Pull from DB, read general settings value
        NÚmax_parallel_requestsÚglobal_max_parallel_requestsÚmax_batch_file_size_mbrÀ  )rÀ  rÌ  )rÌ  r3  Ústore_prompts_in_spend_logsr§  Ú%disable_auto_add_proxy_admin_to_teamsÚapply_user_budget_to_team_keysr4  r?  r@  rA  )r  r  r  )rÔ  rW  ri  rp  rý  r8  rÆ  rS  rÓ  r#  r‚  rÉ  r4  ra  r  rj  r	  )rp  rb  r9  r*  rï  Ú	old_valueÚ	new_valueÚold_session_valueÚnew_session_valueÚold_health_check_valueÚnew_health_check_valueÚcleanup_keyrz  s                rˆ   Ú_update_general_settingsz$ProxyConfig._update_general_settingsç  s  è ø€ ð
 Ð&ØÜ#'Ð(;Ó#<Ðà"Ð&7Ñ7Ø8IÐJaÑ8bÔÐ4Ñ5à)Ð->Ñ>Ø?PÐQoÑ?pÔÐ;Ñ<à#¨4×+KÑ+KÑKØ9J×9NÑ9NÐOgÓ9hÔÐ5Ñ6ð Ð/Ñ/Ø0AÀ/Ñ0RÔ˜_Ñ-Ü×5Ñ5×CÑCÜ.¨Ñ?ð Dô ð
 $Ð'8Ñ8Ø9JÐKcÑ9dÔÐ5Ñ6Ü3ÔK[Ð\tÑKuÔv×vÐvð Ð0Ñ0Ø1BÐCSÑ1TÔÐ-Ñ.ð )Ð,=Ñ=ð -°×0PÑ0PÑPÜ(×,Ñ,Ð-JÓK‘à)Ð*GÑH�àˆ}ØBFÔ Ð!>Ò?Ü˜E¤4Ô(ØBGÔ Ð!>Ò?Ü˜E¤3Ô'àBGÇ+Á+Ã-ÐSYÑBYÔ Ð!>Ò?ô CGÀuÃ+Ô Ð!>Ñ?à2Ð6GÑGØ%Ð&MÑNˆEÜ˜%¤Ô%ØLQÏKÉKËMÐ]cÑLcÔ Ð!HÒIàUZÐUbÉEÔhlÐmrÓhsÔ Ð!HÑIà+Ð/@Ñ@Ø,°D×4TÑ4TÑTà/Ð0PÑQˆHÜ˜(¤CÔ(ØEMÇ^Á^ÓEUÐY_ÑE_Ô Ð!AÒBàQYÐQaÁXÔgkÐltÓguÔ Ð!AÑBð Ð"3Ñ3Ø%Ð&9Ñ:ˆEØˆ}ØÜ˜E¤4Ô(Ø$)Ñ!Ü˜E¤3Ô'Ø$)§K¡K£M°VÑ$;Ñ!ä$(¨£KÐ!Ü4EÔÐ0Ñ1ð 1Ð4EÑEÜ/×3Ñ3Ð4YÓZˆIØ0Ð1VÑWˆIØFOÔÐBÑCà˜IÒ%Ø×<Ñ<Ó>×>Ð>à8Ð<MÑMÜ'7×';Ñ';Ð<iÓ'jÐØ'8Ð9fÑ'gÐØN_ÔÐJÑKØ Ð$5Ò5Ø×<Ñ<Ó>×>Ð>à2Ð6GÑGÜ,<×,@Ñ,@ÐAhÓ,iÐ"Ø,=Ð>eÑ,fÐ"ØH^ÔÐDÑEØ%Ð)?Ò?Ø×<Ñ<Ó>×>Ð>ô <ò 	ˆKØ,=×,AÑ,AØ˜T×@Ñ@×DÑDÀ[ÓQó-Ô˜[Ò)ð	ð

ò 	?ˆCð
 Ð'Ò'Ø(9¸#Ñ(>Ô  Ò%ð	?ô 	%Ð%6Õ7ðI wùðB ?øð ?øð ?úsR   ‚B2NÂ4NÂ5G NÊNÊANËNËANÌN
ÌA
NÍ)NÎNÎNÎ
NÚcurrent_configrT  ©rW  rs  rT  r‚  Údb_param_valuec                 óX  — dt         dt         ddfd„}t        ||¬«      }|dk(  r}| j                  |d¬	«      }i }|j                  «       D ]2  \  }}|||<   |j	                  «       }	|||	<   |t
        j                  |	<   Œ4 |j                  di «      j                  |«       |S |d
k(  rBt        |t         «      r2|j                  «       D ]  \  }}|t        v sŒt        t        ||«       Œ! ||vr|||<   |S t        ||   t         «      rt        |t         «      r |||   |«       |S |||<   |S )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
        ÚdstÚsrcrÐ  Nc                 óJ  — | |fg}|rœ|j                  «       \  }}|j                  «       D ]r  \  }}|€Œ	t        |t        «      rt	        |«      dk(  rŒ(t        |t
        «      r6t        |j                  |«      t
        «      r|j                  ||   |f«       Œn|||<   Œt |rŒ›yy)zÉ
            Deep-merge src into dst, skipping None values and empty lists from src.
            On conflicts, src (DB) wins, but empty lists are treated as "no value" and don't overwrite.
            Nr   )r‡  râ  rÓ  r•  rÈ  rÔ  rp  rã  )rv  rw  ÚstackÚdr”  rF  rG  s          rˆ   Ú_deep_merge_dictsz<ProxyConfig._update_config_fields.<locals>._deep_merge_dicts€  s–   € ð
 ! #˜J˜<ˆEÙØ—y‘y“{‘��1ØŸG™G›Iò 
!‘D�A�qØ�yà ä! !¤TÔ*¬s°1«v¸ª{Ø Ü! !¤TÔ*¬z¸!¿%¹%À»(ÄDÔ/IØŸ™ a¨¡d¨A YÕ/à ˜˜!šð
!ô rŠ   )rî  rï  r‚  T)rõ  rT  )rÔ  r  r   râ  Úupperrn  ro  r  rå  rÓ  r1   rd  r  )
rp  rr  rT  rt  r{  r  Úmerged_env_varsrz  r*  Ú	upper_keys
             rˆ   Ú_update_config_fieldsz!ProxyConfig._update_config_fieldsi  s`  € ð.	!¤4ð 	!¬dð 	!°tó 	!ô2 ?ÀzÐ\jÔkˆàÐ0Ò0Ø!%×!GÑ!GÈÐnrÐ!GÓ!sÐð ,.ˆOØ0×6Ñ6Ó8ò .‘
��UØ',� Ñ$ØŸI™I›K�	Ø-2� 	Ñ*Ø(-”—
‘
˜9Ò%ð	.ð ×%Ñ%Ð&=¸rÓB×IÑIÈ/ÔZØ!Ð!ØÐ-Ò-´*¸^ÌTÔ2RØ,×2Ñ2Ó4ò 1‘
��UØÔ<Ò<ÜœG S¨%Õ0ð1ð
 ˜^Ñ+Ø)7ˆN˜:Ñ&à!Ð!ô �n ZÑ0´$Ô7¼JÀ~ÔW[Ô<\Ù˜n¨ZÑ8¸.ÔIð
 Ðð *8ˆN˜:Ñ&àÐrŠ   r4  c           	   ƒ   óŠ  K  — |durt        j                  d«       |S g }g d¢}|D ]  }|j                  t        ||«      «       Œ t	        j
                  |Ž ƒ d {  –—† }|D ]Z  }|€Œt        |dd «      }	t        |dd «      }
t        j                  d|	t        |	|
«      «       |	€ŒD|
€ŒG| j                  ||	|
¬«      }Œ\ |S 7 Œe­w)NTz4'store_model_in_db' is not True, skipping db updatesrs  rT  rU  zparam_name=%s, param_value=%s)rr  rT  rt  )
rŸ   r  rã  rd  rP  rÙ  rw  r
  Ú&_redact_config_param_value_for_loggingr  )rp  r÷  r^  r4  Ú_tasksr–  rF  r  r  rT  rU  s              rˆ   rÏ  z"ProxyConfig._update_config_from_db¼  sñ   è ø€ ð  DÑ(Ü ×%Ñ%Ð&\Ô]ØˆMàˆò
ˆð ò 	>ˆAØ�M‰MÔ*¨=¸!Ó<Õ=ð	>ô ")§¡°Ð!8×8ˆ	Ø!ò 	ˆHØÐØä  ¨<¸Ó>ˆJÜ! (¨M¸4Ó@ˆKÜ ×&Ñ&Ø/ØÜ6°zÀ;ÓOôð Ñ%¨+Ñ*AØ×3Ñ3Ø#)Ø)Ø#.ð 4ó ‘ð	ð& ˆð) 9ús   ‚ACÁCÁA	CÂ&CÂ)CrS  c                 ó   — t        |¬«      S )N©rS  )rY  )rp  rS  s     rˆ   Ú_should_load_db_objectz"ProxyConfig._should_load_db_objectæ  s   € Ü$°Ô=Ð=rŠ   c              ƒ   óè   K  — 	 t        t        |j                  «      «      j                  j	                  «       ƒ d{  –—† }|S 7 Œ# t
        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)u	  
        Fetch all model deployments from the DB.

        Returns:
        - list: the rows (may be empty if no models exist)
        - None: signals a DB fetch *failure* â€” callers must not treat this
          as "all models deleted" and must not evict existing router deployments.

        Pinned to the writer DB: this read reconciles the router against the rows a
        model write just committed, and reading it through a lagging read replica
        makes the write-triggered reload report its own durable write as missing
        (#38556). It also keeps a stale replica snapshot from evicting a deployment
        another pod just added. While the writer is degraded the pin yields to the
        replica so reader-only mode keeps loading DB-backed models.
        NzQlitellm.proxy_server.py::add_deployment() - Error getting new models from DB - %s)ÚModelRepositoryÚWriterPinnedClientri  rH  Ú	find_manyrÿ  rŸ   r   )rp  r÷  r  r  s       rˆ   Ú_get_models_from_dbzProxyConfig._get_models_from_dbé  sk   è ø€ ð 		Ü@OÜ" =×#3Ñ#3Ó4óAç‰e—I‘I“K÷; ˆJð Ðð; ùô ò 	Ü ×*Ñ*ØcÐefôô ûð		üs>   ‚A2„9A ½A¾A ÁA2ÁA Á	A/ÁA*Á%A2Á*A/Á/A2c              ƒ   ó¶   K  — t         4 ƒd{  –—†  | j                  ||¬«      ƒ d{  –—† cddd«      ƒd{  –—†  S 7 Œ07 Œ7 Œ	# 1 ƒd{  –—†7  sw Y   yxY w­w)aØ  
        - Check db for new models
        - Check if model id's in router already
        - If not, add to router

        Serialized against every other model reconcile by MODEL_RECONCILE_LOCK, because
        the work below is a read-modify-write of the shared ``llm_router`` global: it
        reads the db into a snapshot and then makes the router match that snapshot. Two
        of those interleaving is not a lost update but an eviction -- the request whose
        snapshot predates the other's commit reconciles the newer model *out* of the
        router, since _delete_deployment removes every live deployment absent from the
        snapshot it was handed. The model stays in the db and this pod stops serving it
        until some later reload puts it back.

        Returns what the reconcile saw, captured before the lock is released so a
        caller's verdict cannot be corrupted by the next reconcile's own in-flight
        window. See ReconcileOutcome.
        N©r÷  rý  )r   Ú_add_deployment_locked)rp  r÷  rý  s      rˆ   Úadd_deploymentzProxyConfig.add_deployment  s^   è ø€ ô. (÷ 	wñ 	wØ×4Ñ4À=ÐduÐ4Óv×v÷	w÷ 	wò 	wøØvøð	wø÷ 	w÷ 	wñ 	wüsP   ‚A�>ŽA‘A¨A ©A¬A¸A¹AÁ AÁAÁAÁ
AÁAÁAc              ƒ   ó  K  — d}	 t        |g d¢«      ƒ d{  –—†  | j                  d¬«      r5| j                  |¬«      ƒ d{  –—† }| j                  ||¬«      ƒ d{  –—† }t	        |d«      ƒ d{  –—† }|�$| j                  |j                  ¬«      ƒ d{  –—†  | j                  |¬«      ƒ d{  –—†  t        ||€d¬
«      S t        «       ¬
«      S 7 Œ½7 Œ“7 Œz7 Œh7 ŒD7 Œ,# t        $ r }t        j                  d	|«       Y d}~ŒNd}~ww xY w­w)a(  add_deployment's body, minus the locking. MODEL_RECONCILE_LOCK MUST already
        be held. Split out for the one caller that has to hold the lock across more than
        this reconcile -- clear_cache, which un-serves every db model before calling it
        and would deadlock on a re-acquire.N)rW  rs  rT  r‚  Ú$anthropic_beta_headers_reload_configrs   r„  ©r÷  )r  rý  rW  )rb  z>litellm.proxy.proxy_server.py::ProxyConfig:add_deployment - %s)Ústill_desiredÚ
live_after)ro  r…  rŠ  r  rd  rq  rU  Ú_init_non_llm_objects_in_dbrÿ  rŸ   r   ÚReconcileOutcomer<  )rp  r÷  rý  r  r  rb  r  s          rˆ   r�  z"ProxyConfig._add_deployment_locked  sV  è ø€ ð 48Ðð$	pä(Øòó	÷ 	ð 	ð ×*Ñ*°xÐ*Ô@Ø*.×*BÑ*BÐQ^Ð*BÓ*_×$_�
ð +/×*AÑ*AØ)Ð=Nð +Bó +÷ %Ð!ô HXØÐ1óH÷ BÐð
 #Ð.Ø×3Ñ3Ø(;×(GÑ(Gð 4ó ÷ ð ð
 ×2Ñ2ÀÐ2ÓO×OÐOô  Ø+Ø0Ð8�tô
ð 	
ä>UÓ>Wô
ð 	
ðM	øð %`øð%øðBøðøð
 Pùäò 	pÜ ×*Ñ*Ð+kÐmn×oÑoûð	püs˜   ‚D†C! —C˜+C! ÁCÁC! ÁCÁC! Á2CÁ3%C! ÂCÂC! Â2CÂ3C! Â7DÃC! ÃC! ÃC! ÃC! ÃC! ÃC! Ã!	D
Ã*DÄ DÄD
Ä
Dr  c                 ó’   ‡ ‡‡— |�‰ j                   �y dˆˆˆ fd„}dˆˆ fd„}t        |||f¬«      }|‰ _         |j                  «        y )Nc               “   óH   •K  — ‰j                  ‰ ‰¬«      ƒ d {  –—†  y 7 Œ­w)NrŒ  )rŽ  )r÷  rý  rp  s   €€€rˆ   Ú_resync_config_from_dbzHProxyConfig.start_config_sync_subscriber.<locals>._resync_config_from_dba  s!   øè ø€ Ø×%Ñ%°MÐUfÐ%Óg×gÒgús   ƒ"š ›"c               “   óF   •K  — ‰j                  ‰ ¬«      ƒ d {  –—†  y 7 Œ­w)Nr‘  )Úget_credentials)r÷  rp  s   €€rˆ   Ú_resync_credentials_from_dbzMProxyConfig.start_config_sync_subscriber.<locals>._resync_credentials_from_dbd  s   øè ø€ Ø×&Ñ&°]Ð&ÓC×CÒCús   ƒ!™š!)r  Úresync_callbacksrl  )rd  rê   Ústart)rp  r÷  rý  r  r˜  r›  Ú
subscribers   ```    rˆ   Ústart_config_sync_subscriberz(ProxyConfig.start_config_sync_subscriberX  sS   ú€ ð Ð $×"=Ñ"=Ð"IØ÷	hö	Dô 1Ø#Ø4Ð6QÐRô
ˆ
ð '1ˆÔ#Ø×ÑÕrŠ   c              ƒ   óÆ   K  — | j                   }|€y d | _         	 |j                  «       ƒ d {  –—†  y 7 Œ# t        $ r }t        j                  d|«       Y d }~y d }~ww xY w­w)Nz)Error stopping config sync subscriber: %s)rd  Ústoprÿ  rŸ   rz  ©rp  rž  r  s      rˆ   r­  z'ProxyConfig.stop_config_sync_subscribern  s^   è ø€ Ø ×7Ñ7ˆ
ØÐØØ&*ˆÔ#ð	WØ—/‘/Ó#×#Ò#ùÜò 	WÜ ×&Ñ&Ð'RÐTU×VÑVûð	Wüó6   ‚A!š5 ­3®5 ²A!³5 µ	A¾AÁA!ÁAÁA!rA  c                 óŠ   — |�| j                   �y t        ||t        j                  f¬«      }|| _         |j	                  «        y )N)r  rA  Úadditional_in_memory_caches)re  rè   r$  r|  r�  )rp  r  rA  rž  s       rˆ   Ú(start_auth_cache_invalidation_subscriberz4ProxyConfig.start_auth_cache_invalidation_subscriberx  sJ   € ð
 Ð $×"IÑ"IÐ"UØÜ;Ø#Ø1Ü)<×)LÑ)LÐ(Nô
ˆ
ð
 3=ˆÔ/Ø×ÑÕrŠ   c              ƒ   óÆ   K  — | j                   }|€y d | _         	 |j                  «       ƒ d {  –—†  y 7 Œ# t        $ r }t        j                  d|«       Y d }~y d }~ww xY w­w)Nz5Error stopping auth cache invalidation subscriber: %s)re  r¡  rÿ  rŸ   rz  r¢  s      rˆ   r®  z3ProxyConfig.stop_auth_cache_invalidation_subscriber‡  s^   è ø€ Ø ×CÑCˆ
ØÐØØ26ˆÔ/ð	cØ—/‘/Ó#×#Ò#ùÜò 	cÜ ×&Ñ&Ð'^Ð`a×bÑbûð	cür£  c              ƒ   óü  K  — | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j	                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j                  «       ƒ d{  –—†  | j                  d	¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d
¬«      r| j                  «       ƒ d{  –—†  | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  | j                  d¬«      r!ddlm} |j                  || ¬«      ƒ d{  –—†  | j                  d¬«      r| j!                  |¬«      ƒ d{  –—†  | j                  d¬«      r4| j#                  |¬«      ƒ d{  –—†  | j%                  |¬«      ƒ d{  –—†  | j'                  |¬«      ƒ d{  –—†  y7 �Œ¥7 �Œ|7 �ŒS7 �Œ*7 �Œ7 �ŒÚ7 �Œ³7 �ŒŠ7 �Œa7 �Œ87 �Œ7 Œå7 Œ´7 ŒŠ7 Œ`7 ŒH7 Œ0­w)zŠ
        Use this to read non-llm objects from the db and initialize them

        ex. Vector Stores, Guardrails, MCP tools, etc.
        ró  r„  r‘  Nr³  Úvector_storesÚvector_store_indexesÚmcprš  rÌ  rR  rÜ  ÚtoolsÚanthropic_beta_headersr[  Úcache_settingsr   )ÚCacheSettingsManager)r÷  r~  Úsemantic_filter_settingsÚconfig_overrides)r…  Ú_init_guardrails_in_dbÚ_init_policies_in_dbÚ_init_vector_stores_in_dbÚ _init_vector_store_indexes_in_dbÚ_init_mcp_servers_in_dbÚ_init_agents_in_dbÚ"_init_pass_through_endpoints_in_dbÚ_init_prompts_in_dbÚ_init_search_tools_in_dbÚ_init_tool_policy_in_dbÚ(_check_and_reload_anthropic_beta_headersÚ_init_sso_settings_in_dbÚ;litellm.proxy.management_endpoints.cache_settings_endpointsr¯  Úinit_cache_settings_in_dbÚ$_init_semantic_filter_settings_in_dbÚ%_init_hashicorp_vault_config_overrideÚ_init_cyberark_config_overrideÚ._apply_safe_litellm_settings_overrides_from_db)rp  r÷  r¯  s      rˆ   r”  z'ProxyConfig._init_non_llm_objects_in_db‘  s  è ø€ ð ×&Ñ&°<Ð&Ô@Ø×-Ñ-¸MÐ-ÓJ×JÐJà×&Ñ&°:Ð&Ô>Ø×+Ñ+¸-Ð+ÓH×HÐHà×&Ñ&°?Ð&ÔCØ×0Ñ0¸}Ð0ÓM×MÐMà×&Ñ&Ð3IÐ&ÔJØ×7Ñ7ÀmÐ7ÓT×TÐTà×&Ñ&°5Ð&Ô9Ø×.Ñ.Ó0×0Ð0à×&Ñ&°8Ð&Ô<Ø×)Ñ)¸Ð)ÓF×FÐFà×&Ñ&Ð3KÐ&ÔLØ×9Ñ9Ó;×;Ð;à×&Ñ&°9Ð&Ô=Ø×*Ñ*¸Ð*ÓG×GÐGà×&Ñ&°>Ð&ÔBØ×/Ñ/¸mÐ/ÓL×LÐLà×&Ñ&°7Ð&Ô;Ø×.Ñ.¸]Ð.ÓK×KÐKà×&Ñ&Ð3KÐ&ÔLØ×?Ñ?ÈmÐ?Ó\×\Ð\à×&Ñ&°>Ð&ÔBØ×/Ñ/¸mÐ/ÓL×LÐLØ×&Ñ&Ð3CÐ&ÔDõð '×@Ñ@È}ÐkoÐ@Óp×pÐpà×&Ñ&Ð3MÐ&ÔNØ×;Ñ;È-Ð;ÓX×XÐXà×&Ñ&Ð3EÐ&ÔFØ×<Ñ<È=Ð<ÓY×YÐYØ×5Ñ5ÀMÐ5ÓR×RÐRà×AÑAÐP]ÐAÓ^×^Ñ^ða Kùð Iùð Nùð Uùð 1ùð Gùð <ùð Hùð Mùð Lùð ]ùð Møð qøð Yøð ZøØRøà^ús/  ‚(K<ªK«+K<ÁKÁ+K<ÂKÂ+K<Â.KÂ/)K<ÃKÃ+K<ÄKÄ)K<Ä.K!Ä/+K<ÅK$Å+K<ÆK'Æ+K<Æ2K*Æ3+K<ÇK-Ç+K<È
K0È2K<È=K2È>+K<É)K4É*+K<ÊK6ÊK<Ê/K8Ê0K<Ë	K:Ë
K<ËK<ËK<ËK<ËK<ËK<Ë!K<Ë$K<Ë'K<Ë*K<Ë-K<Ë0K<Ë2K<Ë4K<Ë6K<Ë8K<Ë:K<c              ƒ   óB  K  — t        |d«      ƒ d {  –—† }|�|j                  €y |j                  }t        |t        «      rt	        j
                  |«      n|}t        |t        «      sy |j                  «       D ]  \  }}|t        v sŒt        t        ||«       Œ! y 7 ŒŠ­w)NrT  )rd  rU  rÓ  r‚  rm  r„  rÔ  râ  r1   rd  r  )rp  r÷  Úconfig_recordrª  rT  rz  r*  s          rˆ   rÃ  z:ProxyConfig._apply_safe_litellm_settings_overrides_from_dbÊ  s–   è ø€ Ü%5°mÐEWÓ%X×XˆØÐ  M×$=Ñ$=Ð$EØØ+×7Ñ7ˆÜ>HÈÔWZÔ>[¤$§*¡*¨\Ô":ÐamÐÜÐ*¬DÔ1ØØ*×0Ñ0Ó2ò 	-‰JˆC�ØÔ8Ò8Üœ  eÕ,ñ	-ð  Yús   ‚B’B“A5BÂ	Bc              ƒ   óö  K  — ddl }ddl}ddlm} 	 t	        |d«      ƒ d{  –—† }|�|j
                  €y|j
                  }t        |t        «      r |j                  |«      }|j                  dd«      }|€yt        | d«      r�| j                  |k(  r€|j                  j                  |«      }|rN|D ]I  }	t        |	|«      sŒ|	j                  €Œ|	j                  j                  €Œ4t!        j"                  d«        y t!        j$                  d«       |j                  j'                  |j(                  |«       |j                  d	d
«      rR|j+                  |t,        ¬«      ƒ d{  –—† }
|
rF|j                  j/                  |
«       t!        j$                  d«       nt!        j$                  d«       |j1                  «       | _        y7 �Œ§7 Œe# t2        $ r }t!        j4                  d|«       Y d}~yd}~ww xY w­w)zÀ
        Initialize MCP semantic filter settings from database.
        Called periodically (approximately every 10 seconds) by background task to hot-reload settings across all pods.
        r   N©ÚSemanticToolFilterHookrT  Úmcp_semantic_tool_filterr_  z=Semantic filter settings unchanged, skipping reinitializationzYSemantic filter settings unchanged, but hook is missing or uninitialized. Reinitializing.r»  F©r^  rU  z)MCP Semantic Filter reinitialized from DBzMCP Semantic Filter disabledz7Error initializing semantic filter settings from DB: %s)rm  r  Ú'litellm.proxy.hooks.mcp_semantic_filterrÈ  rd  rU  rÓ  r‚  r„  rp  r¬  r_  rX  Úget_custom_loggers_for_typeÚfilterÚtool_routerrŸ   r
  r  Úremove_callbacks_by_typerà  Úinitialize_from_configrU  rY  rÆ  rÿ  r   )rp  r÷  rm  r  rÈ  rÅ  rT  Úmcp_semantic_filter_configÚactive_hooksÚactive_hookÚhookr  s               rˆ   rÀ  z0ProxyConfig._init_semantic_filter_settings_in_dbÖ  së  è ø€ ó
 	ãÝRð4	iÜ)9¸-ÐI[Ó)\×#\ˆMàÐ$¨×(AÑ(AÐ(IØà,×8Ñ8ÐÜÐ*¬CÔ0Ø#- 4§:¡:Ð.>Ó#?Ð à0@×0DÑ0DÐE_ÐaeÓ0fÐ&à)Ð1Øô �tÐ;Ô<Ø×4Ñ4Ð8RÒRà#*×#CÑ#C×#_Ñ#_Ð`vÓ#w�LÙ#Ø+7ò +˜KÜ)¨+Ð7MÕNØ#.×#5Ñ#5Ñ#AÀk×FXÑFX×FdÑFdÑFpÜ$8×$>Ñ$>Ø(gô%&ñ %+ð+ô )×-Ñ-Øsôð
 ×,Ñ,×EÑEÀg×FWÑFWÐYoÔpð *×-Ñ-¨i¸Ô?à$:×$QÑ$QØ5Ü)ð %Ró %÷ �ñ Ø×4Ñ4×IÑIÈ$ÔOÜ(×-Ñ-Ð.YÕZä$×)Ñ)Ð*HÔIð 1K×0OÑ0OÓ0QˆDÕ-ða $]ùðJùô ò 	iÜ ×*Ñ*Ð+dÐfg×hÑhûð	iüsˆ   ‚G9’G ¡G¢G ´G9µAG Á7G9Á8A	G ÃG ÃG Ã&G Ã<G9Ã=A(G Å%GÅ&A!G ÇG9ÇG ÇG Ç	G6ÇG1Ç,G9Ç1G6Ç6G9c              ƒ   ó  ‡K  — 	 t        dt        ‰ˆfd„d¬«      ƒ d{  –—† «      }|�¢|j                  j                  dd«       |j                  j                  dd«       |j                  j                  dd«       |j                  j	                  «       D ��ci c]  \  }}|j                  «       |“Œ }}}| j                  |¬	«       yy7 Œ­c c}}w # t        $ r }t        j                  d
|«       Y d}~yd}~ww xY w­w)zS
        Initialize SSO settings from database into the router on startup.
        z_SSOConfigRow | Nonec                  óR   •— t        ‰ «      j                  j                  ddi¬«      S )Nr.  Ú
sso_configr�  )ÚSSOConfigRepositoryrH  Úfind_uniquer‘  s   €rˆ   rü  z6ProxyConfig._init_sso_settings_in_db.<locals>.<lambda>   s(   ø€ Ô/°Ó>×DÑD×PÑPÐX\Ð^jÐWkÐPÓl€ rŠ   Ú&init_sso_settings_in_db_lookup_failure©ÚreasonNÚrole_mappingsÚteam_mappingsr3  rƒ  zHlitellm.proxy.proxy_server.py::ProxyConfig:_init_sso_settings_in_db - %s)
r   r  r[  r‡  râ  r|  r   rÿ  rŸ   r   )rp  r÷  r[  rz  r*  Úuppercase_sso_settingsr  s    `     rˆ   r½  z$ProxyConfig._init_sso_settings_in_db  sö   øè ø€ ð
	Ü8<Ø&Ü2Ø!ÛlØCô÷ ó9ˆLð Ð'Ø×)Ñ)×-Ñ-¨o¸tÔDØ×)Ñ)×-Ñ-¨o¸tÔDØ×)Ñ)×-Ñ-Ð.>ÀÔEØVb×VoÑVo×VuÑVuÓVw×0xÉ
ÈÈU°·±³¸eÑ1CÐ0xÐ&Ñ0xØ×6Ñ6ÐMcÐ6Õdð (ðúó 1yøäò 	Ü ×*Ñ*ØZÐ\]÷ñ ûð	üsQ   ƒD…C ŸC
 A;C ÂCÂ6C ÃDÃC ÃC Ã	C>ÃC9Ã4DÃ9C>Ã>Dc              ƒ   óR  ‡K  — ddl m}m}m}m}m} 	 t        dt        ‰ˆfd„d¬«      ƒ d{  –—† «      }|�|j                  €| j                  � || «       y ||j                  «      }| j                  |k(  ry| j                  |«      }	 ||«      }
 ||	«       	 | j                  d¬	«       |j                  «       | _	        t        j                  d
«       y7 Œ¬# t        $ r
  ||
«       ‚ w xY w# t        $ r)}t        j                   dt#        |«      «       Y d}~yd}~ww xY w­w)zû
        Load Hashicorp Vault config override from DB.
        Decrypts sensitive fields, sets HCP_VAULT_* env vars, and reinitializes the secret manager.
        Called periodically via _init_non_llm_objects_in_db to sync config across pods.
        r   )ÚHASHICORP_ENV_VAR_MAPPINGÚ_clear_hashicorp_vault_stateÚ_get_current_env_valuesÚ_parse_config_valueÚ_set_env_varsú_ConfigOverridesRow | Nonec                  óR   •— t        ‰ «      j                  j                  ddi¬«      S )NÚconfig_typeÚhashicorp_vaultr�  ©ÚConfigOverridesRepositoryrH  rÙ  r‘  s   €rˆ   rü  zCProxyConfig._init_hashicorp_vault_config_override.<locals>.<lambda>B  s-   ø€ Ô5°mÓD×JÑJ×VÑVØ,Ð.?Ð@ð Wó € rŠ   Ú3init_hashicorp_vault_config_override_lookup_failurerÛ  Nré  ©r¤  z.Hashicorp Vault config override loaded from DBz9Error loading Hashicorp Vault config override from DB: %s)Ú<litellm.proxy.management_endpoints.config_override_endpointsrá  râ  rã  rä  rå  r   r  rX  r`  r$  r¨  rÿ  rÆ  rŸ   r
  r   r‚  )rp  r÷  rá  râ  rã  rä  rå  Ú	db_recordr  Údecrypted_dataÚprevious_envr  s    `          rˆ   rÁ  z1ProxyConfig._init_hashicorp_vault_config_override/  s:  øè ø€ ÷	
õ 	
ð,	Ü;?Ø,Ü2Ø!óð Qô÷ ó	<ˆIð Ð  I×$:Ñ$:Ð$BØ×4Ñ4Ð@Ù0°Ô6Øá!4°Y×5KÑ5KÓ!LˆKð ×0Ñ0°KÒ?Øð %)×$>Ñ$>¸{Ó$KˆNñ #:Ð:SÓ"TˆLÙ˜.Ô)ðØ×.Ñ.ÐEVÐ.ÔWð 1<×0@Ñ0@Ó0BˆDÔ-Ü ×&Ñ&Ð'WÕXðIùô< ò á˜lÔ+Øðûô ò 	Ü ×*Ñ*ØKÜ�A“÷ñ ûð	üsn   ƒD'“C2 ­C
®*C2 ÁD'Á!C2 Á:D'Á;!C2 ÂC Â/*C2 ÃD'ÃC2 ÃC/Ã/C2 Ã2	D$Ã;DÄD'ÄD$Ä$D'c              ƒ   ój  ‡K  — ddl m}m}m}m}m}m} 	 t        dt        ‰ˆfd„d¬«      ƒ d{  –—† «      }|�|j                  €| j                  � || «       y ||j                  «      }	| j                  |	k(  ry| j                  |	«      }
 || «        ||«      } ||
|«       	 | j                  d¬	«       |	j                  «       | _
        t        j                   d
«       y7 Œµ# t        $ r  |||«       ‚ w xY w# t        $ r)}t        j"                  dt%        |«      «       Y d}~yd}~ww xY w­w)zú
        Load CyberArk Conjur config override from DB.
        Decrypts sensitive fields, sets CYBERARK_* env vars, and reinitializes the secret manager.
        Called periodically via _init_non_llm_objects_in_db to sync config across pods.
        r   )ÚCYBERARK_ENV_VAR_MAPPINGÚ_clear_cyberark_staterã  rä  rå  Ú_snapshot_cyberark_boot_envræ  c                  óR   •— t        ‰ «      j                  j                  ddi¬«      S )Nrè  Úcyberarkr�  rê  r‘  s   €rˆ   rü  z<ProxyConfig._init_cyberark_config_override.<locals>.<lambda>  s,   ø€ Ô5°mÓD×JÑJ×VÑVØ,¨jÐ9ð Wó € rŠ   Ú,init_cyberark_config_override_lookup_failurerÛ  Nr÷  rí  z'CyberArk config override loaded from DBz2Error loading CyberArk config override from DB: %s)rî  ró  rô  rã  rä  rå  rõ  r   r  rX  ra  r$  r¨  rÿ  rÆ  rŸ   r
  r   r‚  )rp  r÷  ró  rô  rã  rä  rå  rõ  rï  r  rð  rñ  r  s    `           rˆ   rÂ  z*ProxyConfig._init_cyberark_config_overridek  sC  øè ø€ ÷	
÷ 	
ð)	Ü;?Ø,Ü2Ø!óð Jô÷ ó	<ˆIð Ð  I×$:Ñ$:Ð$BØ×-Ñ-Ð9Ù)¨$Ô/Øá!4°Y×5KÑ5KÓ!LˆKð ×)Ñ)¨[Ò8Øà$(×$>Ñ$>¸{Ó$KˆNá'¨Ô-Ù"9Ð:RÓ"SˆLÙ˜.Ð*BÔCðØ×.Ñ.ÀZÐ.ÔPð
 *5×)9Ñ)9Ó);ˆDÔ&Ü ×&Ñ&Ð'PÕQðCùô8 ò Ù˜lÐ,DÔEØðûô ò 	Ü ×*Ñ*ØDÜ�A“÷ñ ûð	üsn   ƒD3•C> ¯C%
°*C> ÁD3Á!C> Á<D3Á=*C> Â(C' Â:*C> Ã$D3Ã%C> Ã'C;Ã;C> Ã>	D0ÄD+Ä&D3Ä+D0Ä0D3c              ƒ   ój   K  — | j                  d¬«      r| j                  |¬«      ƒ d{  –—†  yy7 Œ­w)zÔ
        Run the admin-configured periodic model cost map reload.

        Scheduled on its own job so a schedule configured from the Admin UI fires whether
        or not `store_model_in_db` is enabled.
        rN  r„  r‘  N)r…  Ú _check_and_reload_model_cost_map)rp  r÷  s     rˆ   Úcheck_periodic_reloadsz"ProxyConfig.check_periodic_reloads¥  s:   è ø€ ð ×&Ñ&Ð3CÐ&ÔDØ×7Ñ7ÀmÐ7ÓT×TÑTð EØTús   ‚(3ª1«3c              ƒ   ój  K  — 	 t        |t        «      ƒ d{  –—† }|€yt        «       }t        || j                  | j
                  |d¬«      }|syddlm}m}  |t        j                  ¬«      ƒ d{  –—† }t        ||«      r!t        j                  d|j                  «       yt        |j                   «      }|| _        t#        |t        |«      ƒ d{  –—†  |j$                  | _        t        j&                  d|«       y7 Œé7 Œ�7 Œ0# t(        $ r }	t        j*                  d	|	«       Y d}	~	yd}	~	ww xY w­w)
z®
        Check if model cost map needs to be reloaded based on database configuration.
        Runs on the periodic reload job, independently of `store_model_in_db`.
        NzModel cost map)ÚscheduleÚpod_applied_revisionÚpod_data_loaded_atÚcurrent_timerô  r   ©ÚModelCostMapReloadUnavailableÚrefetch_model_cost_mapr  z‚Model cost map reload failed (%s); keeping current pricing data. The revision stays unapplied so this pod retries on its next pollz6Model cost map reloaded successfully. Models count: %sz-Error in _check_and_reload_model_cost_map: %s)rý   rú   r  rü   rh  rg  rf  r	  r	  r  Úmodel_cost_map_urlrÓ  rŸ   r/  rÜ  rR  rN  rÿ   Úreload_revisionr  rÿ  r   )
rp  r÷  rý  r 	  Úis_duer	  r	  Úreload_resultÚmodels_countr  s
             rˆ   rú  z,ProxyConfig._check_and_reload_model_cost_map¯  s+  è ø€ ð
)	_Ü1°-ÔAaÓb×bˆHØÐØä"›9ˆLÜ&Ø!Ø%)×%IÑ%IØ#'×#@Ñ#@Ø)Ø,ôˆFñ Ø÷ñ
 #9¼W×=WÑ=WÔ"X×XˆMÜ˜-Ð)FÔGÜ$×,Ñ,ðEà!×(Ñ(ôð
 ä2°=×3OÑ3OÓPˆLØ,8ˆDÔ)Ü# MÔ3SÐUaÓb×bÐbð 4<×3KÑ3KˆDÔ0ä ×%Ñ%Ð&^Ð`lÕmðK cøð( Yøð cùô ò 	_Ü ×*Ñ*Ð+ZÐ\]×^Ñ^ûð	_üs„   ‚D3„D —D˜D žD3Ÿ0D ÁD3Á"D Á2DÁ30D Â#D3Â$0D ÃDÃ+D Ä D3ÄD ÄD ÄD Ä	D0ÄD+Ä&D3Ä+D0Ä0D3c           
   ƒ   ó"  K  — 	 t        |d«      ƒ d{  –—† }|�|j                  €y|j                  }|j                  d«      }|j                  dd«      }|€|du ryt        j                  «       }d}|rd}t        j                  d«       nu|�st        �V	 t        j                  t        «      }||z
  }	|	j                  «       dz  }
|
|k\  rd}t        j                  d	|
d
›d|› �«       nd}t        j                  d«       |r©ddlm}  |«       }|j                  «       at        |«      j                   j#                  ddidt%        |ddœ«      dœdt%        |ddœ«      idœ¬«      ƒ d{  –—†  t'        d«      ƒ d{  –—†  t)        d„ |D «       «      }t        j                  d|«       yy7 �Œ›# t        $ r"}t        j                  d|«       d}Y d}~ŒÕd}~ww xY w7 Œr7 Œa# t        $ r }t        j*                  d|«       Y d}~yd}~ww xY w­w)zÂ
        Check if anthropic beta headers config needs to be reloaded based on database configuration.
        This function runs every 10 seconds as part of _init_non_llm_objects_in_db.
        r�  NÚinterval_hoursÚforce_reloadFTz<Anthropic beta headers reload triggered by force reload flagr+  zNAnthropic beta headers reload triggered by interval. Hours since last reload: ri  z, Interval: ú"Error parsing last reload time: %szJAnthropic beta headers reload triggered - no previous reload time recordedr   ©Úreload_beta_headers_configrT  ©r
	  r	  r‘  rU  r’  r”  c              3   ó8   K  — | ]  }|d k7  sŒ	|dk7  sŒd–— Œ y­w)Úprovider_aliasesrô  r8  Nrè  ©r’  rF  s     rˆ   r”  zGProxyConfig._check_and_reload_anthropic_beta_headers.<locals>.<genexpr>8  s!   è ø€ Ò$m¨1¸aÐCUÓ>UÐZ[Ð_lÓZl¤QÑ$mùs   ‚
�“zBAnthropic beta headers config reloaded successfully. Providers: %sz5Error in _check_and_reload_anthropic_beta_headers: %s)rd  rU  rp  r
   ÚutcnowrŸ   r  Ú"last_anthropic_beta_headers_reloadÚfromisoformatÚtotal_secondsrÿ  r/  Ú&litellm.anthropic_beta_headers_managerr	  Ú	isoformatrv  rH  r–  r5   rc  r£  r   )rp  r÷  rÅ  r^  r
	  r	  r 	  Úshould_reloadÚlast_reload_timeÚtime_since_last_reloadÚhours_since_last_reloadr  r	  r  Úprovider_counts                  rˆ   r¼  z4ProxyConfig._check_and_reload_anthropic_beta_headersß  s}  è ø€ ð
Z	gä)9¸-ÐIoÓ)p×#pˆMàÐ$¨×(AÑ(AÐ(IØà)×5Ñ5ˆFØ$*§J¡JÐ/?Ó$@ˆNØ"(§*¡*¨^¸UÓ"CˆLàÐ%¨,¸%Ñ*?Øä"*§/¡/Ó"3ˆLð "ˆMáØ $�Ü$×)Ñ)Ð*hÕiØÐ+ô 6ÐAð-Ü2:×2HÑ2HÔIkÓ2lÐ(Ø8DÐGWÑ8WÐ.Ø9O×9]Ñ9]Ó9_ÐbfÑ9fÐ/à2°nÒDØ,0˜MÜ0×5Ñ5Ø"pð  rIð  JMð  qNð  NZð  [ið  Zjð  !kôøð %)�MÜ(×-Ñ-Ødôñ õñ %?Ó$@�
ð 6B×5KÑ5KÓ5MÐ2ô ' }Ó5×;Ñ;×BÑBØ'Ð)OÐPð +QÜ+5à6DØ49ñ!"ó,ñ#ð *¬:à6DØ49ñ!"ó,ð#ñð Có ÷ ð ô, )Ð)OÓP×PÐPô "%Ñ$m°
Ô$mÓ!m�Ü$×)Ñ)ØXÐZhõðM ð[ $qúôD %ò -Ü,×4Ñ4Ð5YÐ[\Ô]à(,�ûð-úð.øð, Qùô ò 	gÜ ×*Ñ*Ð+bÐde×fÑfûð	güsž   ‚H„G# “F.”G# ¦H§5G# ÁHÁ8G# ÂAF1 Ã*BG# Å,GÅ-G# Å?G!Æ ,G# Æ,HÆ.G# Æ1	GÆ:GÇG# ÇGÇG# Ç!G# Ç#	HÇ,HÈHÈHÈHc                 ó    — ddl m}  ||¬«      S )a5  
        Convert a DB prompt object to a PromptSpec object.

        Handles the versioning of the prompt, if the DB prompt has a version, it will be used to create the versioned prompt_id.

        Args:
            db_prompt: The DB prompt object

        Returns:
            The PromptSpec object
        r   )Úcreate_versioned_prompt_spec©Ú	db_prompt)Ú&litellm.proxy.prompts.prompt_endpointsr	  )rp  r!	  r	  s      rˆ   Ú_get_prompt_spec_for_db_promptz*ProxyConfig._get_prompt_spec_for_db_prompt@  s   € õ 	Xá+°iÔ@Ð@rŠ   c              ƒ   ó  ‡ ‡‡‡‡‡K  — ddl mŠ ddlm} dt        d|d z  fˆ fd„Š	 t        ‰j                  «      }t        |«      j                  j                  «       ƒ d {  –—† }t        ˆˆfd„|D «       «      }t        t        |d„ ¬	«      D �ci c]  }|j                  |“Œ c}«      Š‰j                  «       D ]  }	 ‰j                  |¬
«       Œ t'        |«      t'        |«      k(  }	|	r0t        ˆˆˆfd„|D «       «      }
|
D ]  }‰j)                  |¬«       Œ y y 7 Œ»c c}w # t         $ r+}t#        j$                  d|j                  |«       Y d }~Œ˜d }~ww xY w# t         $ r }t#        j*                  d|«       Y d }~y d }~ww xY w­w)Nr   )ÚIN_MEMORY_PROMPT_REGISTRY)Ú
PromptSpecr!	  rÐ  c           	      óš   •— 	 ‰j                  | ¬«      S # t        $ r,}t        j                  dt	        | dd «      |«       Y d }~y d }~ww xY w)Nr 	  zblitellm.proxy.proxy_server.py::ProxyConfig:_init_prompts_in_db - failed to parse prompt row %s: %sÚ	prompt_id)r#	  rÿ  rŸ   r   rw  )r!	  Ú	row_errorrp  s     €rˆ   Ú	parse_rowz2ProxyConfig._init_prompts_in_db.<locals>.parse_rowT  sQ   ø€ ðØ×:Ñ:ÀYÐ:ÓOÐOøÜò Ü$×.Ñ.ØxÜ˜I {°DÓ9Øôô
 ûðús   ƒ •	A
ž"AÁA
c              3   ó8   •K  — | ]  } ‰|«      xŠ€Œ‰–— Œ y ­wrn  rè  )r’  r—  r*	  Úspecs     €€rˆ   r”  z2ProxyConfig._init_prompts_in_db.<locals>.<genexpr>b  s&   øè ø€ ò @Ø¹)ÀC».Ð2H°$Ñ1U”ñ@ùs   ƒ“c                 ód   — | j                   r| j                   j                  «       S t        d«      S )Nú-inf)rå  Ú	timestampr   )r”  s    rˆ   rü  z1ProxyConfig._init_prompts_in_db.<locals>.<lambda>j  s$   € À!Ç,Â, a§l¡l×&<Ñ&<Ó&>€ ÔTYÐZ`ÓTa€ rŠ   ry  )Úpromptz]litellm.proxy.proxy_server.py::ProxyConfig:_init_prompts_in_db - failed to sync prompt %s: %sc              3   ó–   •K  — | ]@  }‰j                   j                  |«      xŠ�!‰j                  j                  dk(  r|‰vr|–— ŒB y ­w)Nri  )ÚIN_MEMORY_PROMPTSrp  Úprompt_infoÚprompt_type)r’  r(	  r%	  Úloaded_specÚnewest_spec_per_ids     €€€rˆ   r”  z2ProxyConfig._init_prompts_in_db.<locals>.<genexpr>z  sS   øè ø€ ò 5à!Ø'@×'RÑ'R×'VÑ'VÐW`Ó'aÐa˜ÐnØ#×/Ñ/×;Ñ;¸tÒCØ!Ð);Ñ;ô	 ñ5ùs   ƒAA	)r(	  zClitellm.proxy.proxy_server.py::ProxyConfig:_init_prompts_in_db - %s)Ú%litellm.proxy.prompts.prompt_registryr%	  Ú"litellm.types.prompts.init_promptsr&	  r\  r@  r2	  ÚPromptRepositoryrH  r‰  rŒ  r   rÆ  r(	  r¢  Úsync_prompt_from_dbrÿ  rŸ   r   rÈ  Úremove_promptr
  )rp  r÷  r&	  Ú prompt_ids_loaded_before_db_readÚprompts_in_dbÚparsed_specsr,	  Úprompt_specÚprompt_sync_errorÚevery_row_parsedÚdeleted_db_prompt_idsÚdeleted_prompt_idr  r%	  r5	  r6	  r*	  s   `     `      @@@@rˆ   r¹  zProxyConfig._init_prompts_in_dbP  s¡  ýè ø€ ÝSÝAð		¤ð 		¨J¸Ñ,=õ 		ð%	qÜ6?Ð@Y×@kÑ@kÓ6lÐ,Ü;KÈMÓ;Z×;`Ñ;`×;jÑ;jÓ;l×5lˆMÜ:?ô @Ø -ô@ó ;ˆLô CSô !'Ø$Ùaô!öàð —N‘N DÑ(òóCÐð  2×8Ñ8Ó:ò �ðØ-×AÑAÈÐAÕUðô '*¨,Ó&7¼3¸}Ó;MÑ&MÐÙÜ/4õ 5à%Eô5ó 0Ð%ð *?ò YÐ%Ø-×;Ñ;ÐFWÐ;ÕXñYð  ð1 6múò
øô !ò Ü(×2Ñ2ØwØ#×-Ñ-Ø)÷ñ ûðûô$ ò 	qÜ ×&Ñ&Ð'lÐno×pÑpûð	qüs}   ˆF§;E Á"DÁ#.E ÂD Â%E Ã D%ÃA
E ÄFÄE Ä E Ä%	EÄ.!EÅE ÅEÅE Å	FÅ%F Å;FÆ FÆFc              ƒ   óÆ  K  — ddl m}m}m}m} 	 |4 ƒd {  –—†  |j                  |¬«      ƒ d {  –—† }t        j                  dt        |«      «       t        «       }|D ]C  }|j                  d«      }	|	r|j                  |	«       	 |j                  t        ||«      ¬«       ŒE |j%                  |¬	«       d d d «      ƒd {  –—†  y 7 Œ²7 Œš# t        $ rE}
t        j                  d|j                  d«      |	t!        |
«      j"                  |
«       Y d }
~
Œ¶d }
~
ww xY w7 ŒZ# 1 ƒd {  –—†7  sw Y   y xY w# t        $ r }
t        j&                  d
|
«       Y d }
~
y d }
~
ww xY w­w)Nr   )ÚGUARDRAIL_RECONCILE_LOCKÚIN_MEMORY_GUARDRAIL_HANDLERÚ	GuardrailÚGuardrailRegistryr‘  zguardrails from the DB %sÚguardrail_id)ré  zllitellm.proxy.proxy_server.py::ProxyConfig:_init_guardrails_in_db - skipping guardrail '%s' (ID: %s): %s: %sÚguardrail_name)Údb_guardrail_idszFlitellm.proxy.proxy_server.py::ProxyConfig:_init_guardrails_in_db - %s)Ú+litellm.proxy.guardrails.guardrail_registryrE	  rF	  rG	  rH	  Úget_all_guardrails_from_dbrŸ   r
  r‚  rð  rp  rä  Úsync_guardrail_from_dbr   rÿ  rz  rw   r   Úreconcile_db_guardrailsr   )rp  r÷  rE	  rF	  rG	  rH	  Úguardrails_in_dbrK	  ré  rI	  r  s              rˆ   r²  z"ProxyConfig._init_guardrails_in_db†  sp  è ø€ ÷	
ó 	
ð	xØ/÷ gñ gØAR×AmÑAmØ"/ð Bnó B÷ <Ð ô %×*Ñ*Ð+FÌÐL\ÓH]Ô^Ü/2«uÐ Ø!1ò �IØ#,§=¡=°Ó#@�LÙ#Ø(×,Ñ,¨\Ô:ðØ3×JÑJÜ&*¨9°iÓ&@ð Kõ ðð( ,×CÑCÐUeÐCÔf÷5g÷ gñ gøð<ùô %ò Ü,×2Ñ2ðGà%ŸM™MÐ*:Ó;Ø(Ü  ›G×,Ñ,Ø÷ñ ûðúðgø÷ g÷ gñ gûô6 ò 	xÜ ×*Ñ*Ð+sÐuv×wÑwûð	xüsº   ‚E!�D5 –C	—D5 šD °C±AD ÂCÂ$D Â8D5 ÃDÃD5 ÃE!Ã	D5 ÃD Ã	DÃ;DÄD ÄDÄD ÄD5 Ä D2Ä&D)Ä'D2Ä.D5 Ä1E!Ä2D5 Ä5	EÄ>EÅE!ÅEÅE!c              ƒ   ó4  K  — ddl m} ddlm} 	  |«       } |«       }|j	                  |¬«      ƒ d{  –—†  |j                  |¬«      ƒ d{  –—†  t        j                  d«       y7 Œ47 Œ# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)zi
        Initialize policies and policy attachments from database into the in-memory registries.
        r   )Úget_attachment_registry)Úget_policy_registryr‘  Nz4Successfully synced policies and attachments from DBzDlitellm.proxy.proxy_server.py::ProxyConfig:_init_policies_in_db - %s)
Ú/litellm.proxy.policy_engine.attachment_registryrR	  Ú+litellm.proxy.policy_engine.policy_registryrS	  Úsync_policies_from_dbÚsync_attachments_from_dbrŸ   r
  rÿ  r   )rp  r÷  rR	  rS	  Úpolicy_registryÚattachment_registryr  s          rˆ   r³  z ProxyConfig._init_policies_in_db­  sž   è ø€ õ	
õ 	Tð	vá%8Ó%:ˆOÙ)@Ó)BÐð "×7Ñ7ÀmÐ7ÓT×TÐTð &×>Ñ>È]Ð>Ó[×[Ð[ä ×&Ñ&Ð']Õ^ð Uøð \ùô ò 	vÜ ×*Ñ*Ð+qÐst×uÑuûð	vüsP   ‚B�#A, ³A(´A, ÁA*ÁA, Á'BÁ(A, Á*A, Á,	BÁ5BÂBÂBÂBc              ƒ   óâ   K  — ddl m} 	  |«       }|j                  |¬«      ƒ d{  –—†  t        j                  d«       y7 Œ# t
        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)z¡
        Initialize tool policy from database into the in-memory registry.
        Synced periodically by add_deployment -> _init_non_llm_objects_in_db.
        r   )Úget_tool_policy_registryr‘  Nz'Successfully synced tool policy from DBzGlitellm.proxy.proxy_server.py::ProxyConfig:_init_tool_policy_in_db - %s)Ú%litellm.proxy.db.tool_registry_writerr[	  Úsync_tool_policy_from_dbrŸ   r
  rÿ  r   )rp  r÷  r[	  Úregistryr  s        rˆ   r»  z#ProxyConfig._init_tool_policy_in_dbÅ  sl   è ø€ õ
 	Sð	yÙ6Ó8ˆHØ×3Ñ3À-Ð3ÓP×PÐPÜ ×&Ñ&Ð'PÕQð Qùäò 	yÜ ×*Ñ*Ð+tÐvw×xÑxûð	yüs>   ‚A/ŠA ¦A§A Á A/ÁA Á	A,ÁA'Á"A/Á'A,Á,A/c              ƒ   ó\  K  — ddl m} 	 |j                  |¬«      ƒ d {  –—† }t        |«      dk  ry t        j
                  € ||¬«      t        _        y |D ]"  }t        j
                  j                  |¬«       Œ$ y 7 Œ^# t        $ r }t        j                  d|«       Y d }~y d }~ww xY w­w)Nr   r¢  r‘  )r©  )Úvector_storeúIlitellm.proxy.proxy_server.py::ProxyConfig:_init_vector_stores_in_db - %s)
r©  r£  Ú_get_vector_stores_from_dbrÈ  r  r¡  Úadd_vector_store_to_registryrÿ  rŸ   r   )rp  r÷  r£  r©  r`	  r  s         rˆ   r´  z%ProxyConfig._init_vector_stores_in_dbÓ  s¨   è ø€ ÝSð	à)<×)WÑ)WÐfsÐ)WÓ)t×#tˆMÜ�=Ó! QÒ&Øä×,Ñ,Ð4Ù0CÐR_Ô0`”Õ-à$1ò j�LÜ×1Ñ1×NÑNÐ\hÐNÕiñjð $uùô ò 	Ü ×*Ñ*Ø[Ð]^÷ñ ûð	üóT   ‚B,ŠB  ŸA> B  ²B,³"B  ÁB,Á'B  Á=B,Á>B  Â 	B)Â	B$ÂB,Â$B)Â)B,c              ƒ   ó\  K  — ddl m} 	 |j                  |¬«      ƒ d {  –—† }t        |«      dk  ry t        j
                  € ||¬«      t        _        y |D ]"  }t        j
                  j                  |¬«       Œ$ y 7 Œ^# t        $ r }t        j                  d|«       Y d }~y d }~ww xY w­w)Nr   )ÚVectorStoreIndexRegistryr‘  )rª  )Úvector_store_indexra	  )
r©  rf	  Ú!_get_vector_store_indexes_from_dbrÈ  r  Úvector_store_index_registryÚupsert_vector_store_indexrÿ  rŸ   r   )rp  r÷  rf	  rª  rg	  r  s         rˆ   rµ  z,ProxyConfig._init_vector_store_indexes_in_dbæ  s·   è ø€ ÝXð	à0H×0jÑ0jØ+ð 1kó 1÷ +Ð ô Ð'Ó(¨AÒ-Øä×2Ñ2Ð:Ù6NØ)=ô7”Õ3ð +?ò yÐ&Ü×7Ñ7×QÑQÐewÐQÕxñyð+ùô ò 	Ü ×*Ñ*Ø[Ð]^÷ñ ûð	ürd	  c              ƒ   ó(  K  — ddl m}  |«       st        j                  d«       y ddlm} ddlm} ddlm	} 	 t        � |t        «      ƒ d {  –—†  	 t        � |t        «      ƒ d {  –—†  	 |j                  «       ƒ d {  –—†  y 7 Œ9# t        $ r }t        j                  d|«       Y d }~Œ[d }~ww xY w7 ŒL# t        $ r }t        j                  d|«       Y d }~Œnd }~ww xY w7 Œa# t        $ r }t        j                  d	|«       Y d }~y d }~ww xY w­w)
Nr   ©Úis_mcp_availablez<MCP module not available, skipping MCP server initializationrž  )Úbackfill_null_oauth2_flows)Ú"backfill_discovery_stamped_issuerszPlitellm.proxy.proxy_server.py::ProxyConfig:_init_mcp_servers_in_db backfill - %sz]litellm.proxy.proxy_server.py::ProxyConfig:_init_mcp_servers_in_db issuer stamp backfill - %szGlitellm.proxy.proxy_server.py::ProxyConfig:_init_mcp_servers_in_db - %s)Ú,litellm.proxy._experimental.mcp_server.utilsrm	  rŸ   r
  r§  rŸ  Ú;litellm.proxy._experimental.mcp_server.oauth2_flow_backfillrn	  ÚBlitellm.proxy._experimental.mcp_server.oauth_issuer_stamp_backfillro	  r÷  rÿ  r   Úreload_servers_from_database)rp  rm	  rŸ  rn	  ro	  r  s         rˆ   r¶  z#ProxyConfig._init_mcp_servers_in_dbþ  s  è ø€ ÝQáÔ!Ü ×&Ñ&Ð'eÔfØõ	
õ	
õ	
ð	ÜÐ(Ù0´Ó?×?Ð?ð	ÜÐ(Ù8¼ÓG×GÐGð	yØ+×HÑHÓJ×JÑJð @ùÜò 	Ü ×*Ñ*ØbÐde÷ñ ûð	úð HùÜò 	Ü ×*Ñ*ØoÐqr÷ñ ûð	úð KùÜò 	yÜ ×*Ñ*Ð+tÐvw×xÑxûð	yüs¬   ‚6D¹B
 ÁBÁB
 ÁB8 Á)B6Á*B8 Á/C& ÂC$ÂC& ÂDÂB
 Â
	B3ÂB.Â)DÂ.B3Â3DÂ6B8 Â8	C!ÃCÃDÃC!Ã!DÃ$C& Ã&	DÃ/D
ÄDÄ
DÄDc              ƒ   óf   K  — | j                  d¬«      r| j                  «       ƒ d {  –—†  y y 7 Œ­w)Nr«  r„  )r…  r¶  ro  s    rˆ   Úinit_mcp_servers_from_dbz$ProxyConfig.init_mcp_servers_from_db$  s1   è ø€ Ø×&Ñ&°5Ð&Ô9Ø×.Ñ.Ó0×0Ñ0ð :Ø0ús   ‚&1¨/©1c              ƒ   óè   K  — | j                  d¬«      syddlm}  |«       syddlm} 	 |j                  «       ƒ d{  –—†  y7 Œ# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)aÓ  Registry refresh only, for the periodic job in store_model_in_db-off deployments.

        Deliberately narrower than ``init_mcp_servers_from_db``: the oauth2_flow backfill is a write
        path that only needs to run once at startup, so the cadence here is purely the read-side
        reload whose fast-path exemption retries failed OAuth discovery. Gated the same way, so an
        admin who excluded mcp from supported_db_objects opts out of this too.
        r«  r„  Nr   rl	  rž  zJlitellm.proxy.proxy_server.py::ProxyConfig:reload_mcp_servers_from_db - %s)	r…  rp	  rm	  r§  rŸ  rs	  rÿ  rŸ   r   )rp  rm	  rŸ  r  s       rˆ   Úreload_mcp_servers_from_dbz&ProxyConfig.reload_mcp_servers_from_db(  sl   è ø€ ð ×*Ñ*°uÐ*Ô=ØÝQáÔ!Øõ	
ð	Ø+×HÑHÓJ×JÒJùÜò 	Ü ×*Ñ*Ø\Ð^_÷ñ ûð	üs>   ‚(A2«A ¾A¿A ÁA2ÁA Á	A/ÁA*Á%A2Á*A/Á/A2c              ƒ   óB  K  — ddl m} ddl m} 	 |4 ƒd {  –—†  |j                  |¬«      ƒ d {  –—† }|j	                  |¬«       d d d «      ƒd {  –—†  y 7 ŒA7 Œ)7 Œ	# 1 ƒd {  –—†7  sw Y   y xY w# t
        $ r }t        j                  d|«       Y d }~y d }~ww xY w­w)Nr   )ÚAGENT_RECONCILE_LOCKrœ  r‘  )Ú	db_agentszBlitellm.proxy.proxy_server.py::ProxyConfig:_init_agents_in_db - %s)rK  ry	  rF  Úget_all_agents_from_dbÚload_agents_from_db_and_configrÿ  rŸ   r   )rp  r÷  ry	  ÚAGENT_REGISTRYrz	  r  s         rˆ   r·  zProxyConfig._init_agents_in_dbA  s¥   è ø€ õ	
õ	
ð	tØ+÷ Sñ SØ)7×)NÑ)NÐ]jÐ)NÓ)k×#k�	Ø×=Ñ=È	Ð=ÔR÷S÷ Sñ SøØ#køðSø÷ S÷ Sñ Sûô ò 	tÜ ×*Ñ*Ð+oÐqr×sÑsûð	tüs�   ‚B�A3 –A—A3 šA°A±AÁA3 ÁAÁA3 ÁBÁA3 ÁAÁA3 ÁA0Á$A'Á%A0Á,A3 Á/BÁ0A3 Á3	BÁ<BÂBÂBÂBc           	   ƒ   ó|  K  — ddl m} ddlm} 	 |j	                  |¬«      ƒ d{  –—† }| j                  | j                  «       «      }|xs g }| j                  ||D �cg c]  }t        |«      ‘Œ c}¬«      }t        j                  dt        |«      t        |«      t        |«      «       t        �?|j                  t        |¬«      ƒ d{  –—†  t        j                  d	t        |«      «       yt        j                  d
«       y7 Œác c}w 7 ŒA# t        $ r }	t        j                   d|	«       Y d}	~	yd}	~	ww xY w­w)zS
        Initialize search tools from database into the router on startup.
        r   )ÚSearchToolRegistry)ÚSearchAPIRouterr‘  N)Úconfig_search_toolsÚdb_search_toolszHLoading %s search tool(s) into router (%s from config, %s from database))Úrouter_instancerÜ  z1Successfully loaded %s search tool(s) into routerzMRouter not initialized yet, search tools will be added when router is createdzHlitellm.proxy.proxy_server.py::ProxyConfig:_init_search_tools_in_db - %s)Ú3litellm.proxy.search_endpoints.search_tool_registryr	  Ú&litellm.router_utils.search_api_routerr€	  Úget_all_search_tools_from_dbrå  r‰  Ú!_merge_config_and_db_search_toolsrÔ  rŸ   r  rÈ  rU  Úupdate_router_search_toolsr
  rÿ  r   )
rp  r÷  r	  r€	  r‚	  Úparsed_toolsr�	  ÚtoolrÜ  r  s
             rˆ   rº  z$ProxyConfig._init_search_tools_in_dbP  s0  è ø€ õ	
õ 	Kð	Ø+=×+ZÑ+ZÐivÐ+ZÓ+w×%wˆOà"&×"9Ñ"9¸$×:OÑ:OÓ:QÓ"RˆLØ)5Ò);¸Ðà"&×"HÑ"HØ$7Ø8GÖ H°¤ d¥Ò Hð #Ió #ˆLô
 !×%Ñ%ØZÜ�LÓ!ÜÐ'Ó(Ü�OÓ$ô	ô Ð%Ø%×@Ñ@ÔQ[ÐjvÐ@Ów×wÐwÜ$×)Ñ)Ð*]Ô_bÐcoÓ_pÕqä$×*Ñ*Øcõð+ &xúò !Ið xùô ò 	Ü ×*Ñ*ØZÐ\]÷ñ ûð	üsi   ‚D<�D ¥D¦9D ÁD	
Á1AD ÃDÃ#D Ã0D<Ã1D ÄD<ÄD Ä	D Ä	D9ÄD4Ä/D<Ä4D9Ä9D<c              ƒ   óð   K  — | j                  d¬«      syt        €yt        4 ƒd{  –—†  | j                  t        ¬«      ƒ d{  –—†  ddd«      ƒd{  –—†  y7 Œ37 Œ7 Œ	# 1 ƒd{  –—†7  sw Y   yxY w­w)a  Refresh this worker's router from the search tools table.

        Driven by the management endpoints so the worker that served the write is correct
        immediately, and by the periodic job in store_model_in_db-off deployments. Gated the same
        way as startup, so an admin who excluded search_tools from supported_db_objects opts out.

        Serialized by MODEL_RECONCILE_LOCK for the reason add_deployment documents: the body is a
        read-modify-write of the shared ``llm_router`` global, so two of them interleaving lets the
        older snapshot's wholesale assignment land last and restore a tool the newer one deleted.
        The lock belongs here rather than in _init_search_tools_in_db, which _init_non_llm_objects_in_db
        already calls while holding it.
        rÜ  r„  Nr‘  )r…  r÷  r   rº  ro  s    rˆ   Úreload_search_tools_from_dbz'ProxyConfig.reload_search_tools_from_dbz  s{   è ø€ ð ×*Ñ*°~Ð*ÔFØÜÐ ØÜ'÷ 	Mñ 	MØ×/Ñ/¼mÐ/ÓL×LÐL÷	M÷ 	Mñ 	MøØLøð	Mø÷ 	M÷ 	Mñ 	MüsV   ‚%A6§A¨A6«A!ÁAÁA!Á
A6ÁAÁA6ÁA!ÁA6Á!A3Á'A*Á(A3Á/A6r�	  r‚	  c                 ó²   — |D �ch c]  }|j                  d«      ’Œ }}g | D �cg c]   }|j                  d«      |vrt        |«      ‘Œ" c}¢|¢S c c}w c c}w )NrÝ  )rp  rÔ  )r�	  r‚	  rŠ	  Údb_tool_namesÚconfig_search_tools        rˆ   r‡	  z-ProxyConfig._merge_config_and_db_search_toolsŽ  sy   € ð
 JYÖYÀ §¡Ð);Õ <ÐYˆÐYð
ð +>öà&Ø%×)Ñ)Ð*<Ó=À]ÑRô Ð'Õ(òð
ð ð
ð 	
ùò  Zùòs
   …A¤%A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‘	  )rp  r‘	  s     rˆ   r¸  z.ProxyConfig._init_pass_through_endpoints_in_db�  s   è ø€ õ	
ñ 6Ó7×7Ò7ús   ‚“”rK  c                 ó  — t        |t        «      rt        di |¤Ž}n)t        |t        «      rt        di |j	                  «       ¤Ž}i }j
                  j                  «       D ]  \  }}t        ||¬«      xs |||<   Œ ||_        |S )N)r*  rz  rè  )rÓ  rÔ  r�  r   r»  Úcredential_valuesrâ  rì   )rp  rK  Úcredential_objectÚdecrypted_credential_valuesrF  rG  s         rˆ   Údecrypt_credentialszProxyConfig.decrypt_credentials¤  s�   € Ü�j¤$Ô'Ü .Ñ <°Ñ <ÑÜ˜
¤IÔ.Ü .Ñ I°×1FÑ1FÓ1HÑ IÐà-/Ð#Ø%×7Ñ7×=Ñ=Ó?ò 	W‰DˆAˆqÜ-AÈÈqÔ-QÒ-VÐUVÐ'¨Ò*ð	Wð /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<  Nr¦  T)Úreverse)
rÓ  rê  rÚ  rc  r  r×  Úcredential_namerã  rÆ  r‡  )	rp  r˜	  r^  r×  Úcombined_listÚidx_to_deleter€  rK  rÙ  s	            rˆ   Údelete_credentialszProxyConfig.delete_credentials±  sÆ   è ø€ ð #Ÿo™oÔ?T˜oÓU×UˆØ!%×!:Ñ!:À&Ð!:Ó!Iˆð  .°Ñ?ˆð  "ˆÜ(¬×)@Ñ)@ÓAò 	*‰OˆC�Ø×)Ñ)ÐS`Ö1aÈ4°$×2FÓ2FÒ1aÒaØ×$Ñ$ SÕ)ð	*ô ˜-°Ô6ò 	-ˆCÜ×#Ñ#×'Ñ'¨Õ,ñ	-ð Vúò 2bùs)   ‚CœC�ACÁ(CÁ;CÂ ACÃCc              ƒ   óV  K  — 	 t        |«      j                  «       ƒ d {  –—† }|D �cg c]  }| j                  |«      ‘Œ }}| j                  |«      ƒ d {  –—†  t	        j
                  |«       y 7 ŒQc c}w 7 Œ!# t        $ r"}t        j                  d|«       g cY d }~S d }~ww xY w­w)NzSlitellm.proxy_server.py::get_credentials() - Error getting credentials from DB - %s)	rr  Úfind_allr—	  rž	  rÂ   Úupsert_credentialsrÿ  rŸ   r   )rp  r÷  ÚcredentialsrÙ  r  s        rˆ   rš  zProxyConfig.get_credentialsÆ  s—   è ø€ ð		Ü 5°mÓ D× MÑ MÓ O×OˆKØFQÖR¸d˜4×3Ñ3°DÕ9ÐRˆKÐRØ×)Ñ)¨+Ó6×6Ð6Ü×1Ñ1°+Õ>ð PúÚRØ6ùäò 	Ü ×*Ñ*ØeÐghôð �Iûð		üsa   ‚B)„A;  A2¡A; ©A4ÁA; ÁA9ÁA; Á1B)Á2A; Á4A; Á;	B&ÂB!ÂB&ÂB)Â!B&Â&B)rl  rn  ©F)ur   r  r  Ú__doc__rk  r‚  r#  r  rÔ  rq  ry  ru  rŒ  rž  r,   r"  r¢  r   r\  r«  r•  r±  r´  r¢   r½  rÄ  rÇ  rÓ  rÐ  r‰  r�  rÚ  r—  rå  rô  rð  r!  rú  rŒ  r  r  r�   r€  ru  r   rs  ri  r¨  rç  ré  r@  rò  r÷  r  r  r   rZ  r  r   r  r	  r  r   r$  rˆ  Ústaticmethodr)  rY  r.  r
  r  ra  rq  r   r  rÏ  rV   r…  r	   rs  rŠ  r•  rŽ  r�  rŸ  r­  r  r¦  r®  r”  rÃ  rÀ  r½  rÁ  rÂ  rû  rú  r¼  r#	  r¹  r²  r³  r»  r´  rµ  r¶  ru	  rw	  r·  rº  rŒ	  r‡	  r¸  r   r—	  rž	  rš  rè  rŠ   rˆ   r[  r[  3  sð  … ñóDð0U¨ð U°ó UðI¨ð I°ó Iñ"¸CÀ$¹Jð "ÐRVó "ðH%¨ð %¸ð %Àó %ñN+M¨Dð +MÀDó +MðZ ?¸¸SÀ#ÈÁ*¸_Ñ8Mð  ?ÐRVó  ?ðF *+Ð=Vñ Øð Ø#&ð Ø7:ð à	ó ðD)
Ø˜c 6˜kÑ*ð)
Ø>AÀD¹jð)
à	ó)
ðV¨ð ¸tÀD¹zð Èdó ð¨ó ð" (¨tð  (¸
ÀTÑ8Ió  (ðJ ).ñ,$àð,$ð "&ð,$ð 
�dÑ	ó	,$ò\cñ5°°t±ð 5Àtó 5ðn¨$ó òð ¨4ð °D¸Ñ4Hó ð5D¨ð 5D°$Ð7JÑ2KÈdÑ2Ró 5Dòr#Ð�s˜3‘xó ð"!;°$ó !;ðF"°$ð "¸5ÀÀcÀ¹?ó "ðMA¨¯©¸Ñ(=ð MAÐQTó MAñ^4&°$ð 4&È#ÐPTÉ*ó 4&ðl&
à�t‘ð&
ð   Ñ/ð&
ð ˜XÑ&ó	&
ðP%W¸ó %WðT (,ñ6Kà" T™zð6Kð  ™*ó6Kñp¸ó ðBB+°$ð B+¸9ÀS¹>ÈDÑ;Pó B+ðH¨Sð ¸ð ÀFó ð(¨ð (°#ó (ðT°Tð ¸dó ð8R!à˜4‘KðR!ð (ðR!ð 
�3‰˜$Ñ	ó	R!ðhPàðPð ˜'Ð"6Ñ7Ñ8ðPð !ð	Pð
 
óPð2¸ð À$ó ñB"¸Dð "ÐVYÐ\`ÑV`ð "Ðlpó "ð JOñ"Ø%)ð"ØBFð"à	ó"ð*#°Dð #¸Tó #ñ
À4ð 
Ð]`ÐcgÑ]gð 
Ðswó 
ð* ð¨Fð °t¸d±{ò ó ðð> 7;ñ	,à#Ð$4Ñ5ð,ð $ dÑ*ð,ð $ NÑ3ð	,ð
 
�‰ó,ð\,Gàð,Gð ˜T‘Mð,Gð $ dÑ*ð	,Gð
 
ó,Gð\F;ØðF;Ø37ðF;ØLXðF;à	óF;òPHfðT@8À$ÈÁ+ó @8ðDQàðQð ð%ñ
ðQð ðQð 
óQðf(à#ð(ð ð(ð   $™;ó	(ðT>°#Ð8MÑ2Mð >ÐRVó >ð°|ð ÈÐQ_ÑH`ÐcgÑHgó ð6wà#ðwð (ðwð 
ó	wð48
à#ð8
ð (ð8
ð 
ó	8
ðtà#ðð (ðð   $Ñ&ð	ð
 
óó,Wðà $Ñ&ðð ,ðð 
ó	ócð7_¸|ó 7_ðr
-ÐR^ð 
-Ðcgó 
-ð>iÈó >ið@¸Ló ð2:Èó :ðx8À,ð 8ÐSWó 8ðtU¸,ó Uð._ÀLó ._ð`_gÈLó _gòBAð 4q°|ó 4qðl%x¸,ó %xðNv¸ó vð0y¸<ó yð¸\ó ð&ÀLó ò0$yóL1óð2t°ló tð(¸Ló (óTMð( ð
Ø!Ð"5Ñ6ð
à˜d 3¨ 8™nÑ-ð
ð 
ˆd�3˜�8‰nÑ	ò
ó ð
ò8ð!¨d°YÑ.>ð !À>ó !ð-°t¸NÑ7Kó -ð*
°<ô 
rŠ   r[  c                  óR   — dd l } |j                  | «      t        j                  d<   y )Nr   r:  )rm  r  rn  ro  )r„  rm  s     rˆ   Úsave_worker_configr§	  Ö  s   € Ûà", $§*¡*¨TÓ"2„B‡J�JˆÒ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 rfdd l}ddl	m
}m}m} |j                  |j                  ¬«        |j                  |j                  ¬«        |j                  |j                  ¬«       �n|d	u �r|d	u �rt        j                   j#                  d
d«      }|�ï|j%                  «       dk(  redd l}ddl	m
}m}m} |j                  |j                  ¬«        |j                  |j                  ¬«        |j                  |j                  ¬«       nw|j%                  «       dk(  rddd l}ddl	m
}m}m} |j                  |j                  ¬«        |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*t?        |	«      t8        _         t8        j@                  |d   d<   tB        r	 |
a"y 7 ŒÝ­w)Nr   )Úshow_bannerÚLITELLM_DONT_SHOW_FEEDBACK_BOXr6  r§  T)Úverbose_loggerrŸ   r    )ÚlevelFÚLITELLM_LOGÚINFOÚDEBUGÚgeneralr>  r9  rz  ÚAZURE_API_VERSIONÚ
max_tokensÚtemperaturer*  ÚaliasÚdrop_paramsÚadd_function_to_promptrd  )#Ú!litellm.proxy.common_utils.bannerr©	  rn  r¨  rÉ  r™   Ú
user_modelÚ
user_debugÚloggingÚlitellm._loggingr«	  rŸ   r    ÚsetLevelr®	  r¯	  ro  rp  r|  r~  r€  rU  r�  rW  Úuser_headersÚuser_api_baseÚuser_temperatureÚuser_request_timeoutr  rµ	  r¶	  r   rd  ÚexperimentalÚuser_telemetry)r{  r´	  rz  Úapi_versionr
  Údetailed_debugr³	  r²	  r*  rd  Ú	telemetryrµ	  r¶	  r9  ÚsaveÚ	use_queuer^  r©	  rº	  r«	  rŸ   r    Úlitellm_log_settingÚdynamic_configs                           rˆ   rƒ  rƒ  Ü  s  è ø€ õH >á„MÜ	‡y�yÐ1°2Ó6×<Ñ<Ó>À&ÒHÜÔØ€JØ€JØ��}Û÷	
ñ 	
ð 	×Ñ g§l¡lÐÔ3Ø&Ð×&Ñ&¨W¯\©\Õ:Ø%Ð×%Ñ%¨G¯L©LÕ9Ø˜ÑÛ÷	
ñ 	
ð 	×Ñ g§m¡mÐÔ4Ø&Ð×&Ñ&¨W¯]©]Õ;Ø%Ð×%Ñ%¨G¯M©M×:Ø	�%Š˜N¨eÒ3ä%'§Z¡Z§^¡^°MÀ2Ó%FÐØÐ*Ø"×(Ñ(Ó*¨fÒ4Û÷ñ ð ×'Ñ'¨g¯l©lÐ'Ô;Ø.Ð%×.Ñ.°W·\±\ÕBØ-Ð$×-Ñ-°G·L±LÖAØ$×*Ñ*Ó,°Ò7Û÷ñ ð ×'Ñ'¨g¯m©mÐ'Ô<Ø.Ð%×.Ñ.°W·]±]ÕCØ-Ð$×-Ñ-°G·M±MÕBØ&¨¬J¸Ð;€NÙô
 ×*Ñ*´*ÈvÐ*ÓV×Vñ		
ØØØáØˆØ07ˆ”zÑ" 9Ñ-ÙØ ˆØ19ˆ”zÑ" :Ñ.ÙØ*5Œ�
‰
Ð&Ñ'ÙØ3=ˆ”zÑ" <Ñ0ÙØ&ÐØ4?ˆ”zÑ" =Ñ1ÙØ.ÐØ8Gˆ”zÑ"Ð#4Ñ5ÙØ.3ˆ”zÑ" 7Ñ+Ø�dÑØ"ŒÔØ37ˆ�yÑ! -Ñ0Ø Ñ%Ø)-ŒÔ&Ø>Bˆ�yÑ!Ð":Ñ;ÙÜ" :Ó.ŒÔÜ29×2DÑ2Dˆ�yÑ! ,Ñ/ÝØØ�Nð= Wús   ‚IL<ÉL:ÉCL<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
  rm  r  rÔ  rÿ  )r  Úchunks     rˆ   Údata_generatorrÎ	  f  s‚   è ø€ Ü×ÑÐ1Ô2Øò 3ˆÜ×"Ñ"Ð#7¸Ô?ð	3Øœ4Ÿ:™: e§j¡j£lÓ3Ð4°DÐ9Ó9ñ3øô ò 	3Øœ4Ÿ:™: eÓ,Ð-¨TÐ2Ô2ð	3üs(   ‚1B
´)A ÁB
Á $BÂB
ÂBÂB
r*  Ú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|› d�­–— Y d }~ŒCd }~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|«       t        j                  |||¬	«      ƒ d {  –—†7   t        j                  d
|«       t        |t        «      r|‚t        |«      }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  r„  Tr·  rÌ	  rå  ú[DONE]zTlitellm.proxy.proxy_server.async_assistants_data_generator(): Exception occured - %s©r*  r™  rÏ	  úl[1;31mAn error occurred: %s

 Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`r�   rw   ÚNoner  r7  rž  ©r�   rw   r  r;  rz  )rŸ   r
  r}  rý  Úasync_post_call_streaming_hookÚmodel_dump_jsonrÿ  r   Úpost_call_failure_hookrÓ  r¨  r‚  rS   rw  rm  r  r:  )
r  r*  rÏ	  rÍ	  rë  r  Údone_messageÚ	error_msgÚproxy_exceptionÚerror_returneds
             rˆ   Úasync_assistants_data_generatorrÝ	  p  sà  è ø€ Ü×ÑÐ1Ô2ð1,Ü�	‰	ŒØ÷ 	+ð 	+˜uä+×JÑJØ"3ØØ!ð Kó ÷ ˆEð !÷ +ð +�aØ×%Ñ%°4Ð%Ó8�ð+Ø" 1 # TÐ*Ô*ð	+øðøð+ùô !ò +Ø" 1 # TÐ*×*Ð*ûð+úð	 !÷	+÷ 	+÷ 	+÷ 	+ó 	+úð" 'ˆØ�|�n DÐ)Ô)øÜò ,Ü×&Ñ&ØbÐdeô	
ô  ×6Ñ6Ø/Ø Ø%ð 7ó 
÷ 	
ñ 	
ô
 	×"Ñ"ØØô	
ô �aœÔ'ØˆGô
  # 1›vˆIä!/Ü˜A˜y¨)Ó4Ü˜˜F FÓ+Ü˜!˜W fÓ-Ü˜˜M¨3Ó/ô	"
ˆô !%§
¡
¨G°_×5LÑ5LÓ5NÐ+OÓ PˆØ�~Ð& dÐ+×+Ð+ûð9,üsÔ   ‚G™C ³B ´C ·B8ÁBÁB8ÁB%ÁBÁB%Á"B8Á6	BÁ?B8Â C ÂB8ÂB%Â	B"Â	BÂB8ÂB"Â"B8Â&C Â1B4Â2C Â8C
Â>CÂ?C
ÃC ÃGÃ	F?Ã"1F:ÄDÄB!F:Æ5GÆ:F?Æ?Gc                 ó’   — | j                  d«      }t        |t        «      r|S | j                  d«      }t        |t        «      r|S dS )a  
    Prefer the original client-requested model (pre-alias mapping) when available.

    Pre-call processing can rewrite `request_data["model"]` for aliasing/routing purposes.
    The OpenAI-compatible public `model` field should reflect what the client sent.
    Ú_litellm_client_requested_modelr{  r6  )rp  rÓ  r‚  )rÏ	  Úrequested_models     rˆ   Ú)_get_client_requested_model_for_streamingrá	  ¦  sI   € ð #×&Ñ&Ð'HÓI€OÜ�/¤3Ô'ØÐà"×&Ñ& wÓ/€OÜ(¨¼#Ô>ˆ?ÐFÀBÐFrŠ   c                 óV   — 	 | d uxr t        | «      dkD  S # t        t        f$ r Y yw xY w)Nr   F)r"  r  rs  rå  s    rˆ   Ú_is_positive_int_likerã	  µ  s6   € ðØ˜DÐ Ò3¤S¨£Z°!¡^Ð3øÜ”zÐ"ò Ùðús   ‚ –(§(c                 óT   — t         j                  d«      sy| j                  d«      du S )NÚ expose_fallback_errors_to_callerFÚinclude_fallback_errorsTr_  ©rÏ	  s    rˆ   Ú_should_include_fallback_errorsrè	  ¼  s+   € Ü×ÑÐ BÔCØØ×ÑÐ5Ó6¸$Ð>Ð>rŠ   Úresponse_objc                 ó  — t        | «      j                  d«      }t        |t        «      sdd g fS t	        |j                  d«      «      sdd g fS |j                  d«      }t        |«      }t        |t        «      r|rd||fS dd |fS )NÚadditional_headersFzx-litellm-attempted-fallbackszx-litellm-model-groupT)rc   rp  rÓ  rÔ  rã	  rb   r‚  )ré	  rë	  Úfallback_modelÚfallback_errorss       rˆ   Ú _get_streaming_fallback_metadatarî	  Â  s•   € ô !7°|Ó D× HÑ HÐI]Ó ^ÐÜÐ(¬$Ô/Ø�d˜BˆÐä Ð!3×!7Ñ!7Ð8WÓ!XÔYØ�d˜BˆÐà.×2Ñ2Ð3JÓK€NÜ=Ð>PÓQ€OÜ�.¤#Ô&©>Ø�^ _Ð4Ð4Ø��Ð&Ð&rŠ   rì	  rí	  c                 óŒ   — dd l }ddt         |j                   «       «      | xs dg | |dœdœ}dt        j                  |«      › d�S )	Nr   zlitellm-fallback-metadatazchat.completion.chunkr6  )rì	  rš  )r.  r\  Úcreatedr{  ÚchoicesÚlitellm_fallbackrÌ	  rå  )r}  r"  rm  r  )rì	  rí	  r}  Úpayloads       rˆ   Ú#_format_fallback_metadata_sse_eventrô	  Ó  sW   € ó
 ð *Ø)Ü�y�t—y‘y“{Ó#ØÒ% 2Øà,Ø%ñ
ñ
€Gð ”D—J‘J˜wÓ'Ð(¨Ð-Ð-rŠ   )Úfallback_was_attemptedÚfallback_model_from_metadatarÍ	  Úrequested_model_from_clientÚmodel_mismatch_loggedrõ	  rö	  c           
      óz  — t        |«      r| |fS |r|n|}|rt        | t        t        f«      s| |fS |st	        |«      r| |fS |s|j                  dd«      r| |fS t        | t        «      r| j                  d«      nt        | dd «      }||k(  r| |fS |s/||k7  r*t        j                  d|j                  d«      |||«       d}t        | t        «      r	|| d<   | |fS 	 || _	        | |fS # t        $ rI}t        j                  d|j                  d«      |t        | «      t        |«      d¬«       Y d }~| |fS d }~ww xY w)	NÚfastest_responseFr{  z‰litellm_call_id=%s: streaming chunk model mismatch - target=%r downstream=%r fallback_was_attempted=%s. Overriding chunk model to target.Úlitellm_call_idTzPlitellm_call_id=%s: failed to override chunk.model=%r on chunk_type=%s. error=%sra  )rä   rÓ  r   rÔ  rã   rp  rw  rŸ   r
  r{  rÿ  rz  rw   r‚  )	rÍ	  r÷	  rÏ	  rø	  rõ	  rö	  Útarget_modelÚdownstream_modelr  s	            rˆ   Ú_restamp_streaming_chunk_modelrþ	  è  s‰  € ô % \Ô2ØÐ+Ð+Ð+á:PÑ6ÐVq€Lñ œz¨%´)¼TÐ1BÔCØÐ+Ð+Ð+ñ "Ô&DÐE`Ô&aØÐ+Ð+Ð+ñ " l×&6Ñ&6Ð7IÈ5Ô&QØÐ+Ð+Ð+ä4>¸uÄdÔ4K˜eŸi™i¨Ô0ÔQXÐY^Ð`gÐimÓQnÐØ˜<Ò'ØÐ+Ð+Ð+á Ð%5¸Ò%EÜ×"Ñ"ð XØ×ÑÐ.Ó/ØØØ"ô	
ð !%Ðä�%œÔØ%ˆˆg‰ØÐ+Ð+Ð+ð

Ø"ˆŒð Ð'Ð'Ð'øô ò 
Ü×"Ñ"Ø^Ø×ÑÐ.Ó/ØÜ�‹KÜ�‹FØ÷	
ñ 	
ð Ð'Ð'Ð'ûð
ús   ÃC( Ã(	D:Ã1<D5Ä5D:c                 ó°  ‡— t        | dd«      €t        | dd«      €t        | dd«      �yt        | dd«      }t        |t        «      rt        |«      dk7  ry|d   }t        |dd«      €t        |d	d«      �yt        |d
d«      Š‰€yd}t	        ˆfd„|D «       «      ryi }t        ‰dd«      }t        ‰dd«      }|�||d<   |�||d<   t        |dd«      |dœ}t        |dd«      }|�||d<   t        | dd«      }	|	€yt        | dd«      t        | dd«      t        | dd«      |	|gdœ}
dD ]  }|
|   �Œ	|
j                  |«       Œ t        j                  |
«      S )zî
    Serialize the common OpenAI text streaming chunk without the full Pydantic
    serializer. Fall back for richer chunks so tool calls, logprobs, usage, and
    provider-specific fields keep the canonical model_dump_json behavior.
    Úprovider_specific_fieldsNÚsystem_fingerprintÚusagerñ	  r8  r   ÚlogprobsÚenhancementsÚdelta)	Úfunction_callÚ
tool_callsÚaudioÚimagesÚannotationsÚreasoning_contentÚthinking_blocksr 
  Úrefusalc              3   ó<   •K  — | ]  }t        ‰|d «      d u–— Œ y ­wrn  )rw  )r’  rû  r
  s     €rˆ   r”  z?_fast_serialize_simple_model_response_stream.<locals>.<genexpr>P   s   øè ø€ Ò
Y°uŒ7�5˜% Ó&¨dÔ2Ñ
Yùs   ƒÚroler8  Úindex)r
  r
  Úfinish_reasonr{  r.  r\  rð	  )r.  r\  rð	  r{  rñ	  )r.  r\  rð	  )rw  rÓ  r•  rÈ  rµ  r‡  Úorjsonr  )rÍ	  rñ	  r•   Úunsupported_delta_fieldsÚ
delta_dictr
  r8  Úchoice_dictr
  r{  ró	  Útop_level_keyr
  s               @rˆ   Ú,_fast_serialize_simple_model_response_streamr
  *   s±  ø€ ô 	�Ð1°4Ó8ÐDÜ�5Ð.°Ó5ÐAÜ�5˜' 4Ó(Ð4àä˜U I¨tÓ4€GÜ�gœtÔ$¬¨G«¸Ò(9Øà˜A‘J€FÜˆv�z 4Ó(Ð4¼ÀÈÐX\Ó8]Ð8iØä˜6 7¨DÓ1€EØ€}Øð
'Ðô Ó
YÐ@XÔ
YÔYØà €JÜ˜% ¨Ó.€DÜ˜U I¨tÓ4€GØÐØ!ˆ
�6ÑØÐØ 'ˆ
�9Ñä#*¨6°7¸AÓ#>ÈÑT€KÜ" 6¨?¸DÓA€MØÐ Ø'4ˆ�OÑ$ô ˜5 '¨4Ó0€EØ€}Øô �e˜T 4Ó(Ü˜% ¨4Ó0Ü˜5 )¨TÓ2ØØ�=ñ€Gð 5ò 'ˆØ�=Ñ!Ñ)Ø�K‰K˜Õ&ð'ô �<‰<˜Ó Ð rŠ   c                 óf   — t        | t        «      rt        | «      }|�|S | j                  dd¬«      S )NT)r¸  Úexclude_unset)rÓ  rh   r
  r×	  )rÍ	  Úserialized_chunks     rˆ   Ú_serialize_streaming_chunkr
  w   s:   € Ü�%Ô,Ô-Ü"NÈuÓ"UÐØÐ'Ø#Ð#à× Ñ ¨dÀ$Ð ÓGÐGrŠ   c                 ó~   — t        | t        «      sy| j                  �yt        d„ | j                  xs g D «       «      S )NFc              3   ó2   K  — | ]  }t        |«      –— Œ y ­wrn  )Ú_is_empty_streaming_choice)r’  r•   s     rˆ   r”  z5_is_injected_stream_usage_artifact.<locals>.<genexpr>…   s   è ø€ ÒT°fÔ)¨&×1ÑTùr•  )rÓ  rh   r 
  r(  rñ	  ©rÍ	  s    rˆ   Ú"_is_injected_stream_usage_artifactr 
  €   s:   € Ü�eÔ0Ô1ØØ×%Ñ%Ð1ØÜÑTÀÇÁÒ@SÐQSÔTÓTÐTrŠ   r•   c                 ó´   — | j                   �yt        | dd «      �yt        | dd «      }|€yt        d„ |j                  «       j	                  «       D «       «      S )NFr
  r
  Tc              3   ó$   K  — | ]  }|d u –— Œ
 y ­wrn  rè  )r’  r*  s     rˆ   r”  z-_is_empty_streaming_choice.<locals>.<genexpr>�   s   è ø€ ÒF ˆu˜Œ}ÑFùrÒ  )r
  rw  r(  r»  r¢  )r•   r
  s     rˆ   r
  r
  ˆ   s\   € Ø×ÑÐ'ØÜˆv�z 4Ó(Ð4ØÜ˜6 7¨DÓ1€EØ€}ØÜÑF¨%×*:Ñ*:Ó*<×*CÑ*CÓ*EÔFÓFÐFrŠ   Ú
str_so_farc              ƒ   óÂ   K  — t         j                  || ||r|nd ¬«      ƒ d {  –—† } t        | t        t        f«      rt        j                  | ¬«      }||z  }| |fS 7 Œ9­w)N)r*  r  r„  r#
  )ré	  )rý  rÖ	  rÓ  rg   rh   r  Úget_response_string)rÍ	  r*  rÏ	  r#
  Úresponse_strs        rˆ   Ú_apply_streaming_chunk_hooksr'
  “   so   è ø€ ô $×BÑBØ+ØØÙ!+‘:°ð	 Có ÷ €Eô �%œ-Ô)<Ð=Ô>Ü%×9Ñ9ÀuÔMˆØ�lÑ"ˆ
à�*ÐÐðús   ‚!A£A¤:Ac                 ó>   — t        | t        «      rd| z   dz   S d| › d�S )Ns   data: s   

rÌ	  rå  )rÓ  Úbytesr
  s    rˆ   Ú_format_streaming_sse_chunkr*
  ¨   s+   € Ü�%œÔØ˜5Ñ  7Ñ*Ð*Ø�E�7˜$ÐÐrŠ   )z

rå  zÚ_SSE_FRAME_DELIMITERSi  € Ú_MAX_RAW_SSE_BUFFER_CHARSÚbufferc                 óÂ   — t         D �cg c]  }| j                  |«      x}dk7  sŒ||f‘Œ }}|sd | fS t        |d„ ¬«      \  }}|t        |«      z   }| d | | |d  fS c c}w )Néÿÿÿÿc                 ó   — | d   S ©Nr   rè  ©rü  s    rˆ   rü  z)_pop_complete_sse_frame.<locals>.<lambda>¹   s
   € ÀDÈÁG€ rŠ   ry  )r+
  ÚfindrÉ  rÈ  )r-
  Ú	delimiterÚpositionÚdelimiter_positionsÚ	frame_ends        rˆ   Ú_pop_complete_sse_framer8
  ²   sŠ   € ä/Dö"Ø"+ÐU[×U`ÑU`ÐajÓUkÐIkÈÐprÓHrˆ�9Òð"Ðð "ñ Ø�Vˆ|ÐäÐ1Ñ7KÔLÑ€HˆiØ¤# i£.Ñ0€IØ�*�9Ð˜v i jÐ1Ð1Ð1ùò"s
   ‰A¥AÚ_STREAM_KEEPALIVEg      ð?Ú_KEEPALIVE_MIN_SECONDSg     Àr@Ú_KEEPALIVE_MAX_SECONDSÚ_EMPTY_MAPPINGÚaiterÚresolve_keepalive_secondsÚkeepalive_secondsc                óà  K  — d}|}	 	 |dk  r'	 | j                  «       ƒ d{  –—† }|­–—  ||«      }Œ-|€#t        j                  | j                  «       «      }t        j                  |f|¬«      ƒ d{  –—† \  }}|s
t
        ­–— Œ�	 |j                  «       }	 d}|­–—  ||«      }Œ¢7 Œˆ# t        $ r Y nw xY w7 ŒF# t        $ r Y d}nw xY w# d}w xY w|�G|j                  «       s6|j                  «        	 |ƒ d{  –—†7   y# t        j                  $ r Y yw xY wyy# |�G|j                  «       s6|j                  «        	 |ƒ d{  –—†7   w # t        j                  $ r Y w w xY ww w xY w­w)aø  Wrap `aiter` with idle-gap heartbeats, re-resolving the interval after each
    real chunk via `resolve_keepalive_seconds`. A mid-stream router fallback can
    swap in a deployment with a different keepalive policy, including one that
    newly enables or newly disables heartbeats, partway through the same stream;
    re-resolving against each chunk's own identity (rather than trusting the
    interval picked before iteration started, or picked the last time it went
    inactive) keeps the heartbeat behavior in sync with whichever deployment
    actually produced it, in both directions. While the interval is <= 0, no
    task is created and no timeout is awaited: a chunk is forwarded the moment
    it arrives, at the same cost as a bare `async for`.Nr   ©Útimeout)
Ú	__anext__ÚStopAsyncIterationrP  r‡  Úwaitr9
  rC  ÚdoneÚcancelr°  )r=
  r>
  r?
  ÚpendingÚcurrent_keepalive_secondsrü  rF
  rÁ  s           rˆ   Ú_iter_with_keepaliverJ
  Å   sƒ  è ø€ ð )-€GØ 1ÐðØØ(¨AÒ-ðØ!&§¡Ó!2×2�Dð “
Ù,EÀdÓ,KÐ)ØàˆÜ!×-Ñ-¨e¯o©oÓ.?Ó@�Ü#ŸL™L¨'¨Ð=VÔW×W‰GˆD�!ÙÜ'Ó'ØðØ—~‘~Ó'‘ð �Ø‹JÙ(AÀ$Ó(GÐ%ð/ ð 3ùÜ)ò Ùðúð Xùô &ò Øà‘ðûð ‘úð Ð w§|¡|¤~Ø�N‰NÔðØ—’øÜ×)Ñ)ò Ùðúð	 (6Ðøˆ7Ð w§|¡|¤~Ø�N‰NÔðØ—’øÜ×)Ñ)ò Ùðúð	 (6Ðüsñ   ‚E.ˆD  �B- ¢B+£B- §AD  Á5B<Á6D  Â
B> ÂD  Â+B- Â-	B9Â6D  Â8B9Â9D  Â>	CÃC ÃD  ÃCÃC ÃCÃD  Ã"E.Ã9D Ã>DÃ?D ÄE.ÄDÄE.ÄDÄE.Ä #E+ÅEÅ	EÅ
EÅE+ÅE&Å#E+Å%E&Å&E+Å+E.c                   ó"   — e Zd ZU eed<   eed<   y)Ú_DeploymentKeepaliveConfigr?
  Úallow_client_overrideN)r   r  r  r\  r!  r#  rè  rŠ   rˆ   rL
  rL
  ø   s   … ØÓØÔrŠ   rL
  r  c           
      óö  — t         €y t        |«      }|j                  d«      }t        |t        «      r[|rYt         j                  |¬«      }|€y t        t        |j                  dd «      t        t        |j                  dd«      «      ¬«      S t        d„ t         j                  | j                  d«      ¬	«      xs d
D «       «      }t        |«      dk(  r$t        t        |«      «      \  }}t        ||¬«      S y )Nr‡  ©r‡  r?
  Úallow_client_keepalive_overrideF)r?
  rM
  c              3   óÐ   K  — | ]^  }|j                  d «      xs t        j                  d«      t        |j                  d «      xs t        j                  dd«      «      f–— Œ` y­w)rô  r?
  rP
  FN)rp  r<
  r#  )r’  Údeployment_dicts     rˆ   r”  z4_keepalive_from_deployment_config.<locals>.<genexpr>!  sg   è ø€ ò ð ð × Ñ Ð!1Ó2ÒD´n×IÑIÐJ]Ó^ÜØ ×$Ñ$Ð%5Ó6ÒH¼.×MÑMÐNoÐqvÓwóô	
ñùs   ‚A$A&r{  ©r1  rè  r8  )rU  rc   rp  rÓ  r‚  Úget_deploymentrL
  rw  rô  r#  r@  rv  rÈ  ÚnextÚiter)rÏ	  r  Úhiddenr‡  rš  Úconfigsr?
  rM
  s           rˆ   Ú!_keepalive_from_deployment_configrY
  ý   sÿ   € ô ÐØä*¨8Ó4€FØ—j‘j Ó,€HÜ�(œCÔ ¡XÜ&×5Ñ5¸xÐ5ÓHˆ
ð ÐØÜ)Ü% j×&?Ñ&?ÐATÐVZÓ[Ü"&¤w¨z×/HÑ/HÐJkÐmrÓ'sÓ"tô
ð 	
ô ñ ô  *×8Ñ8ÀL×DTÑDTÐU\ÓD]Ð8Ó^ÒdÐbdôó €Gô ˆ7ƒ|�qÒÜ37¼¸W»Ó3FÑ0ÐÐ0Ü)Ø/ÐG\ô
ð 	
ð rŠ   Úrawc                 óv   — t        | t        t        t        f«      sy	 t        | «      dk  S # t        $ r Y yw xY w)NFr   )rÓ  r"  r   r‚  rs  )rZ
  s    rˆ   Ú_is_explicit_keepalive_disabler\
  *!  s;   € Ü�cœC¤¬Ð,Ô-ØðÜ�S‹z˜Q‰ÐøÜò Ùðús   ž, ¬	8·8c                 óÔ  — t        | |«      }|�|j                  nd }|�|j                  nd}t        |«      ry|r| j	                  d«      nd }|�|n|�|nt
        j                  }	 t        |t        t        t        f«      rt        |«      nd}|dk  ryt        t        t        |t        «      «      }||k7  r!t!        j"                  d||t        t        «       |S # t        $ r Y yw xY w)NFrã  r?
  r   z3keepalive_seconds=%s clamped to %s [min=%s, max=%s])rY
  r?
  rM
  r\
  rp  r  Ú#sse_keepalive_ping_interval_secondsrÓ  r"  r   r‚  rs  Úmaxr:
  rÉ  r;
  rŸ   r  )	rÏ	  r  Údeployment_configÚdeployment_rawrM
  Úclient_suppliedrZ
  r*  Úclampeds	            rˆ   Ú_resolve_keepalive_secondsrd
  3!  s  € Ü@ÀÈxÓXÐØCTÐC`Ð-×?Ò?Ðfj€NØN_ÐNkÐ#4×#JÒ#JÐqvÐô & nÔ5Øñ G\˜\×-Ñ-Ð.AÔBÐae€Oð Ð&ñ 	ð Ð%ñ ä×8Ñ8ð ðÜ%/°´c¼5Ä#Ð5FÔ%G”u˜S”zÈSˆð �‚zØÜÔ/´°UÔ<RÓ1SÓT€GØ�%ÒÜ×!Ñ!ØAØØÜ"Ü"ô	
ð €Nøô ò Ùðús   Á'(C Ã	C'Ã&C'g      @Ú_KEEPALIVE_CACHE_TTL_SECONDSc                 óV   ‡ ‡‡‡— dŠdŠt        d«      Šdt        dt         fˆˆˆˆ fd„}|S )a  Wrap `_resolve_keepalive_seconds` with a memo keyed on the serving
    deployment's model_id. The steady-state case (no mid-stream fallback, the
    overwhelming majority of streams) sees the same model_id on every chunk, so
    this turns the per-chunk cost from a full `llm_router.get_deployment()`
    Pydantic rebuild into a cheap hidden-params read once per
    `_KEEPALIVE_CACHE_TTL_SECONDS` for that model_id. The cache expires on its
    own rather than living for the life of the stream, so an operator's live
    config change (disabling keepalive, revoking client override, or removing
    the deployment) is observed within a bounded window instead of being able
    to be evaded by an already-in-flight stream indefinitely. A missing/empty
    model_id can't be trusted as a cache key (see
    `_keepalive_from_deployment_config`'s model_name fallback, which reflects
    current router state rather than one deployment's fixed identity), so
    those chunks always resolve fresh, matching prior behavior exactly.
    Nrã  r.	  rü  rÐ  c                 óø   •— t        | «      j                  d«      }t        j                  «       }t	        |t
        «      r|r|‰k(  r|‰z
  t        k  r‰S t        ‰| «      }t	        |t
        «      r	|r|||cŠŠŠ|S )Nr‡  )rc   rp  r}  rÅ  rÓ  r‚  re
  rd
  )rü  r‡  Únowr*  Úlast_model_idÚlast_resolved_atÚ
last_valuerÏ	  s       €€€€rˆ   Ú_resolvez*_make_keepalive_resolver.<locals>._resolvev!  s|   ø€ ä)¨$Ó/×3Ñ3°JÓ?ˆÜ—^‘^Ó%ˆä�x¤Ô%ÙØ˜MÒ)ØÐ&Ñ&Ô)EÒEàÐÜ1°,ÀÓEˆÜ�h¤Ô$©Ø:BÀEÈ3Ð7ˆM˜:Ð'7ØˆrŠ   )r   r\  )rÏ	  rl
  ri
  rj
  rk
  s   ` @@@rˆ   Ú_make_keepalive_resolverrm
  b!  s8   û€ ð  !%€MØ€JÜ# F›mÐð”vð ¤%÷ ð ð  €OrŠ   c                óþ	  K  — t        j                  d«       d}d}	 d }t        |¬«      }t        | «      \  }}	}
d}d}t	        |«      }d}t
        j                  «       }t
        j                  «       }t        |j                  d«      «      }t        |j                  d«      «      }d}|rt
        j                  || |¬«      }n| }t        |«      } || «      }t        €|dkD  rt        |j                  «       ||«      n|}|2 3 d {  –—† }|t        u rd	­–— Œt!        t"        |«      }|rt%        ||||¬
«      ƒ d {  –—† \  }}|	€t        |«      \  }}}|r
d}|}	|
xs |}
|xr |xr |
xr | }t'        ||||||	¬«      \  }}|r t)        |«      r|rt+        |	|
¬«      ­–— d}Œ¥d}t-        |t.        «      rt1        |«      }�n	t-        |t2        «      r…|j5                  dd¬«      }|r=||z  }	 t7        |«      \  }}|€n|­–— Œt9        |«      t:        kD  rt=        d«      ‚d}n§|j?                  d«      r–|jA                  tB        «      r|n|dz   ­–— d}ntt-        |tD        «      r?|r=||z  }	 t7        |«      \  }}|€n|­–— Œt9        |«      t:        kD  rt=        d«      ‚d}n%t-        |tD        «      r|j?                  d«      r|} n*|s	 tG        |¬«      ­–— |s�Œãt+        |	|
¬«      ­–— d}�Œ÷d}|stK        jL                  |«       |r|jA                  tB        «      r|n|dz   ­–— |�|­–— |j                  d«      sd}!d|!› d�­–— tg        jh                  ||| |||t
        ¬#«      ƒ d {  –—†  y 7 �Œy7 �ŒE# tH        $ r} d| › d�­–— Y d } ~ Œ»d } ~ ww xY w6 Œ­# tN        jP                  tR        f$ r |sd}‚ tH        $ rü} t        jT                  d| «       t
        jW                  || |¬«      ƒ d {  –—†7   t        j                  d| «       t-        | tX        «      r| ‚t-        | tZ        «      rtE        | «      }"ntE        | «      }"t]        t_        | d|"«      t_        | dd«      t_        | dd«      t_        | dd «      ¬!«      }#ta        jb                  d"|#je                  «       i«      }$d}d|$› d�­–— Y d } ~ �Œmd } ~ ww xY w7 �ŒR# tg        jh                  ||| |||t
        ¬#«      ƒ d {  –—†7   w xY w­w)$NrË	  Frç	  r6  Ú_litellm_raw_sse_streamÚ_litellm_strip_stream_usage©r*  r  rÏ	  r   z: ping

)rÍ	  r*  rÏ	  r#
  T)rÍ	  r÷	  rÏ	  rø	  rõ	  rö	  )rì	  rí	  rÚ  r  )rš  zGRaw SSE stream exceeded maximum buffered size without a frame delimiter)zdata:zevent:r|   rå  rÌ	  r
  Ú _litellm_skip_openai_stream_donerÑ	  zIlitellm.proxy.proxy_server.async_data_generator(): Exception occured - %srÒ	  rÓ	  r�   rw   rÔ	  r  r7  rž  rÕ	  rz  )r3  rÏ	  r  Ústream_completedÚclient_disconnectedr*  rý  )5rŸ   r
  rá	  rî	  rè	  rý  Úneeds_iterator_wrapÚneeds_per_chunk_streaming_hookr#  rp  Ú'async_post_call_streaming_iterator_hookrm
  rU  rJ
  Ú	__aiter__r9
  r   r   r'
  rþ	  r 
  rô	  rÓ  r   r
  r)
  r
  r8
  rÈ  r,
  rs  r™  ré  r+
  r‚  r*
  rÿ  rZ  Ú_fire_deferred_stream_loggingrP  r°  ÚGeneratorExitr   rØ	  r¨  r×  rS   rw  rm  r  r:  râ   Ú%_finalize_streaming_generator_cleanup)%r  r*  rÏ	  r3  rs
  rt
  Úerror_messager÷	  rõ	  rö	  rí	  rø	  Úfallback_metadata_event_sentræ	  Ú_str_so_farru
  Úneeds_per_chunk_hookÚis_raw_sse_streamÚstrip_stream_usageÚraw_sse_bufferÚstream_iteratorr>
  Úinitial_keepalive_secondsÚstream_sourcerü  rÍ	  Úchunk_fallback_was_attemptedÚchunk_fallback_modelÚchunk_fallback_errorsÚpending_fallback_eventÚraw_passthroughÚframer  rÙ	  rÚ	  rÛ	  rÜ	  s%                                        rˆ   Úasync_data_generatorrŒ
  ‰!  sË  è ø€ ô ×ÑÐ1Ô2ØÐØÐð_
Ø$(ˆÜ-VÐdpÔ-qÐ#ô
 -¨XÓ6ñ		
Ø"Ø(Øà %ÐØ',Ð$Ü)HÈÓ)VÐð ˆô &7×%JÑ%JÓ%LÐÜ&7×&VÑ&VÓ&XÐÜ#'¨×(8Ñ(8Ð9RÓ(SÓ#TÐÜ$(¨×)9Ñ)9Ð:WÓ)XÓ$YÐØˆáÜ/×WÑWØ"3Ø!Ø)ð Xó ‰Oð 'ˆOô ,DÀLÓ+QÐ!Ù+DÀXÓ+NÐ!ô Ð%Ð)BÀQÒ)Fô !Ø×)Ñ)Ó+Ø)Ø)ôð !ð 	ð (÷ `	4ð `	4�$ØÔ(Ñ(Ø"Ó"ØÜœ˜d“OˆEÙ#ä+GØØ&7Ø!-Ø*ô	,÷ &Ñ"��{ð ,Ð3ô
 5°UÓ;ñ	Ø0Ø(Ø)á/Ø-1Ð*Ø3GÐ0Ø&5Ò&NÐ9N�Oð (ò 5Ø*ò5à#ò5ð 5Ð4ð	 #ô ,JØØ,GØ)Ø&;Ø'=Ø-Iô,Ñ(ˆEÐ(ñ "Ô&HÈÔ&OÙ)Ü=Ø'CØ(7ôó ð 48Ð0Øà#ˆOÜ˜%¤Ô+Ü2°5Ó9’Ü˜E¤5Ô)ØŸ™ W°Y˜Ó?�Ù$Ø" eÑ+�NØÜ0GÈÓ0WÑ-˜˜~Ø ˜=Ø!Ø#›ð	 ô
 ˜>Ó*Ô-FÒFÜ(Ð)rÓsÐsØ&*‘OØ×%Ñ%Ð&>Ô?Ø$)§N¡NÔ3HÔ$I™5ÈuÐW]É~Ó^Ø&*‘OÜ˜E¤3Ô'Ñ,=Ø %Ñ'�ØÜ,CÀNÓ,SÑ)�E˜>Ø�}ØØ“Kð	 ô
 �~Ó&Ô)BÒBÜ$Ð%nÓoÐoØ"&‘Ü˜E¤3Ô'¨E×,<Ñ,<¸XÔ,FØ %�Ùá"ð+Ü5¸EÔBÓBó &Ü9Ø#?Ø$3ôó ð 04Ò,àÐÙ"ô ×6Ñ6°|ÔDáØ%3×%<Ñ%<Ô=RÔ%S‘>ÐYgÐjpÑYpÓqàÐ$ØÓà×ÑÐ BÔCØ"*ˆLØ˜<˜.¨Ð-Ó-ôZ ,×QÑQØØ%ØØ-Ø 3Ø/Ü/ô
÷ 	
ñ 	
ð}`	4ùð&úôb !ò +Ø" 1 # TÐ*×*Ð*ûð+úðq (ùôd ×"Ñ"¤MÐ2ò ñ  Ø"&ÐØÜò ,Ü×&Ñ&Ð'rÐtuÔvÜ×6Ñ6Ø/Ø Ø%ð 7ó 
÷ 	
ñ 	
ô
 	×"Ñ"ØØô	
ô
 �aœÔ'ØˆGÜ˜Ô1Ô2Ü˜A›‰Iô
 ˜A›ˆIä!/Ü˜A˜y¨)Ó4Ü˜˜F FÓ+Ü˜!˜W fÓ-Ü˜˜M¨3Ó/ô	"
ˆô !%§
¡
¨G°_×5LÑ5LÓ5NÐ+OÓ PˆØÐØ�~Ð& dÐ+×+Ñ+ûð=,úð@	
úÔ+×QÑQØØ%ØØ-Ø 3Ø/Ü/ô
÷ 	
ò 	
üsÈ   ‚S=�C&N' ÄN%ÄN ÄN%Ä3N' Ä>NÄ?FN' ËNË"N' Ë&A1N' Í#S=Í:SÍ;S=Î N%ÎN' Î	N"Î	NÎN' ÎN"Î"N' Î'&S	Ï1SÏ>PÏ?B?SÒ>S ÓS	Ó	S ÓS=Ó$S:Ó3S6Ó4S:Ó:S=c                 ó    — t        | |||¬«      S )N©r  r*  rÏ	  r3  )rŒ
  rŽ
  s       rˆ   Úselect_data_generatorr�
  t"  s   € ô  ØØ+Ø!Øô	ð rŠ   c                 ó
  — | j                  di «      }| j                  di «      j                  dd «      }	 d|v s|j                  d«      r|j                  dd «      }t        j                  |«      }|S # t        $ r i cY S w xY w)Nr¸  rô  r{  ÚazureÚ
base_model)rp  r  Úget_model_inforÿ  )r{  r¸  Úmodel_to_lookupÚlitellm_model_infos       rˆ   Úget_litellm_model_infor–
  ‚"  s…   € ØŸ	™	 ,°Ó3€JØ—i‘iÐ 0°"Ó5×9Ñ9¸'À4ÓH€OðØ�oÑ%¨¯©¸Ô)EØ(Ÿn™n¨\¸4Ó@ˆOÜ$+×$:Ñ$:¸?Ó$KÐØ!Ð!øÜò ð Š	ðús   ¶=A4 Á4BÂBc                 ó6   — t        j                  d| d   «       y )Nz$Backing off... this was attempt # %sÚtries)rŸ   r
  )rn  s    rˆ   Ú
on_backoffr™
  �"  s   € ä×ÑÐEÀwÈwÑGWÕ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 reachedÚ1disable_retry_on_max_parallel_request_limit_errorTÚgiveup)Úeventr   )rÓ  rS   rw  r�   r‚  rW  rp  rŸ   r
  rm  r  )r  rC  s     rˆ   rœ
  rœ
  •"  s’   € ä�1”nÓ%ò 	>Ü�A�y $Ó'¨tÐ3ò	>ä�q—y‘y¤#Ó&ò	>ð 1°A·I±IÐ=ð	€Fô ×ÑÐOÓPÐTXÑXØáÜ×"Ñ"¤4§:¡:¸ÌsÐSTËvÑ.VÓ#WÔXØ€MrŠ   c                   óf  — e Zd Zededz  dedz  ddfd„«       Zededz  de	de
dz  fd	„«       Zed
eddfd„«       Zed
ede
dz  fd„«       Zedeeef   dedz  de
dz  fd„«       Zed
ede
dz  fd„«       Zededz  deeef   fd„«       Zed
ededz  defd„«       Zed„ «       Zed$d„«       Zedededdfd„«       Zed„ «       Zed„ «       Zed
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 fd„«       Z"ede d
ede	defd„«       Z#ed edz  de	dededz  fd!„«       Z$ed"„ «       Z%ed#„ «       Z&y)%r…  rd  Nr÷  rÐ  c                 óD   — |€| r| dk  ry t        j                  d| «       y )Nr   at  A proxy-wide budget (litellm.max_budget=%s) is configured but no database is connected, so the budget will NOT be enforced and requests will never be blocked. Set DATABASE_URL or general_settings.database_url and restart. Redis and fail_closed_budget_enforcement do not cover the proxy-wide budget because there is no global spend counter; Redis alone is not a substitute.)rŸ   r/  rc  s     rˆ   r�  z)ProxyStartupEvent._warn_budget_without_db¦"  s,   € àÐ$©J¸*Èº/Øä×$Ñ$ðuð õ	
rŠ   rU  rý  rX  c                 ó>   — t        «        |j                  ||¬«       y)z*Initialize logging and alerting on startup)rU  rX  N)r[  Ústartup_event)ÚclsrU  rý  rX  s       rˆ   rŒ  z-ProxyStartupEvent._initialize_startup_logging³"  s   € ô 	Œà×'Ñ'°:ÐQbÐ'ÕcrŠ   rW  c           	      óœ   — ddl m}m} | j                  |d«      duryt	        j
                  dd|dj                  d	„ |D «       «      d«       y)
z@Announce, loudly, that any caller may inject synthetic failures.r   )ÚGATED_MOCK_PARAM_NAMESÚMOCK_TESTING_CONFIG_KEYFTNa“  
%s
 DANGEROUS SETTING ENABLED
 general_settings.%s = true

 Any caller with a valid key on this proxy can now inject synthetic
 failures and latency into their own requests using these body params:
%s

 A request using them consumes a connection and a concurrency slot
 without reaching a provider, and returns an error the caller chose.

 Intended for testing fallback chains. Do not leave enabled.
%szH========================================================================r~   c              3   ó&   K  — | ]	  }d |› �–— Œ y­w)z   Nrè  )r’  rÄ  s     rˆ   r”  zIProxyStartupEvent._warn_if_mock_testing_params_enabled.<locals>.<genexpr>Û"  s   è ø€ ÒF t˜˜D˜6”lÑFùs   ‚)Úlitellm.proxy.route_llm_requestr¤
  r¥
  rp  rŸ   r/  r–  )rW  r¤
  r¥
  s      rˆ   r”  z6ProxyStartupEvent._warn_if_mock_testing_params_enabledÀ"  sS   € ÷	
ð
 ×ÑÐ 7¸Ó?ÀtÑKØä×$Ñ$ðð Ø#Ø�I‰IÑFÐ/EÔFÓFØõ#	
rŠ   c                 ó„   — ddl m} | j                  dd«      }t        |t        «      r ||«      }|r|€t        d«      ‚yy)z�
        Validates that when use_redis_transaction_buffer is enabled,
        a Redis cache is properly configured in litellm_settings.
        r   ©r�  Úuse_redis_transaction_bufferFNa¨  `use_redis_transaction_buffer` is enabled in general_settings but no Redis is configured. This will cause spend updates to not be tracked. Add a Redis cache in litellm_settings:

litellm_settings:
  cache: true
  cache_params:
    type: redis
    url: os.environ/REDIS_URL

or set REDIS_* environment variables (e.g. REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, or REDIS_URL) to use a standalone Redis for the transaction buffer.)Úlitellm.secret_managers.mainr�  rp  rÓ  r‚  rs  )rW  rX  r�  Ú_use_redis_transaction_buffers       rˆ   r“  z;ProxyStartupEvent._validate_redis_transaction_buffer_configß"  sW   € õ 	=à;K×;OÑ;OÐPnÐpuÓ;vÐ%ÜÐ3´SÔ9Ù,7Ð8UÓ,VÐ)á(Ð->Ð-FÜð
4óð ð .GÐ(rŠ   rT  c              ƒ   óü  K  — 	 t        «       ƒ d{  –—† }|€yt	        di t        |«      ¤Ž}|j                  «       st        j                  d«       yt        |j                  d¬«      «      }t        || j                  dd«      du ¬«       |�(|j                  j                  €|j                  |¬	«       t        j                  d
«       |S 7 Œ¼# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)a0  
        Applies a coordination_redis block saved to the database, which the admin
        UI writes and the config file therefore never carries.

        Returns None when nothing is persisted or the persisted block names no
        connection target, leaving the file/env resolution untouched.
        Nz7Could not read coordination_redis from the database: %szQcoordination_redis saved in the database names no connection target; ignoring it.Tr·  r   Fr¹  rP  zƒcoordination_redis: using the standalone Redis saved in the database for usage tracking, rate limiting, and cross-pod coordination.rè  )r3  rÿ  rŸ   r/  rA   r  rº  r  r»  r$  rp  r  r  rr  r  )rT  rU  Ú	persistedr  r¼  r
  s         rˆ   rˆ  z2ProxyStartupEvent._init_coordination_redis_from_dbý"  s  è ø€ ð	Ü%NÓ%P×PˆIð ÐØä%<Ñ%oÔ?cÐdmÓ?nÑ%oÐØ"×8Ñ8Ô:Ü ×(Ñ(Øcôð ä*BÐCV×CaÑCaÐosÐCaÓCtÓ*uÐ Ü!Ø$Ø$4×$8Ñ$8Ð9RÐTYÓ$ZÐ^bÐ$bõ	
ð Ð! j×&6Ñ&6×&BÑ&BÐ&JØ×*Ñ*Ð1IÐ*ÔJÜ×!Ñ!ðMô	
ð (Ð'ð3  QùÜò 	Ü ×(Ñ(Ð)bÐdeÔfÜûð	üs>   ‚C<„C ‘C’C –B8C<ÃC Ã	C9ÃC4Ã/C<Ã4C9Ã9C<c                 ó|   — ddl m} | j                  dd«      }t        |t        «      r ||«      }|syt        «       S )a:  
        Builds a standalone Redis cache from REDIS_* environment variables so
        use_redis_transaction_buffer can run when the proxy cache backend is not
        Redis (e.g. disk, s3).

        Returns None when the buffer is disabled, or when no Redis host or url
        is set in the environment.
        r   r©
  rª
  FN)r«
  r�  rp  rÓ  r‚  r  )rW  r�  r¬
  s      rˆ   r‹  z5ProxyStartupEvent._get_transaction_buffer_redis_cache%#  sB   € õ 	=à;K×;OÑ;OÐPnÐpuÓ;vÐ%ÜÐ3´SÔ9Ù,7Ð8UÓ,VÐ)á,Øä8Ó:Ð:rŠ   c              ƒ   ó”  K  — ddl m} |j                  dd«      }|r|j                  dd«      st        j                  d«       yt        j                  d|du|«       |j                  ||¬	«      ƒ d{  –—† }|r5t        j                  d
«       t        j                  j                  |«       yt        j                  d«       y7 ŒQ­w)z1Initialize MCP semantic tool filter if configuredr   rÇ  rÉ  Nr»  FzKSemantic tool filter not configured or not enabled, skipping initializationz;Initializing semantic tool filter: llm_router=%s, config=%srÊ  z$Semantic tool filter hook registeredzASemantic tool filter hook was configured but failed to initialize)
rË  rÈ  rp  rŸ   r
  rÐ  r  rX  rY  r/  )r¢
  rU  rT  rÈ  rÑ  rÔ  s         rˆ   r—  z2ProxyStartupEvent._initialize_semantic_tool_filter<#  sÇ   è ø€ õ 	Sà,<×,@Ñ,@ÐA[Ð]aÓ,bÐ"ñ *Ð1K×1OÑ1OÐPYÐ[`Ô1aÜ ×&Ñ&Ð'tÔuØä×"Ñ"ØIØ˜dÐ"Ø&ô	
ð
 3×IÑIØ-Ø!ð Jó 
÷ 
ˆñ
 Ü ×&Ñ&Ð'MÔNÜ×,Ñ,×AÑAÀ$ÕGô !×(Ñ(Ð)lÕmð
ús   ‚A2CÁ4CÁ5ACrA  c                 ó4  — |j                  dd«      �d|d   j                  «       D ]9  \  }}t        |t        «      sŒ|j	                  d«      sŒ)t        |«      |d   |<   Œ; t        ddt        i|d   ¤Ž}n
t        «       }t        j                  |||¬«       y)zInitialize JWT auth on startuprõ  Nr  r=  )r÷  rA  rõ  rè  )
rp  râ  rÓ  r‚  r™  r|  rK   rê  r  rš  )r¢
  rW  r÷  rA  rF  rG  rõ  s          rˆ   r˜  z&ProxyStartupEvent._initialize_jwt_auth]#  s®   € ð ×ÑÐ 1°4Ó8ÐDØ(Ð):Ñ;×AÑAÓCò K‘��1Ü˜a¤Õ%¨!¯,©,°}Õ*EÜ=GÈ»]Ð$Ð%6Ñ7¸Ò:ðKô .ñ Ü!6ðà"Ð#4Ñ5ñ‰Oô
 .Ó/ˆOÜ×&Ñ&Ø'Ø1Ø+ð 	'õ 	
rŠ   c                 ó€   — t         j                  €t        d«      ‚t        j                  | j                  «       «       y)z Adds a global proxy budget to dbNzPbudget_duration not set on Proxy. budget_duration is required to use max_budget.)r  r¦  rÿ  rP  r‡  Ú+_upsert_proxy_budget_with_reset_at_backfill)r¢
  s    rˆ   r›  z)ProxyStartupEvent._add_proxy_budget_to_dbz#  s3   € ô ×"Ñ"Ð*ÜÐnÓoÐoä×Ñ˜C×KÑKÓMÕNrŠ   c              ƒ   ó  K  — t        ddt        dg i i dt        j                  t        j                  dt        j                  t        j                  dœ¬«      ƒ d{  –—†  t
        �gt        j                  �V	 t        t
        «      j                  j                  t        ddœt        t        j                  ¬«      dd	œ¬
«      ƒ d{  –—†  yyy7 Œr7 Œ	# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)a•  
        Upsert the proxy budget aggregate user row with the configured
        max_budget / budget_duration, then backfill budget_reset_at if
        currently NULL.

        The backfill uses `WHERE budget_reset_at IS NULL` so it only fires
        when the row pre-existed without a reset schedule (e.g. row created
        via a different path before the proxy budget was configured). On
        subsequent restarts it no-ops, so an active reset window is never
        slid forward. It also zeroes spend at that moment: a row that was
        never on a reset schedule holds lifetime accrual, which must not
        gate the first duration window.
        ÚuserNr   Úupdate_data)rd  r¦  )Úrequest_typer…  rb  rµ  rs   Úaliasesr^  rù  rd  r¦  Ú
query_typeÚupdate_key_values)rb  Úbudget_reset_at)r¦  )r»
  rù  r”  z9Failed to backfill budget_reset_at on proxy admin row: %s)r7  r¯   r  rd  r¦  r÷  ÚUserRepositoryrH  Úupdate_manyr  rÿ  rŸ   r/  )r¢
  r  s     rˆ   r³
  z=ProxyStartupEvent._upsert_proxy_budget_with_reset_at_backfill‚#  s  è ø€ ô %ØØÜ-ØØØØØÜ×)Ñ)Ü#×3Ñ3Ø$ä%×0Ñ0Ü#*×#:Ñ#:ñô
÷ 	
ð 	
ô, Ð$¬×)@Ñ)@Ð)LðmÜ$¤]Ó3×9Ñ9×EÑEä#<Ø+/ñô
 ,AÔQX×QhÑQhÔ+iØ!"ñð Fó 	÷ 	ñ 	ð *MÐ$ð-	
øð0	ùô ò mÜ$×,Ñ,Ð-hÐjk×lÑlûðmüsO   ‚AC?ÁCÁC?Á8AC ÃCÃC ÃC?ÃC Ã	C<ÃC7Ã2C?Ã7C<Ã<C?c              ƒ   ó¢   K  — 	 t         }t        |||¬«      ƒ d{  –—†  y7 Œ# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w­w)zSWarm global spend cache once at startup to reduce impact of first wave of requests.)r	  rA  r÷  Nz;Global spend cache warm-up at startup skipped or failed: %s)r­   rß   rÿ  rŸ   r
  )r¢
  rA  r÷  r	  r  s        rˆ   rœ  z*ProxyStartupEvent._warm_global_spend_cache¶#  sT   è ø€ ð	iÜ;ˆIÜ=Ø#Ø#5Ø+ô÷ ò ùô
 ò 	iÜ ×&Ñ&Ð'dÐfg×hÑhûð	iüs6   ‚A„# ›!œ#  A¡# £	A¬AÁAÁAÁA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 budgetNrq  c              3   ó<   K  — | ]  }t        |t        «      –— Œ y ­wrn  ©rÓ  rÔ  )r’  r°  s     rˆ   r”  zGProxyStartupEvent._update_default_team_member_budget.<locals>.<genexpr>Î#  s   è ø€ ÒD°Tœ* T¬4×0ÑDùs   ‚r   )Ú!update_default_team_member_budgetr¡  )rq  r*  rè  )
r  r  rp  r(  Ú7litellm.proxy.ui_crud_endpoints.proxy_setting_endpointsrÂ
  ÚNewUserRequestTeamrZ   rj  ré  )r¢
  Ú_teamsrÂ
  r°  Úteams_pydantic_objs        rˆ   rŸ  z4ProxyStartupEvent._update_default_team_member_budgetÇ#  s�   è ø€ ô ×/Ñ/Ð7Øä×<Ñ<×@Ñ@ÀÓIÒOÈRˆÙ”cÑD¸VÔDÔDõð QWÖ(WÈÔ);Ñ)C¸dÓ)CÐ(WÐÐ(WÙ3Ø(Ü"0´zÄ*Ó7MÔ"Nô÷ ñ ð Eˆ6ùò
 )Xðús   ‚ABÁBÁ'&BÂBÂBc              ƒ   ó\  K  — 	 ddl }ddlm} t        €yt	        dt        t        «      j                  j                  ddi¬«      ƒ d{  –—† «      }|r¤|j                  r—|j                  }t        |t        «      r |j                  |«      n
t        |«      }|D �ci c]  }||v sŒ|||   “Œ }}|rCt        j                  |«       t        j                   dt#        |j%                  «       «      «       yyyy7 Œ¯c c}w # t&        $ r }t        j(                  d	|«       Y d}~yd}~ww xY w­w)
z¢
        Load persisted UI settings from the database and sync runtime flags
        into general_settings so they take effect immediately after startup.
        r   N)Ú_RUNTIME_GENERAL_SETTINGS_FLAGSz_UISettingsRow | Noner.  r_  r�  z5Synced UI settings to general_settings on startup: %sz1UI settings sync on startup skipped or failed: %s)rm  rÃ
  rÈ
  r÷  r   ÚUISettingsRepositoryrH  rÙ  r_  rÓ  r‚  r„  rÔ  rW  rå  rŸ   r  r•  r–  rÿ  r
  )	r¢
  rm  rÈ
  rï  rZ
  r_  rF  Úflags_to_syncr  s	            rˆ   r   z7ProxyStartupEvent._sync_ui_settings_to_general_settingsÙ#  s#  è ø€ ð	_Ûõô Ð$ØÜ6:Ø'Ü*¬=Ó9×?Ñ?×KÑKÐSWÐYfÐRgÐKÓh×hó7ˆIñ ˜Y×2Ò2Ø&×2Ñ2�Ü8BÀ3ÌÔ8L Z T§Z¡Z°¤_ÔRVÐWZÓR[�ØCbÖ'w¸aÐfgÐkvÒfv¨¨;°q©>Ñ(9Ð'w�Ð'wÙ Ü$×+Ñ+¨MÔ:Ü(×-Ñ-ØOÜ˜]×/Ñ/Ó1Ó2õð !ð	 3ˆyð iúò
 (xøô ò 	_Ü ×&Ñ&Ð'ZÐ\]×^Ñ^ûð	_üsd   ‚D,„D  ”D,•4D  Á	C9
Á
AD  Â	C;Â'C;Â/AD  Ã5D,Ã9D  Ã;D  Ä 	D)Ä	D$ÄD,Ä$D)Ä)D,re  rf  rg  c           
   ƒ   óN  ‡‡‡#‡$K  — ddl m} ddlm} t	        t
        t        t        dœd |«       id |«       id¬«      a|t        j                  dt        d||z
  «      «      z   }	|t        j                  dd	«      z   }
t        ‰¬
«      }|j                  «       ƒ d{  –—†  t        j                  |j                  dt        ddt        ¬«       |j!                  dd«      du rTt#        ‰‰t%        «       ‰j&                  j(                  ¬«      }t        j                  |j*                  d|	ddt        ¬«       t        j                  t,        d|
‰t.        ‰gddt        ¬«       t1        |
t2        z  «      }ddlm} t        j                  |d|‰‰gddt        ¬«       t9        j:                  d|› d||
z  d›d�«       t        j                  t<        d|
‰t>        fddt        ¬«       |j!                  dd«      du r/ddlm } tC        jD                   |‰t.        ‰¬«      «      }|‰_#        tI        dtJ        «      xs tJ        a%tJ        dur�‰�›	 tM        ‰«      jO                  d d!i¬"«      ƒ d{  –—† }|�stQ        |jR                  tT        «      rY|jR                  j!                  d#«      }|du s#tQ        |tV        «      r*|jY                  «       d$k(  rda%t9        j:                  d%«       t^        }tQ        |t0        «      r|dk  rt9        j`                  d'|«       d}t        j                  tb        jd                  d|‰gd(dt        ¬«       tb        jg                  th        tj        ¬)«       tJ        du r¸t        j                  tb        jl                  d|‰gd*dt        ¬«       tb        jm                  ‰¬
«      ƒ d{  –—†  t        j                  tb        jn                  d|‰‰gd+dt        ¬«       tb        jo                  ‰‰¬,«      ƒ d{  –—†  tb        jq                  ‰‰th        ¬-«       tJ        dur±tb        js                  «       ƒ d{  –—†  tb        ju                  «       ƒ d{  –—†  ‰�wt        j                  tb        jt                  d|d.dt        ¬«       t^        }tQ        |t0        «      r|dk  rd}t        j                  tb        jv                  d|d/dt        ¬«       | jy                  t        |‰‰¬0«      ƒ d{  –—†  | j{                  t        ¬1«      ƒ d{  –—†  dd2l>m?}  |«       rUdd3l@mA}mBŠ$ d4tV        d5dfˆfd6„Š#dZˆ#ˆˆˆ$fd7„}t        j                  |d8dd9d:|dt        ¬;«       t9        j:                  d<«       |j!                  d=«      €"|j!                  d>«      €|j!                  d?«      �Öt‡        «       }|j!                  d@«      }|rYddAlDmE} 	 |j�                  |«      }t        j                  |jŽ                  |‰gdBdt        ¬C«       t9        j:                  dD|«       n`|j!                  dFdG«      }	 t•        |«      }t        j                  |jŽ                  d|t        j                  ddH«      z   ‰gdBdt        ¬«       t–        �žt˜        r˜	 ddJlMmN}  |‰‰t–        |j!                  dKd«      ¬L«      } | jŸ                  «       ƒ d{  –—†  t        j                  | j                   dt¢        t        j                  dd«      z   dMdt        ¬«       t9        j:                  dN«       t–        �ut˜        ro	 ddQlRmS}!  |!‰‰t–        ¬R«      }"t        j                  |"j¨                  dt¢        t        j                  dd«      z   dSdt        ¬«       t9        j:                  dT«       t«        t        «       t­        t        t¯        |«      ¬W«       t        j±                  d¬X«       t9        j:                  dYt        «       |S 7 �Œg7 �Œ›# tZ        $ r*}t9        j\                  d&tW        |«      «       Y d}~�ŒRd}~ww xY w7 �Œ‰7 �Œ=7 �Œ 7 �Œç7 �ŒP7 �Œ5# t�        $ r t9        j’                  dE|«       Y �Œêw xY w# t�        $ r t9        j’                  dI«       Y �Œw xY w7 �ŒÍ# tZ        $ r6}t9        j\                  dO|«       t9        j\                  dP«       Y d}~�Œ¬d}~ww xY w# tZ        $ r6}t9        j\                  dU|«       t9        j\                  dV«       Y d}~�Œsd}~ww xY w­w)[z%Initializes scheduled background jobsr   )ÚAsyncIOExecutor)ÚMemoryJobStore)ÚcoalescerG  Úmax_instancesr‹   N)Újob_defaultsÚ	jobstoresÚ	executorsr   é   rJ  r‘  ÚintervalÚproxy_worker_heartbeat_jobT)rL  r.  rF  rG  Údisable_reset_budgetF)rý  r÷  Úreset_settingsÚpod_lock_managerÚreset_budget_jobÚupdate_spend_job)rL  r  r.  rF  rG  )Úupdate_daily_tag_spendÚupdate_daily_tag_spend_jobz"Tag spend update job scheduled at zs interval (z.1fzx main job interval)Úupdate_gateway_requests_jobr<  )Ú_monitor_spend_logs_queuerû  ÚSTORE_MODEL_IN_DBrT  rW  r�  r4  r§  z<store_model_in_db=True loaded from DB, overriding config/envz,Failed to check DB for store_model_in_db: %szWproxy_config_reload_interval_seconds=%s must be a positive integer; falling back to 30sÚperiodic_reload_job)r  rA  Úget_credentials_jobÚadd_deployment_jobrŒ  )r÷  rý  r  Úreload_search_tools_jobÚreload_mcp_servers_job)rQ  rW  rý  r÷  ©rQ  )Úis_ptu_cost_attribution_enabled)ÚPTU_ROLLUP_JOB_IDÚrun_scheduled_ptu_rollupr�   rÐ  c              “   óf   •K  — ‰j                  | dt        j                  ¬«      ƒ d {  –—†  y 7 Œ­w)NÚHigh)r�   r¬	  Ú
alert_type)Úalerting_handlerr‚  Úfailed_tracking_spend)r�   rý  s    €rˆ   Ú_alert_ptu_rollup_failurezYProxyStartupEvent.initialize_scheduled_background_jobs.<locals>._alert_ptu_rollup_failure%  s3   øè ø€ Ø'×8Ñ8Ø#Ø Ü(×>Ñ>ð 9ó ÷ ò ús   ƒ&1©/ª1c               “   ój   •K  —  ‰‰‰j                   j                  ‰ t        ¬«      ƒ d {  –—†  y 7 Œ­w)N)rØ
  ÚalertrÎ   )rû  rØ
  rU  )rî
  r÷  rý  rè
  s   €€€€rˆ   Ú_scheduled_ptu_rollupzUProxyStartupEvent.initialize_scheduled_background_jobs.<locals>._scheduled_ptu_rollup%  s3   øè ø€ ñ /Ø!Ø%6×%MÑ%M×%^Ñ%^Ø3Ü%ô	÷ ò ús   ƒ(3«1¬3Úcroné   ÚUTC)ÚhourÚminuter   r.  rF  rG  zZPTU rollup job scheduled at 00:15 UTC daily (only models with PTU config accrue flat cost)r?  r@  rA  rB  rC  r>  rE  z)Spend log cleanup scheduled with cron: %srH  rI  rJ  r‘   rP  )ÚCheckBatchCostÚtrack_unmanaged_batch_cost)rý  r÷  rU  rø
  Úcheck_batch_cost_jobz+Batch cost check job scheduled successfullyz'Failed to setup batch cost checking: %szSChecking batch cost for LiteLLM Managed Files is an Enterprise Feature. Skipping...)ÚCheckResponsesCost)rý  r÷  rU  Úcheck_responses_cost_jobz/Responses cost check job scheduled successfullyz+Failed to setup responses cost checking: %szWChecking responses cost for LiteLLM Managed Files is an Enterprise Feature. Skipping...)rQ  r  )ÚpausedztAPScheduler started with memory leak prevention settings: removed jitter, increased intervals, misfire_grace_time=%srl  )YÚapscheduler.executors.asynciorÌ
  Úapscheduler.jobstores.memoryrÍ
  r�   r¥   r§   r¦   rQ  r”   ÚrandintrÉ  r  ÚbeatrV  r  rp  r  r
  rû  rØ
  Úreset_budgetrp  rü  r"  r+   rþ  rÛ
  rŸ   r  r  r	  rÞ
  rP  r‡  Úspend_logs_queue_monitor_taskr}  r4  rw  r•  rÓ  rU  rÔ  r‚  rÉ  rÿ  r
  r;  r/  r~  rû  r¦  rX  rA  rš  rŽ  rŸ  ru	  rŒ	  rw	  Ú_initialize_slack_alerting_jobsÚ*_initialize_spend_tracking_background_jobsÚ-litellm.proxy.spend_tracking.ptu_feature_flagræ
  Ú1litellm.proxy.spend_tracking.ptu_flat_cost_rolluprç
  rè
  r  rT  rD  rU  rW  rs  rz  r6  rU  r³   Ú6litellm_enterprise.proxy.common_utils.check_batch_costr÷
  Úconfirm_batch_processed_supportÚcheck_batch_costr:  Ú:litellm_enterprise.proxy.common_utils.check_responses_costrú
  Úcheck_responses_costr  r  r  r�  )%r¢
  rW  r÷  re  rf  rg  rý  rÌ
  rÍ
  Úbudget_intervalÚbatch_writing_intervalr  Úbudget_reset_jobÚtag_spend_update_intervalrÛ
  rÞ
  Úmonitor_taskÚ_db_gs_recordÚ_db_valr  Úconfig_reload_interval_secondsÚmcp_reload_interval_secondsræ
  rç
  rñ
  r\  r]  rD  r^  r_  r`  r÷
  rù
  rú
  rû
  rî
  rè
  s%     `   `                            @@rˆ   rž  z6ProxyStartupEvent.initialize_scheduled_background_jobsù#  so	  ûè ø€ õ( 	BÝ?ä$ä0Ü&DÜ!:ñð !¡.Ó"2Ð3ð ™?Ó,ðð ô
ˆ	ð( "CÄVÇ^Á^ØÜØØ1Ð4UÑUóóF
ñ "
ˆð )=¼v¿~¹~ÈaÐQRÓ?SÑ(SÐô #7À]Ô"SÐØ×#Ñ#Ó%×%Ð%Ü×ÑØ×!Ñ!ØÜ;Ø+Ø!Ü=ð 	ô 	
ð ×ÑÐ 6¸Ó>À%ÑGÜ&4Ø"3Ø+Ü8Ó:Ø!2×!IÑ!I×!ZÑ!Zô	'Ðô ×ÑØ ×-Ñ-ØØ'à%Ø!%Ü#Að ô ô 	×ÑÜØØ*àÔ!1Ð3DÐEØ!Ø!Ü=ð 	ô 		
ô ,/Ð/EÔHhÑ/hÓ+iÐ!Ý>ä×ÑØ"ØØ-ØÐ!2Ð3Ø+Ø!Ü=ð 	ô 	
ô 	×!Ñ!Ø0Ð1JÐ0Kð LØ)Ð,BÑBÀ3ÐGÐG[ð]ô	
ô 	×ÑÜ"ØØ*ØÔ!<Ð=Ø,Ø!Ü=ð 	ô 	
ð ×ÑÐ 4°eÓ<ÀÑEÝEä")×"5Ñ"5Ù)Ø"/Ü%5Ø&7ôó#ˆLð ;GˆMÔ7ô ,Ð,?ÔARÓSÒhÔWhÐô
  DÑ(¨]Ð-Fð
cÜEXÐYfÓEg×ErÑErØ'Ð);Ð<ð Fsó F÷ @�ð !Ð,´¸M×<UÑ<UÔW[Ô1\Ø%2×%>Ñ%>×%BÑ%BÐCVÓ%W�GØ $‘¬:°g¼sÔ+CÈÏÉËÐ[aÒHaØ,0Ð)Ü,×1Ñ1Ð2pÔqô *NÐ&ÜÐ8¼#Ô>ÐB`ÐdeÒBeÜ ×(Ñ(ØiØ.ôð .0Ð*ô 	×ÑÜ×/Ñ/ØØ2Ø�Ø$Ø!Ü=ð 	ô 	
ô 	×=Ñ=Ü)Ü1ð 	>ô 	
ô
  Ñ$ä×ÑÜ×,Ñ,ØØ6à#�_Ø(Ø!%Ü#Að ô 	ô ×.Ñ.¸]Ð.ÓK×KÐKô ×ÑÜ×+Ñ+ØØ6à#Ð%6Ð7Ø'Ø!%Ü#Að ô 	ô ×-Ñ-¸MÐ]nÐ-Óo×oÐoä×5Ñ5Ø+Ø"3Ü-ð 6ô ô  DÑ(Ü×7Ñ7Ó9×9Ð9ô ×:Ñ:Ó<×<Ð<ØÐ(Ü×!Ñ!Ü ×<Ñ<ØØ:Ø0Ø%)Ü'Eð "ô ô /SÐ+Ü!Ð"=¼sÔCÐGbÐfgÒGgØ24Ð/Ü×!Ñ!Ü ×;Ñ;ØØ7Ø/Ø%)Ü'Eð "ô ð ×1Ñ1ÜØ-Ø/Ø'ð	 2ó 
÷ 	
ð 	
ð ×<Ñ<ÄyÐ<ÓQ×QÐQõ	
ñ +Ô,÷ð
¼ð Àõ ÷ð ô ×ÑØ%ØØØØØ$Ø!%Ü#Að ô 	ô !×%Ñ%Ølôð × Ñ Ð!FÓGÐSØ×#Ñ#Ð$QÓRÐ^Ø×#Ñ#Ð$KÓLÐXä'6Ó'8ÐØ"2×"6Ñ"6Ð7XÓ"YˆLáÝAðrØ*5×*BÑ*BÀ<Ó*P�LÜ×%Ñ%Ø)×@Ñ@Ø$Ø+˜_Ø2Ø)-Ü+Ið &ô ô )×-Ñ-Ð.YÐ[gÕhð
 -=×,@Ñ,@ÐAhÐjnÓ,oÐ"ðfÜ.AÐBTÓ.UÐ$Ü×%Ñ%Ø)×@Ñ@Ø"Ø 0´6·>±>À!ÀRÓ3HÑ HØ+˜_Ø2Ø)-Ü+Ið &ô ô Ð!Õ&Aðõñ /=Ø&7Ø"/Ü)Ø/?×/CÑ/CÐD`ÐbgÓ/hô	/Ð$ð +×JÑJÓL×LÐLÜ×!Ñ!Ø(×9Ñ9ØÜ8¼6¿>¹>È!ÈRÓ;PÑPà-Ø%)Ü'Eð "ô ô %×)Ñ)Ð*WÔXô Ð!Õ&Aðõñ 3EØ&7Ø"/Ü)ô3Ð(ô
 ×!Ñ!Ø,×AÑAØÜ8¼6¿>¹>È!ÈRÓ;PÑPà1Ø%)Ü'Eð "ô ô %×)Ñ)Ð*[Ô\ô 	!¤Ô+Ü#ÜÜ+Ð,<Ó=õ	
ô 	�‰˜uˆÔ%Ü×!Ñ!ð CÜ*ô	
ð  ÐðW 	&ùðx@úô ò cÜ$×*Ñ*Ð+YÔ[^Ð_`Ó[a×bÒbûðcúðN Lùð  pùð :ùð =ùð4	
ùð 	RúôF "ò rÜ(×.Ñ.Ð/bÐdp×qðrûô  "ò fÜ(×.Ñ.Ð/d×eðfúð Múô ò Ü$×*Ñ*Ð+TÐVWÔXÜ$×*Ñ*Øi÷ò ûðûô: ò Ü$×*Ñ*Ð+XÐZ[Ô\Ü$×*Ñ*Øm÷ò ûðüsm  †Bd%Â`ÂF-d%É ` É-`É.A9` Ë'Cd%Î8aÎ9Ad%ÐaÐ?d%ÑaÑd%Ñ#a
Ñ$Bd%Ó=aÓ>d%ÔaÔB<d%×Aa Ø*d%Ø>Aa9 Úd%Ú9b! ÛbÛAb! Ü/d%Ü<A.c# Þ*Ad%à` à	`>à`9à3d%à9`>à>d%ád%ád%á
d%ád%ád%áa6á2d%á5a6á6d%á9bâd%âbâd%âb! â!	c â*+cãd%ãc ã d%ã#	d"ã,+däd%äd"ä"d%rQ  c              ƒ   ó^  K  — ddl m} ddlm} ddlm}  |«       ƒ d{  –—† r|j                  |¬«      ƒ d{  –—†  |j                  |¬«      ƒ d{  –—†  ddlm	} ddl
m}m}m}m}	  |«       ƒ d{  –—† r™ |«       sx |	«       ƒ d{  –—† ri	  |«       ƒ d{  –—† }
|
rW ||
j                  d	«      |
j                  d
«      |
j                  d«      ¬«      }t         j"                  j%                  |«       |j-                  |¬«      ƒ d{  –—†  ddlm} |j3                  |¬«      ƒ d{  –—†  t         j4                  du rddlm} |j;                  |¬«       ddlm}m } tC        |«      }t)        jD                  d|«       |du r�	 ddl#m$} tJ        �^tL        jN                  jP                  } |tJ        |¬«      }t)        jD                  d|«       |jS                  |jT                  d|d¬«       nt)        j*                  d«       nt)        jD                  d«       | jW                  |¬«      ƒ d{  –—†  y7 �Œ7 �Œ7 �Œí7 �ŒÏ7 �Œ¼7 �Œ¯# t&        $ r!}t)        j*                  d|«       Y d}~�Œyd}~ww xY w7 �Œl7 �ŒO# t&        $ r }t)        j*                  d|«       Y d}~Œ„d}~ww xY w7 Œv­w)a+  
        Initialize the spend tracking and other background jobs
        1. CloudZero Background Job
        2. Focus Background Job
        3. Prometheus Background Job
        4. Key Rotation Background Job

        Args:
            scheduler: The scheduler to add the background jobs to
        r   )ÚCloudZeroLogger)ÚFocusLogger)Úis_cloudzero_setupNrå
  )ÚVantageLogger)Ú_get_vantage_settingsÚis_vantage_setupÚis_vantage_setup_in_configÚis_vantage_setup_in_dbÚapi_keyÚintegration_tokenÚbase_url)r  r  r   z5Failed to register VantageLogger from DB settings: %s)ÚMavvrikFocusLoggerTr  )Ú+LITELLM_KEY_ROTATION_CHECK_INTERVAL_SECONDSÚLITELLM_KEY_ROTATION_ENABLEDzkey_rotation_enabled: %s)ÚKeyRotationManager)rØ
  zZKey rotation background job scheduled every %s seconds (LITELLM_KEY_ROTATION_ENABLED=true)rÔ
  Úkey_rotation_job©rL  r.  z4Key rotation enabled but prisma_client not availablez$Failed to setup key rotation job: %szGKey rotation disabled (set LITELLM_KEY_ROTATION_ENABLED=true to enable)),Ú(litellm.integrations.cloudzero.cloudzeror  Ú'litellm.integrations.focus.focus_loggerr  Ú0litellm.proxy.spend_tracking.cloudzero_endpointsr  Úinit_cloudzero_background_jobÚ init_focus_export_background_jobÚ+litellm.integrations.vantage.vantage_loggerr  Ú.litellm.proxy.spend_tracking.vantage_endpointsr  r  r  r  rp  r  rX  rY  rÿ  rŸ   r/  Úinit_vantage_background_jobÚ7litellm.integrations.mavvrik_focus.mavvrik_focus_loggerr!  Ú!init_mavvrik_focus_background_jobÚ$prometheus_initialize_budget_metricsr_  r  Ú"initialize_budget_metrics_cron_jobÚlitellm.constantsr"  r#  r�  r
  Ú/litellm.proxy.common_utils.key_rotation_managerr$  r÷  rý  rû  rØ
  rV  Úprocess_rotationsÚ9_initialize_expired_ui_session_key_cleanup_background_job)r¢
  rQ  r  r  r  r  r  r  r  r  Údb_settingsÚvantage_loggerr  r!  r  r"  r#  Úkey_rotation_enabledr$  rØ
  Úkey_rotation_managers                        rˆ   r  z<ProxyStartupEvent._initialize_spend_tracking_background_jobsž%  s”  è ø€ õ& 	MÝGÝWá#Ó%×%Ð%Ø!×?Ñ?È)Ð?ÓT×TÐTð
 ×:Ñ:ÀYÐ:ÓO×OÐOõ
 	N÷	
ó 	
ñ "Ó#×#Ð#ñ .Ô/Ñ:PÓ:R×4RÐ4Rð
mÙ/DÓ/F×)F�KÙ"Ù0=Ø$/§O¡O°IÓ$>Ø.9¯o©oÐ>QÓ.RØ%0§_¡_°ZÓ%@ô1˜ô
  ×8Ñ8×MÑMÈnÔ]ð  ×;Ñ;ÀiÐ;ÓP×PÐPõ
	
ð !×BÑBÈYÐBÓW×WÐWô
 ×7Ñ7¸4Ñ?ÝHà×?Ñ?È)Ð?ÔT÷	
ô
 4?Ð?[Ó3\ÐÜ×"Ñ"Ð#=Ð?SÔTà 4Ñ'ðXõô
 !Ð,ä.?×.VÑ.V×.gÑ.gÐ$Ù2DÜ%Ø)9ô3Ð(ô )×.Ñ.ØtØCôð ×%Ñ%Ø,×>Ñ>Ø"Ø KØ-ð	 &õ ô )×0Ñ0Ð1gÔhøô !×&Ñ&Ð'pÔqà×KÑKÐV_ÐKÓ`×`Ñ`ð &ùØTùð
 	Pùð $ùð 5Sùà)Fúô !ò mÜ(×0Ñ0Ð1hÐjk×lÒlûðmúàPùð 	Xúô\ ò XÜ$×,Ñ,Ð-SÐUV×WÑWûðXúð
 	aúsè   ‚J-ŸH: J-¹H=ºJ-ÁI Á J-Á4IÁ5J-Â
IÂJ-Â
I ÂI	ÂAI Ã8J-ÄI9ÄJ-Ä-I<Ä.AJ-Æ
A?I? È	+J-È4J+È5J-È=J-É J-ÉJ-ÉJ-É	I É	I6ÉI1É+J-É1I6É6J-É<J-É?	J(ÊJ#ÊJ-Ê#J(Ê(J-c              ƒ   óú  K  — ddl m}m}m} t	        |«      }t        j                  d|«       |du r‡	 ddlm} t        �ct        j                  j                  } |t        t        |¬«      }t        j                  d|«       |j                  |j                  d	||¬
«       nt        j                   d«       yyt        j                  d«       y# t"        $ r }	t        j                   d|	«       Y d}	~	yd}	~	ww xY w­w)zO
        Initialize the expired UI session key cleanup background job.
        r   )Ú'EXPIRED_UI_SESSION_KEY_CLEANUP_JOB_NAMEÚ.LITELLM_EXPIRED_UI_SESSION_KEY_CLEANUP_ENABLEDÚ7LITELLM_EXPIRED_UI_SESSION_KEY_CLEANUP_INTERVAL_SECONDSz*expired_ui_session_key_cleanup_enabled: %sT)Ú!ExpiredUISessionKeyCleanupManagerN)r÷  rA  rØ
  z~Expired UI session key cleanup background job scheduled every %s seconds (LITELLM_EXPIRED_UI_SESSION_KEY_CLEANUP_ENABLED=true)rÔ
  r&  zFExpired UI session key cleanup enabled but prisma_client not availablez6Failed to setup expired UI session key cleanup job: %szkExpired UI session key cleanup disabled (set LITELLM_EXPIRED_UI_SESSION_KEY_CLEANUP_ENABLED=true to enable))r3  r<  r=  r>  r�  rŸ   r
  ÚAlitellm.proxy.common_utils.expired_ui_session_key_cleanup_managerr?  r÷  rý  rû  rØ
  rA  rV  Úcleanup_expired_keysr/  rÿ  )
r¢
  rQ  r<  r=  r>  Ú&expired_ui_session_key_cleanup_enabledr?  rØ
  Ú&expired_ui_session_key_cleanup_managerr  s
             rˆ   r6  zKProxyStartupEvent._initialize_expired_ui_session_key_cleanup_background_job&  s  è ø€ ÷	
ñ 	
ô FQØ:óF
Ð.ô 	×"Ñ"Ð#OÐQwÔxà1°TÑ9ðjõô !Ð,Ü.?×.VÑ.V×.gÑ.gÐ$ÙDeÜ&3Ü+=Ø)9ôEÐ:ô
 )×.Ñ.ð YØOôð ×%Ñ%Ø>×SÑSØ"Ø WØBð	 &õ ô )×0Ñ0Ø`õðô !×&Ñ&ðQõøô ò jÜ$×,Ñ,Ð-eÐgh×iÑiûðjüs/   ‚0C;³BC Â7C;Ã	C8ÃC3Ã.C;Ã3C8Ã8C;c              ƒ   óú  ‡‡
‡‡K  — ‰��n‰j                   j                  ��V|��Rt        d«       |j                  dd«      xs dŠt	        ‰dd «      }‰d   j                  «       dk7  s|dk  rt        d«      ‚‰j                  j                  Š
t        ‰«      d	z
  Šdˆ
ˆˆˆfd
„}dˆ
ˆfd„}|j                  |d|t        j                  «       t        dt        j                  dd«      z   ¬«      z   t         dt"        ¬«       |j                  |ddt$        d¬«       t'        j(                  d«      rCddlm} dˆ
ˆfd„}	|j                  |	dt.        d |d«      t0        d¬«        |	«       ƒ d{  –—†  yyyyy7 Œ	­w)z<Initialize Slack alerting background jobs for spend reports.Nz3Alerting: Initializing Weekly/Monthly Spend ReportsÚspend_report_frequencyÚ7dr/
  rz  r   zJspend_report_frequency must be a positive number of days, e.g., '1d', '7d'r+  c               “   ó¢   •K  — ‰ j                  t        ‰d¬«      ƒ d {  –—† du ry ‰j                  j                  ‰«      ƒ d {  –—†  y 7 Œ+7 Œ­w)NF©Ú
cronjob_idr‹  Úallow_reentrant)Úacquire_lockr¹   r8  Úsend_weekly_spend_report)rØ
  rý  rE  Úweekly_lock_ttls   €€€€rˆ   Ú_scheduled_weekly_spend_reportzYProxyStartupEvent._initialize_slack_alerting_jobs.<locals>._scheduled_weekly_spend_reporth&  s_   øè ø€ ð
 +×7Ñ7Ü#=À?Ðdið 8ó ÷ ð ñð
 Ø'×?Ñ?×XÑXÐYoÓp×pÑpðøð qús!   ƒAŸA %AÁAÁAÁAc               “   ó    •K  — ‰ j                  t        dd¬«      ƒ d {  –—† du ry ‰j                  j                  «       ƒ d {  –—†  y 7 Œ*7 Œ­w©Nr+  FrH  )rK  r°   r8  Úsend_monthly_spend_report©rØ
  rý  s   €€rˆ   Ú_scheduled_monthly_spend_reportzZProxyStartupEvent._initialize_slack_alerting_jobs.<locals>._scheduled_monthly_spend_reportu&  sZ   øè ø€ à*×7Ñ7Ü#>ÀDÐZ_ð 8ó ÷ ð ñð
 Ø'×?Ñ?×YÑYÓ[×[Ñ[ðøð \úó!   ƒAŸA
 $AÁAÁAÁArÔ
  r«  i,  rK  T)ÚdaysÚnext_run_timer.  rF  rG  rò
  r8  )r~  r.  rF  ÚPROMETHEUS_URL)ÚZoneInfoc               “   ó    •K  — ‰ j                  t        dd¬«      ƒ d {  –—† du ry ‰j                  j                  «       ƒ d {  –—†  y 7 Œ*7 Œ­wrP  )rK  r±   r8  Ú#send_fallback_stats_from_prometheusrR  s   €€rˆ   Ú_scheduled_fallback_statszTProxyStartupEvent._initialize_slack_alerting_jobs.<locals>._scheduled_fallback_stats”&  sZ   øè ø€ à.×;Ñ;Ü'GÈTÐchð <ó ÷ ð !ñ!ð
 Ø+×CÑC×gÑgÓi×iÑiðøð júrT  zAmerica/Los_Angeles)rõ
  rö
  r   r.  rF  rl  )r8  r¼  r–   rp  r"  rÉ  rs  rû  rØ
  r6  rV  r
   rh
  r   r”   rÿ
  r¹   r§   r°   rn  r¨  ÚzoneinforX  r²   r±   )r¢
  rQ  rW  rý  r÷  rU  rN  rS  rX  r[  rØ
  rE  rM  s      `      @@@rˆ   r  z1ProxyStartupEvent._initialize_slack_alerting_jobsP&  sœ  ûè ø€ ð Ñ)Ø!×9Ñ9×BÑBÑNØÑ)äÐGÔHØ1A×1EÑ1EÐF^Ð`dÓ1eÒ1mÐimÐ"äÐ4°S°bÐ9Ó:ˆDØ% bÑ)×/Ñ/Ó1°SÒ8¸DÀAºIÜ Ð!mÓnÐnà&7×&NÑ&N×&_Ñ&_ÐÜ%8Ð9OÓ%PÐSWÑ%WˆO÷qð qö\ð ×ÑØ.ØØÜ&Ÿl™l›n¬yÀÄfÇnÁnÐUVÐX[ÓF\ÑA\Ô/]Ñ]Ü-Ø!%Ü#Að ô ð ×ÑØ/ØØÜ.Ø!%ð ô ô �y‰yÐ)Ô*Ý-öjð ×!Ñ!Ø-ØÜBØÙ%Ð&;Ó<Ü7Ø%)ð "ô ñ 0Ó1×1Ñ1ð- +ðk *ð Oð *ðZ 2ús   †E)E;Å/E9Å0
E;rÊ  c              ƒ   ó†  K  — d}	 |€yt        ||¬«      }	 |j                  «       ƒ d{  –—†  |}t        |d«      r8t        |j                  d	«      r"|j                  j                  «       ƒ d{  –—†  t        j                  |j                  «       «       t        j                  |j                  «       «       t        |d
«      r|j                  «       ƒ d{  –—†  t        dd«      dur|j                  «       ƒ d{  –—†  |S 7 ŒÜ# t        $ r`}dt        |«      v sdt        |«      v r?t	        j
                  d«       t	        j
                  d«       t	        j
                  d«       |‚d}~ww xY w7 �Œ7 Œ�7 Œy# t        $ r9}t!        j"                  |«       |�t	        j$                  d|«       |cY d}~S d}~ww xY w­w)zQ
        - Sets up prisma client
        - Adds necessary views to proxy
        N)rÊ  rý  ÚP3018ÚP3009z#CRITICAL: DATABASE MIGRATION FAILEDz$Your database is in a 'dirty' state.z<FIX: Run 'prisma migrate resolve --applied <migration_name>'ri  Ústart_token_refresh_taskÚstart_db_health_watchdog_taskÚ&DISABLE_PRISMA_HEALTH_CHECK_ON_STARTUPFTz£Retaining the connected Prisma client after a post-connect startup step failed: %s. The DB health watchdog keeps probing and reconnects once the database recovers.)rY  Úconnectrÿ  r‚  rŸ   r
  r¬  ri  r`  rP  r‡  Úcheck_view_existsÚ(_set_spend_logs_row_count_in_proxy_statera  r}  Úhealth_checkr  Úhandle_db_exceptionr/  )r¢
  rÊ  rý  rA  Úconnected_clientr÷  r  s          rˆ   r†  z&ProxyStartupEvent._setup_prisma_client©&  s´  è ø€ ð 15Ðð0	$ØÐ#Øä(°lÐVgÔhˆMðØ#×+Ñ+Ó-×-Ð-ð  -Ðô
 �} dÔ+´¸×8HÑ8HÐJdÔ0eØ#×&Ñ&×?Ñ?ÓA×AÐAô ×ÑØ×/Ñ/Ó1ôô ×ÑØ×FÑFÓHôô �}Ð&EÔFØ#×AÑAÓC×CÐCô ÐGÈÓOÐW[Ñ[Ø#×0Ñ0Ó2×2Ð2à Ð ðA .ùÜò Øœc !›fÑ$¨´3°q³6Ñ(9Ü(×.Ñ.Ð/TÔUÜ(×.Ñ.Ð/UÔVÜ(×.Ñ.Ð/mÔnØ�ûðúð Bùð Døð 3ùô ò 	$Ü$×8Ñ8¸Ô;ØÐ+Ü$×,Ñ,ðfàôð
 $Õ#ûð	$üs£   ‚G†E< ˆG‰E< —D	 ªD«D	 ¯AE< Á0E5Á1A)E< ÃE8Ã%E< Ä E:ÄE< ÄGÄD	 Ä		E2ÄAE-Å-E2Å2E< Å8E< Å:E< Å<	F>Æ.F9Æ3F>Æ4GÆ9F>Æ>G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_tracingrj  rk  ÚddtraceÚ	patch_allÚddtrace.profilingrm  r�  rŸ   r
  )r¢
  rj  rk  ro  rm  Úprofs         rˆ   r§  z!ProxyStartupEvent._init_dd_tracerç&  sR   € ÷	
ñ
 !Ô"Ûà×Ñ d°5ÐÔ9á"Ô$Ý2á"›*ˆDØ�J‰JŒLÜ ×&Ñ&Ð'GÕHð %rŠ   c                 ót  — t        dd«      st        j                  d«       y	 ddl}t	        j
                  d«      }|st        d«      ‚t	        j
                  d«      }|st        d	«      ‚i }t	        j
                  d
«      xs t	        j
                  d«      }|r||d<   t	        j
                  d«      }t        t        dd¬«      «      }t        t        dd¬«      «      }|r|st        d«      ‚|r|st        d«      ‚|||r|nddœ}	|r|r
||	d<   ||	d<   |�	 t        t        |«      «      |	d<    |j                  di |	¤Ž d|› d|› d|› d�}
d|	v r|
d|	d   › �z  }
t        j                  |
«       y# t        t        f$ r t        d|›�«      ‚w xY w# t        $ r t        j                  d«       Y yw xY w)aé  
        Optional continuous profiling via Grafana Pyroscope.

        Off by default. Enable with LITELLM_ENABLE_PYROSCOPE=true.
        Requires: pip install pyroscope-io (optional dependency).
        When enabled, PYROSCOPE_SERVER_ADDRESS and PYROSCOPE_APP_NAME are required (no defaults).
        Optional: PYROSCOPE_SAMPLE_RATE (parsed as integer) to set the sample rate.
        Optional: PYROSCOPE_GRAFANA_USER and PYROSCOPE_GRAFANA_API_TOKEN for Grafana Cloud basic auth.
        ÚLITELLM_ENABLE_PYROSCOPEFzWLiteLLM: Pyroscope profiling is disabled (set LITELLM_ENABLE_PYROSCOPE=true to enable).Nr   ÚPYROSCOPE_APP_NAMEzsLITELLM_ENABLE_PYROSCOPE is true but PYROSCOPE_APP_NAME is not set. Set PYROSCOPE_APP_NAME when enabling Pyroscope.ÚPYROSCOPE_SERVER_ADDRESSzLITELLM_ENABLE_PYROSCOPE is true but PYROSCOPE_SERVER_ADDRESS is not set. Set PYROSCOPE_SERVER_ADDRESS when enabling Pyroscope.ÚOTEL_ENVIRONMENT_NAMEÚLITELLM_DEPLOYMENT_ENVIRONMENTÚenvironmentÚPYROSCOPE_SAMPLE_RATEÚPYROSCOPE_GRAFANA_USER)Údefault_valueÚPYROSCOPE_GRAFANA_API_TOKENz“PYROSCOPE_GRAFANA_API_TOKEN is set but PYROSCOPE_GRAFANA_USER is not set. Set PYROSCOPE_GRAFANA_USER to the Grafana Cloud Pyroscope user/tenant id.z—PYROSCOPE_GRAFANA_USER is set but PYROSCOPE_GRAFANA_API_TOKEN is not set. Set PYROSCOPE_GRAFANA_API_TOKEN to the Grafana Cloud API/access policy token.)Úapplication_nameÚserver_addressr  Úbasic_auth_usernameÚbasic_auth_passwordÚsample_ratez-PYROSCOPE_SAMPLE_RATE must be a number, got: z/LiteLLM: Pyroscope profiling started (app_name=z, server_address=zA). View CPU profiles at the Pyroscope UI and select application 'z'.z sample_rate=z¢LiteLLM: LITELLM_ENABLE_PYROSCOPE is set but the 'pyroscope-io' package is not installed. Pyroscope profiling will not run. Install with: pip install pyroscope-iorè  )r}  rŸ   r
  Ú	pyroscopern  r¨  rs  r  r~  r"  r   r  Ú	configurer  ÚImportErrorr/  )r¢
  rƒ  Úapp_namer  r  Úenv_nameÚsample_rate_envÚgrafana_pyroscope_userÚgrafana_api_tokenÚconfigure_kwargsr‹  s              rˆ   r¨  z!ProxyStartupEvent._init_pyroscope '  sB  € ô Ð9¸5ÔAÜ ×&Ñ&Øiôð ðA	Ûä Ÿi™iÐ(<Ó=ˆHÙÜ ðFóð ô %'§I¡IÐ.HÓ$IˆNÙ!Ü ðLóð ð ˆDÜ Ÿi™iÐ(?Ó@ò ÄBÇIÁIØ0óEˆHñ Ø&.��]Ñ#Ü%'§Y¡YÐ/FÓ%GˆOä,IÜÐ7ÀtÔLó-Ð"ô (EÜÐ<ÈDÔQó(Ðñ !Ñ)?Ü ð`óð ñ &Ñ.?Ü ðdóð ð
 %-Ø"0Ù $™¨$ñ'Ðñ
 !Ñ%;Ø:PÐ Ð!6Ñ7Ø:KÐ Ð!6Ñ7ØÐ*ðjä69¼%ÀÓ:PÓ6QÐ$ ]Ñ3ð  ˆI×ÑÑ3Ð"2Ò3àAÀ(ÀÐK\Ð]kÐ\lð mQØQYÐPZÐZ\ð^ð ð Ð 0Ñ0Ø˜Ð'7¸Ñ'FÐ&GÐHÑH�Ü ×%Ñ% cÕ*øô #¤IÐ.ò jÜ$Ð'TÐUdÐTgÐ%hÓiÐiðjûô ò 	Ü ×(Ñ(ð[öð	ús+   ¤C6F ÄE5 Ä2AF Å5FÆF ÆF7Æ6F7rl  )'r   r  r  r¥	  r   rY  r�  Úclassmethodr�   rZ  r¢   rŒ  rÔ  r”  r“  r   r‚  r\  rˆ  r‹  r   r—  r  r˜  r›  r³
  rœ  rŸ  r   r"  r  rž  r�   r  r6  r  r†  r§  r¨  rè  rŠ   rˆ   r…  r…  ¥"  sr  „ Øð

¨E°D©Lð 

ÈÐX\ÑI\ð 

Ðaeò 

ó ð

ð ð
dà˜T‘Mð
dð (ð
dð &¨Ñ,ò	
dó ð
dð ð
¸tð 
Èò 
ó ð
ð< ðØðà%¨Ñ,òó ðð: ð%(Ø! # v +Ñ.ð%(à˜T‘Mð%(ð 
�dÑ	ò%(ó ð%(ðN ð;Øð;à	�dÑ	ò;ó ð;ð, ðnà˜T‘Mðnð ˜s C˜x™.ònó ðnð@ ð
àð
ð $ dÑ*ð
ð ,ò	
ó ð
ð8 ñOó ðOð ò1mó ð1mðf ðià+ðið $ðið 
ò	ió ðið  ñó ðð" ñ_ó ð_ð> ðb àðb ð $ðb ð ,/ð	b ð
 ,/ðb ð "ðb ð (ðb ð 
òb ó ðb ðH ðuaÐIYò uaó ðuaðn ð7ÐXhò 7ó ð7ðr ðV2à#ðV2ð ðV2ð (ð	V2ð
 $òV2ó ðV2ðp ð;$à˜D‘jð;$ð (ð;$ð ,ð	;$ð
 
˜Ñ	ò;$ó ð;$ðz ñIó ðIð0 ñPó ñPrŠ   r…  z
/v1/modelsúmodel management)Údependenciesr  z/modelsÚreturn_wildcard_routesÚinclude_model_access_groupsÚonly_model_access_groupsÚinclude_metadataÚfallback_typeÚscopeÚhealthy_onlyc
              ƒ   ó  K  — t        t        t        t        f   t        «      }
ddlm} ddlm} ddl	m
}m} ddlm} t        t        dz  | «      }|duxr |j                  j!                  d«      du}|�|dk7  rt#        d	d
|› �¬«      ‚d}|dk(  r-t%        |«      xs   ||t&        t(        t*        ¬«      ƒ d{  –—† }t,        �t,        j/                  «       n	t1        «       }t3        |	|
t,        ¬«      ƒ d{  –—† }||z  }|�rt,        €g }i }n(t,        j5                  «       }t,        j7                  «       }|r.t9        t1        |t9        |j;                  «       «      z   «      «      }ddlm}  |g g |dd|xs dt,        ||xs d|xs d¬«
      }|r|D �cg c]	  }||vsŒ|‘Œ }}g }tA        jB                  |t,        |
«      D ]0  \  }} ||d|xs d|t,        ¬«      }||d<   |jE                  |«       Œ2 |rt        tF        |   |«      } ||«      S t        |d¬«      S  ||t,        t        tH        t&        t*        ||xs d|xs d|xs dt(        ¬«      ƒ d{  –—† }|r|D �cg c]	  }||vsŒ|‘Œ }}g }tA        jB                  |t,        |
«      D ]0  \  }} ||d|xs d|t,        ¬«      }||d<   |jE                  |«       Œ2 |rt        tF        |   |«      }  || «      S t        |d¬«      S 7 �Œ57 �Œúc c}w 7 ŒŸc c}w ­w)av  
    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
    - scope: Optional scope parameter. Currently only accepts "expand".
             When scope=expand is passed, proxy admins, team admins, and org admins
             will receive all proxy models as if they are a proxy admin.
    - healthy_only: When true, hide models whose backing deployments are all marked
                    unhealthy by background health checks. Set
                    `general_settings.model_list_healthy_only: true` to apply this
                    to every caller without the query parameter. Requires
                    `background_health_checks: true` in general_settings, plus
                    either `model_list_healthy_only` or `enable_health_check_routing`
                    to keep deployment health state cached; without health state
                    the listing is returned unfiltered (fail open).
                    Models expanded from wildcard routes (e.g. `openai/*`) are not
                    filtered, and nothing is hidden when `allowed_fails_policy` is
                    configured (cooldown remains the sole exclusion mechanism).
                    Hiding is presentation-only: a hidden model can still be
                    called directly.
    r   )Ú$create_anthropic_model_list_response)r0  )Úcreate_model_info_responseÚget_available_models_for_user)ÚModelInfoResponseNzanthropic-versionÚexpandrD  zIInvalid scope parameter. Only 'expand' is currently supported. Received: rc  F©r*  r÷  rA  rý  ©r•  rW  rU  )rÛ   )
Ú
key_modelsÚteam_modelsÚproxy_model_listr¸	  Úinfer_model_from_keysr�  rU  r›  r�  r‘  rl  ©r‡  r  r’  r“  rU  r.  r•  )r„  r\  ©r*  rU  rW  r¸	  r÷  rý  r•  r�  r‘  r�  rA  )%r   rÔ  r‚  r\  rW  Ú#litellm.llms.anthropic.common_utilsr—  Ú/litellm.proxy.management_endpoints.common_utilsr0  rþ  r˜  r™  Ú!litellm.types.proxy.model_listingrš  r«  r9  rp  r¨  r1  r÷  rA  rý  rU  Úget_fully_blocked_model_namesrð  rî   Úget_model_namesÚget_model_access_groupsr•  r–  Úlitellm.proxy.auth.model_checksrÛ   rø   Úlisting_entriesrã  r	   r¸	  )!r3  r*  r�  r•  r�  r‘  r’  r“  r”  r•  r  r—  r0  r˜  r™  rš  Úhttp_requestÚwants_anthropic_formatÚshould_expand_scopeÚblocked_namesÚunhealthy_namesÚhidden_namesr   r›  rÛ   Ú
all_modelsrÎ  Ú
model_dataÚresponse_idÚ	lookup_idr¸  Úadmin_listingÚlistings!                                    rˆ   rm  rm  U'  s…  è ø€ ôX œ4¤¤V Ñ,Ô.>Ó?€Hõõ÷õ Däœw¨™~¨wÓ7€Là˜DÐ Ò^ \×%9Ñ%9×%=Ñ%=Ð>QÓ%RÐZ^Ð%^ð ð
 Ð˜U hÒ.ÜØØ^Ð_dÐ^eÐfô
ð 	
ð  ÐØ�ÒÜ2Ð3DÓEò 
ÑOiØ/Ü'Ü1Ü/ô	P
÷ J
Ðô JTÐI_œ:×CÑCÔEÔehÓej€Mô $DØ!Ø!Üô$÷ €Oð (¨/Ñ9€Lò äÐØ!ÐØ"$Ñä)×9Ñ9Ó;ÐÜ",×"DÑ"DÓ"FÐñ 'Ü#¤CÐ(8¼4Ð@S×@XÑ@XÓ@ZÓ;[Ñ([Ó$\Ó]Ðõ 	Lá,ØØØ-ØØ"'Ø#9Ò#B¸UÜ!Ø 3Ø(CÒ(LÀuØ%=Ò%FÀô
ˆ
ñ Ø%/ÖI °1¸LÒ3Hš!ÐIˆJÐIð
 ˆ
Ü&=×&MÑ&MÈjÔZdÐfnÓ&oò 		*Ñ"ˆK˜Ù3Ø"Ø!Ø!1Ò!:°UØ+Ü%ôˆJð  +ˆJ�tÑØ×Ñ˜jÕ)ð		*ñ "Ü#'¬Ð1BÑ(CÀZÓ#PˆMÙ7¸ÓFÐFäØØô
ð 	
ñ 5Ø+ÜÜ)ÜÜ#Ü+ØØ$?Ò$HÀ5Ø!9Ò!B¸UØ5Ò>¸Ü-ô÷ €Jñ Ø!+ÖE˜A¨q¸Ò/D’aÐEˆ
ÐEð
 €JÜ"9×"IÑ"IÈ*ÔV`ÐbjÓ"kò 	&Ñˆ�YÙ/ØØØ-Ò6°Ø'Ü!ô
ˆ
ð 'ˆ
�4ÑØ×Ñ˜*Õ%ð	&ñ ÜœhÐ'8Ñ9¸:ÓFˆÙ3°GÓ<Ð<äØØôð ðkJ
ùðûòP Jð8úò  Fùsc   ‚B8LÂ:K/Â;=LÃ8K2Ã9BLÆ	K5Æ K5Æ$B6LÉK:É
LÉ%	K<É/K<É3A=LË2LË5LË<Lz/v1/models/{model_id}z/models/{model_id}r‡  c              ƒ   ó(  K  — t        t        t        t        f   t        «      }ddlm}m}m}  ||t        t        t        t        t        |dddt        ¬«      ƒ d{  –—† }t        �t        j                  «       n	t        «       }	t!        ||t        ¬«      ƒ d{  –—† }
|	|
z  }|r|D �cg c]	  }||vsŒ|‘Œ }}t#        j$                  t        |«      }t#        j&                  | |t        |¬«      } |||¬«       t        €t)        d	d
¬«      ‚t        j+                  |«      }|€t)        dd| › d�¬«      ‚t-        j.                  |j0                  j2                  ¬«      \  }}}}|j5                  || «      } |||ddt        ¬«      S 7 �Œ,7 Œðc c}w ­w)aO  
    Retrieve information about a specific model accessible to your API key.

    Returns model details only if the model is available to your API key/team.
    Returns 404 if the model doesn't exist or is not accessible.

    Follows OpenAI API specification for individual model retrieval.
    https://platform.openai.com/docs/api-reference/models/retrieve

    Query parameters mirror `/v1/models` so the same caller context (team
    scoping, health filtering, paused deployments) drives both endpoints; the
    listing's public id must resolve to the same internal deployment here.
    r   )r˜  r™  Úvalidate_model_accessFr£  Nr�  )r‡  Úavailable_modelsrU  rW  )r‡  rº  rž  zRouter not initializedrc  é”  zModel 'z#' not found in router configurationrì  r¢  )r   rÔ  r‚  r\  rW  rþ  r˜  r™  r¹  rU  r¸	  r÷  rý  rA  r§  rð  rî   rø   Úbuild_internal_to_public_mapÚresolve_public_namer¨  Ú"get_deployment_by_model_group_namer  Úget_llm_providerrô  r{  rp  )r‡  r*  r•  r•  r  r˜  r™  r¹  r²  r¯  r°  r±  rÎ  Úinternal_to_publicÚresolved_model_idrš  rÁ  r  r´  s                      rˆ   r¸  r¸  (  s©  è ø€ ô> œ4¤¤V Ñ,Ô.>Ó?€H÷ñ ñ 5Ø+ÜÜ)ÜÜ#Ü+ØØ$)Ø!&Ø$Ü-ô÷ €Jô  JTÐI_œ:×CÑCÔEÔehÓej€MÜ#CØ!Ø!Üô$÷ €Oð
 (¨/Ñ9€LÙØ!+ÖE˜A¨q¸Ò/D’aÐEˆ
ÐEä 7× TÑ TÔU_ÐaiÓ jÐÜ6×JÑJØØ#ÜØ!ô	 Ðñ Ð#4ÀzÕRô ÐÜ¨Ð4LÔMÐMä"×EÑEÐFWÓX€JØÐÜØØ˜X˜JÐ&IÐJô
ð 	
ô  ×0Ñ0°z×7PÑ7P×7VÑ7VÔWÑ€A€x��Aà+×/Ñ/Ð0AÀ8ÓL€KÙ%ØØØØÜôð ðiùð"úò Fùs=   ‚AFÁFÁ=FÂFÂFÂ*	FÂ4FÂ8CFÆFÆFÚoriginal_responsezlitellm.Usagec                 óŒ   — | �t        | dd«      nd}t        |t        j                  «      r|S t        j                  ddd¬«      S )aŽ  
    Token usage for a synthetic guardrail-blocked response.

    A post-call block replaces the LLM's response with the violation message,
    but the upstream call already consumed tokens -- report that real usage
    (carried on ``ModifyResponseException.original_response``) rather than
    discarding it. Pre-call blocks never invoked the LLM (no original_response),
    so usage is zero.
    Nr
  r   ©Úprompt_tokensÚcompletion_tokensÚtotal_tokens)rw  rÓ  r  ÚUsage)rÂ  r
  s     rˆ   Ú_blocked_response_usagerÉ  }(  sC   € ð ARÐ@]”7Ð,¨g°tÔ<Ðcg€EÜ�%œŸ™Ô'ØˆÜ�=‰= q¸AÈAÔNÐNrŠ   z/v1/chat/completionszchat/completionsz/chat/completionsz&/engines/{model:path}/chat/completionsz1/openai/deployments/{model:path}/chat/completionséÈ   rô  zSuccessful response)rŽ  r  r  Úfastapi_responsec              ƒ   óØ  K  — t        | ¬«      ƒ d{  –—† }|�öt        |j                  d«      t        «      si |d<   t	        |d«      r|j
                  �|j
                  |d   d<   t	        |d«      r|j                  �|j                  |d   d<   t	        |d«      r|j                  �|j                  |d   d	<   t	        |d
«      r|j                  �|j                  |d   d<   t	        |d«      r|j                  �|j                  |d   d<   t        |¬«      }	 |j                  | ||dt        t        t        t        t         |t"        t$        t&        t(        t*        t,        ¬«      ƒ d{  –—† }t        |t.        «      rt1        |d¬«      S |S 7 �Œ~7 Œ&# t2        $ �rD}|j4                  }|j                  d«      }	t        j7                  |||¬«      ƒ d{  –—†7   t9        j:                  «       }
|j<                  |
_        |j>                  |
j@                  d   j>                  _!        d|
j@                  d   _"        tG        |jH                  «      |
_%        |j                  dd«      �m|d   du rft8        jL                  jO                  |
d¬«      }t9        jP                  ||j<                  d|	¬«      }t!        |||| ¬«      }tS        |dd¬«      cY d}~S |
cY d}~S d}~wtT        $ �rO}|j4                  }t        j7                  |||¬«      ƒ d{  –—†7   t9        j:                  «       }
|j>                  |
j@                  d   j>                  _!        |j                  dd«      �©|d   du r¢t8        jL                  jO                  |
d¬«      }t9        jP                  ||j                  dd«      d|j                  dd«      ¬«      }t!        |||| ¬«      }tS        |dt	        |d «      r|jV                  ntX        jZ                  ¬«      cY d}~S t9        j\                  ddd¬!«      }||
_%        |
cY d}~S d}~wt^        $ r&}|ja                  ||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!"
            }
        ]
    }'
    ```

    ©r3  NÚmetadatarb  Úuser_api_key_user_idr•  Úuser_api_key_team_idr—  Úuser_api_key_org_idÚorganization_aliasÚuser_api_key_org_aliasÚagent_id©r„  Úacompletion©r3  rË  r*  Ú
route_typerý  rU  rW  r~  r�
  r{  r¸	  r¿	  rÀ	  Úuser_max_tokensr¾	  r¢  T)r
  Úlitellm_logging_objrÒ	  r   Úcontent_filterÚstream©Úmodel_responseÚconvert_to_deltaÚcached_response)Úcompletion_streamr{  Úcustom_llm_providerÚlogging_objrŽ
  útext/event-streamrÊ  ©Ú
media_typer7  r{  r6  r7  rÄ  )r  r*  rý  )1rñ   rÓ  rp  rÔ  r¬  rb  r•  r—  rÒ  rÔ  râ   Úbase_process_llm_requestrý  rU  rW  r~  r�
  r¸	  r¿	  rÀ	  rÙ  r¾	  r¢  r   rn  r»   rÏ	  rØ	  r  rg   r{  r�   rñ	  r8  r
  rÉ  rÂ  r
  ÚutilsÚModelResponseIteratorÚCustomStreamWrapperr»  rº   r7  r±  ÚHTTP_400_BAD_REQUESTrÈ  rÿ  Ú_handle_llm_api_exception)r3  rË  r{  r*  r„  Úbase_llm_response_processorrC  r  Ú_dataÚ_logging_objÚ_chat_responseÚ	_iteratorÚ_streaming_responseÚselected_data_generatorÚ_usages                  rˆ   Úchat_completionrõ  �(  sO  è ø€ ôh +°7Ô;×;€DØÐ$Ü˜$Ÿ(™( :Ó.´Ô5ð  "ˆD�ÑÜÐ$ iÔ0Ð5F×5NÑ5NÐ5ZØ7H×7PÑ7PˆD�ÑÐ3Ñ4ÜÐ$ iÔ0Ð5F×5NÑ5NÐ5ZØ7H×7PÑ7PˆD�ÑÐ3Ñ4ÜÐ$ hÔ/Ð4E×4LÑ4LÐ4XØ6G×6NÑ6NˆD�ÑÐ2Ñ3ÜÐ$Ð&:Ô;Ð@Q×@dÑ@dÐ@pØ9J×9]Ñ9]ˆD�ÑÐ5Ñ6ÜÐ$ jÔ1Ð6G×6PÑ6PÐ6\Ø+<×+EÑ+EˆD�Ñ˜ZÑ(ä)FÈDÔ)QÐðd
Ø9×RÑRØØ-Ø/Ø$Ü/Ü!Ü-Ü%Ü"7ØÜ!Ü-Ü!5Ü+Ü'Üð! Só 
÷ 
ˆô$ �fœiÔ(Ü3°FÈ$ÔOÐOàˆMðS <ùð(
ùô, #ó &à—‘ˆà#Ÿi™iÐ(=Ó>ˆÜ×6Ñ6Ø/Ø Øð 7ó 
÷ 	
ñ 	
ô
 !×.Ñ.Ó0ˆØ Ÿw™wˆÔØ45·I±Iˆ×Ñ˜qÑ!×)Ñ)Ô1Ø2Bˆ×Ñ˜qÑ!Ô/ô  7°q×7JÑ7JÓKˆÔà�8‰8�H˜dÓ#Ð/°D¸±NÀdÑ4JÜŸ™×;Ñ;È>ÐlpÐ;ÓqˆIÜ")×"=Ñ"=Ø"+Ø—g‘gØ$5Ø(ô	#Ðô '<Ø,Ø"3Ø"Øô	'Ð#ô %Ø'Ø.Øôõ ð
 ÕûÜó  Ø—‘ˆÜ×6Ñ6Ø/Ø Øð 7ó 
÷ 	
ñ 	
ô
 !×.Ñ.Ó0ˆØ45·I±Iˆ×Ñ˜qÑ!×)Ñ)Ô1à�8‰8�H˜dÓ#Ð/°D¸±NÀdÑ4JÜŸ™×;Ñ;È>ÐlpÐ;ÓqˆIÜ")×"=Ñ"=Ø"+Ø—h‘h˜w¨Ó+Ø$5Ø!ŸI™IÐ&;¸TÓBô	#Ðô '<Ø,Ø"3Ø"Øô	'Ð#ô %Ø'Ø.Ü.5°a¸Ô.G˜QŸ]š]ÌV×MhÑMhôõ ô
  Ÿ™°AÈÐYZÔ[ˆØ%ˆÔØÕûÜò 
Ø/×IÑIØØ/Ü/ð Jó 
÷ 
ð 
ð 	
ûð
üsÍ   ‚Q*’F“DQ*ÄAF Å,FÅ- F ÆQ*ÆF ÆQ*ÆF Æ
Q'Æ8KÇGÇC9KËQ'ËQ*ËKËQ'ËQ*ËQ'Ë+'P5ÌLÌC6P5Ð	Q'Ð
Q*Ð P5Ð/Q'Ð0Q*Ð5Q'ÑQ"ÑQÑQ"Ñ"Q'Ñ'Q*z/v1/completionsÚcompletionsz/completionsz!/engines/{model:path}/completionsz,/openai/deployments/{model:path}/completionsc              ƒ   óü	  K  — i }	 t        | ¬«      ƒ d{  –—† }|�è|j                  d«      €i |d<   t        |d«      r|j                  �|j                  |d   d<   t        |d«      r|j                  �|j                  |d   d<   t        |d«      r|j
                  �|j
                  |d   d	<   t        |d
«      r|j                  �|j                  |d   d<   t        |d«      r|j                  �|j                  |d   d<   t        |¬«      }|j                  | ||dt        t        t        t        t        |t        t         t"        t$        t&        t(        ¬«      ƒ d{  –—† S 7 �ŒP7 Œ# t*        $ �r€}|j,                  }t        j/                  |||¬«      ƒ d{  –—†7   |j                  dd«      �Ö|d   du rÏt1        j2                  «       }t5        |j6                  d   d|j8                  «       |j:                  |_        t=        |j>                  «      }	t5        |d|	«       t0        j@                  jC                  |d¬«      }
t1        jD                  |
|j:                  ¬«      }t        |||| ¬«      }tG        |dd¬«      cY d}~S t1        jH                  «       }|j8                  |j6                  d   _%        |j:                  |_        t=        |j>                  «      }	|	|_&        |cY d}~S d}~wtN        $ �rp}|j,                  }t        j/                  |||¬«      ƒ d{  –—†7   |j                  dd«      �ó|d   du rìt1        j2                  «       }t1        jP                  ddd¬«      }	|	|_&        |j8                  |j6                  d   j8                  _)        t0        j@                  jC                  |d¬«      }
t1        jD                  |
|j                  dd«      ¬«      }t        |||| ¬«      }tG        |di t        |d«      r|jT                  ntV        jX                  ¬ «      cY d}~S t1        jH                  «       }|j8                  |j6                  d   _%        |cY d}~S d}~wtZ        $ r†}t        j/                  |||¬«      ƒ d{  –—†7   t]        j^                  d!|«       |› }ta        tc        |d"|«      tc        |d#d$«      tc        |d%d$«      tc        |d&d«      tc        |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Î  rb  rÏ  r•  rÐ  r—  rÑ  rÒ  rÓ  rÔ  rÕ  Úatext_completionr×  rÒ	  rÜ  Tr   Útextr
  rÝ  )rá  r{  rŽ
  rä  rÊ  rå  rÄ  r{  r6  r7  )ræ  r9  r7  z?litellm.proxy.proxy_server.completion(): Exception occured - %sr�   rw   rÔ	  r  r;  rž  ©r�   rw   r  Úopenai_coder;  )2rñ   rp  r¬  rb  r•  r—  rÒ  rÔ  râ   rç  rý  rU  rW  r~  r�
  r¸	  r¿	  rÀ	  rÙ  r¾	  r¢  r»   rÏ	  rØ	  r  rg   rd  rñ	  r�   r{  rÉ  rÂ  rè  ré  ÚTextCompletionStreamWrapperr»  rj   rù  r
  rº   rÈ  r8  r7  r±  rë  rÿ  rŸ   r   rS   rw  )r3  rË  r{  r*  r„  rí  r  rî  Ú_text_responserô  rñ  rò  ró  Ú	_responserð  rÚ	  s                   rˆ   Ú
completionrÿ  ;)  sÐ  è ø€ ðJ €Dð
Ü'°Ô8×8ˆØÐ(Ø�x‰x˜
Ó#Ð+Ø#%��ZÑ ÜÐ(¨)Ô4Ð9J×9RÑ9RÐ9^Ø;L×;TÑ;T��ZÑ Ð!7Ñ8ÜÐ(¨)Ô4Ð9J×9RÑ9RÐ9^Ø;L×;TÑ;T��ZÑ Ð!7Ñ8ÜÐ(¨(Ô3Ð8I×8PÑ8PÐ8\Ø:K×:RÑ:R��ZÑ Ð!6Ñ7ÜÐ(Ð*>Ô?ÐDU×DhÑDhÐDtØ=N×=aÑ=a��ZÑ Ð!9Ñ:ÜÐ(¨*Ô5Ð:K×:TÑ:TÐ:`Ø/@×/IÑ/I��ZÑ  Ñ,Ü-JÐPTÔ-UÐ#Ø0×IÑIØØ-Ø/Ø)Ü/Ü!Ü-Ü%Ü"7ØÜ!Ü-Ü!5Ü+Ü'Üð! Jó 
÷ 
ð 	
ð 9ùð
ùô$ #ó )à—‘ˆÜ×6Ñ6Ø/Ø Øð 7ó 
÷ 	
ñ 	
ð �9‰9�X˜tÓ$Ð0°U¸8±_ÈÑ5LÜ$+×$9Ñ$9Ó$;ˆNä�N×*Ñ*¨1Ñ-¨v°q·y±yÔAØ#$§7¡7ˆNÔ Ü,¨Q×-@Ñ-@ÓAˆFä�N G¨VÔ4ÜŸ™×;Ñ;È>ÐlpÐ;ÓqˆIÜ")×"EÑ"EØ"+Ø—g‘gô#Ðô
 '<Ø,Ø"3Ø"Øô	'Ð#ô %Ø'Ø.Øôõ ô  ×6Ñ6Ó8ˆIØ()¯	©	ˆI×Ñ˜aÑ Ô%ØŸg™gˆIŒOÜ,¨Q×-@Ñ-@ÓAˆFØ$ˆIŒOØÕûÜó &Ø—‘ˆÜ×6Ñ6Ø/Ø Øð 7ó 
÷ 	
ñ 	
ð
 �9‰9�X˜tÓ$Ð0°U¸8±_ÈÑ5LÜ$+×$9Ñ$9Ó$;ˆNÜ—]‘]ØØ"#ØôˆFð
 $*ˆNÔ Ø89¿	¹	ˆN×"Ñ" 1Ñ%×-Ñ-Ô5ÜŸ™×;Ñ;È>ÐlpÐ;ÓqˆIÜ")×"EÑ"EØ"+Ø—i‘i ¨Ó,ô#Ðô
 '<Ø,Ø"3Ø!Øô	'Ð#ô %Ø'Ø.ØÜ.5°a¸Ô.G˜QŸ]š]ÌV×MhÑMhô	õ ô  ×6Ñ6Ó8ˆIØ()¯	©	ˆI×Ñ˜aÑ Ô%ØÕûÜò 
Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×&Ñ&Ð'hÐjkÔlØ˜Sˆ	ÜÜ˜A˜y¨)Ó4Ü˜˜F FÓ+Ü˜!˜W fÓ-Ü  6¨4Ó0Ü˜˜M¨3Ó/ô
ð 	
ûð
üsÇ   ‚S<†E* •E%–E
E* Å E(Å!E* Å$S<Å%E* Å(E* Å*
S9Å4'K/ÆFÆC'K/ÊS9ÊS<Ê	A K/Ë)S9Ë*S<Ë/S9Ë<'Q'Ì#L&Ì$DQ'Ð(S9Ð)S<Ð.3Q'Ñ!S9Ñ"S<Ñ'S9Ñ3S4ÒRÒA%S4Ó4S9Ó9S<z/v1/embeddingsÚ
embeddings)rŽ  Úresponse_classr  z/embeddingsz /engines/{model:path}/embeddingsz+/openai/deployments/{model:path}/embeddingsc              ƒ   ó¬  ‡K  — t        | ¬«      ƒ d{  –—† }t        |¬«      }	 t        �t        j                  ng }d|v �rt	        |d   t
        «      �rt        |d   «      dkD  rðt	        |d   d   t
        «      rÚt	        |d   d   d   t        «      rÁt        �»|j                  d«      |v r¨t        j                  |d   ¬«      }|��|j                  di «      xs i }|j                  dd	«      Š‰t        j                  v xs t        ˆfd
„t        D «       «      }	|	s7g }
|d   D ](  }|
j                  t        j                  d|¬«      «       Œ* |
|d<   |�è|j                  d«      €i |d<   t!        |d«      r|j"                  �|j"                  |d   d<   t!        |d«      r|j$                  �|j$                  |d   d<   t!        |d«      r|j&                  �|j&                  |d   d<   t!        |d«      r|j(                  �|j(                  |d   d<   t!        |d«      r|j*                  �|j*                  |d   d<   |j-                  | ||dt.        t        t0        t2        t4        |t6        t8        t:        t<        t>        t@        ¬«      ƒ d{  –—† }|S 7 �Œ…7 Œ	# tB        $ r+}|jE                  ||t.        t@        ¬«      ƒ d{  –—†7  ‚d}~ww xY w­w)a”  
    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"
    }'
    ```

rÍ  NrÕ  Úinputr   r{  )Úmodel_group_namerô  r6  c              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrn  )r™  )r’  r  Úlitellm_models     €rˆ   r”  zembeddings.<locals>.<genexpr>(*  s&   øè ø€ ò là$ð &×0Ñ0°×:ñlùs   ƒzgpt-3.5-turbo)r{  ÚtokensrÎ  rb  rÏ  r•  rÐ  r—  rÑ  rÒ  rÓ  rÔ  Ú
aembeddingr×  )r  r*  rý  r¢  )#rñ   râ   rU  Úmodel_namesrÓ  r•  rÈ  r"  rp  r¾  r  Úopen_ai_embedding_modelsrµ  r0   rã  r
  r¬  rb  r•  r—  rÒ  rÔ  rç  rý  rW  r~  r�
  r¸	  r¿	  rÀ	  rÙ  r¾	  r¢  rÿ  rì  )r3  rË  r{  r*  r„  rí  Úrouter_model_namesrš  rô  Úsupports_token_arraysÚ
input_listÚir  r  r  s                 @rˆ   r   r   ã)  s  øè ø€ ô` +°7Ô;×;€DÜ)FÈDÔ)QÐðF
ô ?IÐ>T¤J×$:Ò$:ÐZ\Ðà�tŠOÜ˜4 ™=¬$Õ/Ü�D˜‘MÓ" QÒ&Ü˜4 ™=¨Ñ+¬TÔ2Ü˜4 ™=¨Ñ+¨AÑ.´Ô4ô Ð%¨$¯(©(°7Ó*;Ð?QÑ*Qä$.×$QÑ$QÐcgÐhoÑcpÐ$QÓ$q�
ØÐ)Ø,6¯N©NÐ;KÈRÓ,PÒ,VÐTV�NØ+9×+=Ñ+=¸gÀrÓ+J�Mà3@ÄG×DdÑDdÐ3dò 4Ôhkó lä(dôló iÐ)ñ 1à,.˜
Ø!% g¡ò _˜AØ&×-Ñ-¬g¯n©nÀ?Ð[\Ô.]Õ^ð_à(2˜˜W™àÐ(Ø�x‰x˜
Ó#Ð+Ø#%��ZÑ ÜÐ(¨)Ô4Ð9J×9RÑ9RÐ9^Ø;L×;TÑ;T��ZÑ Ð!7Ñ8ÜÐ(¨)Ô4Ð9J×9RÑ9RÐ9^Ø;L×;TÑ;T��ZÑ Ð!7Ñ8ÜÐ(¨(Ô3Ð8I×8PÑ8PÐ8\Ø:K×:RÑ:R��ZÑ Ð!6Ñ7ÜÐ(Ð*>Ô?ÐDU×DhÑDhÐDtØ=N×=aÑ=a��ZÑ Ð!9Ñ:ÜÐ(¨*Ô5Ð:K×:TÑ:TÐ:`Ø/@×/IÑ/I��ZÑ  Ñ,à ;× TÑ TØØ-Ø/Ø#Ü/Ü!Ü-Ü%Ü"7ØÜ!Ü-Ü!5Ü+Ü'Üð! !Uó !
÷ 
ˆð& ˆðC <ùð\
ùô( ò 
Ø/×IÑIØØ/Ü/Üð	 Jó 
÷ 
ð 
ð 	
ûð
üsQ   ƒK“J”K¥I,J ÊJÊJ ÊKÊJ Ê	KÊ& KËK	ËKËKËK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|«       t5        |t6        «      r‚ t5        |t8        «      rRt7        t#        |dt;        |«      «      t#        |dd«      t#        |dd«      t#        |dt<        j>                  «      ¬«      ‚|› }t7        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"}'
    ```
    N©r„  r3  rW  r*  r¢  r~  Úmoderation_modelr{  Ú
moderation©r*  r„  Ú	call_typeÚamoderation©r„  rØ  rU  r¸	  rû	  r6  r  ©rû	  r±  Ú_hidden_paramsr‡  r	  rz  Úallowed_model_region©r*  r‡  r	  rz  r¢  Úmodel_regionrÏ	  Úhidden_paramsrÒ	  z@litellm.proxy.proxy_server.moderations(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  rž  ) r	  r
  r„  r.  rW  r¢  r~  rp  r¸	  rý  Úpre_call_hookr}  rT  rU  rP  r‡  Úupdate_request_statusrw  r9  rå  râ   Úget_custom_headersrÿ  rØ	  rŸ   r   rÓ  rS   r¨  r‚  r±  rë  )r3  rË  r*  r„  r	  Úllm_callr  r  r‡  r	  rz  r  rÚ	  s                rˆ   r  r  ^*  sÎ  è ø€ ð8 €DðUà#ŸL™L›N×*ˆÜ�|‰|˜DÓ!ˆô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô × Ñ Ð!3°TÓ:ò !Üò!à�x‰x˜Ó ð 	ˆW‰õ
 Ü&ˆD�‰Mô '×4Ñ4Ø/°dÀlð 5ó 
÷ 
ˆô 	�	‰	Œô !.ØØ$Ü!Ü!ô	!
÷ 
ˆð !)Ÿ.ˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆð{ +ùð
ùð$
ùð
øð )ùô6 ò Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×&Ñ&Ð'iÐklÔmÜ�aœÔ(ØÜ�aœÔ'Ü Ü  9¬c°!«fÓ5Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ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rþ  c                ót   K  — | j                  t        ¬«      ƒ d {  –—† }|2 3 d {  –—† }|­–— Œ7 Œ7 Œ6 y ­w)N)Ú
chunk_size)Úaiter_bytesr)   )rþ  Ú
_generatorrÍ	  s      rˆ   Ú_audio_speech_chunk_generatorr&  Ó*  sB   è ø€ ð (×3Ñ3Ô?VÐ3ÓW×W€JØ!÷ ð ˆeØŒð Xøðø‘zùs$   ‚8œ2�8£6§4¨6«8´6¶8z/v1/audio/speechr
  z/audio/speechc              ƒ   ó¶  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	}t%        j&                  |||	|
t
        |t#        |dd	«      d|||¬«      }t        j)                  |||t+        | j,                  «      ¬«      ƒ d{  –—† }|r|j/                  |«       d}|j                  dd	«      }|r|j1                  «       }d|v r
d|v sd|v rd}t3        t5        |«      ||¬«      S 7 �Œ>7 �Œ7 �Œ®7 �Œ’7 �Œ‹7 Œq# t6        $ re}t        j9                  |||¬«      ƒ d{  –—†7   t;        j<                  d|«       t;        j>                  tA        jB                  «       «       |‚d}~ww xY w­w)z`
    Same params as:

    https://platform.openai.com/docs/api-reference/audio/createSpeech
    Nr  rµ
  r{  Úaspeechr  r  rû	  r6  r  r  r  r‡  r	  rz  r–  r  )r*  r‡  r	  rz  r¢  r–  r  Ú!fastest_response_batch_completionÚcall_idrÏ	  r  ©r„  r*  r  Úrequest_headersz
audio/mpegÚgeminiÚttszpreview-ttsz	audio/wav)ræ  r9  rÒ	  zAlitellm.proxy.proxy_server.audio_speech(): Exception occured - %s)"r	  r
  r„  r.  rW  r¢  r~  rp  rb  r¸	  rý  r  rT  rU  rP  r‡  r  rw  râ   r   Úpost_call_response_headers_hookrÔ  r9  rå  rÉ  r»  r&  rÿ  rØ	  rŸ   rz  r
  r2  r3  )r3  rË  r*  r„  r	  r!  r  r  r‡  r	  rz  r–  rû	  Úcustom_headersÚcallback_headersræ  Úrequest_modelÚrequest_model_lowerr  s                      rˆ   Úaudio_speechr4  ß*  s  è ø€ ð* €Dð`à#ŸL™L›N×*ˆÜ�|‰|˜DÓ!ˆô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆð �8‰8�F˜DÓ!Ð)Ð.?×.GÑ.GÐ.SØ,×4Ñ4ˆD�‰LåÜ&ˆD�‰Mô '×4Ñ4Ø/°dÀið 5ó 
÷ 
ˆô
 !.ØØ Ü!Ü!ô	!
÷ 
ˆð !)Ÿ.ˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆØ,×0Ñ0°À$ÓGÒMÈ2ˆØ!.×!2Ñ!2Ð3DÀdÓ!KÒ!QÈrˆä =× PÑ PØ/ØØØÜØ'Ü Ð!2Ð4JÈBÓOØ.2Ø#ØØ'ô!
ˆô ):×(YÑ(YØØ/ØÜ  §¡Ó1ð	 )Zó )
÷ #
Ðñ Ø×!Ñ!Ð"2Ô3ð "ˆ
Ø#Ÿx™x¨°Ó4ˆÙØ)6×)<Ñ)<Ó)>ÐØÐ.Ñ.ØÐ,Ñ,°ÐATÑ0Tà(�
ä Ü)¨(Ó3Ø!Ø"ô
ð 	
ða +ùð
ùð 
ùð

ùð )ùð<#
ùô2 ò Ü×6Ñ6Ø/Ø Øð 7ó 
÷ 	
ñ 	
ô
 	×"Ñ"Ð#fÐhiÔjÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Øˆûðüs¢   ‚K†I( ™Iš9I( ÁIÁAI( Â/IÂ0I( ÃI Ã	I( ÃI#ÃDI( Ç4I&Ç5A!I( ÉKÉI( ÉI( ÉI( É I( É#I( É&I( É(	KÉ1KÊJÊAKËKËKz/v1/audio/transcriptionsz/audio/transcriptionsr…   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{  –—† }	 |
j1                  «        t3        j4                  t(        j7                  |j                  dd«      d¬«      «       t9        |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:                  j=                  t?        j@                  d'||||t        |t9        |dd«      |||dœ
|¤Ž«       t(        jC                  |||tE        | j:                  «      ¬«      ƒ d{  –—† }|r|j:                  j=                  |«       |S 7 �Œc c}}w 7 �ŒÖ7 �Œ7 �Œ¸7 �Œœ7 �Œ•# t.        $ r}|‚d}~ww xY w# |
j1                  «        w xY w7 Œc# t.        $ rò}t(        jG                  |||¬«      ƒ d{  –—†7   tI        jJ                  d|«       tM        |tN        «      r\t        t9        |dtQ        |jR                  «      «      t9        |dd «      t9        |d!d «      t9        |d"t        j                  «      ¬#«      ‚|› }t        t9        |d|«      t9        |dd «      t9        |d!d «      t9        |d$d«      t9        |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  rµ
  r  r{  z.File name is None. Please check your file nameÚbad_request)r�   r;  rw   r  )rÏ	  r…   r  Útranscriptionr  Úatranscriptionr  rû	  r6  r  r  r  r‡  r	  rz  r–  rë	  r  )
r*  r‡  r	  rz  r¢  r–  r  r*  rÏ	  r  r+  rÒ	  zHlitellm.proxy.proxy_server.audio_transcription(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rž  rú  rè  )*rô   râ  r.  rW  r¢  r~  rp  rb  r¸	  rU  r	  rƒ   rS   r±  rë  ró   ÚreadÚioÚBytesIOrÄ  rý  r  rT  rÿ  r  rP  r‡  r  rw  r9  rå  râ   r   r/  rÔ  rØ	  rŸ   r   rÓ  r¨  r‚  r—  )r3  rË  r…   r*  r„  Ú	form_datarz  r*  r  Úfile_contentÚfile_objectr!  r  r  r  r‡  r	  rz  r–  rû	  rë	  r1  rÚ	  s                          rˆ   Úaudio_transcriptionsr?  X+  s‚  è ø€ ð, €DðBä!.¨wÓ!7×7ˆ	Ø-6¯_©_Ó->×P™z˜s EÀ#ÈÃ-��U‘
ÐPˆÑPô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆð �8‰8�F˜DÓ!Ð)Ð.?×.GÑ.GÐ.SØ,×4Ñ4ˆD�‰Lô × Ñ Ð!3°TÓ:ò 'Üò'à�x‰x˜ Ó&ð 	ˆW‰õ
 Ü&ˆD�‰Mä>HÐ>T¤J×$:Ò$:ÐZ\Ðà�=‰=Ð Ü ØHÜ×0Ñ0Ø"Øô	ð ô 	$ØØØ1õ	
ð %)§I¡I£K×/ˆÜŸZ™Z¨Ó5ˆØŸ=™=ˆÔØ"ˆˆV‰ð	 ä*×8Ñ8Ø"3ØØ)ð 9ó ÷ ˆDô %2ØØ+Ü%Ü%ô	%÷ ˆHð %-Ÿn‰Hð ×ÑÔô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆØ,×0Ñ0°À$ÓGÒMÈ2ˆØ!.×!2Ñ!2Ð3DÀdÓ!KÒ!QÈrˆØ*7×*;Ñ*;Ð<PÐRTÓ*UÒ*[ÐY[Ðà× Ñ ×'Ñ'Ü)×<Ñ<ð Ø"3Ø!Ø#Ø!ÜØ+Ü$Ð%6Ð8NÐPRÓSØ'Ø!Ø+ñð %ñô	
ô" ):×(YÑ(YØØ/ØÜ  §¡Ó1ð	 )Zó )
÷ #
Ðñ Ø×$Ñ$×+Ñ+Ð,<Ô=àˆðW 8ûÛPð
ùðJ 0ùðùðùð -úÜò 	ØˆGûð	ûð ×ÑÕúðB#
ùô ò Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×&Ñ&Ð'qÐstÔuÜ�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü# A v¨tÓ4Ü˜Q ¨sÓ3ôð ûðüsì   ‚Q/†M1 ”L/•M1 ¬L2ºL2¿#M1 Á"L8Á#CM1 Ä:L;Ä;/M1 Å+M ÆL>ÆM Æ%MÆ&	M Æ/MÆ0M Æ5EM1 ÌM/Ì"M1 Ì.Q/Ì/M1 Ì2M1 Ì;M1 Ì>M ÍM ÍM Í	MÍMÍMÍM ÍM,Í,M1 Í1	Q,Í:Q'ÎNÎCQ'Ñ'Q,Ñ,Q/z/vertex_ai/livezGOptional model name, used to determine Vertex region for global models.)rô  zCOverride the Vertex AI project id used for the upstream connection.z;Override the Vertex AI region (for example, 'us-central1').Ú	websocketÚvertex_projectÚvertex_locationc              ƒ   ó>   K  — t        | ||||¬«      ƒ d{  –—† S 7 Œ­w)z›
    Vertex AI Live API WebSocket Pass-through Endpoint

    This endpoint delegates to the WebSocket function defined in llm_passthrough_endpoints.py
    ©r@  r{  rA  rB  r*  N)rR  rD  s        rˆ   Ú#vertex_ai_live_passthrough_endpointrE  û+  s.   è ø€ ô, 6ØØØ%Ø'Ø+ô÷ ð ð ús   ‚–—©ÚmaxsizeÚintentc                 óp   — g }| �|j                  d| f«       |�|j                  d|f«       t        |«      S )z„
    Build a hashable representation of the realtime query params so we can cache
    the repetitive model/intent combinations.
    r{  rH  )rã  rŒ  )r{  rH  Úparamss      rˆ   Ú_realtime_query_params_templaterK  !,  sA   € ð ,.€FØÐØ�‰�w Ð&Ô'ØÐØ�‰�x Ð(Ô)Ü�‹=ÐrŠ   z/openai/v1/realtimez	/realtimez.The model to use for the websocket connection.z'The intent of the websocket connection.zAComma-separated list of guardrail names to apply to this request.ró  c              ƒ   ó´  ‡K  — | j                   j                  d«      xs dj                  d«      D �cg c]#  }|j                  «       sŒ|j                  «       ‘Œ% }}i }|r|d   |d<   |Š‰€$|dk(  rdŠn| j	                  dd	¬
«      ƒ d {  –—†  y ‰€J ‚	 t        ‰t        |t        ¬«      ƒ d {  –—†   | j                  d%i |¤Žƒ d {  –—†  t        t        t        t        ||«      «      «      }	‰| |	dœ}
|rA|j                  d«      D �cg c]#  }|j                  «       sŒ|j                  «       ‘Œ% c}|
d<   t        | j                   j                  d«      xs g «      }t"        j%                  «       }||d<   t'        |¬«      }| j(                  |_        ˆfd„}||_        t/        |
¬«      }	 |j1                  |t2        |t4        t6        t8        t:        t<        t>        t@        tB        ‰d¬«      ƒ d {  –—† \  }
}	 ||
d<   tS        |
dt        t:        ¬«      ƒ d {  –—† }|ƒ d {  –—†  y c c}w 7 �Œ©7 �Œ‡# t        $ r3}| j	                  d|j                  d d ¬
«      ƒ d {  –—†7   Y d }~y d }~ww xY w7 �Œ¯c c}w 7 Œ‰# tD        $ rˆ}tG        jH                  d«       	 | jK                  tM        jN                  ddtQ        |«      dœdœ«      «      ƒ d {  –—†7   n# tD        $ r Y nw xY w| j	                  dd¬
«      ƒ d {  –—†7   Y d }~y d }~ww xY w7 Œ÷7 Œï# tT        jV                  jX                  $ rE}tG        jH                  d«       | j	                  |jZ                  d¬
«      ƒ d {  –—†7   Y d }~y d }~wtD        $ rÐ}tG        jH                  d«       t]        tQ        |«      «      }	 | jK                  t_        |d ¬!«      «      ƒ d {  –—†7   n$# tD        $ r tG        j`                  d"«       Y nw xY w	 | j	                  dtc        |d¬#«      ¬
«      ƒ d {  –—†7   n)# tD        $ r tG        j`                  d$«       Y nw xY wY d }~y Y d }~y d }~ww xY w­w)&Nzsec-websocket-protocolr6  r7  r   Úsubprotocolr7  zgpt-realtime-whisperið  z!model query parameter is required)r;  rÜ  )r{  r�  Úvalid_tokenrU  éx   )r{  r@  r  ró  r9  )r”  c               “   ó"   •K  — t        ‰ «      S ­wrn  r`   )Úroute_models   €rˆ   Úreturn_bodyz0realtime_websocket_endpoint.<locals>.return_bodyn,  s   øè ø€ Ü% kÓ2Ð2ùs   ƒrÕ  Ú
_arealtime)r3  rW  r*  r¢  rý  r~  r¸	  r¿	  rÀ	  rÙ  r¾	  r{  rØ  zRealtime pre-call errorrz  Úguardrail_error)rw   r�   )rw   rz  ió  zPre-call errorr*  r  zInvalid status coderŸ  Úserver_error)Ú
error_typez=Could not send realtime error event to client; closing anyway)Úfallbackz=Could not close realtime client websocket; it is already gonerè  )2r9  rp  rq  rr  r  rÐ   r�  rU  rS   r�   Úacceptr   r’  rÔ  rK  r•  r”  rz   rÆ  r«  r   Ú_urlr	  râ   Ú common_processing_pre_call_logicrW  r¢  rý  r~  r¸	  r¿	  rÀ	  rÙ  r¾	  rÿ  rŸ   r   Ú	send_textrm  r  r‚  rT  Ú
websocketsr…  ÚInvalidStatusCoder7  rž   rÄ   r
  rÅ   )r@  r{  rH  ró  r*  ÚpÚrequested_protocolsÚaccept_kwargsr  r  r„  ÚgÚheaders_listr”  r3  rR  rí  rÚ  r!  Úredacted_errorrQ  s                       @rˆ   Úrealtime_websocket_endpointrd  /,  s=  øè ø€ ð &×-Ñ-×1Ñ1Ð2JÓKÒQÈr×XÑXÐY\Ó]ö"ØÐab×ahÑahÕajˆ�‰�	ð"Ðð "ð "$€MÙØ':¸1Ñ'=ˆ�mÑ$à€KØÐØ�_Ò$Ø0‰Kà—/‘/ tÐ4W�/ÓX×XÐXØØÐ"Ð"Ð"ð	Ü)ØÜ)Ø)Ü!ô	
÷ 	
ð 	
ð ˆ)×
Ñ
Ñ
+˜]Ñ
+×+Ð+ô Ô2´DÔ9XÐY^Ð`fÓ9gÓ4hÓi€Lð ØØ$ñ€Dñ Ø1;×1AÑ1AÀ#Ó1FÖT¨AÈ!Ï'É'Í)˜aŸg™g�iÒTˆˆ\Ñô ˜yŸ™×2Ñ2°9Ó=ÒCÀÓD€Lä2×7Ñ7Ó9€EØ#€Eˆ)Ñä 5Ô)€Gà—=‘=€G„Lô3ð €G„Lô *GÈDÔ)QÐð
$ð .×NÑNØÜ-Ø/ÜÜ/Ü%Ü!Ü-Ü!5Ü+Ü'ØØ#ð Oó 
÷ 
ñ	
ØØðHhØ$5ˆÐ Ñ!Ü -ØØ#Ü!Ü!ô	!
÷ 
ˆð �‰ùòY"ð Yùð	
úô ò Ø�o‰o 4°·	±	¸$¸3°ˆoÓ@×@Ñ@Üûðúð ,ûò Uð6
ùô ò Ü×&Ñ&Ð'@ÔAð	Ø×%Ñ%Ü—
‘
à 'à$5Ü'*¨1£vñ"ñóó
÷ 
ò 
øô ò 	Ùð	úà�o‰o 4Ð0@ˆoÓA×AÑAÜûð#úð,
øð 	ùÜ× Ñ ×2Ñ2ò PÜ×&Ñ&Ð'<Ô=Ø�o‰o 1§=¡=Ð9NˆoÓO×OÖOûÜò hÜ×&Ñ&Ð'>Ô?Ü .¬s°1«vÓ 6ˆð	hØ×%Ñ%Ô&:¸>ÐVdÔ&eÓf×fÒføÜò 	hÜ ×&Ñ&Ð'fÖgð	húð	hØ—/‘/ØÜ-¨nÐG^Ô_ð "ó ÷ ò øô ò 	hÜ ×&Ñ&Ð'fÖgð	húÜgôûðhüsÏ  ƒ1Q´H0Á
H0Á0QÂH5Â	QÂH; Â1H8Â2H; Â6QÃI:ÃAQÄI=Ä$I=Ä6A<QÆ3AJ Ç8JÇ9J ÈL È LÈ!	L È*LÈ+L È/QÈ8H; È;	I7É#I2É'I*É(I2É-QÉ2I7É7QÉ=QÊJ Ê	LÊLÊ#6K ËKËK ËLË 	K,Ë)LË+K,Ë,LÌLÌLÌQÌLÌQÌL ÌL ÌQÌ95M9Í.M1Í/M9Í4QÍ9QÎ)QÎ/OÏOÏOÏQÏO6Ï3QÏ5O6Ï6QÏ:!P"ÐPÐP"Ð!QÐ"QÑ QÑQÑQÑ
QÑQÑQz/v1/assistantsÚ
assistantsz/assistantsc              ƒ   ó"  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*        $ �r}	t        j-                  ||	|¬«      ƒ d{  –—†7   t/        j0                  d|	«       t/        j2                  t5        j6                  «       «       t9        |	t        «      r\t;        t!        |	dt=        |	j>                  «      «      t!        |	dd«      t!        |	dd«      t!        |	dt@        jB                  «      ¬«      ‚|	› }
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ž  rz  rc  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  zClitellm.proxy.proxy_server.get_assistants(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rú  rè  )"r	  r.  rW  r¢  r~  rU  r¨  r:   Úno_llm_routerr*  Úaget_assistantsrP  r‡  rý  r  rp  rw  r9  rå  râ   r   rÿ  rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  ©r3  rË  r*  r„  r  r  r‡  r	  rz  r  rÚ	  s              rˆ   Úget_assistantsrj  Ä,  sv  è ø€ ð* €DðAà�l‰l‹n×Ðô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ *× :Ñ :Ñ B¸TÑ B×Bˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðS 	ùð
ùð Cùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#hÐjkÔlÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü# A v¨tÓ4Ü˜Q ¨sÓ3ôð ûðüsi   ‚J†E) ™E!š$E) ¾E$¿A	E) ÂE'Â	CE) Å JÅ!E) Å$E) Å'E) Å)
JÅ3JÆFÆC8JÊJÊJc              ƒ   óJ  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.        $ �r}
t        j1                  ||
|¬«      ƒ d{  –—†7   t3        j4                  d|
«       t3        j6                  t9        j:                  «       «       t=        |
t        «      r\t?        t%        |
dtA        |
jB                  «      «      t%        |
dd«      t%        |
dd«      t%        |
dtD        jF                  «      ¬«      ‚|
› }t?        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ž  rz  rc  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  zElitellm.proxy.proxy_server.create_assistant(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rè  )$r	  r
  r„  r.  rW  r¢  r~  rU  r¨  r:   rg  r*  Úacreate_assistantsrP  r‡  rý  r  rp  rw  r9  rå  râ   r   rÿ  rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  )r3  rË  r*  r„  r	  r  r  r‡  r	  rz  r  rÚ	  s               rˆ   Úcreate_assistantrm  -  s€  è ø€ ð* €DðAà#ŸL™L›N×*ˆÜ�|‰|˜DÓ!ˆô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ *× =Ñ =Ñ EÀÑ E×Eˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðU +ùð
ùð Fùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#jÐlmÔnÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬°°=À#Ó(FÓGô	ð ûðüsk   ‚J#†E> ™E6š9E> ÁE9ÁA	E> ÂE<ÂCE> Å5J#Å6E> Å9E> Å<E> Å>
J ÆJÆ#F&Æ$C7JÊJ Ê J#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(        $ �r}
t        j+                  ||
|¬«      ƒ d{  –—†7   t-        j.                  d|
«       t-        j0                  t3        j4                  «       «       t7        |
t
        «      r\t9        t        |
dt;        |
j<                  «      «      t        |
dd«      t        |
dd«      t        |
dt>        j@                  «      ¬«      ‚|
› }t9        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ž  rz  rc  rn  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  zElitellm.proxy.proxy_server.delete_assistant(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rè  )!r.  rW  r¢  r~  rU  r¨  r:   rg  r*  Úadelete_assistantrP  r‡  rý  r  rp  rw  r9  rå  râ   r   rÿ  rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  )r3  rn  rË  r*  r„  r  r  r‡  r	  rz  r  rÚ	  s               rˆ   Údelete_assistantrq  x-  sc  è ø€ ð, €Dð?ô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ *× <Ñ <Ñ _È,Ð _ÐZ^Ñ _×_ˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðM
ùð `ùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#jÐlmÔnÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬°°=À#Ó(FÓGô	ð ûðüóY   ‚I5† E ¦E§AE Á2EÁ3CE Å
I5ÅE ÅE Å
I2ÅI-Å5E8Å6C7I-É-I2É2I5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*        $ �r}	t        j-                  ||	|¬«      ƒ d{  –—†7   t/        j0                  d|	«       t/        j2                  t5        j6                  «       «       t9        |	t        «      r\t;        t!        |	dt=        |	j>                  «      «      t!        |	dd«      t!        |	dd«      t!        |	dt@        jB                  «      ¬«      ‚|	› }
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ž  rz  rc  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  zClitellm.proxy.proxy_server.create_threads(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rè  )"r	  r.  rW  r¢  r~  rU  r¨  r:   rg  r*  Úacreate_threadrP  r‡  rý  r  rp  rw  r9  rå  râ   r   rÿ  rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  ri  s              rˆ   Úcreate_threadsru  Ñ-  ss  è ø€ ð* €Dð@à�l‰l‹n×Ðô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ *× 9Ñ 9Ñ A¸DÑ A×Aˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðS 	ùð
ùð Bùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#hÐjkÔlÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ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ÆC7JÊ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(        $ �r}
t        j+                  ||
|¬«      ƒ d{  –—†7   t-        j.                  d|
«       t-        j0                  t3        j4                  «       «       t7        |
t
        «      r\t9        t        |
dt;        |
j<                  «      «      t        |
dd«      t        |
dd«      t        |
dt>        j@                  «      ¬«      ‚|
› }t9        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ž  rz  rc  rv  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  z?litellm.proxy.proxy_server.get_thread(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rè  )!r.  rW  r¢  r~  rU  r¨  r:   rg  r*  Úaget_threadrP  r‡  rý  r  rp  rw  r9  rå  râ   r   rÿ  rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  ©r3  rv  rË  r*  r„  r  r  r‡  r	  rz  r  rÚ	  s               rˆ   Ú
get_threadrz  *.  s`  è ø€ ð, €Dð=ä0ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ *× 6Ñ 6Ñ SÀÐ SÈdÑ S×Sˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðM
ùð Tùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#dÐfgÔhÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬°°=À#Ó(FÓGô	ð ûðürr  z /v1/threads/{thread_id}/messagesz/threads/{thread_id}/messagesc              ƒ   óN  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.        $ �r}t        j1                  |||¬«      ƒ d{  –—†7   t3        j4                  d|«       t3        j6                  t9        j:                  «       «       t=        |t        «      r\t?        t%        |dtA        |jB                  «      «      t%        |dd«      t%        |dd«      t%        |dtD        jF                  «      ¬«      ‚|› }t?        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ž  rz  rc  rv  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  zAlitellm.proxy.proxy_server.add_messages(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rè  )$r	  r
  r„  r.  rW  r¢  r~  rU  r¨  r:   rg  r*  Úa_add_messagerP  r‡  rý  r  rp  rw  r9  rå  râ   r   rÿ  rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  )r3  rv  rË  r*  r„  r	  r  r  r‡  r	  rz  r  rÚ	  s                rˆ   Úadd_messagesr}  �.  s†  è ø€ ð, €DðAà#ŸL™L›N×*ˆÜ�|‰|˜DÓ!ˆô 1ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ *× 8Ñ 8Ñ UÀ9Ð UÐPTÑ U×Uˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðU +ùð
ùð Vùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#fÐhiÔjÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬°°=À#Ó(FÓGô	ð ûðüsk   ‚J%†F  ™E8š9F  ÁE;ÁAF  ÂE>Â CF  Å7J%Å8F  Å;F  Å>F  Æ 
J"Æ
JÆ%F(Æ&C7JÊJ"Ê"J%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(        $ �r}
t        j+                  ||
|¬«      ƒ d{  –—†7   t-        j.                  d|
«       t-        j0                  t3        j4                  «       «       t7        |
t
        «      r\t9        t        |
dt;        |
j<                  «      «      t        |
dd«      t        |
dd«      t        |
dt>        j@                  «      ¬«      ‚|
› }t9        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ž  rz  rc  rv  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  zAlitellm.proxy.proxy_server.get_messages(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rè  )!r.  rW  r¢  r~  rU  r¨  r:   rg  r*  Úaget_messagesrP  r‡  rý  r  rp  rw  r9  rå  râ   r   rÿ  rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  ry  s               rˆ   Úget_messagesr€  Ü.  sa  è ø€ ð, €Dð=ä0ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ *× 8Ñ 8Ñ UÀ9Ð UÐPTÑ U×Uˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðM
ùð Vùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#fÐhiÔjÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬°°=À#Ó(FÓGô	ð ûðürr  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        Šd‰v rY‰d   du rRdt        t        z  fˆˆ ˆˆˆfd	„}d
t        dt        dz  fˆˆfd„}t         |«       t!        ‰‰«      |¬«      ƒ d{  –—† S  ‰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}|j0                  j3                  t5        j6                  ‰|	|
|t
        t/        ‰dd«      ‰|¬«      «       |S 7 �Œ¿7 �Œˆ7 Œú7 Œà# t        $ �r}t(        j9                  ‰|‰¬«      ƒ d{  –—†7   t;        j<                  d|«       t;        j>                  tA        jB                  «       «       tE        |t        «      r\tG        t/        |dtI        |jJ                  «      «      t/        |dd«      t/        |dd«      t/        |dtL        jN                  «      ¬«      ‚|› }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ž  rz  rc  rÜ  TrÐ  c               “   ó’   •K  —  ‰j                   dd‰i‰¤Žƒ d {  –—† } t        t        ‰| ‰¬«      di ‰¬«      ƒ d {  –—† S 7 Œ'7 Œ­w)Nrv  rq
  rä  )Ú	generatorræ  r9  r3  rè  )Úarun_threadrå   rÝ	  )Ú
run_streamr„  r3  rÎ   rv  r*  s    €€€€€rˆ   Úproduce_run_streamz&run_thread.<locals>.produce_run_stream^/  s_   øè ø€ Ø*<¨&×*<Ñ*<Ñ*YÀyÐ*YÐTXÑ*Y×$Y�
Ü,Ü=Ø*;Ø!+Ø%)ôð
  3ØØ#ô	÷ 	ð 	ð %Zøð	ús   ƒA›Aœ"A¾A¿AÁAr4  c              “   óP   •K  — t         j                  ‰| ‰¬«      ƒ d {  –—† S 7 Œ­w)NrÒ	  )rý  rØ	  )r4  r„  r*  s    €€rˆ   Úaudit_late_failurez&run_thread.<locals>.audit_late_failurek/  s4   øè ø€ ô /×EÑEØ&7ÈCÐ^bð Fó ÷ ð ð ús   ƒ&Ÿ$ &)Úping_interval_secondsÚon_late_failurerv  rû	  r6  r  r  r  r‡  r	  rz  r  r  rÒ	  z?litellm.proxy.proxy_server.run_thread(): Exception occured - %sr�   rw   rÔ	  r  r7  rÕ	  r;  rè  )(r	  r
  r„  r.  rW  r¢  r~  rU  r¨  r:   rg  r*  r»  r¸  rÿ  ræ   rç   r„  rP  r‡  rý  r  rp  rw  r9  rå  râ   r   rØ	  rŸ   rz  r
  r2  r3  rÓ  rS   r‚  r—  r±  rë  )r3  rv  rË  r*  r	  r†  rˆ  r  r  r‡  r	  rz  r  rÚ	  r„  rÎ   s   `` `          @@rˆ   Ú
run_threadr‹  3/  sý  üè ø€ ð, €Dð`Ø#ŸL™L›N×*ˆÜ�|‰|˜DÓ!ˆä0ØØÜ-Ø/ÜÜ%ô
÷ 
ˆô ÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiÜ"ˆà�tÑ  X¡°$Ñ 6ðÔ.?Ä,Ñ.N÷ ñ ð¬ið ¼MÈDÑ<Pö ô 4Ù"Ó$Ü&=¸dÀFÓ&KØ 2ô÷ ð ð !3 × 2Ñ 2Ñ O¸YÐ OÈ$Ñ O×Oˆô 	×ÑÜ×3Ñ3ÀDÇHÁHÐM^Ð`bÓDcÐluÐ3Óvô	
ô
  ' xÐ1AÀ2ÓFÒLÈ"ˆØ'×+Ñ+¨J¸Ó=ÒCÀˆØ(×,Ñ,¨[¸$Ó?ÒEÀ2ˆ	Ø'×+Ñ+¨J¸Ó=ÒCÀˆà× Ñ ×'Ñ'Ü)×<Ñ<Ø"3Ø!Ø#Ø!ÜÜ$Ð%6Ð8NÐPRÓSØ!Ø+ô	ô	
ð ˆðU +ùð
ùðNøð Pùô6 ó Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô 	×"Ñ"Ð#dÐfgÔhÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  9¬c°!·(±(«mÓ<Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ð #$ ˆIÜ Ü  9¨iÓ8Ü˜Q ¨Ó/Ü˜a ¨&Ó1Ü˜Q ¬°°=À#Ó(FÓGô	ð ûðüs‰   ‡L‹G' žGŸ9G' ÁG ÁBG' Ã(G#Ã)G' Ã,LÃ-G' ÄG%ÄCG' ÇLÇG' Ç G' Ç#G' Ç%G' Ç'
L	Ç1LÈHÈC7LÌL	Ì	L)ÚBaseTokenCounter)rˆ  )rv  )r‡  )ÚAccessGroupRepositoryrë  ÚInvitationLinkRepositoryr9	  rØ  rÉ
  )ÚTeamRepository)r¼
  rš  Úmodel_to_usec           	      ód  — | €yddl m} | j                  di «      j                  dd«      }d}d}	  ||| j                  di «      j                  d«      | j                  di «      j                  d«      | j                  di «      j                  d	«      ¬
«      \  }}}}ddlm} ddlm}	  ||«      }
|
r(|	j                  ||
¬«      }|�|j                  «       ||fS y# t        $ rH |j                  d«      sd|j                  «       v r"ddlm}  |«       }|j                  «       ||fcY S Y yw xY w)z®
    Auto-route to the correct provider's token counter based on model/deployment.
    Uses the existing get_provider_model_info infrastructure with switch-case pattern.
    Nr   )r¿  rô  r{  r6  râ  rz  r  )r{  râ  rz  r  )ÚLlmProviders)ÚProviderConfigManager)r{  r  z
anthropic/Ú	anthropic)ÚAnthropicModelInfo)NNN)Ú1litellm.litellm_core_utils.get_llm_provider_logicr¿  rp  r[  r’  r  r“  Úget_provider_model_infoÚget_token_counterrÿ  r™  rÉ  r¤  r•  )rš  r�  r¿  Ú
full_modelr{  râ  Údynamic_api_keyrz  r’  r“  Úllm_provider_enumÚprovider_model_infor•  Úanthropic_model_infos                 rˆ   Ú_get_provider_token_counterrž  Å/  sf  € ð ÐØåRà"Ÿ™Ð'7¸Ó<×@Ñ@ÀÈ"ÓM€JØ€EØ&*Ðð"Xá@PØØ *§¡Ð/?ÀÓ D× HÑ HÐI^Ó _Ø—^‘^Ð$4°bÓ9×=Ñ=¸jÓIØ—N‘NÐ#3°RÓ8×<Ñ<¸YÓGô	A
Ñ=ˆÐ" O°Xõ 	5Ý7ñ $0Ð0CÓ#DÐñ Ø)>×)VÑ)VØ Ð+<ð *Wó *Ðð #Ð.à'×9Ñ9Ó;ØØ'ðð ð øô ò Xà× Ñ  Ô.°+À×AQÑAQÓASÑ2SÝNá*<Ó*>Ð Ø'×9Ñ9Ó;¸UÐDWÐWÒWð	 3Tð ðXús   ±B+C ÃAD/Ä.D/Úprovider_counterrŒ  râ  Úcontentsr2  r¬  Úsystemrk   c	           	   ƒ   óF  K  — | j                  |¬«      sy	 | j                  |xs d||||||¬«      ƒ d{  –—† }	|	�w|	j                  d
u rit        j                  d
u r+t        |	j                  xs ddd|	j                  xs d¬	«      ‚t        j                  d|	j                  |	j                  «       y|	S 7 Œ# t        j                  $ rS}
t	        |
dd«      xs t        |
«      }t	        |
dd«      xs |
j                  j                  }t        |dd|¬	«      ‚d}
~
ww xY w­w)zlAttempt provider-specific token counting. Returns result on success, None to fall through to local counting.©râ  Nr6  )r�  rŒ   r   rš  r2  r¬  r¡  r�   r7  Útoken_counting_errorr{  rÕ	  TzToken counting failedrž  zIProvider token counting failed (%s): %s. Falling back to local tokenizer.)Úshould_use_token_counting_apiÚcount_tokensÚhttpxÚHTTPStatusErrorrw  r‚  r  r7  rS   rz  r  Údisable_token_counterr|
  rŸ   r/  )rŸ  râ  r�  rŒ   r   rš  r2  r¬  r¡  rC  r  r|
  r7  s                rˆ   Ú_try_provider_token_countrª  ü/  s@  è ø€ ð ×9Ñ9ÐNaÐ9ÔbØð
Ø.×;Ñ;Ø%Ò+¨ØØØ!Ø'ØØð <ó 
÷ 
ˆð$ Ð˜fŸl™l¨dÑ2Ü×(Ñ(¨DÑ0Ü Ø×,Ñ,ÒGÐ0GØ+ØØ×'Ñ'Ò.¨3ô	ð ô 	×$Ñ$ØWØ×ÑØ× Ñ ô	
ð
 Ø€MðA
ùô × Ñ ò 
Ü& q¨)°TÓ:ÒD¼cÀ!»fˆÜ$ Q¨°tÓ<ÒVÀÇ
Á
×@VÑ@VˆÜØ!Ø'ØØô	
ð 	
ûð
üs9   ‚D!—B8 ¶B6·B8 »A;D!Â6B8 Â8DÃADÄDÄD!c                 óB   — t        | t        t        f«      r| sy d| dœ}|S )Nr¡  )r
  r8  )rÓ  r‚  r•  )r¡  r�   s     rˆ   Ú_system_messager¬  .0  s%   € Ü�fœs¤D˜kÔ*±&ØØ;CÐPVÑ2W€GØ€NrŠ   z/utils/token_counterz	llm utils)r  rŽ  Úresponse_modelÚcall_endpointc              ƒ   ó
  K  — | j                   }| j                  }| j                  }| j                  }| j                  }|€|€|€t        dd¬«      ‚d}d}d}	t        �*	 t        j                  | j                  i ¬«      ƒ d{  –—† }|�g|j                  di «      j                  d«      }|j                  d	i «      }	t        |j                  di «      «       d
|v r|j                  d
d«      d   }|xs | j                  }
d}d}|du r|�t        ||
«      \  }}}|�|}
|�*t!        |||
|||| j                  ||¬«	      ƒ d{  –—† }|�|S t"        j$                  du rt'        dddd¬«      ‚d}|	�#t)        t*        dz  |	j                  dd«      «      }t"        j,                  j/                  |
|¬«      }t1        |d   «      }t3        |«      }t)        t4        t6           dz  |«      }|�|€|n|g|¢­}t)        t8        t:           dz  |�|nd«      } t=        t"        j>                  «      |
||||¬«      ƒ d{  –—† }tA        || j                  |
|¬«      S 7 �ŒÓ# t        $ r t        j                  d«       Y �Œòw xY w7 �Œ<7 ŒH­w)zî
    Args:
        request: TokenCountRequest
        call_endpoint: bool - When set to "True" it will call the token counting endpoint - e.g Anthropic or Google AI Studio Token Counting APIs.

    Returns:
        TokenCountResponse
    NrD  z/prompt or messages or contents must be providedrc  )r{  Úrequest_kwargszVlitellm.proxy.proxy_server.token_counter(): Exception occured while getting deploymentrô  r{  r¸  r  r8  T)	rŸ  râ  r�  rŒ   r   rš  r2  r¬  r¡  z?Token counting is disabled and no provider API result availableÚtoken_counting_disabledé÷  rÕ	  Úcustom_tokenizer)r{  r³  rw   )r{  rù  rŒ   r¬  r³  )rÇ  r2  Ú
model_usedÚtokenizer_type)!r0	  rŒ   r   r¬  r¡  r¨  rU  Úasync_get_available_deploymentr{  rÿ  rŸ   r   rp  rm   rq  rž  rª  r  r©  rS   r   rž  rè  Ú_select_tokenizerr‚  r¬  r	   rˆ  r•  rŠ  r¿   Útoken_counterrk   )r3  r®  r0	  rŒ   r   r¬  r¡  rš  r�  r¸  r�  rŸ  râ  Ú_modelrC  r³  Ú_tokenizer_usedÚtokenizer_usedÚsystem_messageÚtyped_messagesÚcounted_messagesÚcounted_toolsrÇ  s                          rˆ   r¸  r¸  50  s  è ø€ ð" —N‘N€FØ×&Ñ&€HØ×&Ñ&€HØ—=‘=€EØ—N‘N€Fð
 €~˜(Ð*¨xÐ/?Ü¨Ð4eÔfÐfà(,€JØÐØ&*€JÜÐð	Ü)×HÑHØ—m‘mØ!ð  Ió  ÷ ˆJð ÐØ'Ÿ^™^Ð,<¸bÓA×EÑEÀgÓNÐØ—^‘^ L°"Ó5ˆ
Ü" :§>¡>Ð2BÀBÓ#GÔHàÐ$Ñ$Ø!3×!9Ñ!9¸#¸qÓ!AÀ!Ñ!DÐð 	Ò+˜gŸm™mð ð
 15ÐØ&*ÐØ˜Ñ Ð!7ä8SÐT^Ð`lÓ8mÑ5Ð˜&Ð"5ØÐØ!ˆLàÐ#Ü7Ø-Ø 3Ø%ØØØ!Ø!Ÿ-™-ØØô

÷ 

ˆð ÐØˆMô ×$Ñ$¨Ñ,ÜØUØ*ØØô	
ð 	
ð ;?ÐØÐÜÜ&¨Ñ-Ø�N‰NÐ-¨tÓ4ó
Ðô %Ÿ]™]×<Ñ<À<ÐbrÐ<Ós€Oä °Ñ 7Ó8€NÜ+¨FÓ3€NÜ ÜÔ!Ñ" TÑ)¨8ó€Nð )Ð0°NÐ4J‰ÐQ_ÐPqÐbpÑPqð ô  ÜÔ$Ñ%¨Ñ,Ð7GÐ7S©eÐY]ó€Mð !@¤¬×)>Ñ)>Ó ?ØØØ!ØØ(ô!÷ €Lô Ø!Ø—m‘mØØ%ô	ð ðaúô ò 	Ü ×*Ñ*Øh÷ð	úð4

ùðVús\   ‚AJÁ$I ÂIÂI ÂB:JÅI>ÅC5JÈ8JÈ9JÉI ÉI;É7JÉ:I;É;JÊJz/utils/supported_openai_params)r  rŽ  c              ƒ   ó²   K  — 	 t        j                  | ¬«      \  } }}}dt        j                  | |¬«      iS # t        $ r t	        ddd| › �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'
    ```
    rì  Úsupported_openai_params©r{  râ  rD  rz  zCould not map model=rc  )r  r¿  Úget_supported_openai_paramsrÿ  r¨  )r{  râ  rÁ  s      rˆ   rÁ  rÁ  °0  st   è ø€ ð"_Ü+2×+CÑ+CÈ%Ô+PÑ(ˆÐ" A qà%¤w×'JÑ'JØÐ1Dô(ð
ð 	
øô
 ò _Ü¨°WÐ@TÐUZÐT[Ð>\Ð4]Ô^Ð^ð_üs   ‚A„38 ·A¸AÁAz/utils/transform_requestc           	   ƒ   ó  K  — ddl m} 	 t        | j                  t        t
        | j                  j                  dd«      ¬«        || j                  | j                  ¬	«      S # t        $ r}t        ddt        |«      i¬«      ‚d }~ww xY w­w)
Nr   )Úreturn_raw_requestr{  r6  )Úrequest_bodyrW  rU  r{  rD  rz  rc  )r„  r  )r  rÅ  rÔ   rÆ  rW  rU  rp  rs  r¨  r‚  r  )r3  rÅ  r  s      rˆ   Útransform_requestrÇ  Ì0  s‚   è ø€ õ 1ðGÜØ ×-Ñ-Ü-Ü!Ø×&Ñ&×*Ñ*¨7°BÓ7õ		
ñ  w×'8Ñ'8À×AUÑAUÔVÐVøô ò GÜ¨°W¼cÀ!»fÐ4EÔFÐFûðGüs(   ‚BŠ;A# ÁBÁ#	B	Á,BÂB	Â	Brs   c              ƒ   óz  K  — |€'t        ddt        j                  j                  i¬«      ‚g }| D ]„  }|j	                  di «      j	                  dd«      }|€Œ(t        |«      j                  j                  d|i¬«      ƒ d{  –—† }|€ŒZ|j                  |j                  k(  sŒt|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ž  rz  rc  r¸  r.  r‡  r�  )r¨  r:   Údb_not_connected_errorr*  rp  r‡  rH  rÙ  rf  rb  rã  )rs   r*  r÷  Úfiltered_modelsr{  r.  râ  s          rˆ   Ú_check_if_model_is_user_addedrÌ  â0  sÍ   è ø€ ð ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð  €OØò .ˆØ�Y‰Y�| RÓ(×,Ñ,¨T°4Ó8ˆØˆ:ØÜ0?ÀÓ0N×0TÑ0T×0`Ñ0`ÐhrÐtvÐgwÐ0`Ó0x×*xˆØÑØ×"Ñ"Ð&7×&?Ñ&?Ó?Ø×&Ñ& uÕ-ð.ð Ðð	 +yús   ‚B B;ÂB9Â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
    r¸  r•  N)rp  rq  rã  r   rÔ  )rs   rÍ  Úuser_team_modelsr{  Úmodel_team_ids        rˆ   Ú_check_if_model_is_team_modelrÑ  ÿ0  se   € ð +-ÐØò ;ˆØŸ	™	 ,°Ó3×7Ñ7¸	À4ÓHˆàÑ$Ø §¡Ò.Ø ×'Ñ'¬¬T°5Ó(9Õ:ð;ð ÐrŠ   r²  c              ƒ   ó¸  K  — |€'t        ddt        j                  j                  i¬«      ‚t	        | ||¬«      ƒ d{  –—† } |j
                  r^	 t        |«      j                  j                  d|j
                  i¬«      ƒ d{  –—† }|�"| t        |j                  «       xs g |¬
«      z  } t        | ¬«      }|S 7 Œ|7 Œ8# t        $ r t        ddd	i¬«      ‚w xY w­w)rÉ  Nrž  rz  rc  )rs   r*  r÷  rb  r�  rD  zUser not found)rs   rÍ  rr   )r¨  r:   rÊ  r*  rÌ  rb  r¼
  rH  rÙ  rÿ  rÑ  rv  r;  )r²  rU  r*  r÷  rÍ  Úunique_modelss         rˆ   Únon_admin_all_modelsrÔ  1  s  è ø€ ð ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô 5ØØ+Ø#ô÷ €Jð × Ò ð	UÜ$2°=Ó$A×$GÑ$G×$SÑ$SØ Ð"3×";Ñ";Ð<ð %Tó %÷ ˆHð ÐØÔ7Ø!×0Ñ0Ó2Ò8°bØ!ôñ ˆJô >ÀZÔP€MØÐð/øðùô ò 	UÜ¨C¸ÐBRÐ8SÔTÐTð	Uüs9   ‚;C½B:¾CÁ4B> ÂB<ÂB> Â3CÂ<B> Â>CÃCÚteam_db_objects_typedc                 óT  — i }|j                  «       }|j                  «       }| D �]  }|j                  r&t        j                  j
                  |j                  v r¬|j                  «       }|€ŒI|D ]“  }|j                  di «      j                  dd«      }|€Œ(|j                  di «      j                  dd«      }	d}
|	�|	|j                  v rd}
|
sŒa|j                  |t        «       «      j                  |j                  «       Œ• Œât        |j                  ||¬«      }|D ]�  }|j                  ||j                  ¬«      }|€Œ#|D ]Z  }|j                  di «      j                  dd«      }|€Œ(|j                  |t        «       «      j                  |j                  «       Œ\ Œƒ �Œ‚ |S )	z'
    Add team models to all models
    Nr¸  r.  r•  FT©rŸ  r   r›  ©r1  r•  )r¨  r©  rs   rU   Úall_proxy_modelsr*  rv  rp  r•  r  rð  rä  rÞ   )rÕ  rU  rŸ  r   r›  Úteam_objectrm  r{  r‡  Úteam_model_idÚcan_add_modelÚresolved_model_namesr1  Ú_modelss                 rˆ   Ú_add_team_models_to_all_modelsrß  ?1  s·  € ð /1€KØ(×8Ñ8Ó:ÐØ!+×!CÑ!CÓ!EÐà,ó ]ˆà×"Ò"Ü ×1Ñ1×7Ñ7¸;×;MÑ;MÑMà#×2Ñ2Ó4ˆJØÑ%Ø'ò Y�EØ$Ÿy™y¨°rÓ:×>Ñ>¸tÀTÓJ�HØÐ'Ø à$)§I¡I¨l¸BÓ$?×$CÑ$CÀIÈtÓ$T�MØ$)�MØ$Ð,°À×ATÑATÑ0TØ(,˜â$Ø#×.Ñ.¨x¼»Ó?×CÑCÀK×DWÑDWÕXñYô $3Ø'×.Ñ.Ø!1Ø$7ô$Ð ð
 3ò ]�
Ø$×3Ñ3¸zÐS^×SfÑSfÐ3Óg�ØÑ&Ø!(ò ]˜Ø#(§9¡9¨\¸2Ó#>×#BÑ#BÀ4ÈÓ#N˜Ø#Ñ/Ø'×2Ñ2°8¼S»UÓC×GÑGÈ×H[ÑH[Õ\ñ]ò]ð3]ð@ ÐrŠ   rŸ  c              ƒ   ó€  K  — g }t        «       }| D ]n  }|j                  sŒ|j                  r&t        j                  j
                  |j                  v rŒC|j                  |«       |j                  |j                  «       Œp |s|S t        |«      j                  j                  ddt        |«      ii¬«      ƒ d{  –—† }|D �ci c]  }|j                  |j                  xs g “Œ }	}|D ]È  }t        «       }
|j                  xs g D ]#  }|
j                  |	j                  |g «      «       Œ% |
D ]�  }|j                  ||j                   ¬«      }|€Œ#|D ]Z  }|j                  di «      j                  dd«      }|€Œ(|j#                  |t        «       «      j%                  |j                   «       Œ\ Œƒ ŒÊ |S 7 Œûc c}w ­w)a…  
    Resolve models reachable via team access groups and merge them into team_models.

    Batch-fetches all distinct access groups in a single DB query, then resolves
    each eligible team's access group models via the pre-fetched map.

    This ensures models associated with a team only through access groups
    (not directly in team.models) are included in the UI model listing.
    Úaccess_group_idr  r�  NrØ  r¸  r.  )rð  Úaccess_group_idsrs   rU   rÙ  r*  rã  rå  r�  rH  r‰  r•  rá  Úaccess_model_namesrp  rv  r•  r  rä  )rÕ  rU  r÷  rŸ  Úeligible_teamsÚall_access_group_idsrÚ  Úaccess_group_rowsr—  Úag_model_mapr	  Úag_idr1  Údeploymentsrš  r‡  s                   rˆ   Ú'_add_access_group_models_to_team_modelsrê  m1  så  è ø€ ð  68€NÜ,/«EÐà,ò 
BˆØ×+Ò+Øð ×!Ò!Ô%6×%GÑ%G×%MÑ%MÐQ\×QcÑQcÑ%cØà×Ñ˜kÔ*Ø×#Ñ# K×$@Ñ$@ÕAð
Bñ ØÐô &;¸=Ó%I×%OÑ%O×%YÑ%YØ  4¬Ð.BÓ)CÐ"DÐEð &Zó &÷  Ðð FWö1Ø>Aˆ×Ñ˜S×3Ñ3Ò9°rÑ9ð1€Lð 1ð
 &ò YˆÜ #£ˆØ ×1Ñ1Ò7°Rò 	<ˆEØ×Ñ˜|×/Ñ/°°rÓ:Õ;ð	<ð &ò 	YˆJØ$×3Ñ3¸zÐS^×SfÑSfÐ3ÓgˆKØÑ&Ø"-ò Y�JØ)Ÿ~™~¨l¸BÓ?×CÑCÀDÈ$ÓO�HØÑ+Ø#×.Ñ.¨x¼»Ó?×CÑCÀK×DWÑDWÕXñYñ	YðYð Ðð+ úò1ùs1   ‚B9F>Â;F7Â<F>Ã"F9Ã&A+F>Å)F>Å<<F>Æ9F>Ú
user_teamsc              ƒ   óN  K  — g }| dk(  r\t        |«      j                  j                  «       ƒ d{  –—† }|D �cg c]%  }t        j                  |j                  «       «      ‘Œ' }}nat        |«      j                  j                  dd| ii¬«      ƒ d{  –—† }|D �cg c]%  }t        j                  |j                  «       «      ‘Œ' }}t        ||¬«      }t        ||||¬«      ƒ d{  –—† }i }|j                  «       D ]  \  }}	t        |	«      ||<   Œ |S 7 Œäc c}w 7 Œ‰c c}w 7 Œ<­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"]}
    rÌ   Nr•  r  r�  )rÕ  rU  )rÕ  rU  r÷  rŸ  )
r�  rH  r‰  rM   rü  r»  rß  rê  râ  r•  )
rë  r÷  rU  rÕ  Úteam_db_objectsÚteam_db_objectrŸ  Úreturned_team_modelsr‡  Úteam_idss
             rˆ   Úget_all_team_modelsrñ  ¨1  sM  è ø€ ð 68Ðà�SÒÜ=KÈMÓ=Z×=`Ñ=`×=jÑ=jÓ=l×7lˆà`oö!
ØN\Ô×,Ñ,¨^×-FÑ-FÓ-HÕIð!
Ðñ !
ô !/¨}Ó =× CÑ C× MÑ MÐU^ÐaeÐgqÐ`rÐTsÐ MÓ t×tˆð apö!
ØN\Ô×,Ñ,¨^×-FÑ-FÓ-HÕIð!
Ðð !
ô 1Ø3Øô€Kô @Ø3ØØ#Øô	÷ €Kð 9;ÐØ)×/Ñ/Ó1ò 8Ñˆ�(Ü)-¨h«Ð˜XÒ&ð8ð  Ðð; 8múò!
ð uúò!
ðúsJ   ‚.D%°D±D%¹*DÁ#/D%ÂDÂD%Â*DÃ!D%Ã&D#Ã'/D%ÄD%ÄD%c                 óì   ‡‡‡— | rt         j                  j                  | v rt        ‰j	                  d¬«      «      S ‰j                  «       Št        ˆfd„| D «       «      }t        ˆˆfd„|D «       «      S )aÙ  
    Resolve a `models` grant (a user's or a key's) to the deployment ids it can call.

    An empty grant and the 'all-proxy-models' sentinel both mean unrestricted at call
    time (see `_check_model_access_helper`), so both expand to every non-team deployment.
    A grant entry naming an access group also grants that group's members, and naming a
    deployed model that shares the name grants the model itself, matching the union the
    call-time check applies.
    T©Úexclude_team_modelsc              3   óX   •K  — | ]!  }|g‰j                  |d «      ¢­D ]  }|–— Œ Œ# y­w)rè  Nr’  )r’  r{  rÄ  Úaccess_groupss      €rˆ   r”  z9_resolve_model_grant_to_deployment_ids.<locals>.<genexpr>é1  s5   øè ø€ Ò&s°ÈUÐLrÐUb×UfÑUfÐglÐnpÓUqÑLrÒ&sÀD¤tÐ&s tÑ&sùs   ƒ'*c              3   ó    •K  — | ]E  }‰j                  |¬ «      xs dD ]*  }|j                  di «      j                  dd«      xŠ�‰–— Œ, ŒG y­w)rS
  rè  r¸  r.  N)rv  rp  )r’  rÄ  rš  rU  r‡  s      €€rˆ   r”  z9_resolve_model_grant_to_deployment_ids.<locals>.<genexpr>ê1  sd   øè ø€ ò àØ%×4Ñ4ÀÐ4ÓEÒKÈòð Ø"Ÿ™ |°RÓ8×<Ñ<¸TÀ4ÓHÐHˆHÐUô 	ðØñùs   ƒAA)rU   rÙ  r*  rŒ  rî  r©  )rs   rU  Úgranted_model_namesrö  r‡  s    ` @@rˆ   Ú&_resolve_model_grant_to_deployment_idsrù  Ø1  sn   ú€ ñ Ô&×7Ñ7×=Ñ=ÀÑGÜ�Z×-Ñ-À$Ð-ÓGÓHÐHà%×=Ñ=Ó?€MÜ!&Ó&s¸Ô&sÓ!sÐÜô à'ôó ð rŠ   Úuser_db_objectrž  c                 óì   ‡— t        t        t        t           | j                  «      |«      }|rt
        j                  j                  |v r|S t        t        ||«      «      Št        ˆfd„|D «       «      S )a6  
    Get all models the caller has direct (non-team) access to.

    Both the user record and the calling key are enforced at call time, so direct access
    is the intersection of the two grants. An unrestricted key (empty grant, or the
    'all-proxy-models' sentinel) leaves the user's grant untouched.
    c              3   ó,   •K  — | ]  }|‰v sŒ|–— Œ y ­wrn  rè  )r’  r‡  Úkey_model_idss     €rˆ   r”  z+get_direct_access_models.<locals>.<genexpr>2  s   øè ø€ ÒV˜h¸HÈÒ<U”ÑVùrý  )
rù  r   r	   r‚  rs   rU   rÙ  r*  r@  rŒ  )rú  rU  rž  Úuser_model_idsrý  s       @rˆ   Úget_direct_access_modelsrÿ  ò1  sj   ø€ ô CÜŒX”c‰]˜N×1Ñ1Ó2Øó€Nñ Ô*×;Ñ;×AÑAÀZÑOØÐä$Ô%KÈJÐXbÓ%cÓd€MÜÓV¨.ÔVÓVÐVrŠ   c                 ó´   — | D �cg c]H  }|j                  di «      j                  dd«      s"|j                  di «      j                  dg «      r|‘ŒJ c}S c c}w )zNKeep only deployments the caller can use via direct access or team membership.r¸  Údirect_accessFÚaccess_via_team_idsr’  )r²  r¹  s     rˆ   Ú!_filter_models_to_user_accessibler  	2  s[   € ð !öàØ�:‰:�l BÓ'×+Ñ+¨O¸UÔCØ�:‰:�l BÓ'×+Ñ+Ð,AÀ2ÔFò 	òð ùò s   …AAc              ƒ   ó†  K  — d}d}t        | «      rd}t        |j                  d¬«      «      }n§| j                  �›t	        |«      j
                  j                  d| j                  i¬«      ƒ d{  –—† }|�`t        j                  |j                  «       «      }|j                  xs g }t        ||t        t        t           | j                  «      ¬«      }|� 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<   Œ‡ t%        |«      }|D ]1  }	|	j#                  d
i «      j#                  dd«      }
|
€Œ(|
|v |	d
   d<   Œ3 |S 7 �ŒL7 ŒÔ­w)zx
    Populate `model_info.access_via_team_ids` and `model_info.direct_access`
    without filtering the model list.
    Nrè  rÌ   Tró  rb  r�  )rú  rU  rž  )rë  r÷  rU  r¸  r.  r•  Fr  r  )r1  rŒ  rî  rb  r¼
  rH  rÙ  rO   rü  r»  rq  rÿ  r   r	   r‚  rs   rñ  rp  r@  )r*  r÷  rU  r²  rë  Údirect_access_modelsrú  Úuser_objectrŸ  r¹  r‡  Úteam_only_model_idÚcan_use_modelrð  Údirect_access_model_idss                  rˆ   Ú_populate_team_access_on_modelsr
  2  s  è ø€ ð 37€JØ*,ÐÜÐ-Ô.Øˆ
Ü$ Z×%=Ñ%=ÐRVÐ%=Ó%WÓXÑØ	×	"Ñ	"Ð	.Ü@NÈ}Ó@]×@cÑ@c×@oÑ@oØÐ/×7Ñ7Ð8ð Apó A
÷ ;
ˆð Ð%Ü!2×!AÑ!AÀ.×B[ÑB[ÓB]Ó!^ˆKØ$×*Ñ*Ò0¨bˆJÜ#;Ø*Ø%Ü¤¬¡Ð/@×/GÑ/GÓHô$Ð ð
 ÐÜ#6Ø!Ø'Ø!ô$
÷ 
ˆð
 !ò 	`ˆFØ—z‘z ,°Ó3×7Ñ7¸¸dÓCˆHØ!'§¡¨L¸"Ó!=×!AÑ!AÀ)ÈTÓ!RÐØÑ#Ø %�Ø%Ð1Ø*Ÿ™¨x¸Ó<�HÙÐ$6¸(Ñ$BØ(,™à$(�MÚ ØBMÇ/Á/ÐRZÐ\^ÓB_�F˜<Ñ(Ð)>Ò?ð	`ô &/Ð/CÓ%DÐØò XˆØ—:‘:˜l¨BÓ/×3Ñ3°D¸$Ó?ˆØÑØ4<Ð@WÐ4WˆF�<Ñ  Ò1ðXð
 ÐðK;
ùð
ús9   ‚A.GÁ0F<Á1A9GÃ*F?Ã+AGÄ;#GÅAGÆ.GÆ?Gc              ƒ   óR   K  — t        | |||¬«      ƒ d{  –—† }t        |«      S 7 Œ­w)z5
    Get all models across all teams user is in.
    ©r*  r÷  rU  r²  N)r
  r  r  s       rˆ   Ú%get_all_team_and_direct_access_modelsr  K2  s5   è ø€ ô 7Ø+Ø#ØØô	÷ €Jô -¨ZÓ8Ð8ðús   ‚'•%–'r
  c                 óª  — | j                  di «      }|du r/d}|�|j                  | i d¬«      xs d}nd}t        |«      }|| d<   t        | ¬	«      }|i k(  r;| j                  d
i «      }|j                  dd«      }	 t	        j
                  |¬	«      }|i k(  re| j                  d
i «      }|j                  dd«      }|r?|j                  d«      }	t        |	«      dkD  r|	d   }	 t	        j
                  ||	d   ¬«      }|j                  «       D ]  \  }
}|
|vsŒ|||
<   Œ || d<   t        | dh¬«      } | S # t        $ r i }Y Œ®w xY w# t        $ r i }Y ŒUw xY w)a…  
    Enrich a model dictionary with litellm model info (pricing, context window, etc.)
    and remove sensitive information.

    Args:
        model: Model dictionary to enrich
        debug: Whether to include debug information like openai_client
        llm_router: Optional router instance for debug info

    Returns:
        Enriched model dictionary with sensitive info removed
    r¸  TrÔ	  NÚasync)rš  r  Úclient_typeÚllm_router_is_NoneÚopenai_clientrì  rô  r{  r  r   r/
  rÂ  Úlitellm_credential_name)Úexcluded_keys)rp  Ú_get_clientr‚  r–
  r  r“
  rÿ  rq  rÈ  râ  rù   )r{  r
  rU  r¸  Ú_openai_clientr  r•
  rô  r  Úsplit_modelrF  rG  s               rˆ   Ú$_enrich_model_info_with_litellm_datar  ]2  s¡  € ð  Ÿ	™	 ,°Ó3€JØ��}ØˆØÐ!Ø'×3Ñ3¸uÈRÐ]dÐ3ÓeÒoÐio‰Nà1ˆNÜ" >Ó2ˆØ!.ˆˆoÑô 0°eÔ<Ðð ˜RÒàŸ™Ð#3°RÓ8ˆØ&×*Ñ*¨7°DÓ9ˆð	$Ü!(×!7Ñ!7¸mÔ!LÐð ˜RÒàŸ™Ð#3°RÓ8ˆØ&×*Ñ*¨7°DÓ9ˆÙØ!.×!4Ñ!4°SÓ!9ˆKÜ�;Ó !Ò#Ø +¨B¡�ð(Ü%,×%;Ñ%;À-ÐepÐqrÑesÔ%tÐ"ð #×(Ñ(Ó*ò ‰ˆˆ1Ø�JÒØˆJ�qŠMðð %€Eˆ,Ñô 2°%ÐHaÐGbÔc€EØ€Løô- ò 	$Ø!#Òð	$ûô ò (Ø%'Ò"ð(ús$   Á<D3 Ã"E Ä3EÅ EÅEÅEc              ƒ   óÄ  K  — | �|€y| j                   t        j                  t        j                  fv ry| j                  r| j                  hn	t        «       }| j                  }|€|S 	 t        |«      j                  j                  d|i¬«      ƒ d{  –—† }|€|S |t        |j                  xs g «      z  S 7 Œ$# t        $ r t        j                  d«       |cY S w xY w­w)uß  
    Return the team IDs whose BYOK rows the caller is allowed to see via
    `/v2/model/info` search results.

    `None` means "no scoping" â€” used for admins and for callers/paths that
    have already been scoped upstream (or in tests that supply their own
    pre-filtered input set). A returned set (possibly empty) means BYOK rows
    must have `model_info.team_id` âˆˆ that set, otherwise they belong to a
    team the caller is not a member of and must be dropped.
    Nrb  r�  z\Failed to look up caller teams while scoping BYOK search; defaulting to key team scope only.)rj  rP   ÚPROXY_ADMINÚPROXY_ADMIN_VIEW_ONLYr•  rð  rb  r¼
  rH  rÙ  rÿ  rŸ   r   rq  )r*  r÷  Úkey_team_scoperb  rÍ  s        rˆ   Ú_get_caller_byok_team_scoper  ›2  sô   è ø€ ð Ð  MÐ$9ØØ×"Ñ"Ü×$Ñ$Ü×.Ñ.ð'ñ ð ØEV×E^ÒE^Ð'8×'@Ñ'@Ñ&AÔdgÓdi€NØ&×.Ñ.€GØ€ØÐðÜ .¨}Ó =× CÑ C× OÑ OÐW`ÐbiÐVjÐ OÓ k×kˆð ÐØÐØœC §¡Ò 4°"Ó5Ñ5Ð5ð lùÜò Ü×&Ñ&Øjô	
ð Òð	üs<   ‚A&C Á)*B: ÂB8ÂB: Â C Â8B: Â: CÃC ÃCÃC Úmodel_info_dictÚallowed_team_idsc                 ó8   — |€y| j                  d«      }|€y||vS )záWhether a team BYOK row belongs to a team the caller is not a member of.

    `team_id` is only set on team BYOK rows; non-team rows fall through
    unaffected. `allowed_team_ids is None` means no scoping (e.g. admins).
    Fr•  r’  )r  r  r•  s      rˆ   Ú_byok_row_outside_caller_teamsr!  À2  s1   € ð ÐØØ$×(Ñ(¨Ó3€GØ€ØØÐ*Ð*Ð*rŠ   rž  Ú_SORTED_SEARCH_DB_FETCH_CAPr~  Úsearch_lowerÚdb_model_ids_in_routerÚrouter_models_countÚpageÚsizeÚsort_byÚis_byok_outside_caller_teamsc
           	   ƒ   ó4  K  — d|	€|ddœn|	i}
|rddt        |«      ii|
d<   |rt        }nt        d||z  |z
  «      }t        | «      j                  j                  |
¬	«      ƒ d{  –—† }g }|dkD  r.t        | «      j                  j                  |
|¬
«      ƒ d{  –—† }|D �cg c]2  } |t        |j                  t        «      r|j                  ni «      s|‘Œ4 }}g }|D ](  }|j                  |g«      }|sŒ|j                  |«       Œ* ||fS 7 Œ©7 Œvc c}w ­w)a  
    Run the bounded DB query that backs `/v2/model/info?search=`. Returns
    `(decrypted_models, total_count)` where `total_count` is the cheap
    `count(...)` of rows matching `search` (not yet team-scoped) so the
    UI's pagination stays accurate without materializing every row.

    Earlier iterations also OR'd a JSON-path match on
    `model_info.team_public_model_name` to surface BYOK rows that live
    only in the DB. That branch fell back to `string_contains: ""`
    because Prisma's JSON `string_contains` is case-sensitive on
    Postgres, which let any authenticated caller force a full BYOK-table
    read via `/v2/model/info?search=x`. We rely on the router-side
    filter for `team_public_model_name` instead and keep the DB cost
    bounded by `search`.
    r1  NÚinsensitive)ÚcontainsÚmodeÚnotr  r‡  r   r�  )r�  Útake)r•  r"  r_
  r‡  rH  Úcountr‰  rÓ  r¸  rÔ  r  r|  )r÷  r~  r#  r$  r%  r&  r'  r(  r)  r1  Údb_where_conditionÚ
take_limitÚdb_models_total_countÚdb_models_rawrÎ  Úmatching_db_rowsÚ	decryptedrâ  Údecrypted_modelss                      rˆ   Ú_fetch_db_models_for_searchr8  Õ2  sT  è ø€ ð8 	È:ÐK] <¸ÒGÐcmð1Ðñ Ø*/°$¼Ð=SÓ8TÐ1UÐ)VÐ˜:Ñ&ñ
 Ü0‰
ä˜˜D 4™KÐ*=Ñ=Ó>ˆ
ä)8¸Ó)G×)MÑ)M×)SÑ)SÐZlÐ)SÓ)m×#mÐà.0€MØ�A‚~Ü-¨mÓ<×BÑB×LÑLØ$Øð Mó 
÷ 
ˆð öàÙ+¼JÀqÇ|Á|ÔUYÔ<Z¨A¯LªLÐ`bÔcò 	
ðÐð ð 13€IØ$ò /ˆØ'×BÑBÀHÀ:ÓNÐÚØ×ÑÐ-Õ.ð/ð
 Ð+Ð+Ð+ð/ $nøð
úòùs<   ‚A#DÁ%DÁ&4DÂDÂDÂ#7DÃDÃ8DÄDÄDr8  é2   rr  c	              ƒ   ó   ‡‡K  — |r|j                  «       s| dfS |j                  «       j                  «       Št        ||¬«      ƒ d{  –—† Šdt        t        t
        f   dt        fˆfd„}	dt        t        t        f   dt        fˆfd„}
| D �cg c]'  } |
|«      r |	|j                  d«      xs i «      s|‘Œ) }}g }t        «       }|D ]^  }|j                  di «      }|j                  d	d
«      }|j                  d«      }|r|r|j                  |«       ŒN|j                  |«       Œ` t        |«      }t        |«      }||z   }g }|du xs ‰|j                  «       v }|�)|r'	 t        ||‰||||||	|¬«
      ƒ d{  –—† \  }}||z   }n|}||z   |fS 7 �ŒMc c}w 7 Œ# t        $ r"}t        j                   d|«       |}Y d}~Œ7d}~ww xY w­w)u³  
    Apply search filter to models, querying database for additional matching models.

    Args:
        all_models: List of models to filter
        search: Search term (case-insensitive)
        prisma_client: Prisma client for database queries
        proxy_config: Proxy config for decrypting models
        user_api_key_dict: Caller identity used to scope BYOK matches to
            teams the caller belongs to. When omitted (None), no team
            scoping is applied â€” pass it from request handlers that expose
            this function to non-admin callers.
        page: Current page number (1-indexed). Used with ``size`` to bound
            the DB ``find_many(take=...)`` so a broad search term can't
            force a full table read + decrypt on every request.
        size: Page size. See ``page``.
        sort_by: Sort field. When set, results must be sorted across the
            full match set, so the DB fetch is capped at
            ``_SORTED_SEARCH_DB_FETCH_CAP`` instead of one page.
        model_name: Exact ``model_name`` the caller already narrowed
            ``all_models`` to (``?model=``). The DB query matches it
            exactly instead of the substring, and is skipped when the
            substring cannot occur in it, otherwise rows from other model
            groups leak into the result and the count.

    Returns:
        Tuple of (filtered_models, total_count). total_count is None if not searching.
    N©r*  r÷  r  rÐ  c                 ó   •— t        | ‰«      S rn  )r!  )r  r  s    €rˆ   Ú_is_byok_outside_caller_teamszE_apply_search_filter_to_models.<locals>._is_byok_outside_caller_teamsI3  s   ø€ Ü-¨oÐ?OÓPÐPrŠ   rÎ  c                 óÄ   •— ‰| j                  d«      xs dj                  «       v ry| j                  d«      xs i j                  d«      xs d}‰|j                  «       v S )Nr1  r6  Tr¸  Úteam_public_model_name)rp  rÉ  )rÎ  r?  r#  s     €rˆ   Ú_model_matches_searchz=_apply_search_filter_to_models.<locals>._model_matches_searchL3  sb   ø€ ð
 ˜AŸE™E ,Ó/Ò5°2×<Ñ<Ó>Ñ>ØØ)*¯©¨|Ó)<Ò)BÀ×(GÑ(GÐH`Ó(aÒ(gÐegÐØÐ5×;Ñ;Ó=Ð=Ð=rŠ   r¸  râ  Fr.  )
r÷  r~  r#  r$  r%  r&  r'  r(  r)  r1  z.Error querying database models with search: %s)rr  rÉ  r  rÔ  r‚  r   r#  r   rp  rð  rä  rã  rÈ  r8  rÿ  rŸ   r   )r²  rr  r÷  r~  r*  r&  r'  r(  r1  r=  r@  rÎ  Úfiltered_router_modelsÚfiltered_config_modelsr$  r¸  Úis_db_modelr‡  Úconfig_models_countÚdb_models_in_router_countr%  rê  Úexact_name_can_matchr3  Úsearch_total_countr  r  r#  s                             @@rˆ   Ú_apply_search_filter_to_modelsrH  3  s  ùè ø€ ñN ˜Ÿ™œØ˜4ÐÐà Ÿ,™,›.×.Ñ.Ó0€Lä$?Ø+Ø#ô%÷ Ðð
Q´t¼CÄ¸NÑ7Kð QÔPTõ Qð>¤¤c¬3 h¡ð >´Dõ >ð  ö%àÙ  Ô#Ñ,IÈ!Ï%É%ÐP\ÓJ]ÒJcÐacÔ,dò 	
ð%Ðð %ð %'ÐÜ$'£EÐà#ò -ˆØ—U‘U˜<¨Ó,ˆ
Ø —n‘n Z°Ó7ˆØ—>‘> $Ó'ˆá™8Ø"×&Ñ& xÕ0à"×)Ñ)¨!Õ,ð-ô "%Ð%;Ó!<ÐÜ'*Ð+AÓ'BÐØ!4Ð7PÑ!PÐð ')€IØ",°Ð"4Ò"Z¸È
×HXÑHXÓHZÐ8ZÐØÐ Ñ%9ð	5Ü5PØ+Ø)Ø)Ø'=Ø$7ØØØØ-JØ%ô6÷ 0Ñ,ˆIÐ,ð "5Ð7LÑ!LÑð
 1Ðà! IÑ-Ð/AÐAÐAðMûò,%ð:0ùô ò 	5Ü ×*Ñ*Ð+[Ð]^Ô_Ø!4Õûð	5üsb   „AGÁ	FÁ
AGÂ,FÂ<B*GÅ'F  Å?FÆ F  ÆGÆGÆF  Æ 	GÆ)GÇGÇGÇGÚdtc                 ó  — | €yt        | t        «      rŠ	 | j                  d«      r| j                  dd«      n| }t	        j
                  |«      }|j                  €"|j                  t        j                  ¬«      }|S |j                  t        j                  «      }|S t        | t        «      rK| j                  € | j                  t        j                  ¬«      S | j                  t        j                  «      S y# t        t        f$ r Y yw xY w)aÞ  
    Normalize a datetime value to a timezone-aware UTC datetime for sorting.

    This function handles:
    - None values: returns None
    - String values: parses ISO format strings and converts to UTC-aware datetime
    - Datetime objects: converts naive datetimes to UTC-aware, and aware datetimes to UTC

    Args:
        dt: Datetime value (None, str, or datetime object)

    Returns:
        UTC-aware datetime object, or None if input is None or cannot be parsed
    NÚZz+00:00©Útzinfo)rÓ  r‚  ré  r  r
   r	  rM  r   ÚutcÚ
astimezoners  r  )rI  Údt_strÚ	parsed_dts      rˆ   Ú_normalize_datetime_for_sortingrR  �3  sé   € ð 
€zØä�"”cÔð	à9;¿¹ÀSÔ9I˜BŸJ™J s¨HÔ5ÈrˆFÜ ×.Ñ.¨vÓ6ˆIà×ÑÐ'Ø%×-Ñ-´X·\±\Ð-ÓB�	ð Ðð &×0Ñ0´·±Ó>�	ØÐô �"”hÔà�9‰9ÐØ—:‘:¤X§\¡\�:Ó2Ð2à�}‰}œXŸ\™\Ó*Ð*àøô œNÐ+ò 	Ùð	ús   •A'C: Á= C: Ã:DÄDÚascÚ
sort_orderc                 óü   ‡‡— ‰r‰dvr| S |j                  «       dk(  Šdt        t        t        f   dt        fˆˆfd„}	 t	        | |‰¬«      }|S # t
        $ r#}t        j                  d‰|«       | cY d}~S d}~ww xY w)	a  
    Sort models by the specified field and order.

    Args:
        all_models: List of models to sort
        sort_by: Field to sort by (model_name, created_at, updated_at, costs, status)
        sort_order: Sort order (asc or desc)

    Returns:
        Sorted list of models
    )r1  rä  rå  Úcostsr±  Údescr{  rÐ  c                 ó´  •— | j                  di «      }‰dk(  rL|j                  d«      }|rt        |«      j                  «       S | j                  dd«      j                  «       S ‰dk(  r~|j                  d«      }t        |«      }|€^‰
s.t        j
                  j                  t        j                  ¬«      S t        j                  j                  t        j                  ¬«      S |S ‰dk(  r~|j                  d«      }t        |«      }|€^‰
s.t        j
                  j                  t        j                  ¬«      S t        j                  j                  t        j                  ¬«      S |S ‰dk(  rP|j                  d	d
«      xs d
}|j                  dd
«      xs d
}||z   }|d
k(  r‰
st        d«      S t        d«      S |S ‰dk(  r|j                  dd«      }	|	S y )Nr¸  r1  r?  r6  rä  rL  rå  rV  Úinput_cost_per_tokenr   Úoutput_cost_per_tokenÚinfr.	  r±  râ  F)rp  r‚  rÉ  rR  r
   r_
  r  r   rN  rÉ  r   )r{  r¸  r?  rä  Únormalized_dtrå  Ú
input_costÚoutput_costÚ
total_costrâ  rš	  r(  s             €€rˆ   Úget_sort_keyz"_sort_models.<locals>.get_sort_keyÒ3  sÅ  ø€ Ø!ŸI™I l°BÓ7ˆ
à�lÒ"ð -7¯N©NÐ;SÓ,TÐ"Ù%ÜÐ1Ó2×8Ñ8Ó:Ð:Ø—9‘9˜\¨2Ó.×4Ñ4Ó6Ð6à˜Ò$Ø *§¡¨|Ó <ˆJÜ;¸JÓGˆMØÐ$ñ #ô —L‘L×(Ñ(´·±Ð(Ó=ðô "Ÿ™×-Ñ-´X·\±\Ð-ÓBðð
 !Ð à˜Ò$Ø *§¡¨|Ó <ˆJÜ;¸JÓGˆMØÐ$ñ #ô —L‘L×(Ñ(´·±Ð(Ó=ðô "Ÿ™×-Ñ-´X·\±\Ð-ÓBðð
 !Ð à˜ÒØ *§¡Ð/EÀqÓ IÒ NÈQˆJØ!+§¡Ð0GÈÓ!KÒ!PÈqˆKØ *¨[Ñ 8ˆJà˜QŠÙ+2”u˜U“|ÐE¼¸f»ÐEØÐà˜Ò à(Ÿn™n¨Z¸Ó?ˆHØˆOàrŠ   )rz  rš	  zError sorting models by %s: %sN)rÉ  rÔ  r‚  r   rÆ  rÿ  rŸ   r   )r²  r(  rT  r`  Úsorted_modelsr  rš	  s    `    @rˆ   Ú_sort_modelsrb  ·3  sŽ   ù€ ñ  �gð &ñ ð Ðà×%Ñ%Ó'¨6Ñ1€Gð4œD¤¤c ™Nð 4¬sö 4ðlÜ% j°lÈGÔTˆØÐøÜò Ü×&Ñ&Ð'GÈÐRSÔTØÕûðús   ¿A Á	A;ÁA6Á0A;Á6A;c                 ó®   — | j                  d«      }t        |t        «      sy|j                  d«      }t        |t        «      xr |j	                  d«      S )a[  
    True for any auto-router deployment, i.e. every `auto_router/*` strategy
    (semantic, complexity, adaptive, quality).

    Router._is_auto_router_deployment is deliberately narrower; it answers "is this the
    *semantic* auto-router strategy" and returns False for the complexity and adaptive
    prefixes, so it is not reusable here.
    rô  Fr{  zauto_router/)rp  rÓ  r   r‚  r™  )r{  rô  r  s      rˆ   Ú_is_auto_router_modelrd  4  sM   € ð "ŸI™IÐ&6Ó7€NÜ�n¤gÔ.ØØ)×-Ñ-¨gÓ6€MÜ�m¤SÓ)ÒV¨m×.FÑ.FÀ~Ó.VÐVrŠ   Útotal_countc                 óœ   — |€t        | «      }|dz
  |z  }|dkD  r| |z   nd}| |||z    }t        j                  d|||||«       |||||dœS )aD  
    Paginate models and return response dictionary.

    Args:
        all_models: List of all models
        page: Current page number
        size: Page size
        total_count: Total count (if None, uses len(all_models))
        search: Search term (for logging)

    Returns:
        Paginated response dictionary
    r8  r   zGPagination: skip=%s, take=%s, total_count=%s, total_pages=%s, search=%s©r„  re  Úcurrent_pageÚtotal_pagesr'  )rÈ  rŸ   r
  )r²  r&  r'  re  rr  Úskipri  Úpaginated_modelss           rˆ   Ú_paginate_models_responserl   4  s„   € ð( ÐÜ˜*“oˆà˜!‘8˜tÑ#€DØ4?À!²O˜K˜<¨4Ñ/Ñ0È€KØ(¨°°t±Ð<Ðä×ÑØQØØØØØôð !Ø"ØØ"Øñð rŠ   rö  c                 ól   — g }| D ],  }||v r|j                  ||   «       Œ|j                  |«       Œ. |S )zQExpand team model entries (including access group names) to concrete model names.)r|  rã  )rŸ  rö  rK  rÄ  s       rˆ   Ú_team_models_resolve_to_namesrn  M4  sB   € à!#€HØò "ˆØ�=Ñ Ø�O‰O˜M¨$Ñ/Õ0à�O‰O˜DÕ!ð	"ð
 €OrŠ   c              ƒ   ó@  K  — 	 t        |«      j                  j                  d| i¬«      ƒ d{  –—† }|€t        j                  d| «       yt        j                  |j                  «       «      S 7 Œ@# t        $ r!}t        j                  d| |«       Y d}~yd}~ww xY w­w)z;Load team row from DB; returns None if missing or on error.r•  r�  NzTeam %s not found in databasezError fetching team %s: %s)
r�  rH  rÙ  rŸ   r/  rM   rü  r»  rÿ  r   )r•  r÷  rî  r  s       rˆ   Ú"_load_team_object_for_model_filterrp  X4  s�   è ø€ ð
Ü@NÈ}Ó@]×@cÑ@c×@oÑ@oØ˜gÐ&ð Apó A
÷ ;
ˆð Ð!Ü ×(Ñ(Ð)HÈ'ÔRØÜ ×/Ñ/°×0IÑ0IÓ0KÓLÐLð;
ùô ò Ü×&Ñ&Ð'CÀWÈaÔPÜûðüsJ   ‚B„*A1 ®A/¯A1 ÁBÁ"A1 Á.BÁ/A1 Á1	BÁ:BÂBÂBÂBrÚ  c              ƒ   ó¤  K  — t        «       }|r|j                  «       ni }| j                  r&t        j                  j
                  | j                  v r|r|j                  «       ng }|��|D ]b  }|j                  di «      j                  dd«      }|€Œ(|j                  di «      j                  dd«      }	|	�|	|k(  sŒR|j                  |«       Œd n£t        «       }
| j                  D ],  }||v r|
j                  ||   «       Œ|
j                  |«       Œ. |
D ]Y  }|r|j                  ||¬«      ng }|€Œ|D ]8  }|j                  di «      j                  dd«      }|€Œ(|j                  |«       Œ: Œ[ 	 | j                  rœt        j                  j
                  | j                  vrvt        | j                  |«      }t        |«      j                  j                  dd|ii¬«      ƒ d{  –—† }|D ]*  }|j                  sŒ|j                  |j                  «       Œ, |S 7 Œ5# t        $ r"}t!        j"                  d	||«       Y d}~|S d}~ww xY w­w)
z=Collect model IDs the team can use from router config and DB.Nr¸  r.  r•  rØ  r1  r  r�  z.Error querying database models for team %s: %s)rð  r©  rs   rU   rÙ  r*  rv  rp  rä  rå  rn  r‡  rH  r‰  r‡  rÿ  rŸ   r
  )rÚ  r•  r÷  rU  Úteam_accessible_model_idsrö  rm  r{  r‡  rÛ  rÝ  r1  rÞ  Ú_resolved_namesrê  râ  r  s                    rˆ   Ú!_gather_team_accessible_model_idsrt  g4  sh  è ø€ ô 25³ÐÙCM˜:×=Ñ=Ô?ÐSU€Mà×ÒÔ!2×!CÑ!C×!IÑ!IÈ[×M_ÑM_Ñ!_Ù;E˜J×5Ñ5Ô7È2ˆ
ØÑ!Ø#ò <�Ø Ÿ9™9 \°2Ó6×:Ñ:¸4ÀÓF�ØÐ#ØØ %§	¡	¨,¸Ó ;× ?Ñ ?À	È4Ó P�Ø Ð(¨M¸WÓ,DØ-×1Ñ1°(Õ;ñ<ô 14³ÐØ%×,Ñ,ò 	5ˆJØ˜]Ñ*Ø$×+Ñ+¨M¸*Ñ,EÕFà$×(Ñ(¨Õ4ð		5ð /ò 	@ˆJÙ[e�j×/Ñ/¸:ÈwÐ/ÔWÐkmˆGØÑ"Ø$ò @�EØ$Ÿy™y¨°rÓ:×>Ñ>¸tÀTÓJ�HØÑ+Ø1×5Ñ5°hÕ?ñ@ð	@ð
aØ×ÒÔ"3×"DÑ"D×"JÑ"JÐR]×RdÑRdÑ"dÜ%BÀ;×CUÑCUÐWdÓ%eˆOÜ?NÈ}Ó?]×?cÑ?c×?mÑ?mØ# d¨OÐ%<Ð=ð @nó @÷ :ˆIð &ò E�Ø×$Ó$Ø-×1Ñ1°(×2CÑ2CÕDðEð %Ð$ð:ùô ò aÜ×"Ñ"Ð#SÐU\Ð^_×`Ð`à$Ð$ûðaüs\   ‚B;IÂ>A7IÄ6)IÅ IÅ6A4H" Ç*H Ç+H" ÈH" ÈIÈ H" È"	IÈ+IÉIÉIÉIc              ƒ   ó¬  K  — |j                   t        j                  t        j                  fv ry|j                  }|€t        dddi¬«      ‚	 t        |«      j                  j                  d|i¬«      ƒ d{  –—† }|�| |j                  xs g vrt        dddi¬«      ‚y7 Œ(# t        $ r% t        j                  d«       t        dddi¬«      ‚w xY w­w)	aj  
    `teamId` arrives untrusted via the /v2/model/info query string and the
    filter below includes BYOK rows solely on `model_info.team_id == team_id`.
    Without this guard, any authenticated user who knows (or guesses) another
    team's id could enumerate that team's BYOK model metadata. Allow only
    proxy admins or members of the requested team.
    Né“  rz  z)Not authorized to view this team's modelsrc  rb  r�  z>Failed to look up caller teams while authorizing teamId filter)rj  rP   r  r  rb  r¨  r¼
  rH  rÙ  rÿ  rŸ   r   rq  )r•  r*  r÷  rb  rÍ  s        rˆ   Ú_authorize_team_id_queryrw  š4  sû   è ø€ ð ×"Ñ"Ü×$Ñ$Ü×.Ñ.ð'ñ ð 	à&×.Ñ.€GØ€ÜØØÐHÐIô
ð 	
ð
Ü .¨}Ó =× CÑ C× OÑ OÐW`ÐbiÐVjÐ OÓ k×kˆð Ð˜7¨8¯>©>Ò+?¸RÑ@ÜØØÐHÐIô
ð 	
ð Að lùÜò 
Ü×&Ñ&Ð'gÔhÜØØÐHÐIô
ð 	
ð
üs0   ‚ACÁ*B# Á8B!Á9B# Á=$CÂ!B# Â#.CÃCc              ƒ   óî  K  — |�t        |||¬«      ƒ d{  –—†  t        ||«      ƒ d{  –—† }|€g S t        ||||«      ƒ d{  –—† }g }| D ]�  }|j                  di «      }	|	j                  dd«      }
|	j                  d«      |k(  r|j	                  |«       ŒM|	j                  dg «      }t        |t        «      r||v r|j	                  |«       Œ…|
sŒˆ|
|v sŒ�|j	                  |«       ŒŸ |S 7 ŒØ7 ŒÆ7 Œ®­w)am  
    Filter models by team ID. Returns models where:
    - team_id matches the model's BYOK team_id, OR
    - team_id is in access_via_team_ids, OR
    - model_id is reachable via team.models / access groups

    Args:
        all_models: List of models to filter
        team_id: Team ID to filter by
        prisma_client: Prisma client for database queries
        llm_router: Router instance for config queries
        user_api_key_dict: Caller auth context. When provided, the caller must
            be a proxy admin or a member of `team_id`; otherwise raises 403.

    Returns:
        Filtered list of models
    N)r•  r*  r÷  r¸  r.  r•  r  )rw  rp  rt  rp  rã  rÓ  r•  )r²  r•  r÷  rU  r*  rÚ  rr  rË  r¹  r¸  r‡  r  s               rˆ   Ú_filter_models_by_team_idry  Â4  s$  è ø€ ð0 Ð$Ü&ØØ/Ø'ô
÷ 	
ð 	
ô  BÀ'È=ÓY×Y€KØÐØˆ	ä&GÈÐU\Ð^kÐmwÓ&x× xÐð  €OØò +ˆØ—Z‘Z ¨bÓ1ˆ
Ø—>‘> $¨Ó-ˆð �>‰>˜)Ó$¨Ò/Ø×"Ñ" 6Ô*Øà(Ÿn™nÐ-BÀBÓGÐÜÐ)¬4Ô0°WÐ@SÑ5SØ×"Ñ" 6Ô*Øò ˜Ð$=Ò=Ø×"Ñ" 6Õ*ð%+ð( ÐðO	
øð Zøð !yús>   ‚C5–C/—C5ªC1«C5ÁC3ÁBC5ÃC5ÃC5Ã1C5Ã3C5c              ƒ   ó8  K  — d}|�)|j                  | ¬«      }|rt        j                  |«      }|€K	 t        |«      j                  j                  d| i¬«      ƒ d{  –—† }|r|j                  |g«      }|r|d   }|�V|�T|j                  «       rD|j                  «       j                  «       }	|j                  dd«      }
|	|
j                  «       vrd}|�|gng }t        |«      }||fS 7 Œ�# t        $ r!}t        j                  d| |«       Y d}~Œ•d}~ww xY w­w)	z<Find a model by its ID and optionally filter by search term.Nrí  r‡  r�  r   z*Error querying database for modelId %s: %sr1  r6  )r“
  rÆ  rÇ  r‡  rH  rÙ  r  rÿ  rŸ   r   rr  rÉ  rp  rÈ  )r‡  rr  rU  r÷  r~  Úfound_modelrâ  r7  r  r#  r1  r²  rG  s                rˆ   Ú_find_model_by_idr|  5  s;  è ø€ ð €Kð ÐØ ×/Ñ/°8Ð/Ó<ˆÙÜŸ-™-¨Ó4ˆKð Ðð	fÜ$3°MÓ$B×$HÑ$H×$TÑ$TÐ\fÐhpÐ[qÐ$TÓ$r×rˆHÙà*6×*QÑ*QÐS[ÐR\Ó*]Ð Ù#Ø"2°1Ñ"5�Kð
 ÐØÐ &§,¡,¤.Ø"(§,¡,£.×"6Ñ"6Ó"8ˆLØ +§¡°¸bÓ AˆJØ :×#3Ñ#3Ó#5Ñ5à"�ð *5Ð)@˜™Àb€JÜ,/°
«OÐØÐ)Ð)Ð)ð+ sùô ò 	fÜ ×*Ñ*Ð+WÐYaÐcd×eÑeûð	füsA   ‚0D³*C- ÁC+ÁC- Á=A.DÃ+C- Ã-	DÃ6DÄDÄDÄDz/v2/model/infoz!Specify the model name (optional)z%Only return models added by this userz.Return all models across all teams user is in.zPage number)rô  Úgez	Page sizez3Search model names (case-insensitive partial match)z,Search for a specific model by its unique IDzaFilter models by team ID. Returns models with direct_access=True or teamId in access_via_team_idszLField to sort by. Options: model_name, created_at, updated_at, costs, statuszSort order. Options: asc, desczÿOmit auto-router deployments (litellm model prefixed `auto_router/`). They select among deployments rather than being deployments themselves, so a caller rendering a deployment list can leave them out. Defaults to false, so existing callers are unaffectedÚuser_models_onlyÚinclude_team_modelsÚmodelIdÚteamIdÚsortByÚ	sortOrderÚexclude_auto_routersc              ƒ   óz  K  — t         �t         j                  sg d|d|dœS t        €'t        ddt        j
                  j                  i¬«      ‚t        j                  «       ƒ d{  –—†  |�(t        ||t         t        t        ¬«      ƒ d{  –—† \  }}n†t        j                  t         j                  «      }t        �
|t        gz  }|�&|D �cg c]  }t        |t        |f«      «      sŒ|‘Œ }}t        ||xs dt        t        | |||
|¬	«	      ƒ d{  –—† \  }}|rt!        |t         | t        ¬
«      ƒ d{  –—† }|rt#        | t        t         |¬«      ƒ d{  –—† }t%        |«      D ]  \  }}t'        ||�|ndt         ¬«      ||<   Œ  |	�I|	j)                  «       r9t+        ||	j)                  «       t        t         | ¬«      ƒ d{  –—† }t-        |«      }|�t-        |«      }|
r7|r#|j/                  «       dvrt        dd|› d�¬«      ‚t1        ||
|xs d¬«      }t3        j4                  d|«       ddlm}  ||| ¬«      ƒ d{  –—† }|du r|D �cg c]  }t;        |«      rŒ|‘Œ }}t-        |«      }|D �cg c]  }t=        |«      ‘Œ }}t?        |||||¬«      S 7 �Œ47 �Œc c}w 7 �Œ’7 �Œq7 �ŒS7 Œé7 Œlc c}w c c}w ­w)a¯  
    Paginated model metadata for proxy deployments (pricing, provider, team access).

    Returns configured router deployments with enriched `model_info` (costs, provider,
    context window, etc.). Sensitive fields such as API keys and api_base are omitted.

    Query parameters:
        model: Filter to a single public `model_name`.
        user_models_only: When true, only return models created by the calling user.
        include_team_models: When true, populate `access_via_team_ids` and `direct_access`
            on each model and filter to deployments the caller can use.
        page / size: Pagination controls (defaults: page=1, size=50).
        search: Case-insensitive partial match on model name or team public name.
        modelId: Return a single deployment by LiteLLM model id.
        teamId: Filter to models with direct access or team membership for this team id.
        sortBy / sortOrder: Sort by model_name, created_at, updated_at, costs, or status.

    Example request:
    ```
    curl -X GET 'http://localhost:4000/v2/model/info?include_team_models=true&page=1&size=50' \
    --header 'Authorization: Bearer sk-1234'
    ```

    Example response:
    ```json
    {
        "data": [
            {
                "model_name": "gpt-4",
                "litellm_params": {"model": "openai/gpt-4.1"},
                "model_info": {
                    "id": "abc123",
                    "litellm_provider": "openai",
                    "access_via_team_ids": ["team-1"],
                    "direct_access": true
                }
            }
        ],
        "total_count": 1,
        "current_page": 1,
        "total_pages": 1,
        "size": 50
    }
    ```
    Nr   rg  rž  rz  rc  )r‡  rr  rU  r÷  r~  r6  )	r²  rr  r÷  r~  r*  r&  r'  r(  r1  )r²  rU  r*  r÷  r  F)r{  r
  rU  ©r²  r•  r÷  rU  r*  )rS  rW  rD  zInvalid sortOrder: z. Must be 'asc' or 'desc'rS  )r²  r(  rT  úall_models: %s)Úappend_agents_to_model_info)rs   r*  T)r²  r&  r'  re  rr  ) rU  rm  r÷  r¨  r:   rÊ  r*  r~  rÓ  r|  rÆ  rÇ  r¸	  Ú'_deployment_matches_allowed_model_namesr@  rH  rÔ  r  rc  r  rr  ry  rÈ  rÉ  rb  rŸ   r
  Ú0litellm.proxy.agent_endpoints.model_list_helpersrˆ  rd  Ú"_translate_model_name_for_responserl  )r*  r{  r~  r  r
  r&  r'  rr  r€  r�  r‚  rƒ  r„  r²  rG  rÎ  r  r¹  rˆ  s                      rˆ   Úmodel_info_v2rŒ  05  s  è ø€ ôn Ð¤×!6Ò!6àØØ ØØñ
ð 	
ô ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô ×
!Ñ
!Ó
#×#Ð#ð ÐÜ/@ØØÜ!Ü'Ü%ô0
÷ *
Ñ&ˆ
Ñ&ô —]‘]¤:×#8Ñ#8Ó9ˆ
äÐ!àœ:˜,Ñ&ˆJàÐØ%/Ös Ô3ZÐ[\Ô^gÐinÐhpÓ^qÕ3rš!ÐsˆJÐsô 0NØ!Ø’<˜RÜ'Ü%Ø/ØØØØô
0
÷ 
*
Ñ&ˆ
Ð&ñ Ü/Ø!Ü!Ø/Ü'ô	
÷ 
ˆ
ñ Ü@Ø/Ü'Ü!Ø!ô	
÷ 
ˆ
ô ˜zÓ*ò 
‰	ˆˆ6Ü<ØØ Ð,‘%°%Ü!ô
ˆ
�1Šð
ð Ð˜fŸl™lœnÜ4Ø!Ø—L‘L“NÜ'Ü!Ø/ô
÷ 
ˆ
ô ! ›_Ðð ÐÜ  ›_Ðñ á˜Ÿ™Ó*°/ÑAÜØØ,¨Y¨KÐ7PÐQôð ô "Ø!ØØ Ò) Eô
ˆ
ô ×ÑÐ/°Ô<õñ 3ØØ+ô÷ €Jð ˜tÑ#Ø!+ÖL˜AÔ3HÈÕ3K’aÐLˆ
ÐLô ˜Z›Ðð BLÖL¸AÔ4°QÕ7ÐL€JÐLä$ØØØØ&Øôð ðe $ùð*
ûò  tð
*
ùð
ùð
ùð$
øðHúò Mùò Mùs·   ‚A#J;Á%JÁ&%J;ÂJÂAJ;ÃJÃ)JÃ-%J;ÄJ$Ä#J;Ä6J'Ä7 J;ÅJ*ÅA+J;ÇJ-ÇA>J;ÉJ/ÉJ;ÉJ1É J1É$J;É5J6ÊJ;ÊJ;ÊJ;Ê'J;Ê*J;Ê-J;Ê/J;Ê1
J;z/model/streaming_metricsz1View time to first token for models in spend logs)rô  r  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Õ	  é   ©rU  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;
        rz  r{  r|  r6  r}  r~  úhttps://ú/openai/r   c                 ó   — | d   S r1
  rè  r2
  s    rˆ   rü  z)model_streaming_metrics.<locals>.<lambda>‰6  ó   € ÈdÐSTÉg€ rŠ   ry  Údate©r„  Úall_api_bases)r÷  rS   r:   rÊ  r*  r±  r<  r
   rh
  r   r˜  rð  ri  Ú	query_rawr‚  rq  rä  rÔ  rÆ  râ  rã  r•  )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  r~  rÆ  Ú	model_keyÚlatencys                         rˆ   Úmodel_streaming_metricsr¨  6  sI  è ø€ ô ÐÜÜ%×<Ñ<×BÑBØ!ØÜ×6Ñ6ô	
ð 	
ð Ò?œXŸ\™\›^¬i¸QÔ.?Ñ?€IØÒ'œŸ™›€Gà"Ÿ™Ó)¨W¯\©\«^Ñ;€KÙð‰	ð0ˆ	ô.  ›E€NÜ:G×:JÑ:J×:TÑ:TØÐ(¨)°Wó;÷ 5€Kð €NØÑØ%ò 	SˆJØ" :Ñ.ˆIØ Ñ(ˆFØ",Ð-BÑ"CÐØˆJÙØ(¨Ñ6�Ø(�
Ø nÑ4Ø24�N ;Ò/à! %Ñ(�Ø!�
Ø&0Ð1FÑ&GÐ#Ø˜~Ñ-Ø+-�N 4Ñ(Ü#& v£;Ð Ø˜YÑ&Ü'*¨9£~Ð$ØÐ1Ñ1Ø';×'AÑ'AÀ*Ó'MÈaÑ'PÐ$à×ÑÐ3Ô4à?RˆN˜:Ñ&Ð';Ò<ð1	Sð4	ð ')ˆô œf ^×%9Ñ%9Ó%;ÑAUÔVÓWˆØ!ò 	#ˆCØœS ›XÐ&ˆEØ&4°SÑ&9×&?Ñ&?Ó&Aò +Ñ"�	˜7Ø#*��iÒ ð+à�O‰O˜EÕ"ð		#ð Ü! .Ó1ñ
ð 	
ð_ ð	5ûs   ‚CG&ÃG#ÃDG&z/model/metricsz>View number of requests & avg latency per model on config.yamlz	gpt-4-32kr  Ú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;
    rz  r{  r~  r‚  r”  r•  r   c                 ó   — | d   S r1
  rè  r2
  s    rˆ   rü  zmodel_metrics.<locals>.<lambda>ü6  r—  rŠ   ry  r˜  r™  )r÷  rS   r±  r<  r
   rh
  r   rª   rð  ri  r›  r‚  rq  rä  rÔ  rÆ  râ  rã  r•  )r*  r�  rŽ  r�  r  r©  r�  rž  rŸ  r   r³  r¡  r¹  r¤  Ú_avg_latency_per_tokenr¥  r  r~  rÆ  r¦  r§  s                        rˆ   Úmodel_metricsr°  –6  s  è ø€ ô  ÐÜØ6Ø!ØÜ×6Ñ6ô	
ð 	
ð ÒMœXŸ\™\›^¬i¼_Ô.MÑM€IØÒ'œŸ™›€Gà€˜' [Ò0ØˆàÐ˜8 {Ò2Øˆð!€IôD  ›E€NÜ=J×=MÑ=M×=WÑ=WØÐ(¨)°W¸gÀxó>÷ 8€Kð €NàÐØ%ò 	PˆJØ" :Ñ.ˆIØ Ñ(ˆFØ˜eÑ$ˆDØ%/Ð0GÑ%HÐ"Ø˜>Ñ)Ø')�˜tÑ$Ü#& v£;Ð ØÐ$¨°yÑ)@Ü'*¨9£~Ð$Ø#Ð/°JÐBVÑ4VØ';×'AÑ'AÀ*Ó'MÈaÑ'PÐ$à×ÑÐ3Ô4Ø9OˆN˜4Ñ Ð!5Ò6ð	Pð 	ð ')ˆô œf ^×%9Ñ%9Ó%;ÑAUÔVÓWˆØ!ò 	#ˆCØœS ›XÐ&ˆEØ&4°SÑ&9×&?Ñ&?Ó&Aò +Ñ"�	˜7Ø#*��iÒ ð+à�O‰O˜EÕ"ð		#ð Ü! .Ó1ñ
ð 	
ðK ð8ú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;
    rz  r6  r•  r   )r÷  rS   r±  r<  r
   rh
  r   rª   rý  r8  r½  r/   r"  ri  r›  rp  rq  )r*  r�  rŽ  r�  r  r©  r½  r�  rŸ  r—  r¡  s              rˆ   Úmodel_metrics_slow_responsesr²  	7  s;  è ø€ ô  ÐÜØ6Ø!ØÜ×6Ñ6ô	
ð 	
ð €˜' [Ò0ØˆàÐ˜8 {Ò2ØˆàÒMœXŸ\™\›^¬i¼_Ô.MÑM€IØÒ'œŸ™›€Gô 	×1Ñ1×DÑDÒhÔHhð ô Ð/Ó0Ðð€IôB  -×/Ñ/×9Ñ9ØØØØØØØó ÷ €Kð ÐØò 	(ˆCØŸ™ 
Ó+Ò1¨rˆIØ˜YÑ&Ø%ŸO™O¨JÓ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­  a?  
        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;
    r…  r6  r†  r   r‡  )r{  r†  )r„  Úexception_types)r÷  rS   r±  r<  r
   rh
  r   rª   ri  r›  rð  rp  rå  rã  râ  rä  r•  )r*  r�  rŽ  r�  r  r©  r�  rŸ  r  r´  r³  r{  r†  r‡  Úcurr_rowrF  rG  s                    rˆ   Úmodel_metrics_exceptionsr¶  b7  sj  è ø€ ô  ÐÜØ6Ø!ØÜ×6Ñ6ô	
ð 	
ð ÒMœXŸ\™\›^¬i¼_Ô.MÑM€IØÒ'œŸ™›€Gà€˜' [Ò0Øˆðð€Iô, @M×?OÑ?O×?YÑ?YØ�9˜gÐ'<¸gó@÷ :€Kð #%€HÜ ›U€Oðð Ðà%ò 	'ˆJØ—N‘NÐ#<¸bÓAˆEØ)Ÿ~™~Ð.@À!ÓDÐØ)Ÿ~™~Ð.@À"ÓEÐàØ$4ñˆHð �O‰OÐ,Ô-Ø�O‰O˜HÔ%Ø(×.Ñ.Ó0ò '‘��1Ø×#Ñ# AÕ&ñ'ð	'ð ´°oÓ1FÑGÐGð?:ús   ‚BE
ÂEÂB/E
Úallowed_model_namesc                 ó¼   — | j                  d«      |v ry| j                  d«      }t        |t        «      sy|j                  d«      }t        |t        «      xr ||v S )zýMatch a router deployment against allowed public model names.

    Team-scoped rows store an internal routing key in ``model_name``; callers
    with key/team restrictions still refer to the public name in
    ``model_info.team_public_model_name``.
    r1  Tr¸  Fr?  )rp  rÓ  rÔ  r‚  )r{  r·  r¸  r?  s       rˆ   r‰  r‰  º7  s^   € ð ‡y�y�ÓÐ"5Ñ5ØØŸ	™	 ,Ó/€JÜ�j¤$Ô'ØØ$.§N¡NÐ3KÓ$LÐÜÐ,¬cÓ2ÒdÐ7MÐQdÐ7dÐdrŠ   c                 óþ   — |j                  «       }|j                  «       }t        | ||¬«      }t        | j                  ||¬«      }|s|syt        t        |||t        t        j                  dd«      |d¬«      «      S )zHReturn key/team allowlisted public model names, or None if unrestricted.)r*  r   r›  r×  Nr¡  F)rž  rŸ  r   r¸	  r¡  rU  r�  )
r©  r¨  rÜ   rÞ   rŸ  rð  rÛ   r¸	  rW  rp  )r*  rU  r›  r   rž  rŸ  s         rˆ   Ú&_get_v1_model_info_allowed_model_namesrº  Ê7  s“   € ð
 ",×!CÑ!CÓ!EÐØ(×8Ñ8Ó:ÐÜ&Ø+Ø)Ø/ô€Jô
 )Ø%×1Ñ1Ø)Ø/ô€Kñ
 ™kØÜÜØ!Ø#Ø-Ü!Ü"2×"6Ñ"6Ð7NÐPUÓ"VØ!Ø#(ô	
ó
ð 
rŠ   c                 óN   — |€| S | D �cg c]  }t        ||«      sŒ|‘Œ c}S c c}w rn  )r‰  )r²  r·  r{  s      rˆ   Ú!_filter_v1_model_info_deploymentsr¼  ê7  s0   € ð Ð"ØÐØ)Öq�eÔ-TÐUZÐ\oÕ-pŠEÒqÐqùÒqs   ‰"›"c                 ó,  — t        | t        «      s| S | j                  d«      xs i }t        |t        «      s| S |j                  d«      }|j                  d«      }|r|s| S | j                  d«      xs d}|j                  d|› d�«      s| S i | ¥d|i¥S )ay  For team-scoped DB rows, replace `model_name` with the public name
    in `model_info.team_public_model_name` before returning. The DB column
    and the in-memory router index keep the internal mangled name
    (`model_name_{team_id}_{uuid}`) as the routing key -- this swap is a
    presentation-layer concern. Returns a shallow copy; never mutates.

    Without this swap the internal name leaks into `/v1/model/info` and
    `/v2/model/info`, the dashboard binds its edit form to it, and a
    non-rename save round-trips the internal name back -- corrupting
    `team_public_model_name` and the team ACL (see issue #28382).
    r¸  r?  r•  r1  r6  Úmodel_name_rÁ  )rÓ  rÔ  rp  r™  )r{  r¸  Úteam_publicr•  rs  s        rˆ   r‹  r‹  ó7  s�   € ô �eœTÔ"ØˆØŸ	™	 ,Ó/Ò5°2€JÜ�j¤$Ô'ØˆØ#Ÿ™Ð(@ÓA€KØ—^‘^ IÓ.€GÙ™gØˆØ—Y‘Y˜|Ó,Ò2°€GØ×Ñ ¨G¨9°AÐ6Ô7ØˆØ/ˆeÐ/�\ ;Ñ/Ð/rŠ   c                 óR  — | 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        | d	h¬
«      } t        | «      S # t        $ r i }Y Œµw xY w# t        $ r i }Y Œ^w xY w)Nr¸  rì  rô  r{  r  r   r/
  rÂ  r  ©rR
  r  )
rp  r–
  r  r“
  rÿ  rq  rÈ  râ  rù   r‹  )r{  r¸  r•
  rô  r  r  rF  rG  s           rˆ   Ú_get_proxy_model_inforÂ  8  sW  € àŸ	™	 ,°Ó3€Jô 0°eÔ<Ðð ˜RÒàŸ™Ð#3°RÓ8ˆØ&×*Ñ*¨7°DÓ9ˆð	$Ü!(×!7Ñ!7¸mÔ!LÐð ˜RÒàŸ™Ð#3°RÓ8ˆØ&×*Ñ*¨7°DÓ9ˆØ*×0Ñ0°Ó5ˆÜˆ{Ó˜aÒØ'¨™OˆMð	$Ü!(×!7Ñ!7¸mÐalÐmnÑaoÔ!pÐð #×(Ñ(Ó*ò ‰ˆˆ1Ø�JÒØˆJ�qŠMðð %€Eˆ,Ñä1À%ÐXqÐWrÔs€Eä-¨eÓ4Ð4øô+ ò 	$Ø!#Òð	$ûô ò 	$Ø!#Òð	$ús$   Á	D Â-D ÄDÄDÄD&Ä%D&z/model/infoz/v1/model/infozYWhen true, filter to deployments the caller can use via direct access or team membership.Úlitellm_model_idc           	   ƒ   ó‚  K  — t        |t        «      sd}t        |t        «      sd}t        �g	 t	        t
        t        j                  t        ¬«      «      }t        dt        t        ¬«      |¬«      }|j                  «       }t        |dh¬«      }d|iS t        €t        d	d
di¬«      ‚t        €t        d	d
di¬«      ‚t         €;|s|�7|j#                  «       r't        d	d
t$        j&                  j(                  i¬«      ‚|�Àt        j+                  |¬«      }|€t        dd
d|› d�i¬«      ‚t-        |j                  d¬«      ¬«      }|g}	t         �lt/        | t         t        |	¬«      ƒ d{  –—† }	|rt1        |	«      }	|�>|j#                  «       r.t3        |	|j#                  «       t         t        | ¬«      ƒ d{  –—† }	d|	iS t5        j6                  t        j8                  «      }
t5        j6                  t        j;                  «       «      }|
j=                  |«       t?        |
«      }
tA        | t        ¬«      }tC        |
|¬«      }
tE        | t         ¬«      ƒ d{  –—† }|
D �cg c]#  }tG        |jI                  d«      xs i |«      s|‘Œ% }
}t         �t/        | t         t        |
¬«      ƒ d{  –—† }
|rt1        |
«      }
|
D �cg c]  }tK        tM        |t        ¬«      «      ‘Œ }
}|�L|j#                  «       r<t3        |
|j#                  «       t	        tN        t         «      t        | ¬«      ƒ d{  –—† }
tQ        |tR        t        ¬«      ƒ d{  –—† }|
D �cg c]  }|jI                  d«      |vsŒ|‘Œ }}tU        jV                  d|«       d|iS # t        $ r i }Y �ŒFw xY w7 �Œ57 �Œë7 �ŒMc c}w 7 �Œc c}w 7 Œ‡7 Œkc c}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
        - include_team_models: When true, filter to deployments the caller can use (same as /v2/model/info).
        - teamId: Filter to models accessible by the given team.
        - healthy_only: When true, hide models whose backing deployments are all marked
          unhealthy by background health checks, matching `/v1/models?healthy_only=true`.
          Set `general_settings.model_list_healthy_only: true` to apply this to every
          caller without the query parameter. Requires `background_health_checks: true`,
          plus either `model_list_healthy_only` or `enable_health_check_routing` to keep
          deployment health state cached; without health state the listing is returned
          unfiltered (fail open). Ignored when `litellm_model_id` is passed, since that
          is a direct lookup of one deployment rather than a listing. Hiding is
          presentation-only: a hidden model can still be called directly.

    Each model in the list response includes `model_info.access_via_team_ids` and
    `model_info.direct_access` when the proxy database is connected.

    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
                        }
                    }
                ]
    }

    ```
    FNrì  rÌ   rú  r  rÁ  r„  rž  rz  z–LLM 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/configsrc  z•LLM 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/configsrO
  rD  zModel id = z not found on litellm proxyTr·  r  r†  )r*  rU  )r²  r·  r;  r¸  )r{  rU  r�  r1  r‡  ),rÓ  r#  r‚  r¸	  r   rÔ  r  r“
  rÿ  ru  rv  r»  rù   r�  r¨  rU  r÷  rr  r:   rÊ  r*  rT
  rÂ  r
  r  ry  rÆ  rÇ  rm  Úget_model_list_from_model_aliasr|  rÙ   rº  r¼  r  r!  rp  r‹  r  rY  rî   rW  rŸ   r
  )r*  rÃ  r  r�  r•  r¸  Ú_deployment_infoÚ_deployment_info_dictÚdeployment_infoÚsingle_model_listr²  Úalias_modelsr·  r  r{  r±  Úvisible_modelss                    rˆ   Úmodel_info_v1rÌ  58  s  è ø€ ôP Ð)¬4Ô0Ø#ÐÜ�fœcÔ"ØˆäÐð	Ü#¤D¬'×*@Ñ*@ÄzÔ*RÓSˆJô #-ØÜ)Ü ôð "ô#
Ðð !1× ;Ñ ;Ó =ÐÜ EØ1Ø4Ð5ô!
Ðð Ð-Ð.Ð.äÐÜØàð  rðô
ð 	
ô ÐÜØàð  qðô
ð 	
ô ÐÑ"5¸&Ð:LÐQW×Q]ÑQ]ÔQ_ÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð
 Ð#ä!+×!:Ñ!:ÐDTÐ!:Ó!UˆØÐ"ÜØØ ;Ð/?Ð.@Ð@[Ð!\Ð]ôð ô !6¸O×<VÑ<VÐdhÐ<VÓ<iÔ jÐØ)>Ð(?ÐÜÐ$Ü&EØ"3Ü+Ü%Ø,ô	'÷ !Ðñ #Ü$EÐFWÓ$XÐ!ØÐ! f§l¡l¤nÜ*CØ0Ø"ŸL™L›NÜ"/Ü)Ø&7ô+÷ %Ð!ð Ð)Ð*Ð*ô "Ÿ]™]¬:×+@Ñ+@ÓA€JÜŸ-™-¬
×(RÑ(RÓ(TÓU€LØ×Ñ�lÔ#ä;¸JÓG€Jä!GØ+Üô"Ðô
 3ØØ/ô€Jô %@Ø+Ü#ô%÷ Ðð  öàÜ-¨e¯i©i¸Ó.EÒ.KÈÐM]Ô^ò 	ð€Jð ô Ð Ü:Ø/Ü'Ü!Ø!ô	
÷ 
ˆ
ñ Ü6°zÓBˆ
ð  öàô 	+Ô+OÐV[ÔhrÔ+sÕtð€Jð ð
 Ð˜fŸl™lœnÜ4Ø!Ø—L‘L“NÜœ|¬]Ó;Ü!Ø/ô
÷ 
ˆ
ô !AØ!Ü)Üô!÷ €Lð
 1;Öj u¸e¿i¹iÈÓ>UÐ]iÒ>išUÐj€NÐjä×ÑÐ/°Ô@Ø�NÐ#Ð#øôK ò 	Ø‹Jð	úðb!ùð%ùð@ûòð
ûòð
øðúò
 kùsÂ   ‚+N?®(N ÁDN?Å+N Å,AN?Æ8N#Æ9B N?ÉN&ÉN?É"(N)Ê
"N?Ê,N.Ê-N?Ë!N1Ë#AN?Ì.N6Ì/N?ÍN8ÍN?ÍN:Í.N:Í2N?ÎNÎN?ÎNÎN?Î#N?Î&N?Î)N?Î1N?Î8N?Î:N?z/model/deprecations)r�  z/v1/model/deprecationsÚwarn_within_daysc              ƒ   ó,   K  — t        t        | ¬«      S ­w)aZ  List models with known deprecation/sunset dates, bucketed by urgency.

    Reads `deprecation_date` metadata from `model_prices_and_context_window.json`
    (and any per-deployment `model_info.deprecation_date` overrides) for the
    models configured on this proxy.

    Parameters:
        warn_within_days: Window (in days) used to bucket "imminent" models,
            30 by default.

    Returns:
        A payload with three lists of `ModelDeprecationInfo` entries:

        - `deprecated`: deprecation date is in the past, so these requests may
          fail at any time.
        - `imminent`: deprecation date is within `warn_within_days` from today.
        - `upcoming`: deprecation date is further out.

    Example:
    ```shell
    curl -X GET 'http://localhost:4000/model/deprecations' \
        -H 'Authorization: Bearer sk-1234'
    ```
    )rU  rÍ  )r÷   rU  )rÍ  s    rˆ   Úmodel_deprecationsrÏ  9  s   è ø€ ôN &´ÐN^Ô_Ð_ùs   ‚Úall_models_strrF  c                 ó¦  — g }g }|D ]  }||vsŒ|j                  |«       Œ |D ]o  }|�||k7  rŒ| j                  |¬«      }|�3|j                  t        j                  |j	                  «       «      «       ŒRt        |g ¬«      }|j                  |«       Œq t
        j                  �+|D ]&  }|j                  t
        j                  v sŒ d|_        Œ( |S )N)rF  )rF  Ú	providersT)	rã  Úget_model_group_infor�  rü  r»  r  Úpublic_model_groupsrF  Úis_public_model_group)	rU  rÐ  rF  Úmodel_groupsrÓ  r{  Ú_model_group_infoÚmodel_group_infoÚmgs	            rˆ   Ú_get_model_group_inforÚ  89  só   € ð 68€Là€MØò (ˆØ˜Ò%Ø× Ñ  Õ'ð(ð ò 2ˆØÐ" {°eÒ';Øà&×;Ñ;ÈÐ;ÓNÐàÐ(Ø×ÑÔ 3× BÑ BÐCT×C_ÑC_ÓCaÓ bÕcä2Ø!Øô Ðð ×ÑÐ 0Õ1ð2ô  ×"Ñ"Ð.Øò 	0ˆBØ�~‰~¤×!<Ñ!<Ò<Ø+/�Õ(ð	0ð ÐrŠ   z/model_group/infoc              ƒ   ó  K  — t         �t        �t         sdg iS ddlm}  || t        t        t
        t        t        ddddt        ¬«      ƒ d{  –—† }t        t        ||¬«      }ddl
m}  ||| ¬	«      ƒ d{  –—† }d|iS 7 Œ27 Œ
­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   )r™  Fr£  )rU  rÐ  rF  )Úappend_agents_to_model_group)rÖ  r*  )r�  rU  rþ  r™  rW  r¸	  r÷  rý  rA  rÚ  rŠ  rÜ  )r*  rF  r™  rÐ  rÖ  rÜ  s         rˆ   rØ  rØ  Z9  sž   è ø€ ôD Ð¤Ð!3½>Ø˜ˆ|ÐåAñ #@Ø+ÜÜ)ÜÜ#Ü+ØØ$)Ø!&Ø$Ü-ô#÷ €Nô /DÜ¨nÈ+ô/€Lõ
ñ 6Ø!Ø+ô÷ €Lð
 �LÐ!Ð!ð7øð,ús$   ‚ABÁB Á)BÁ7BÁ8	BÂBz/model/settingszMReturns provider name, description, and required parameters for each provider)rô  r  rŽ  r  c            	   ƒ   óœ   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£  )rÄ  Úfields)r  Úprovider_listrã  ÚProviderInfoÚget_provider_fields)Úreturned_listr  s     rˆ   Úmodel_settingsrã   :  sQ   è ø€ ð$ €MÜ×)Ñ)ò 
ˆØ×ÑÜØÜ×2Ñ2ÀxÔ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¬«      ‚t        | «      s6t        ddt        j                  j                  › d| j                  › �i¬«      ‚t        t         «      j                  ddi¬«      ƒ d {  –—† }|�x|j                  �lt        |j                  «      }t        t        t        t        f   |j                  di «      «      }t        t         t           d z  |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)NrD  rz  rc  ú, your role=rT  rW  r�  rÀ  r¼  rw   Ú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_fieldr6  rí  )r÷  r¨  r:   rÊ  r*  r1  Únot_allowed_accessrj  rw  r•  rU  rÔ  r   r‚  r   rp  r•  rý  r8  rÀ  r»  rW  rÓ  r?   rã  rƒ  Úmodel_fieldsrâ  rô  r‹   )r*  rb  Údb_general_settings_dictÚalerting_args_dictÚalerting_valuesÚallowed_argsÚ_slack_alertingÚ_slack_alerting_args_dictÚ
return_valÚis_slack_enabledÚ_response_objrñ  Ú
field_infoÚ_stored_in_dbs                 rˆ   Úalerting_settingsr  A:  sÐ  è ø€ ðô ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô
  Ð 1Ô2ÜØØÔ 1× DÑ D× JÑ JÐKÈ<ÐXi×XsÑXsÐWtÐuÐvô
ð 	
ô (;¼=Ó'I×'TÑ'TØÐ/Ð0ð (Uó (÷ "Ðð Ð&Ð+>×+JÑ+JÐ+VÜ*.Ð/B×/NÑ/NÓ*OÐ Ü#'Ü””i�Ñ Ð":×">Ñ">¸ÐPRÓ"Só$
Ðô (,Ü”‰O˜dÑ"Ð$<×$@Ñ$@ÀÓ$Ló(
‰ð  ÐØˆð " 9Ð-Ø#)¨9Ð"5Ø"(¨)Ð!4Ø# YÐ/Ø# YÐ/Ø$*¨IÐ#6Ø)/°Ð(;Ø)/°Ð(;Ø'-¨yÐ&9ñ
€Lô ->×,UÑ,U€OØ'6×'DÑ'D×'OÑ'OÓ'QÐà€JàÐä×Ñ˜JÔ'¬JÔ7GÈ
Ñ7SÔUYÔ,ZØÔ& zÑ2Ñ2Ø#ÐäØ#ØÐ 0Ñ1°&Ñ9ð EØ$Ø,Ð8‘T¸eØ Øô€Mð ×Ñ�mÔ$ä"3×"@Ñ"@×"FÑ"FÓ"Hò -Ñˆ
�JØ˜Ò%Ø)-ˆMØÐ/Ñ/Ø $‘à %�ä&Ø%Ø'¨
Ñ3°FÑ;Ø",×"8Ñ"8Ò">¸BØ5×9Ñ9¸*ÀdÓKØ*Ø$.×$6Ñ$6Ø'1Ð5NÒ'N™tÐTYôˆMð ×Ñ˜mÕ,ð#-ð$ ÐðI"ûs   ‚BIÂIÂEIÇ4A(Iz/queue/chat/completionsrÁ	  )r  rŽ  r  c              ƒ   ó|  K  — 	 i }	 | j                  «       ƒ d {  –—† }|j                  d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<   t        |j                  d«      t        «      si |d<   |j                  |d   d	<   t!        |j"                  «      |d   d
<   t        | «      j                  «       }|j                  dd «       ||d   d<   t%        |dd «      |d   d<   |j                  |d   d<   t%        |dd «      |d   d<   t%        |dd «      |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.        €'t1        ddt2        j4                  j6                  i¬«      ‚t/        j8                  d.i |¤Žƒ d {  –—† }d|v r!|d   du rt;        t=        |||| ¬ «      d!¬"«      S |j>                  jA                  d#t        |d$   «      i«       |S 7 �Œ·7 ŒW# tB        $ rÚ}tD        jG                  |||¬%«      ƒ d {  –—†7   t        |t0        «      rPtI        t%        |d&d'|› d(�«      tJ        jL                  t%        |d)d*«      t%        |d+tN        jP                  «      ¬,«      ‚t        |tH        «      r|‚tI        d-t        |«      z   tJ        jL                  t%        |d)d*«      tN        jP                  ¬,«      ‚d }~ww xY w­w)/Nrp
  )r   rx   r9  r	  Úproxy_server_requestzreceiving data: %sÚcompletion_modelr{  rµ
  rÎ  Úuser_api_keyÚuser_api_key_metadataÚauthorizationr9  r  Úuser_api_key_aliasrÏ  r•  rÐ  Úobject_permission_idÚ!user_api_key_object_permission_idÚteam_object_permission_idÚ&user_api_key_team_object_permission_idr„  r³	  r*  r²	  rz  rž  rz  rc  rÜ  T)r*  r  rÏ	  r3  rä  ©ræ  zx-litellm-priorityÚpriorityrÒ	  r—  úAuthentication Error(rà  r  rÔ	  r7  rÕ	  úAuthentication Error, rè  ))rm  r‡  r‚  r   rx   rò   rÆ  rŸ   r
  rW  rp  r¸	  rb  rÓ  rÔ  r  r_   rÎ  rw  r¿	  rÀ	  rÙ  r¾	  rU  r¨  r:   rg  r*  Úschedule_acompletionr»  rŒ
  r9  rå  rÿ  rý  rØ	  rS   rR   Ú
auth_errorr±  rë  )r3  rË  r{  r*  r„  Ú_headersr  r  s           rˆ   Úasync_queue_requestr  ª:  sË  è ø€ ðð €DðZ
Ø—\‘\“^×#ˆØ�‰Ð.°Ô5ô �w—{‘{Ó#Ø—n‘nÜ0°Ó9×>Ñ>Ó@Ü—I‘I˜d“Oñ	(
ˆÐ#Ñ$ô 	×"Ñ"Ð#7¸Ô>ä× Ñ Ð!3°TÓ:ò 'Üò'àò'ð �x‰x˜ Ó&ð	 	ˆW‰ð �8‰8�F˜DÓ!Ð)Ð.?×.GÑ.GÐ.Sà,×4Ñ4ˆD�‰Lä˜$Ÿ(™( :Ó.´Ô5ð  "ˆD�ÑØ+<×+DÑ+DˆˆZÑ˜Ñ(Ü4IÐJ[×JdÑJdÓ4eˆˆZÑÐ0Ñ1Ü3°GÓ<×AÑAÓCˆØ�‰�_ dÔ+Ø&.ˆˆZÑ˜Ñ#Ü18Ð9JÈKÐY]Ó1^ˆˆZÑÐ-Ñ.Ø3D×3LÑ3LˆˆZÑÐ/Ñ0Ü3:Ð;LÈiÐY]Ó3^ˆˆZÑÐ/Ñ0Ü@GÐHYÐ[qÐswÓ@xˆˆZÑÐ<Ñ=ÜELØÐ:¸DóF
ˆˆZÑÐAÑBô (+¨7¯;©;Ó'7ˆˆZÑ˜Ñ$õ Ü"2ˆD�ÑÝÜ&:ˆDÐ"Ñ#ÝÜ!0ˆD�ÑÝÜ,ˆD�ÑäÐÜ¨C¸ÔBS×BaÑBa×BgÑBgÐ8hÔiÐiä *× ?Ñ ?Ñ GÀ$Ñ G×Gˆà�tÑ  X¡°$Ñ 6Ü$Ü$Ø&7Ø%Ø!%Ø#ô	ð /ôð ð 	× Ñ ×'Ñ'Ð)=¼sÀ4È
ÑCSÓ?TÐ(UÔVØˆðM $ùðp Hùô ò 
Ü×6Ñ6Ø/ÀAÐTXð 7ó 
÷ 	
ñ 	
ô �aœÔ'Ü Ü  8Ð/DÀQÀCÀqÐ-IÓJÜ$×/Ñ/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ô ˜œ>Ô*ØˆGÜØ,¬s°1«vÑ5Ü ×+Ñ+Ü˜!˜W fÓ-Ü×,Ñ,ô	
ð 	
ûð
üsd   ‚N<‡K šK›I!K É<KÉ=(K Ê%N<Ê&*K ËN<ËK ËK Ë	N9ËN4Ë:K=Ë;B9N4Î4N9Î9N<)r  r  c              ƒ   óB  K  — ddl m} t        t        | j                  «      «      }|j                  d«      r|dz  }n|dz  }ddlm} t        j                  dd«      j                  «       d	k(  xs t        j                  d
d«      du } |t        d|¬«      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   )rÝ  r  zsso/callbackz/sso/callbackr  Ú%LITELLM_HIDE_DEFAULT_CREDENTIALS_HINTr3  r§  Úhide_default_credentials_hintFT)Úshow_deprecation_bannerr  rÊ  ©r8  r7  )Úlitellm.proxy.proxy_serverrÝ  re  r‚  r   ré  r  r  rn  r¨  rÉ  rW  rp  rð   )r3  rÝ  Úredirect_urlr  r  s        rˆ   Úfallback_loginr   ;  s©   è ø€ õ 3ô "¤# g×&6Ñ&6Ó"7Ó8€LØ×Ñ˜SÔ!Ø˜Ñ&‰à˜Ñ'ˆå.ô 	�	‰	Ð9¸7ÓC×IÑIÓKÈvÑUò 	PÜ×ÑÐ ?ÀÓGÈ4ÐOð "ñ Ü#Ø$)Ø*Gô
ð ôð ùs   ‚BBz/loginc              ƒ   ó  K  — ddl m}m}m} ddlm} | j                  «       ƒ d {  –—† }t        |j                  d«      «      }t        |j                  d«      «      } |||t        t        ¬«      ƒ d {  –—† } ||t        t        ¬«      }	 ||	t        t        t        «      «      }
 |t        | j                  «      «      }|j                  d«      }|d	z  }dd
lm} | j$                  j                  d«      }|r!	  |||
t&        t(        ¬«      ƒ d {  –—† }|�|S t1        |d¬«      }|j3                  d|
¬«       |r|j5                  d¬«       |S 7 �Œ.7 Œà7 ŒC# t*        $ r t-        j.                  d«       d }Y Œcw xY w­w)Nr   ©Úauthenticate_userÚcreate_ui_token_objectÚencode_ui_session_jwt©re  Úusernamer
  ©r'  r
  ré  r÷  ©Úlogin_resultrW  rÄ  r  ú/ui?login=success)Ú_sso_return_to_redirectÚlitellm_cp_return_to)Ú	return_toÚ	jwt_tokenrX  rA  z@Ignoring stale litellm_cp_return_to cookie; landing on dashboardi/  )r   r7  r”  r{  ry  )Úlitellm.proxy.auth.login_utilsr#  r$  r%  rþ  re  Úformr‚  rp  ré  r÷  rW  rÄ  r   r   r  Ú)litellm.proxy.management_endpoints.ui_ssor,  ÚcookiesrX  rA  rÿ  rŸ   r  rº  Ú
set_cookieÚdelete_cookie)r3  r#  r$  r%  re  r1  r'  r
  r*  Úreturned_ui_token_objectr/  Úlitellm_dashboard_uir,  Úcp_return_toÚresumedÚredirect_responses                   rˆ   Úloginr;  ;;  sŠ  è ø€ ÷ pÑoÝ2àŸ™›×&€DÜ˜$Ÿ(™( :Ó.Ó/€HÜ˜$Ÿ(™( :Ó.Ó/€Hñ !2ØØÜÜ#ô	!÷ €Lñ '=Ø!Ü)Ü!ô'Ðñ -Ð-EÄtÌCÔQ[ÓG\Ó]€Iñ *¬#¨g×.>Ñ.>Ó*?Ó@ÐØ/×6Ñ6°sÓ;ÐØÐ/Ñ/Ðõ Rð "Ÿ/™/×-Ñ-Ð.DÓE€LÙð	Ù3Ø&Ø#Ü"3Ü#5ô	÷ ˆGð ÐØˆNô  0Ð4HÐVYÔZÐØ× Ñ  W°IÐ Ô>ÙØ×'Ñ'Ð,BÐ'ÔCØÐðC 'ùð
øðLùô ò 	ô !×%Ñ%Ð&hÔiØŠGð	üsY   ‚$F¦E§AFÁ6EÁ7BFÃ>E ÄEÄE Ä;FÅFÅE Å E>Å;FÅ=E>Å>Fz	/v2/loginc              ƒ   óÀ  K  — ddl m}m}m} ddlm} 	 | j                  «       ƒ d {  –—† }t        |j                  d«      «      }t        |j                  d«      «      } |||t        t        ¬«      ƒ d {  –—† } ||t        t        ¬«      }	 ||	t        t        t        «      «      }
 |t        | j                  «      «      }|j                  d«      }|d	z  }t!        ||
d
œt"        j$                  ¬«      }|j'                  d|
¬«       |S 7 Œæ7 Œ˜# t(        $ rÀ}t+        j,                  d|«       t/        |t0        «      r|‚t/        |t2        «      rUt1        t5        |dt        |«      «      t6        j8                  t5        |dd«      t5        |dt"        j:                  «      ¬«      ‚|› }t1        |t6        j8                  dt"        j:                  ¬«      ‚d }~ww xY w­w)Nr   r"  r&  r'  r
  r(  r)  r  r+  )r  r”  r  r”  r{  z>litellm.proxy.proxy_server.login_v2(): Exception occurred - %sr—  r  rÔ	  r7  rÕ	  )r0  r#  r$  r%  rþ  re  rm  r‚  rp  ré  r÷  rW  rÄ  r   r   r  r¸  r±  ÚHTTP_200_OKr4  rÿ  rŸ   r   rÓ  rS   r¨  rw  rR   r  r<  )r3  r#  r$  r%  re  r	  r'  r
  r*  r6  r/  r7  Újson_responser  rÚ	  s                  rˆ   Úlogin_v2r?  …;  s¹  è ø€ ÷ pÑoÝ2ð3Ø#ŸL™L›N×*ˆÜ˜dŸh™h zÓ2Ó3ˆÜ˜dŸh™h zÓ2Ó3ˆá$5ØØÜ!Ü'ô	%
÷ 
ˆñ +AØ%Ü-Ü%ô+
Ð ñ 1Ð1IÌ4ÔPSÔU_ÓK`Óaˆ	á-¬c°'×2BÑ2BÓ.CÓDÐØ3×:Ñ:¸3Ó?ÐØÐ 3Ñ3Ðô
  ,Ø%9ÀIÑNÜ×*Ñ*ô 
ˆð 	× Ñ  W°IÐ Ô>ØÐð? +øð
ùô8 ò Ü×&Ñ&Ð'gÐijÔkÜ�aœÔ(ØˆGÜ˜œ=Ô)Ü Ü  8¬S°«VÓ4Ü$×/Ñ/Ü˜a ¨&Ó1Ü˜Q ¬v×/TÑ/TÓUô	ð ð #$ ˆIÜ Ø!Ü$×/Ñ/ØÜ×:Ñ:ô	ð ûðüsM   ‚G”D §D¨AD Á7DÁ8BD ÄGÄD ÄD Ä	GÄB;GÇGÇGz	/v3/loginc              ƒ   óì  K  — ddl m}m}m} ddlm} 	 t        j                  d«      s+t        dt        j                  dt        j                  ¬«      ‚| j                  «       ƒ d {  –—† }t        |j                  d«      «      }t        |j                  d«      «      } |||t        t         ¬	«      ƒ d {  –—† } ||t        t"        ¬
«      }	 ||	t%        t        t        «      «      }
 |t        | j&                  «      «      }|j)                  d«      }|dz  }t+        j,                  d«      }d|› �}|
|dœ}t.        �!t.        j1                  ||d¬«      ƒ d {  –—†  n t2        j1                  ||d¬«      ƒ d {  –—†  t5        |ddœt        j6                  ¬«      S 7 �Œ87 Œê7 ŒH7 Œ)# t8        $ rÀ}t;        j<                  d|«       t?        |t        «      r|‚t?        |t@        «      rUt        tC        |dt        |«      «      t        jD                  tC        |dd«      tC        |dt        jF                  «      ¬«      ‚|› }t        |t        jD                  dt        jF                  ¬«      ‚d }~ww xY w­w)Nr   r"  r&  r4  zH/v3/login is only available on workers with control_plane_url configuredrÕ	  r'  r
  r(  r)  r  r+  é    úlogin_code:©r”  r  r‘   rŠ  )r;  Ú
expires_inr  z>litellm.proxy.proxy_server.login_v3(): Exception occurred - %sr—  r  rÔ	  r7  )$r0  r#  r$  r%  rþ  re  rW  rp  rS   rR   Únot_found_errorr±  ÚHTTP_404_NOT_FOUNDrm  r‚  ré  r÷  rÄ  r   r   r  ÚsecretsÚtoken_urlsaferX  Úasync_set_cacherA  r¸  r=  rÿ  rŸ   r   rÓ  r¨  rw  r  r<  )r3  r#  r$  r%  re  r	  r'  r
  r*  r6  r/  r7  r;  r	  Úcache_valuer  rÚ	  s                    rˆ   Úlogin_v3rK  Á;  sH  è ø€ ÷
 pÑoÝ2ð?Ü×#Ñ#Ð$7Ô8Ü ØbÜ$×4Ñ4Ø)Ü×.Ñ.ô	ð ð $ŸL™L›N×*ˆÜ˜dŸh™h zÓ2Ó3ˆÜ˜dŸh™h zÓ2Ó3ˆá$5ØØÜ!Ü'ô	%
÷ 
ˆñ +AØ%Ü-Ü%ô+
Ð ñ 1Ð1IÌ4ÔPSÔU_ÓK`Óaˆ	á-¬c°'×2BÑ2BÓ.CÓDÐØ3×:Ñ:¸3Ó?ÐØÐ 3Ñ3Ðô ×+Ñ+¨BÓ/ˆØ(¨¨Ð/ˆ	Ø'0ÐBVÑWˆÜÐ(Ü#×3Ñ3¸	ÈÐZ\Ð3Ó]×]Ñ]ä$×4Ñ4¸È+Ð[]Ð4Ó^×^Ð^äØ!°Ñ4Ü×*Ñ*ô
ð 	
ðA +ùð
øð0 ^øà^ùô ò Ü×&Ñ&Ð'gÐijÔkÜ�aœÔ(ØˆGÜ˜œ=Ô)Ü Ü  8¬S°«VÓ4Ü$×/Ñ/Ü˜a ¨&Ó1Ü˜Q ¬v×/TÑ/TÓUô	ð ð #$ ˆIÜ Ø!Ü$×/Ñ/ØÜ×:Ñ:ô	ð ûðüst   ‚I4”AF( Á'FÁ(AF( Â7F"Â8B#F( ÅF$Å F( Å<F&Å=!F( ÆI4ÆF( Æ"F( Æ$F( Æ&F( Æ(	I1Æ1B;I,É,I1É1I4z/v3/login/exchangec              ƒ   ó  K  — 	 t         j                  d«      s+t        dt        j                  dt
        j                  ¬«      ‚| j                  «       ƒ d {  –—† }|j                  d«      }|s+t        dt        j                  dt
        j                  ¬«      ‚d|› �}t        �t        j                  |¬«      ƒ d {  –—† }nt        j                  |¬«      ƒ d {  –—† }|rt        |t        «      s+t        dt        j                  dt
        j                  ¬«      ‚t        �t        j!                  |¬«      ƒ d {  –—†  nt        j!                  |¬«      ƒ d {  –—†  t#        |d	   |d
   dœt
        j$                  ¬«      }|j'                  d	|d	   ¬«       |S 7 �ŒG7 Œâ7 ŒÅ7 Œf7 ŒI# t        $ r ‚ t(        $ rO}t+        j,                  d|«       t        t/        |«      t        j                  dt
        j0                  ¬«      ‚d }~ww xY w­w)Nr4  zQ/v3/login/exchange is only available on workers with control_plane_url configuredrÕ	  r;  zMissing 'code' parameterrB  ry  zInvalid or expired login coder”  r  rC  r  r{  zGlitellm.proxy.proxy_server.login_v3_exchange(): Exception occurred - %srÔ	  )rW  rp  rS   rR   rE  r±  rF  rm  r  rë  rX  r�  rA  rÓ  rÔ  ÚHTTP_401_UNAUTHORIZEDr  r¸  r=  r4  rÿ  rŸ   r   r‚  r<  )r3  r	  r;  r	  Úcached_datar>  r  s          rˆ   Úlogin_v3_exchangerO  <  sé  è ø€ ð9
Ü×#Ñ#Ð$7Ô8Ü ØkÜ$×4Ñ4Ø)Ü×.Ñ.ô	ð ð $ŸL™L›N×*ˆØ—h‘h˜vÓ&ˆÙÜ Ø2Ü$×/Ñ/ØÜ×0Ñ0ô	ð ð )¨¨Ð/ˆ	ÜÐ(Ü 1× AÑ AÀiÐ AÓ P×P‰Kä 2× BÑ BÀyÐ BÓ Q×QˆKá¤*¨[¼$Ô"?Ü Ø7Ü$×/Ñ/ØÜ×1Ñ1ô	ð ô Ð(Ü#×6Ñ6¸9Ð6ÓE×EÑEä$×7Ñ7¸IÐ7ÓF×FÐFä+à$ WÑ-Ø +¨NÑ ;ñô ×*Ñ*ô 
ˆð 	× Ñ  W°KÀÑ4HÐ ÔIØÐðM +ùð QøàQøð FøàFùô ò ØÜò 
Ü×&Ñ&Ð'pÐrsÔtÜÜ˜“FÜ ×+Ñ+ØÜ×6Ñ6ô	
ð 	
ûð
üs†   ‚H„AF) ÁFÁA&F) Â>F!Â?F) ÃF#ÃA F) Ä>F%Ä?F) ÅF'Å?F) ÆHÆF) Æ!F) Æ#F) Æ%F) Æ'F) Æ)H
Æ;A
HÈH
È
Hz/onboarding/get_tokenÚinvite_linkc              ƒ   óP  K  — ddl m} t        €+t        dt        j
                  dt        j                  ¬«      ‚t        €'t        ddt        j                  j                  i¬	«      ‚t        t        «      j                  j                  d
| i¬«      ƒ d{  –—† }|€t        dddi¬	«      ‚t         j"                  j%                  «       j'                  «       }|j(                  j'                  «       }||k  rt        dddi¬	«      ‚|j*                  du s|j,                  �t        dddi¬	«      ‚t/        t        «      j                  j                  d|j0                  i¬«      ƒ d{  –—† }|€t        dddi¬	«      ‚t3        t5        |j6                  «      «      }|j9                  d«      }|dz  }ddl}|j<                  }	|j?                  d| |j0                  t         j"                  j%                  «       tA        d¬«      z   dœt        d¬«      }
tC        «       } ||j0                  |
|j<                  |jD                  dtF        tH        jK                  dd«      |tM        «       ¬«	      }|j?                  tO        tP        |«      t        d¬«      }|d|› d |	› �z  }|||	d!œS 7 �Œ7 �Œ=­w)"z¤
    - Get the invite link
    - Validate it's still 'valid'
    - Return a short-lived onboarding token
    - Get user from db
    - Pass in user_email if set
    r   ©ÚReturnedUITokenObjectNúùMaster 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Õ	  rž  rz  rc  r.  r�  é‘  ú%Invitation link does not exist in db.úInvitation link has expired.Tú&Invitation link has already been used.rb  úUser does not exist in db.r  z/ui/onboardingÚlitellm_onboardingró
  )Úminutes)Ú
token_typeÚinvitation_linkrb  ÚexpÚHS256©Ú	algorithmÚusername_passwordÚlitellm_key_header_nameÚAuthorization©	rb  rz  ri  rj  Úlogin_methodrÄ  Úauth_header_nameÚ(disabled_non_admin_personal_key_creationrÃ  z?token=z&user_email=)Ú	login_urlr”  ri  ))Úlitellm.types.proxy.ui_ssorS  ré  rS   rR   r  r±  r<  r÷  r¨  r:   rÊ  r*  rŽ  rH  rÙ  r  rè  Úget_utc_datetimer˜  rc  rd  re  r¼
  rb  re  r‚  r   r  rÿ  ri  Úencoder   r?  rj  rÄ  rW  rp  rg  r   rÔ  )rP  r3  rS  Ú
invite_objÚutc_now_dateÚexpires_at_dateÚuser_objr7  rÿ  ri  Úonboarding_tokenrh  r6  r/  s                 rˆ   Ú
onboardingrr  I<  sÅ  è ø€ õ AäÐÜð PÜ ×+Ñ+ØÜ×6Ñ6ô	
ð 	
ô ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô
 :RÔR_Ó9`×9fÑ9f×9rÑ9rØ�[Ð!ð :só :÷ 4€Jð ÐÜ¨°WÐ>eÐ4fÔgÐgô "Ÿ-™-×8Ñ8Ó:×?Ñ?ÓA€LØ'×2Ñ2×7Ñ7Ó9€OØ˜Ò%Ü¨°WÐ>\Ð4]Ô^Ð^ð ×Ñ Ñ%¨×)?Ñ)?Ð)KÜØØÐEÐFô
ð 	
ô 3AÄÓ2O×2UÑ2U×2aÑ2aØ˜*×,Ñ,Ð-ð 3bó 3÷ -€Hð ÐÜ¨°WÐ>ZÐ4[Ô\Ð\ä)¬#¨g×.>Ñ.>Ó*?Ó@ÐØ/×6Ñ6°sÓ;ÐØÐ,Ñ,ÐÛà ×+Ñ+€JØ!Ÿj™jà.Ø*Ø×'Ñ'Ü—=‘=×1Ñ1Ó3´iÈÔ6KÑKñ		
ô 	Øð )ó 	Ðô 7cÓ6dÐ,á&;Ø× Ñ ØØ×&Ñ&Ø×$Ñ$Ø(Ü!Ü)×-Ñ-Ð.GÈÓYØ1YÜ-Ó/ô
'Ðð —z‘zÜŒTÐ+Ó,ÜØð "ó €Ið ˜g i [°¸Z¸LÐIÑIÐà)ØØ ñð ð4ùð(-ûs&   ‚BJ&ÂJ ÂCJ&Å&J#Å'D:J&Ê#J&c                 óÈ  — t         €+t        dt        j                  dt        j
                  ¬«      ‚t        j                  dd«      }| j                  j                  |«      }|€t        dddi¬	«      ‚|}|j                  «       j                  d
«      r|j                  dd«      d   }dd l}	 |j                  |t         dg¬«      S # t        $ r t        dddi¬	«      ‚w xY w)NrT  ré  rÕ	  rc  rd  rU  rz  z/Missing onboarding session for invitation link.rc  zbearer r“   r8  r   r_  )Ú
algorithmsú/Invalid onboarding session for invitation link.)ré  rS   rR   r  r±  r<  rW  rp  r9  r¨  rÉ  r™  rq  rÿ  r
  rÿ  )r3  rg  Úonboarding_auth_headerrq  rÿ  s        rˆ   Ú#_get_onboarding_claims_from_requestrw  ©<  s  € ô ÐÜð PÜ ×+Ñ+ØÜ×6Ñ6ô	
ð 	
ô /×2Ñ2Ð3LÈoÓ^ÐØ$+§O¡O×$7Ñ$7Ð8HÓ$IÐØÐ%ÜØØÐNÐOô
ð 	
ð .ÐØ×ÑÓ×*Ñ*¨9Ô5Ø+×1Ñ1°#°qÓ9¸!Ñ<Ðãð

Ø�z‰zØÜØ�yð ó 
ð 	
øô
 ò 
ÜØØÐNÐOô
ð 	
ð
ús   Â/C ÃC!r]  c              ƒ   ó  K  — t         €y 	 t        t         «      j                  j                  | ddœd dt        j
                  j                  «       |dœ¬«      ƒ d {  –—†  y 7 Œ# t        $ r t        j                  d«       Y y w xY w­w)NT©r.  rd  F)re  rd  rå  ræ  r”  zHFailed to roll back onboarding invitation after session key mint failed.)
r÷  rŽ  rH  r½
  r  rè  rk  rÿ  rŸ   r   ©r]  rb  s     rˆ   Ú!_rollback_onboarding_invite_claimr{  Î<  s‡   è ø€ ô ÐØðsÜ&¤}Ó5×;Ñ;×GÑGØ(¸Ñ>à#Ø$Ü%Ÿm™m×<Ñ<Ó>Ø%ñ	ð Hó 
÷ 	
ò 	
ùô ò sÜ×&Ñ&Ð'qÖrðsüs;   ‚B‹AA$ ÁA"ÁA$ Á!BÁ"A$ Á$BÂBÂBÂBrp  c              ƒ   óÌ  K  — t        dddi| j                  t        t        j                  g i i d| j
                  t        dœ	¤Žƒ d {  –—† }|d   }dd l}ddlm	} t        «       } || j
                  || j                  | j                  dt        t        j                  dd	«      |t        «       ¬
«	      }t         €J ‚|j#                  t%        t&        |«      t         d¬«      S 7 Œš­w)Nr·
  rz  r   )	rj  rµ  Úkey_max_budgetrs   r¸
  r^  rù  rb  r•  r”  rR  rb  rc  rd  re  r_  r`  rè  )r7  rj  r3   r  r%  rb  r7   rÿ  rj  rS  r?  ri  rÄ  rW  rp  rg  ré  rl  r   rÔ  )rp  r  rz  rÿ  rS  rh  r6  s          rˆ   Ú%_generate_onboarding_ui_session_tokenr~  å<  s÷   è ø€ ô 3ñ Øðð "×+Ñ+Ü3Ü%×;Ñ;ØØØØØ×'Ñ'Ü!ñ

ñ÷ €Hð ˜'Ñ"€Cãå@ä6bÓ6dÐ,Ù&;Ø× Ñ ØØ×&Ñ&Ø×$Ñ$Ø(Ü!Ü)×-Ñ-Ð.GÈÓYØ1YÜ-Ó/ô
'Ðô Ð!Ð!Ð!Ø�:‰:ÜŒTÐ+Ó,ÜØð ó ð ðCús   ‚AC$ÁC"ÁBC$z/onboarding/claim_tokenr„  c              ƒ   ó.  K  — t         €'t        ddt        j                  j                  i¬«      ‚t        t         «      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 s|j                  �t        dddi¬«      ‚|j                   | j                   k7  r)t        ddd| j                   › d|j                   › �i¬«      ‚t#        |¬«      }|j%                  d«      dk7  s<|j%                  d«      | j                  k7  s|j%                  d«      | j                   k7  rt        dddi¬«      ‚t'        | j(                  «      }t        j                  j                  «       }t         j*                  j-                  «       4 ƒd{  –—† }|j.                  j1                  | j                  ddœd
||j                   dœ¬«      ƒ d{  –—† }	|	dk(  rt        dddi¬«      ‚|j2                  j5                  d|j                   id|i¬«      ƒ d{  –—† }
|
€t        dddi¬«      ‚t        j                  j                  «       }|j.                  j5                  d| j                  i|||j                   dœ¬«      ƒ d{  –—†  ddd«      ƒd{  –—†  
r(t7        |
d«      r|
j8                  j;                  dd«       	 t=        |
¬«      ƒ d{  –—† }tE        tG        |jH                  «      «      }|jK                  d «      }|d!z  }|||
jL                  |
d"œS 7 �Œ)7 �Œ‘7 �ŒT7 �Œ7 Œ¤7 Œ–# 1 ƒd{  –—†7  sw Y   Œ¦xY w7 Œn# t>        $ rQ}tA        | j                  | j                   ¬«      ƒ d{  –—†7   tC        |t        «      r|‚t        dddi¬«      |‚d}~ww xY w­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ž  rz  rc  r.  r�  rU  rV  rW  TrX  zhInvalid invitation link. The user id submitted does not match the user id this link is attached to. Got=z, Expected=rÍ  r\  rZ  r]  rb  ru  Fry  )rd  rå  ræ  r”  r   r
  rY  )re  rå  ræ  Ú__dict__)rp  rz  zFFailed to create onboarding session. Please retry the invitation link.r  r+  )ri  r”  ri  rµ
  )'r÷  r¨  r:   rÊ  r*  rŽ  rH  rÙ  r]  r  rè  rk  r˜  rc  rd  re  rb  rw  rp  ri  r
  ri  ÚtxÚlitellm_invitationlinkr½
  Úlitellm_usertablerå  r¬  r€  r‡  r~  rÿ  r{  rÓ  re  r‚  r   r  ri  )r„  r3  rm  rn  ro  Úonboarding_claimsÚ	hashed_pwr 	  r�  Úupdated_countrp  r/  r  r7  s                 rˆ   Úclaim_onboarding_linkr‡  =  sk  è ø€ ô ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô
 :RÔR_Ó9`×9fÑ9f×9rÑ9rØ�T×)Ñ)Ð*ð :só :÷ 4€Jð ÐÜ¨°WÐ>eÐ4fÔgÐgô "Ÿ-™-×8Ñ8Ó:×?Ñ?ÓA€LØ'×2Ñ2×7Ñ7Ó9€OØ˜Ò%Ü¨°WÐ>\Ð4]Ô^Ð^ð ×Ñ Ñ%¨×)?Ñ)?Ð)KÜØØÐEÐFô
ð 	
ð ×Ñ˜TŸ\™\Ò)ÜØàð  Dð  EI÷  EQñ  EQð  DRð  R]ð  ^h÷  ^pñ  ^pð  ]qð  rðô
ð 	
ô  CÈ7ÔSÐà×Ñ˜lÓ+Ð/CÒCØ× Ñ Ð!2Ó3°t×7KÑ7KÒKØ× Ñ  Ó+¨t¯|©|Ò;äØØÐNÐOô
ð 	
ô
 % T§]¡]Ó3€IÜ—=‘=×1Ñ1Ó3€LÜ×Ñ×"Ñ"Ó$÷  
ð  
¨Ø%'×%>Ñ%>×%JÑ%JØ×-Ñ-¸eÑDà#Ø*Ø(×0Ñ0ñð &Kó &
÷  
ˆð ˜AÒÜØØÐ!IÐJôð ð 79×6JÑ6J×6QÑ6QØ˜j×0Ñ0Ð1¸ÀYÐ8Oð 7Ró 7
÷ 1
ˆð ÐÜ¨C¸ÐB^Ð8_Ô`Ð`ô —}‘}×5Ñ5Ó7ˆØ×'Ñ'×.Ñ.Ø˜×-Ñ-Ð.à+Ø*Ø(×0Ñ0ñð /ó 
÷ 	
ð 	
÷3 
÷  
ñD ”G˜H jÔ1Ø×Ñ×Ñ˜j¨$Ô/ðÜ!FÐPXÔ!Y×Yˆ	ô *¬#¨g×.>Ñ.>Ó*?Ó@ÐØ/×6Ñ6°sÓ;ÐØÐ/Ñ/Ðà)ØØ×)Ñ)Øñ	ð ð4ùðR 
ùð 
ùð1
ùð	
øð3 
ø÷  
÷  
ñ  
úðL ZùÜò 
Ü/Ø ×0Ñ0Ø—L‘Lô
÷ 	
ñ 	
ô �aœÔ'ØˆGÜØØÐeÐfô
ð ð	ûð
üsÖ   ‚A&PÁ(NÁ)FPÈNÈPÈ<N!ÉNÉAN!Ê
NÊA-N!Ë8NË9N!Ë=PÌNÌ	.PÌ8N8 ÍN6ÍN8 ÍAPÎPÎN!ÎN!ÎN!ÎPÎ!N3Î'N*Î(N3Î/PÎ6N8 Î8	PÏ$PÏ%O(Ï&'PÐPÐPz/get_logo_urlc                  ó`   — t        j                  dd«      } | j                  d«      rd| iS ddiS )u  Get the current logo URL from environment.

    Only HTTP(S) URLs are returned â€” those are intended to be loaded
    directly by the browser from a public/internal CDN. Local file
    paths set via ``UI_LOGO_PATH`` are NOT returned: they are admin-
    only filesystem details, the dashboard falls back to ``/get_image``
    which serves the file only when it is a supported image. Without
    this filter, the unauthenticated endpoint would disclose internal
    hostnames or filesystem paths to any caller.
    ÚUI_LOGO_PATHr6  ©zhttp://r”  Úlogo_url)rn  r¨  r™  )Ú	logo_paths    rˆ   Úget_logo_urlr�  Œ=  s9   € ô —y‘y °Ó4€IØ×ÑÐ3Ô4Ø˜IÐ&Ð&Ø˜ÐÐrŠ   Ú	candidatec                 ó®   — ddl m} | j                  d«      rt        | ¬«      S  || «      }|€t	        j
                  d| «       y|\  }}t        ||¬«      S )zVServe one admin-configured logo, or None when it is unusable so the caller falls back.r   ©Ú"resolve_validated_local_image_pathrŠ  r  NzOCustom UI logo %r is not a supported image file or does not exist, falling backr  )Ú-litellm.proxy.common_utils.static_asset_utilsr‘  r™  rº  rŸ   r/  r·  )rŽ  r‘  Ú	safe_logoÚsafe_logo_pathræ  s        rˆ   Ú_serve_custom_ui_logor•  ž=  sc   € õð ×ÑÐ3Ô4Ü IÔ.Ð.á9¸)ÓD€IØÐÜ×$Ñ$Ø]Øô	
ð à!*Ñ€N�JÜ˜°:Ô>Ð>rŠ   z
/get_imageÚtheme)ÚlightÚdarkc              ƒ   ó
  K  — t         j                  j                  t         j                  j                  t        «      «      }t         j                  j                  |d«      }t         j                  j                  |d«      }| dk(  r!t         j                  j                  |«      r|n|}t         j                  j                  |«      }t        j                  dd«      j                  «       dk(  }|rdn|}t        j                  d|«      }t         j                  j                  |«      s.	 t        j                  |d	¬
«       t        j                  d|«       ||k7  r t         j                  j                  ||«      n|}
||k7  r!t         j                  j                  |
«      s|}
t#        d„ | dk(  rt        j                  dd«      ndt        j                  dd«      fD «       «      }t        j                  d|«       t%        d„ d„ |D «       D «       d«      }|�|S ddlm}  ||
«      }|�|\  }}t+        ||¬«      S t+        |d¬«      S # t        t        f$ r$}	t        j                   d||	«       |}Y d}	~	�Œ!d}	~	ww xY w­w)zGet logo to show on admin UIzlogo.jpgzlogo_dark.pngr˜  rÓ  r6  r§  z/var/lib/litellm/assetsÚLITELLM_ASSETS_PATHTrÌ  zCreated assets directory at %szhCannot create assets directory at %s: %s. Logo caching may not work. Using current directory for assets.Nc              3   ó\   K  — | ]$  }|j                  «       r|j                  «       –— Œ& y ­wrn  )rr  ©r’  rŽ  s     rˆ   r”  zget_image.<locals>.<genexpr>Û=  s+   è ø€ ò *àð �?‰?Ôð 	�‰×ñ*ùs   ‚*,ÚUI_LOGO_PATH_DARKr‰  z-Custom logo candidates, in fallback order: %sc              3   ó$   K  — | ]  }|�|–— Œ
 y ­wrn  rè  )r’  r  s     rˆ   r”  zget_image.<locals>.<genexpr>æ=  s   è ø€ ò 	
àØÐ#ô ñ	
ùrÒ  c              3   ó2   K  — | ]  }t        |«      –— Œ y ­wrn  )r•  rœ  s     rˆ   r”  zget_image.<locals>.<genexpr>è=  s   è ø€ ÒfÀ)Ô2°9×=Ñfùr•  r   r�  r  z
image/jpeg)rn  ry   rv  rw  Ú__file__r–  r}  Úbasenamer¨  rÉ  r½  rÏ  rŸ   r
  rÃ  rÄ  r/  rŒ  rU
  r’  r‘  r·  )r–  r  Úbundled_light_logoÚbundled_dark_logoÚdefault_site_logoÚdefault_logo_filenamerÔ  Údefault_assets_dirÚ
assets_dirr  Údefault_logoÚcustom_logo_candidatesÚcustom_logo_responser‘  r“  r”  ræ  s                    rˆ   Ú	get_imager«  µ=  s7  è ø€ ô
 Ÿ™Ÿ™¬¯©¯©¼Ó)BÓC€KÜ "§¡§¡¨[¸*Ó EÐÜ!Ÿw™wŸ|™|¨K¸ÓIÐà" fš_´·±·±Ð@QÔ1RÑÐXjð ô $&§7¡7×#3Ñ#3Ð4EÓ#FÐäŸ™Ð#5°rÓ:×@Ñ@ÓBÀfÑL€Kñ >IÑ 9ÈkÐÜ—‘Ð0Ð2DÓE€Jô �7‰7�>‰>˜*Ô%ð		%Ü�K‰K˜
¨TÕ2Ü ×&Ñ&Ð'GÈÔTð GQÐT_ÒF_”2—7‘7—<‘< 
Ð,AÔBÐev€LØ�[Ò ¬¯©¯©¸Ô)EØ(ˆä$)ñ *ð 38¸6²/ŒB�I‰IÐ)¨2Ô.ÀrÜ�I‰I�n bÓ)ð
ô*ó %Ðô ×ÑÐNÐPfÔgä"&ñ	
áfÐOeÔfô	
ð
 	ó#Ðð Ð'Ø#Ð#õñ
 :¸,ÓG€IØÐØ%.Ñ"ˆ˜
Ü˜N°zÔBÐBÜÐ*°|ÔDÐDøôW  ¤Ð)ò 	%Ü ×(Ñ(ØzØØôð
 %ŽJûð	%üs1   ‚D*JÄ--I ÅC3JÉJ ÉI;É5JÉ;J Ê Jz/get_faviconc               ƒ   óŒ  K  — ddl m}  t        j                  j	                  t        j                  j                  t        «      «      }t        j                  j                  |ddd«      }t        j                  dd«      }|s9t        j                  j                  |«      rt        |d¬	«      S t        d
d¬«      ‚|j                  d«      rt        |¬«      S  | |«      }|�|\  }}t        ||¬	«      S t        j                  d|«       t        j                  j                  |«      rt        |d¬	«      S t        d
d¬«      ‚­w)z$Get custom favicon for the admin UI.r   r�  r¯  r°  zfavicon.icoÚLITELLM_FAVICON_URLr6  zimage/x-iconr  r»  zDefault favicon not foundrc  rŠ  r  zgLITELLM_FAVICON_URL %r is not a supported image file or does not exist, falling back to default faviconzFavicon not found)r’  r‘  rn  ry   rv  rw  r   r–  r¨  r½  r·  r¨  r™  rº  rŸ   r/  )r‘  r  Údefault_faviconÚfavicon_urlÚsafe_faviconÚsafe_favicon_pathræ  s          rˆ   Úget_faviconr²  ü=  s  è ø€ õô Ÿ™Ÿ™¬¯©¯©¼Ó)BÓC€KÜŸW™WŸ\™\¨+°ÈÈ}Ó]€OäŸ™Ð#8¸"Ó=€KáÜ�7‰7�>‰>˜/Ô*Ü ¸NÔKÐKÜ¨Ð4OÔPÐPà×ÑÐ5Ô6Ü KÔ0Ð0á@ÀÓMˆØÐ#Ø,8Ñ)Ð˜zÜÐ 1¸jÔIÐIÜ×$Ñ$ØuØô	
ô �7‰7�>‰>˜/Ô*Ü ¸NÔKÐKÜ¨Ð4GÔHÐHùs   ‚EEz/invitation/newzInvite Links)r  rŽ  r­  r  c              ƒ   óŠ  K  — 	 ddl m} t        €'t        ddt        j
                  j                  i¬«      ‚|j                  t        j                  k(  xs# t        |t        t        t        ¬«      ƒ d{  –—† }|s6t        ddt        j                  j                  › d|j                  › �i¬«      ‚|j                  t        j                  k7  r?t        | j                  |t        t        t        ¬	«      ƒ d{  –—† }|st        ddd
i¬«      ‚ || |¬«      ƒ d{  –—† }|S 7 Œ¬7 Œ+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_userNrD  rz  rc  rœ  rå  )Útarget_user_idr*  r÷  rA  rý  zGYou can only create invitations for users in your organization or team.)r„  r*  )Ú0litellm.proxy.management_helpers.user_invitationrµ  r÷  r¨  r:   rÊ  r*  rj  rP   r  r0  rA  rý  rø  r2  rb  rÿ  rh  )r„  r*  rµ  Ú
has_accessÚ
can_inviter  r  s          rˆ   Únew_invitationrº   >  s[  è ø€ ð&1+õ	
ô Ð ÜØØÔ!2×!IÑ!I×!OÑ!OÐPôð ð '×0Ñ0Ô4D×4PÑ4PÑPò 
ÔZtØ/Ü'Ü1Ü/ô	[
÷ U
ˆ
ñ ÜØàÔ 1× DÑ D× JÑ JÐKÈ<ÐXi×XsÑXsÐWtÐuðôð ð ×&Ñ&Ô*:×*FÑ*FÒFÜ&;Ø#Ÿ|™|Ø"3Ü+Ü#5Ü"3ô'÷ !ˆJñ Ü#Ø #Ø#Ð%nÐoôð ñ
 )CØØ/ô)
÷ #
ˆð ˆðCU
øð !øð#
ùô
 ò +Ü'¨Ó*Ð*ûð+üs`   ‚E„A0D' Á4D!Á5BD' Ã7D#Ã8"D' ÄD%ÄD' Ä EÄ!D' Ä#D' Ä%D' Ä'	E Ä0D;Ä;E Å Ez/invitation/infoÚinvitation_idc              ƒ   óv  K  — t         €'t        ddt        j                  j                  i¬«      ‚t        |«      s6t        ddt        j                  j                  › d|j                  › �i¬«      ‚t        t         «      j                  j                  d| i¬«      ƒ d{  –—† }|€t        dddi¬«      ‚|S 7 Œ­w)	r´  NrD  rz  rc  rå  r.  r�  ú-Invitation id does not exist in the database.)r÷  r¨  r:   rÊ  r*  r1  rø  rj  rŽ  rH  rÙ  )r»  r*  r  s      rˆ   Úinvitation_infor¾  g>  sÔ   è ø€ ô* ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô
  Ð 1Ô2ÜØØÔ 1× DÑ D× JÑ JÐKÈ<ÐXi×XsÑXsÐWtÐuÐvô
ð 	
ô
 %=¼]Ó$K×$QÑ$Q×$]Ñ$]Ø�]Ð#ð %^ó %÷ €Hð ÐÜØØÐLÐMô
ð 	
ð €Oðús   ‚BB9ÂB7Â B9z/invitation/updatec           	   ƒ   óÞ  K  — t         €'t        ddt        j                  j                  i¬«      ‚|j
                  €t        ddd|j
                  › �i¬«      ‚t        j                  j                  «       }t        t         «      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
        }'
    ```
    NrD  rz  rc  rž  z%Unable to identify user id. Received=r.  )r.  rd  re  rå  ræ  r”  r½  )r÷  r¨  r:   rÊ  r*  rb  r  rè  rk  rŽ  rH  rå  r»  rd  )r„  r*  r 	  r  s       rˆ   Úinvitation_updaterÀ  ”>  s  è ø€ ô2 ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð
 × Ñ Ð(ÜØØÐDÐEV×E^ÑE^ÐD_Ð`Ðaô
ð 	
ô
 "Ÿ-™-×8Ñ8Ó:€LÜ$<¼]Ó$K×$QÑ$Q×$XÑ$XØ�T×'Ñ'Ð(à×$Ñ$Ø×+Ñ+Ø'Ø&Ø+×3Ñ3ñ
ð %Yó 	%÷ 	€Hð ÐÜØØÐLÐMô
ð 	
ð €Oð!	ús   ‚CC-ÃC+ÃC-z/invitation/deletec              ƒ   óú  K  — t         €'t        ddt        j                  j                  i¬«      ‚|j
                  t        j                  k(  }t        |t         t        t        ¬«      ƒ d{  –—† }|s8|s6t        ddt        j                  j                  › d|j
                  › �i¬«      ‚|rx|svt        t         «      j                  j                  d| j                  i¬«      ƒ d{  –—† }|€t        ddd	i¬«      ‚|j                   |j"                  k7  rt        d
ddi¬«      ‚t        t         «      j                  j%                  d| j                  i¬«      ƒ d{  –—† }|€t        ddd	i¬«      ‚|S 7 �Œ	7 Œ�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'
        }'
    ```
    NrD  rz  rc  rœ  rå  r.  r�  r½  rv  z=Organization admins can only delete invitations they created.)r÷  r¨  r:   rÊ  r*  rj  rP   r  r0  rA  rý  rø  rŽ  rH  rÙ  r»  rf  rb  rÑ  )r„  r*  Úis_proxy_adminÚis_other_adminÚ
invitationr  s         rˆ   Úinvitation_deleterÅ  Í>  s¤  è ø€ ô0 ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð .×7Ñ7Ô;K×;WÑ;WÑW€NÜ"<Ø+Ü#Ü-Ü+ô	#÷ €Nñ ¡.ÜØØÔ 1× DÑ D× JÑ JÐKÈ<ÐXi×XsÑXsÐWtÐuÐvô
ð 	
ñ ™nÜ=UÔVcÓ=d×=jÑ=j×=vÑ=vØ˜×+Ñ+Ð,ð >wó >
÷ 8
ˆ
ð ÐÜØØÐ!PÐQôð ð × Ñ Ð$5×$=Ñ$=Ò=ÜØØÐ!`Ðaôð ô
 %=¼]Ó$K×$QÑ$Q×$XÑ$XØ�T×'Ñ'Ð(ð %Yó %÷ €Hð ÐÜØØÐLÐMô
ð 	
ð €OðMùð8
øðús8   ‚A)E;Á+E4Á,A:E;Ã&E7Ã'A5E;ÅE9ÅE;Å7E;Å9E;z/config/updatezconfig.yamlÚconfig_infoc              ƒ   óŽ	  K  — 	 |j                   t        j                  k7  rt        dd¬«      ‚t        €t        d«      ‚dt        dt        fd„}dt        d	t        ddfd
„}| j                  �Ï |d«      ƒ d{  –—† }t        j                  |«      }| j                  j                  d¬«      }|j                  «       D ]H  \  }}|dk(  r9d|vrdg|d<   n.t        |d   t        «      rd|d   vr|d   j                  d«       |||<   ŒJ  |d|«      ƒ d{  –—†  t        j                   t#        dd|||«      «       | j$                  �‡ |d«      ƒ d{  –—† }t        j                  |«      }	|j'                  t(        j+                  | j$                  ¬«      «        |d|«      ƒ d{  –—†  t        j                   t#        dd|	||«      «       | j,                  �� |d«      ƒ d{  –—† }t        j                  |«      }
t        | j,                  «      }|j/                  d«      }t        |t        «      rt1        |«      |d<   i |¥|¥}|j/                  d«      }|j/                  d«      }t        |t        «      rKt        |t        «      r$t        t3        t1        |«      |z   «      «      |d<   nt        t3        |«      «      |d<    |d|«      ƒ d{  –—†  t        j                   t#        dd|
||«      «       | j4                  �z |d«      ƒ d{  –—† }t        j                  |«      }| j4                  j                  d¬«      }i |¥|¥} |d|«      ƒ d{  –—†  t        j                   t#        dd|||«      «       t(        j7                  t        t8        ¬«      ƒ d{  –—†  ddiS 7 �Œ47 �Œš7 �Œ_7 �Œ7 �ŒÑ7 Œæ7 Œª7 Œd7 Œ# t
        $ rö}t;        j<                  d|«       t;        j>                  tA        jB                  «       «       t        |t        «      rPtE        tG        |dd|› d�«      tH        jJ                  tG        |dd«      tG        |d tL        jN                  «      ¬!«      ‚t        |tD        «      r|‚tE        d"t        |«      z   tH        jJ                  tG        |dd«      tL        jN                  ¬!«      ‚d}~ww xY w­w)#uY  
    For Admin UI - allows admin to update config via UI.

    Writes only the sections present in the request body to LiteLLM_Config rows
    (one row per top-level section). Sections the caller did not send are left
    untouched â€” this endpoint never persists pre-existing YAML values to DB as
    a side effect of an unrelated update.
    rv  z#Only proxy admins can update configrc  NzNo DB ConnectedrT  rÐ  c              “   óª   K  — t        t        «      j                  d| i¬«      ƒ d {  –—† }|�|j                  €i S t	        |j                  «      S 7 Œ)­w)NrT  r�  )rw  r÷  r•  rU  rÔ  )rT  r—  s     rˆ   Ú_read_sectionz$update_config.<locals>._read_section1?  sW   è ø€ Ü7JÌ=Ó7Y×7dÑ7dØ# ZÐ0ð 8eó 8÷ 2ˆCð ˆ{˜cŸo™oÐ5Ø�	Ü˜Ÿ™Ó(Ð(ð2ús   ‚%A§A¨*Ar*  c              “   óÜ   K  — t        j                  |«      }t        t        «      j                  j                  d| i| |dœd|idœ¬«      ƒ d {  –—†  t        | «      ƒ d {  –—†  y 7 Œ7 Œ­w)NrT  r‘  rU  r’  r”  )rm  r  rv  r÷  rH  r–  rk  )rT  r*  r�  s      rˆ   Ú_upsert_sectionz&update_config.<locals>._upsert_section9?  st   è ø€ Ü $§
¡
¨5Ó 1ˆJÜ"¤=Ó1×7Ñ7×>Ñ>Ø# ZÐ0à-7È
ÑSØ,¨jÐ9ñð ?ó ÷ ð ô *¨*Ó5×5Ñ5ðøð 6ús$   ‚AA,ÁA(ÁA,Á"A*Á#A,Á*A,rW  Tr·  rË  r¼  rÂ  Úupdatedr‚  rƒ  rT  r  rs  rŒ  r�   zConfig updated successfullyzBlitellm.proxy.proxy_server.update_config(): Exception occured - %sr—  r  rà  r  rÔ	  r7  rÕ	  r  )(rj  rP   r  r¨  r÷  rÿ  r‚  rÔ  rW  rÆ  rÇ  râ  rÓ  r•  rã  rP  r‡  Úcreate_config_audit_logr‚  rå  r~  rˆ  rT  rp  r]   rð  rs  rŽ  rý  rŸ   rz  r
  r2  r3  rS   rw  rR   r  r±  rë  )rÆ  r*  rÉ  rË  r˜  Úbefore_general_settingsr�  rF  rG  Úbefore_environment_variablesÚbefore_litellm_settingsÚupdated_litellm_settingsÚincoming_cbrœ  Úexisting_cbÚbefore_router_settingsÚnew_router_settingsr  s                     rˆ   Úupdate_configrÖ  ?  s»  è ø€ ð&I
Ø×&Ñ&Ô*:×*FÑ*FÒFÜ¨CÐ8]Ô^Ð^äÐ ÜÐ-Ó.Ð.ð	)¬Cð 	)´Dó 	)ð	6¬cð 	6¼$ð 	6À4ó 	6ð ×'Ñ'Ð3Ù*Ð+=Ó>×>ˆHÜ-1¯]©]¸8Ó-DÐ#Ø/:×/KÑ/K×/PÑ/PÐ^bÐ/PÓ/cˆGØŸ™›ò  ‘��1ØÐ.Ò.Ø!¨Ñ1Ø07¨y˜ Ò,Ü# H¨ZÑ$8¼$Ô?ÀGÐS[Ð\fÑSgÑDgØ  Ñ,×3Ñ3°GÔ<Ø�˜’ð ñ "Ð"4°hÓ?×?Ð?Ü×ÑÜ'Ø&¨	Ð3JÈHÐVgóôð ×,Ñ,Ð8Ù*Ð+BÓC×CˆHÜ26·-±-ÀÓ2IÐ(Ø�O‰OÜ×:Ñ:ÐQ\×QrÑQrÐ:Ósôñ "Ð"9¸8ÓD×DÐDÜ×ÑÜ'Ø+¨YÐ8TÐV^Ð`qóôð ×'Ñ'Ñ3Ù*Ð+=Ó>×>ˆHÜ-1¯]©]¸8Ó-DÐ#Ü.2°;×3OÑ3OÓ.PÐ$à2×6Ñ6Ð7IÓJˆKÜ˜+¤tÔ,Ü?WÐXcÓ?dÐ(Ð);Ñ<àD˜xÐDÐ+CÐDˆFà2×6Ñ6Ð7IÓJˆKØ!)§¡Ð.@Ó!AˆKÜ˜+¤tÔ,Ü˜k¬4Ô0ô
 26´cÔ:RÐS^Ó:_ÐbmÑ:mÓ6nÓ1o�FÐ-Ò.ä15´c¸+Ó6FÓ1G�FÐ-Ñ.á!Ð"4°fÓ=×=Ð=Ü×ÑÜ'Ø&¨	Ð3JÈFÐTeóôð ×&Ñ&Ð2Ù*Ð+<Ó=×=ˆHÜ,0¯M©M¸(Ó,CÐ"Ø!×1Ñ1×6Ñ6ÀDÐ6ÓIˆGØ)@¨HÐ)@¸Ð)@ÐÙ!Ð"3Ð5HÓI×IÐIÜ×ÑÜ'Ø% yÐ2HÐJ]Ð_póôô ×)Ñ)¼ÔYjÐ)Ók×kÐkàÐ8Ð9Ð9ðq ?ùð @ùð Dùð
 Eùð  ?ùð, >øð >øð Jøð 	lùô ò 
Ü×"Ñ"Ð#gÐijÔkÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:Ü�aœÔ'Ü Ü  8Ð/DÀQÀCÀqÐ-IÓJÜ$×/Ñ/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ô ˜œ>Ô*ØˆGÜØ,¬s°1«vÑ5Ü ×+Ñ+Ü˜!˜W fÓ-Ü×,Ñ,ô	
ð 	
ûð
üsÑ   ‚S„A4O Á8N,Á9BO ÄN/Ä=O ÅN2ÅAO Æ(N5Æ)>O Ç'N8Ç(C,O ËN;Ë=O ÌN=ÌAO ÍN?ÍAO Î#OÎ$O Î+SÎ,O Î/O Î2O Î5O Î8O Î;O Î=O Î?O ÏO Ï	SÏC1R=Ò=SÓSú***Ú_PLUGIN_KEY_REDACTEDrd  rç  re  Úmax_request_size_mbrf  Úmax_response_size_mbr;  rÌ  ÚPydanticModelræ  rg  r?  ÚStringrA  Ú%maximum_spend_logs_cleanup_batch_sizeÚ&maximum_spend_logs_cleanup_max_batchesÚ%maximum_spend_logs_cleanup_run_budgetÚ(maximum_spend_logs_cleanup_batch_timeoutÚmcp_internal_ip_rangesÚListÚmcp_trusted_proxy_ranges)Úmcp_xff_num_trusted_hopsÚalways_include_stream_usageÚ!forward_client_headers_to_llm_apiÚmcp_required_fieldsÚcancel_on_disconnectrh  ri  Ú)_GENERAL_SETTINGS_CONFIG_LIST_FIELD_TYPESÚincomingr˜  c                 óB  ‡— t        | t        «      s| S t        |t        «      r|ng D �ci c]=  }t        |t        «      r+|j                  d«      r|j                  d«      r	|d   |d   “Œ? c}Šdt        dt        fˆfd„}| D �cg c]
  } ||«      ‘Œ c}S c c}w c c}w )aõ  Restore real plugin_key values the client never sees.

    /config/field/info redacts every plugin_key to ``"***"``, so an admin
    editing a plugin posts that placeholder (or a blank, when the UI clears the
    field) straight back. Treat a blank or redacted plugin_key as "keep the
    stored credential" by sourcing it from the existing config; only a real,
    non-redacted value replaces it, and a blank with no stored key drops the
    field entirely instead of persisting the placeholder.
    rÄ  Ú
plugin_keyÚpluginrÐ  c                 ó  •— t        | t        «      s| S | j                  d«      }|d dt        fvr| S | j                  d«      }|‰v ri | ¥d‰|   i¥S | j	                  «       D ��ci c]  \  }}|dk7  sŒ||“Œ c}}S c c}}w )Nrì  r6  rÄ  )rÓ  rÔ  rp  rØ  râ  )rí  rz  rÄ  rF  rG  Ústored_keyss        €rˆ   Úresolvez/_preserve_redacted_plugin_keys.<locals>.resolveñ?  s‹   ø€ Ü˜&¤$Ô'ØˆMØ—Z‘Z Ó-ˆØ�t˜RÔ!5Ð6Ñ6ØˆMØ—j‘j Ó(ˆØ�;ÑØ>�fÐ>˜l¨K¸Ñ,=Ñ>Ð>Ø!'§¡£×E™˜˜A°1¸Ó3D��1‘ÓEÐEùÓEs   Á%A<Á3A<)rÓ  r•  rÔ  rp  r\  )rê  r˜  r^  rð  rï  s       @rˆ   Ú_preserve_redacted_plugin_keysrñ  Þ?  sœ   ø€ ô �h¤Ô%Øˆô )¨´4Ô8‘(¸böàÜ�aœÔ 1§5¡5¨¤=°Q·U±U¸<Ô5Hð 	
ˆ&‰	�1�\‘?Ñ"ò€Kð	Fœð 	F¤6õ 	Fð !)Ö)˜1‰G�A�JÒ)Ð)ùò#ùò" *s   ªABÂB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        v r)t        | j                  | j                  |«      ƒ d{  –—† S | j                  t        j                  vrt        ddd| j                  › d�i¬«      ‚	 t        j                  | j                  | j                  i«       t%        t         «      j'                  dd	i¬
«      ƒ d{  –—† }|�|j(                  €i }nt+        |j(                  «      }t-        j.                  |«      }| j                  }| j                  dk(  rt1        ||j3                  d«      «      }t5        t6        |«      || j                  <   t9        t         «      j:                  j=                  dd	id	t?        j@                  |«      dœdt?        j@                  |«      idœ¬«      ƒ d{  –—† }tC        d	«      ƒ d{  –—†  tE        jF                  tI        d	d|||«      «       | j                  dk(  r&tK        t5        t*        tL        tN        f   |«      «       tQ        |«       |S 7 �Œú# t         $ r' t        dddt#        | j                  «      › d�i¬«      ‚w xY w7 �Œ¢7 Œ´7 Œ£­w)z=
    Update a specific field in litellm general settings
    NrD  rz  rc  úInvalid field=ú passed in.zInvalid type of field value=rT  rW  r�  r4  r‘  rU  r’  r”  rÌ  ))r÷  r¨  r:   rÊ  r*  rj  rP   r  rø  rñ  Ú#_GENERAL_SETTINGS_UI_LITELLM_FIELDSÚ*_persist_general_settings_ui_litellm_fieldrô  r>   rù  rü  rÿ  rw   rw  r•  rU  rÔ  rÆ  rÇ  rñ  rp  r   r   rv  rH  r–  rm  r  rk  rP  r‡  rÍ  rG  r‚  r\  r	  )r„  r*  rb  rW  rÎ  rô  r  s          rˆ   Úupdate_config_general_settingsr÷  ÿ?  sÍ  è ø€ ðô ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð
 ×"Ñ"Ô&6×&BÑ&BÒBÜØØÔ.×AÑA×GÑGÐHô
ð 	
ð
 ‡�Ô=Ñ=Ü?ÀÇÁÐQU×QaÑQaÐctÓu×uÐuà‡�Ô3×@Ñ@Ñ@ÜØØ˜~¨d¯o©oÐ->¸kÐJÐKô
ð 	
ð

Ü×,Ñ,¨d¯o©o¸t×?OÑ?OÐ-PÔQô (;¼=Ó'I×'TÑ'TØÐ/Ð0ð (Uó (÷ "Ðð
 Ð"Ð&9×&EÑ&EÐ&MØÑäÐ 3× ?Ñ ?Ó@Ðä%)§]¡]Ð3CÓ%DÐð ×"Ñ"€KØ‡�˜)Ò#Ü4°[ÐBR×BVÑBVÐW`ÓBaÓbˆä(,¬Y¸Ó(DÐ�T—_‘_Ñ%ä,¬]Ó;×AÑA×HÑHØÐ/Ð0ð 1Ü#Ÿz™zÐ*:Ó;ñð %¤d§j¡jÐ1AÓ&BÐCñ
ð Ió 	÷ 	€Hô "Ð"4Ó
5×5Ð5Ü×ÑÜØ 	Ð+BÐDTÐVgó	
ôð ‡�˜)Ò#Ü$¤T¬$¬s´F¨{Ñ*;Ð=MÓ%NÔOÜ Ð!1Ô2à€Oðu vúô ò 
ÜØØÐ;¼DÀ×AQÑAQÓ<RÐ;SÐS^Ð_Ð`ô
ð 	
ð
úð"ùð(	øð 6ús\   ‚B)K"Â+J%Â,=K"Ã*+J( Ä$K"Ä9KÄ:C/K"È)KÈ*K"È<K È=A)K"Ê(0KËK"ËK"Ë K"rñ  c                 ó@   — | t         v xs t        j                  | «      S rn  )rÎ  rÉ  Úis_sensitive_key)rñ  s    rˆ   Ú _is_secret_general_setting_fieldrú  _@  s    € ØÔ>Ð>ÒtÔBW×BhÑBhÐisÓBtÐtrŠ   Ú_REDACT_SECRET_MAX_DEPTHrŸ  c           
      ó&  — |t         k\  ryt        | t        «      r>| j                  «       D ��ci c]"  \  }}|t	        |«      rdnt        ||dz   «      “Œ$ c}}S t        | t        «      r| D �cg c]  }t        ||dz   «      ‘Œ c}S | S c c}}w c c}w )aF  Recursively redact secret leaves inside a structured field so a nested
    credential (e.g. aws_web_identity_token under database_args) is never
    returned to a non-admin, while non-secret siblings stay visible. At
    _REDACT_SECRET_MAX_DEPTH the whole subtree is replaced with "REDACTED"
    so depth-overrun fails closed.ÚREDACTEDr8  )rû  rÓ  rÔ  râ  rú  rÕ  r•  )r*  rŸ  rz  rÃ  rü  s        rˆ   rÕ  rÕ  j@  s™   € ð Ô(Ò(ØÜ�%œÔð "ŸK™K›M÷
á��Sð Ô @ÀÔ E‘*ÔKgÐhkÐmrÐuvÑmvÓKwÑwó
ð 	
ô �%œÔØJOÖPÀ$Ô,¨T°5¸1±9Õ=ÒPÐPØ€Lùó
ùò
 Qs   ®'BÁ-BrT  rU  c                 óž   — | dk(  r!t        |t        «      r|D �ci c]  }|d“Œ c}S t        |t        t        f«      rt        |«      S |S c c}w )Nr‚  rý  )rÓ  rÔ  r•  rÕ  )rT  rU  rz  s      rˆ   r�  r�  |@  sM   € ØÐ,Ò,´¸KÌÔ1NØ+6Ö7 C��Z‘Ò7Ð7Ü�+¤¤d˜|Ô,Ü+¨KÓ8Ð8ØÐùò 8s   š
A
r  c                 óh   — |r|S t        | «      ryt        |t        t        f«      rt	        |«      S |S ©Nrý  )rú  rÓ  rÔ  r•  rÕ  )rñ  r*  r  s      rˆ   r]  r]  „@  s3   € ÙØˆÜ'¨
Ô3ØÜ�%œ$¤˜Ô&Ü+¨EÓ2Ð2Ø€LrŠ   ©Úredact_all_valuesr  c                óÒ   — | €y |r:t        | t        «      r*t        j                  | D �ci c]  }|d“Œ c}t        ¬«      S t        j                  t        | «      t        ¬«      S c c}w )Nrý  rÒ  )rÓ  rÔ  rm  r  r‚  rÕ  )r*  r  rz  s      rˆ   Ú_dump_redacted_configr  Ž@  sT   € ð
 €}ØÙœZ¨¬tÔ4Ü�z‰z°eÖ<¨s˜3 
™?Ò<ÄcÔJÐJÜ�:‰:Ô2°5Ó9Ä3ÔGÐGùò =s   ©
A$ÚactionÚbefore_valueÚafter_valuer…  c           
   ƒ   ó„   K  — | dk(  }t        | ||t        ||¬«      t        ||¬«      |dt        ¬«      ƒ d{  –—†  y7 Œ­w)a�  Record a system-wide settings change in LiteLLM_AuditLog.

    Secret leaves are redacted before the row is written. environment_variables
    hold arbitrary credentials under non-secret-looking uppercase keys (e.g.
    DATABASE_URL), so every value in that section is redacted rather than
    relying on key-name matching; other sections reuse the same matcher
    /config/field/info applies for non-admins.
    r‚  r  N)Ú	object_idr  r…  r  r  r*  Úlitellm_changed_byÚlitellm_proxy_admin_name)rA  r  r®   )rT  r  r  r  r*  r…  r  s          rˆ   rÍ  rÍ  š@  sN   è ø€ ð   *Ð-DÑDÐÜ
!ØØØÜ*¨<ÐK\Ô]Ü)¨+ÐIZÔ[Ø+ØÜ!9ô	÷ 	ò 	ús   ‚6A ¸>¹A >   ÚOTEL_HEADERSÚSMTP_USERNAMEÚGALILEO_USERNAMErÔ  ÚGENERIC_LOGGER_HEADERSÚ_EXTRA_SECRET_CALLBACK_ENV_VARSÚenv_varsc           	      ó€   — | j                  «       D ��ci c]  \  }}||�t        |t        ¬«      rdn|“Œ c}}S c c}}w )z¾Return a copy of ``env_vars`` with values for keys classified as
    sensitive by ``is_sensitive_callback_key`` replaced with ``"REDACTED"``.
    ``None`` values pass through unchanged.
    )Úextrarý  )râ  r\   r  )r  rz  r*  s      rˆ   Ú_redact_callback_env_varsr  Â@  sO   € ð #Ÿ.™.Ó*÷ñ ˆC�ð 	àÐ Ô%>¸sÔJiÕ%jñ àñ	óð ùó s   ”":Úentriesc           
      óx   — |r| S | D �cg c]&  }i |¥dt        |j                  d«      xs i «      i¥‘Œ( c}S c c}w )NÚ	variables)r  rp  )r  r  rÆ  s      rˆ   Ú_apply_callback_role_gater  Ñ@  sA   € ÙØˆØipÖqÐ`eÐ[ˆuÐ[�kÔ#<¸U¿Y¹YÀ{Ó=SÒ=YÐWYÓ#ZÓ[ÒqÐqùÒqs   ‰+7c                   ó>   — e Zd ZU ee   ed<   eeeedz  f      ed<   y)Ú_AlertingDestinationEntryrÄ  Nr  )r   r  r  r!   r‚  r!  r   rè  rŠ   rˆ   r  r  ×@  s$   … Ø
�3‰-ÓØ˜  S¨4¡Z Ñ0Ñ1Ô1rŠ   r  c                 ó<   — |rt        | t        «      S t        | «      S rn  )rÇ   rÖ  r  )r  r  s     rˆ   Ú_apply_alerting_env_role_gater  Ü@  s   € ÙÜ" 8Ô-EÓFÐFÜ$ XÓ.Ð.rŠ   c                 óV   — |st        | t        «      s| S | D �ci c]  }|d“Œ c}S c c}w r   rÁ
  )Úwebhook_mapr  rë
  s      rˆ   Ú_apply_webhook_role_gater  â@  s-   € ÙœJ {´DÔ9ØÐØ5@ÖA zˆJ˜
Ñ"ÒAÐAùÒAs   ™
&z/config/field/infoc              ƒ   óT  K  — 	 t         €'t        ddt        j                  j                  i¬«      ‚t        |«      s't        ddt        j                  j                  i¬«      ‚| t        j                  vrt        ddd| › d�i¬«      ‚t        t         «      j                  ddi¬«      ƒ d {  –—† }|�|j                  €t        ddd	| › d
�i¬«      ‚t        |j                  «      }| |v r›t        | ||    |j                  t        j                   k(  «      }| dk(  r^t#        |t$        «      rN|D ���cg c]?  }t#        |t        «      r+|j'                  «       D ��ci c]  \  }}||dk(  rdn|“Œ c}}n|‘ŒA }}}}t)        | |¬«      S t        ddd	| › d
�i¬«      ‚7 Œìc c}}w c c}}}w ­w)NrD  rz  rc  ró  rô  rT  rW  r�  úField name=z
 not in DBr4  rì  r×  )rñ  rô  )r÷  r¨  r:   rÊ  r*  r1  rø  r>   rù  rw  r•  rU  rÔ  r]  rj  rP   r  rÓ  r•  râ  r<   )rñ  r*  rb  rW  rô  r^  rF  rG  s           rˆ   Úget_config_general_settingsr"  è@  sô  è ø€ ðô
 ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô
  Ð 1Ô2ÜØØÔ.×AÑA×GÑGÐHô
ð 	
ð
 Ô.×;Ñ;Ñ;ÜØØ˜~¨j¨\¸ÐEÐFô
ð 	
ô @SÔS`Ó?a×?lÑ?lØÐ/Ð0ð @mó @÷ :Ðð
 Ð"Ð&9×&EÑ&EÐ&MÜØØ˜{¨:¨,°jÐAÐBô
ð 	
ô
  Ð 3× ?Ñ ?Ó@ÐàÐ)Ñ)Ü7ØØ  Ñ,Ø!×+Ñ+Ô/?×/KÑ/KÑKóˆKð
 ˜YÒ&¬:°kÄ4Ô+Hð )÷ð àô XbÐbcÔeiÔWjÈÏÉË×SÁÀÀA�a 1¨Ò#4™%¸!Ñ;ÔSÐpqÑqð�ò ô #¨jÀkÔRÐRäØØ ;¨z¨l¸*Ð!EÐFôð ð5:úó* Tùôùs7   ‚B*F(Â,FÂ-BF(Ä1(F!ÅFÅ-F!Å5%F(ÆF!Æ!F(c                   ób   — e Zd ZU ed   ed<   eed<   eeedf      ed<   ee   ed<   ee   ed<   y)	Ú!GeneralSettingsUILiteLLMFieldSpec)ÚFloatÚDollarræ  ÚSelectrw   rô  .rÒ  Útabr‹   N)	r   r  r  r   r!  r‚  r    rŒ  r   rè  rŠ   rˆ   r$  r$  1A  s=   … Ø
Ð8Ñ
9Ó9ØÓØ˜˜s C˜x™Ñ)Ó)Ø	�SÑ	ÓØ˜ÑÔrŠ   r$  r%  z®Fraction (0, 1] of a key's configured TPM/RPM that an over-budget key with 'Throttle on budget exceeded' enabled keeps serving at. Leave empty to hard-block over-budget keys.)rw   rô  Úprompt_cachingz¶Auto-adds cache_control to the system prompt and trailing turn for supported Anthropic and Bedrock Claude models. The cache is shared across callers on the same upstream credentials.)rw   r(  rô  r'  )Ú5mÚ1hz[Empty uses Anthropic's 5m default. 1h suits long sessions but doubles the cache write cost.)rw   rÒ  r(  rô  z§Carry spend beyond max_budget into the next window when budgets reset, instead of forgiving it. Applies to key, user, team, team member, org, tag and end-user budgets.r&  zæUSD spend cap for each dashboard login session; covers LLM calls made from the dashboard such as the playground and auto router Test Connection. Each login starts a fresh session with this budget. Clearing restores the $1 default.)rw   r‹   rô  )Ú#budget_exceeded_throttle_percentageÚenable_anthropic_prompt_cachingÚanthropic_prompt_caching_ttlÚbudget_rolloverr%  rõ  r,	  c                 ó,   — d| v r| d   S | d   dk(  rdS dS )z<The value a field falls back to when it is cleared or reset.r‹   rw   ræ  FNrè  )r,	  s    rˆ   Ú$_general_settings_ui_litellm_defaultr1  cA  s,   € ð �DÑØ�I‰ÐØ˜‘L IÒ-ˆ5Ð7°4Ð7rŠ   c           	      óº  — t         |    }|d   }|�|dk(  rt        |«      S |xdk(  r% t        |t        «      st	        dd| › d�i¬«      ‚|S xdk(  rK |j                  d	d
«      }||vr$t	        dd| › ddj                  |«      › d�i¬«      ‚t        t        |«      S xdk(  rZ t        |t        «      s,t        |t        t        f«      rdt        |«      cxk  rdk  sn t	        dd| › d�i¬«      ‚t        |«      S dk(  rQt        |t        «      s$t        |t        t        f«      rt        |«      dk  rt	        dd| › d�i¬«      ‚t        |«      S 	 t        |«       y )Nrw   r6  ræ  rD  rz  z must be true or falserc  r'  rÒ  rè  z must be one of: rÿ  z
, or emptyr%  r   r8  z$ must be a number in (0, 1] or emptyr&  z* must be a positive dollar amount or empty)rõ  r1  rÓ  r#  r¨  rp  r–  r   r‚  r"  r   r"   )rñ  r*  r,	  rò  rÒ  s        rˆ   Ú+_validate_general_settings_ui_litellm_valuer3  lA  sx  € Ü5°jÑA€DØ˜V™€JØ€}˜ šÜ3°DÓ9Ð9Ø
ÝÜ˜e¤TÔ*Ü#Ø #Ø#¨
 |Ð3IÐ%JÐKôð ð ˆLÝØ!ŸX™X i°Ó4ˆGØ˜GÑ#Ü#Ø #Ø#¨
 |Ð3DÀTÇYÁYÈwÓEWÐDXÐXbÐ%cÐdôð ô œ˜UÓ#Ð#ÝÜ˜%¤Ô&¬j¸ÄÄeÀÔ.MÐVWÔZ_Ð`eÓZfÔVkÐjkÔVkÜ#Ø #Ø#¨
 |Ð3WÐ%XÐYôð ô ˜“<ÐÛÜ˜%¤Ô&¬j¸ÄÄeÀÔ.MÔQVÐW\ÓQ]ÐabÒQbÜ#Ø #Ø#¨
 |Ð3]Ð%^Ð_ôð ô ˜“<ÐØÜ˜Õ$rŠ   c           	   ƒ   óz  K  — t        | |«      }t        j                  «       ƒ d {  –—† }|j                  di «      j                  | «      }t	        t
        | |«       d|vri |d<   ||d   | <   t        j                  |¬«      ƒ d {  –—†  t        j                  t        | d|||«      «       d| › d�ddœS 7 Œ�7 Œ1­w)NrT  ©r  rÌ  úField z updatedr  ©r�   r±  )
r3  r~  rÓ  rp  rd  r  rŒ  rP  r‡  rÍ  )rñ  r*  r*  Ú	validatedr^  r  s         rˆ   rö  rö  “A  sÅ   è ø€ ô CÀ:ÈuÓU€IÜ&×1Ñ1Ó3×3€FØ Ÿ*™*Ð%7¸Ó<×@Ñ@ÀÓL€LÜŒG�Z Ô+Ø Ñ'Ø%'ˆÐ!Ñ"Ø-6€FÐÑ˜zÑ*Ü
×
"Ñ
"¨fÐ
"Ó
5×5Ð5Ü×ÑÔ/°
¸IÀ|ÐU^Ð`qÓrÔsØ 
˜|¨8Ð4À	ÑJÐJð 4øð 6ús"   ‚$B;¦B7§A B;ÂB9Â0B;Â9B;c           	   ƒ   ó–  K  — t         j                  «       ƒ d {  –—† }|j                  di «      j                  | «      }t        t        |    «      }t        t        | |«       d|v r|d   j                  | d «       t         j                  |¬«      ƒ d {  –—†  t        j                  t        | d|||«      «       d| › d�ddœS 7 Œª7 Œ1­w)NrT  r5  Údeletedr6  z resetr  r7  )r~  rÓ  rp  r1  rõ  rd  r  r‡  rŒ  rP  r‡  rÍ  )rñ  r*  r^  r  r|  s        rˆ   Ú(_reset_general_settings_ui_litellm_fieldr;  ¢A  sÂ   è ø€ Ü&×1Ñ1Ó3×3€FØ Ÿ*™*Ð%7¸Ó<×@Ñ@ÀÓL€LÜ?Ô@cÐdnÑ@oÓp€MÜŒG�Z Ô/Ø˜VÑ#ØÐ!Ñ"×&Ñ& z°4Ô8Ü
×
"Ñ
"¨fÐ
"Ó
5×5Ð5Ü×ÑÔ/°
¸IÀ|ÐUbÐduÓvÔwØ 
˜|¨6Ð2¸iÑHÐHð 4øð 6ús"   ‚C	šC›A:C	ÂCÂ0C	ÃC	z/config/listrè  c              ƒ   óÈ  K  — 	 t         €'t        ddt        j                  j                  i¬«      ‚t        |«      s6t        ddt        j                  j                  › d|j                  › �i¬«      ‚|j                  t        j                  k(  }t        t         «      j                  ddi¬«      ƒ d{  –—† }|�"|j                  �t        |j                  «      }ni }t        }g }t        j                   j#                  «       D �]á  \  }}||v sŒ||   }	|	d	k(  �rL|d
k(  rt$        g}
ng }
|
D �]5  }|j&                  j#                  «       D ��cg c]H  \  }}t)        |t+        |dt-        |«      «      dt/        |t0        j3                  |d«      |«      d¬«      ‘ŒJ }}}d}|j                   j#                  «       D ]6  \  }}t5        |d«      r |j6                  �|j6                  ||   _        |dz  }Œ8 d}||v rd}n
|t0        v rd}t;        |||   |j6                  xs dt/        |t0        j3                  |d«      |«      ||j<                  |¬«      }|j?                  |«       �Œ8 �Œcd}d}||v rd}n
|t0        v rd}t0        j3                  |d«      }|€	||v r||   }t;        |||   |j6                  xs dt/        |||«      ||j<                  |¬«      }|j?                  |«       �Œä t        t         «      j                  ddi¬«      ƒ d{  –—† }|�!|j                  �t        |j                  «      ni }t@        j#                  «       D ]‡  \  }}t+        tB        |d«      }tE        |«      }||v rd}n
||k7  rd}nd}|j?                  t;        ||d   |d   |||tG        |j3                  dd«      «      xs d|j3                  d«      d¬«	      «       Œ‰ |S 7 �Œ$c c}}w 7 ŒÒ­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),)
    NrD  rz  rc  rå  rT  rW  r�  rÛ  rÌ  r   r6  )rñ  rò  ró  rö  rõ  r   rô  r8  TF)rñ  rò  ró  rô  rõ  rö  Únested_fieldsrT  rw   rÒ  rè  r(  )	rñ  rò  ró  rô  rõ  rö  Úfield_optionsÚ	field_tabr=  )$r÷  r¨  r:   rÊ  r*  r1  rø  rj  rP   r  rw  r•  rU  rÔ  ré  r>   rù  râ  rQ   r!  rC   rw  r‚  r]  rW  rp  r¬  rô  ró  r?   r‹   rã  rõ  r  r1  r•  )rè  r*  r  rb  rú  rý  r   rñ  r  Útyped_dict_typeÚpydantic_class_listÚpydantic_classÚ	sub_fieldÚsub_field_typer=  r€  Úsub_field_infor  r  Ú_field_valueÚdb_litellm_settings_rowÚdb_litellm_settingsÚlitellm_field_namer,	  r  r|  Ústored_in_db_litellms                              rˆ   Úget_config_listrK  ®A  s�  è ø€ ð ô
 ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ô
  Ð 1Ô2ÜØØÔ 1× DÑ D× JÑ JÐKÈ<ÐXi×XsÑXsÐWtÐuÐvô
ð 	
ð
 -×6Ñ6Ô:J×:VÑ:VÑV€Mô @SÔS`Ó?a×?lÑ?lØÐ/Ð0ð @mó @÷ :Ðð Ð&Ð+>×+JÑ+JÐ+VÜ<@ÐAT×A`ÑA`Ó<aÑ à#%Ð äC€Là€Jä"7×"DÑ"D×"JÑ"JÓ"Ló Q1Ñˆ
�JØ˜Ò%ð +¨:Ñ6ˆOà /Ó1ØÐ!9Ò9Ü+EÐ*FÑ'à*,Ð'à&9ó -5�Nð :H×9WÑ9W×9]Ñ9]Ó9_÷%ñ 6˜I ~ô $Ø'0Ü'.¨~¸zÌ3È~ÓK^Ó'_Ø.0Ü0MØ )Ü 0× 4Ñ 4°YÀÓ EØ -ó1ð
 *.ö
ð%�Mñ %ð �Cð (×4Ñ4×:Ñ:Ó<ò!ñ Ø!Ø&ä" >°=ÔAÀn×F`ÑF`ÐFlØCQ×C]ÑC]˜M¨#Ñ.Ô@Ø˜q™™ð!ð %)�MØ!Ð%=Ñ=Ø(,™Ø#Ô'7Ñ7Ø(-˜ä$.Ø#-Ø#/°
Ñ#;Ø*4×*@Ñ*@Ò*FÀBÜ$AØ&Ü,×0Ñ0°¸TÓBØ)ó%ð
 &3Ø,6×,>Ñ,>Ø&3ô%�Mð ×%Ñ% mÖ4ò[-5ð` !%�à $�ØÐ!9Ñ9Ø$(‘MØÔ#3Ñ3Ø$)�Mä/×3Ñ3°JÀÓE�ØÐ'¨JÐ:RÑ,RØ#;¸JÑ#G�Lä *Ø)Ø+¨JÑ7Ø&0×&<Ñ&<Ò&BÀÜ =¸jÈ,ÐXeÓ fØ!.Ø(2×(:Ñ(:Ø"/ô!�ð ×!Ñ! -Ö0ðcQ1ôf DWÔWdÓCe×CpÑCpØÐ/Ð0ð Dqó D÷ >Ðð
 #Ð.Ð3J×3VÑ3VÐ3bô 	Ð$×0Ñ0Ô1àð ô
 %H×$MÑ$MÓ$Oò 
Ñ Ð˜DÜ7>¼wÐHZÐ\`Ó7aˆÜ<¸TÓBˆàÐ!4Ñ4Ø#'Ñ Ø˜mÒ+Ø#(Ñ à#'Ð Ø×ÑÜØ-Ø ™<Ø"& }Ñ"5Ø)Ø1Ø$1Ü" 4§8¡8¨I°rÓ#:Ó;ÒC¸tØŸ(™( 5›/Ø"ô
õ	
ð
ð0 ÐðA:ûó6%ðJ>ús:   ‚B1O"Â3OÂ4AO"Ä=O"ÅAO
ÆE3O"ÌO ÌC
O"ÏO"z/config/field/deletec           	   ƒ   óX  K  — 	 t         €'t        ddt        j                  j                  i¬«      ‚|j
                  t        j                  k7  r6t        ddt        j                  j                  › d|j
                  › �i¬«      ‚| j                  t        v rt        | j                  |«      ƒ d{  –—† S | j                  t        j                  vrt        ddd| j                  › d�i¬«      ‚t        t         «      j                  dd	i¬
«      ƒ d{  –—† }|�|j                   €t        ddd| j                  › d�i¬«      ‚t#        |j                   «      }t%        j&                  |«      }|j)                  | j                  d«       t+        t         «      j,                  j/                  dd	id	t1        j2                  |«      dœdt1        j2                  |«      idœ¬«      ƒ d{  –—† }t5        d	«      ƒ d{  –—†  t7        j8                  t;        d	d|||«      «       |S 7 �Œq7 �Œ7 ŒA7 Œ0­w)z|
    Delete the db value of this field in litellm general settings. Resets it to it's initial default value on litellm.
    NrD  rz  rc  rå  ró  rô  rT  rW  r�  r!  z not in configr‘  rU  r’  r”  r:  )r÷  r¨  r:   rÊ  r*  rj  rP   r  rø  rñ  rõ  r;  r>   rù  rw  r•  rU  rÔ  rÆ  rÇ  r‡  rv  rH  r–  rm  r  rk  rP  r‡  rÍ  )r„  r*  rb  rW  rÎ  r  s         rˆ   Údelete_config_general_settingsrM  UB  s>  è ø€ ðô
 ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð
 ×"Ñ"Ô&6×&BÑ&BÒBÜØØÔ 1× DÑ D× JÑ JÐKÈ<ÐXi×XsÑXsÐWtÐuÐvô
ð 	
ð
 ‡�Ô=Ñ=Ü=¸d¿o¹oÐO`Óa×aÐaà‡�Ô3×@Ñ@Ñ@ÜØØ˜~¨d¯o©oÐ->¸kÐJÐKô
ð 	
ô @SÔS`Ó?a×?lÑ?lØÐ/Ð0ð @mó @÷ :Ðð
 Ð"Ð&9×&EÑ&EÐ&MÜØØ˜{¨4¯?©?Ð*;¸>ÐJÐKô
ð 	
ô
  Ð 3× ?Ñ ?Ó@Ðä%)§]¡]Ð3CÓ%DÐð ×Ñ˜Ÿ™¨$Ô/ä,¬]Ó;×AÑA×HÑHØÐ/Ð0ð 1Ü#Ÿz™zÐ*:Ó;ñð %¤d§j¡jÐ1AÓ&BÐCñ
ð Ió 	÷ 	€Hô "Ð"4Ó
5×5Ð5Ü×ÑÜØ 	Ð+BÐDTÐVgó	
ôð €Oð[ bùð:ùð&	øð 6úsJ   ‚B-H*Â/H Â0A!H*ÄH#ÄCH*Ç$H&Ç%H*Ç7H(Ç8)H*È#H*È&H*È(H*z/config/callback/deletec           	   ƒ   óÒ  K  — t         €'t        ddt        j                  j                  i¬«      ‚|j
                  t        j                  k7  r6t        ddt        j                  j                  › d|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¬«      ‚t        |«      }|j!                  |«       ||j#                  d	i «      d
<   t        j%                  |¬«      ƒ d{  –—†  t'        j(                  t+        d	dd
|id
|i|«      «       t        j-                  t         t.        ¬«      ƒ d{  –—†  d|› �||t1        j2                  «       j5                  «       dœS 7 �Œ 7 Œ~7 Œ3# t        $ r ‚ t6        $ ry}t9        j:                  d|«       t9        j<                  t?        j@                  «       «       tC        dtE        |«      z   tF        jH                  dtJ        jL                  ¬«      ‚d}~ww xY w­w)z>
    Delete specific logging callback from configuration.
    NrD  rz  rc  rå  Trž  zCSet `'STORE_MODEL_IN_DB='True'` in your env to enable this feature.rT  r  r»  z
Callback 'z#' not found in active configurationr5  r:  rŒ  zSuccessfully deleted callback: )r�   Úremoved_callbackÚremaining_callbacksÚ
deleted_atzElitellm.proxy.proxy_server.delete_callback(): Exception occurred - %szError deleting callback: Úcallback_namerÕ	  )'r÷  r¨  r:   rÊ  r*  rj  rP   r  rø  r4  r~  rÓ  rR  rÉ  rp  r•  Úremover  rŒ  rP  r‡  rÍ  rŽ  rý  r
   rh
  r	  rÿ  rŸ   rz  r
  r2  r3  rS   r‚  rR   r   r±  r<  )r„  r*  r^  rR  rT  r  Úbefore_success_callbacksr  s           rˆ   Údelete_callbackrU  ¦B  st  è ø€ ô ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð
 ×"Ñ"Ô&6×&BÑ&BÒBÜØØÔ 1× DÑ D× JÑ JÐKÈ<ÐXi×XsÑXsÐWtÐuÐvô
ð 	
ô
  Ñ$ÜØØÐbÐcô
ð 	
ð
6
ä*×5Ñ5Ó7×7ˆØ#×1Ñ1×7Ñ7Ó9ˆð #)§*¡*Ð-?ÀÓ"DÐØ#3×#7Ñ#7Ð8JÈBÓ#OÐàÐ 1Ñ1ÜØØ :¨m¨_Ð<_Ð!`Ðaôð ô
 +/Ð/@Ó*AÐ ð 	× Ñ  Ô/ØHYˆ×ÑÐ,¨bÓ1Ð2DÑEô ×&Ñ&°&Ð&Ó9×9Ð9ä×ÑÜ#Ø"ØØ#Ð%=Ð>Ø#Ð%6Ð7Ø!óô	
ô ×)Ñ)¼ÔYjÐ)Ók×kÐkð 9¸¸ÐHØ -Ø#4Ü"Ÿ,™,›.×2Ñ2Ó4ñ	
ð 	
ðG 8ùð( 	:øð 	lùô ò ØÜò 
Ü×"Ñ"Ð#jÐlmÔnÜ×"Ñ"¤9×#7Ñ#7Ó#9Ô:ÜØ/´#°a³&Ñ8Ü ×6Ñ6Ø!Ü×6Ñ6ô	
ð 	
ûð
üsc   ‚BI'ÂG Â2GÂ3B#G ÅGÅAG Æ#GÆ$-G ÇI'ÇG ÇG ÇG ÇI$Ç+A4IÉI$É$I'z/get/config/callbacks)r  r  rŽ  c              ƒ   ó2  K  — 	 t        «       }t        j                  «       ƒ d{  –—† }|j                  di «      }|j                  di «      }|j                  di «      }| j                  t
        j                  k(  }|j                  dg «      }|j                  dg «      }|j                  dg «      }	d„ }
 |
|«      } |
|«      } |
|	«      }	g }	 |D ]  }|j                  t        |d	|«      «       Œ  |D ]  }|j                  t        |d
|«      «       Œ  |	D ]  }|j                  t        |d|«      «       Œ  t        ||«      }|j                  dg «      }g }d|v r¢t        t        |t        j                  d¬«      \  }}t        ||«      }t        j                   j"                  }t        j                   j%                  «       }t'        t        j                   j(                  |«      }|j                  d|||dœ«       t        t*        |t        j                  d¬«      \  }}t        ||«      }|j                  d|dœ«       t        t,        |t        j                  d¬«      \  }}t        ||«      }d|dœ}|j                  |«       t.        €i }nt.        j1                  «       }d	||t3        |«      ||dœS 7 �Œ”# t4        $ rÏ}t7        j8                  d|«       t;        |t<        «      rPt?        tA        |dd|› d�«      tB        jD                  tA        |dd«      tA        |dtF        jH                  «      ¬«      ‚t;        |t>        «      r|‚t?        dtK        |«      z   tB        jD                  tA        |dd«      tF        jH                  ¬«      ‚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

    NrT  rW  r‚  r  rá  rà  c                 ó4   — t        | t        «      r| gS | €g S | S rn  rî  )r~  s    rˆ   Únormalize_callbackz&get_config.<locals>.normalize_callbackC  s$   € Ü˜(¤CÔ(Ø �zÐ!ØÐ!Ø�	ØˆOrŠ   r  r  Úsuccess_and_failurer¼  rÂ  T)Úempty_db_is_set)rÄ  r  Úactive_alertsÚalerts_to_webhookÚemail)rÄ  r  Úms_teams)r±  rà  ÚalertsÚactive_alerting_destinationsrs  Úavailable_callbacksz?litellm.proxy.proxy_server.get_config(): Exception occured - %sr—  r  rà  r  rÔ	  r7  rÕ	  r  )&ÚAllCallbacksr~  rÓ  rp  rj  rP   r  rã  r^   r  r  r  rn  ro  r  rý  r8  r¿  Ú_all_possible_alert_typesr  rË  r  r  rU  Úget_settingsrŒ  rÿ  rŸ   r   rÓ  r¨  rS   rw  rR   r  r±  rë  r‚  )r*  Úall_available_callbacksr  r»  r9  r‚  r  Ú_success_callbacksÚ_failure_callbacksÚ_success_and_failure_callbacksrX  Ú_data_to_returnÚ	_callbackÚ	_alertingÚalerting_dataÚ_slack_valuesrÁ  Ú_slack_env_varsÚ_alerting_typesÚ_all_alert_typesÚ_alerts_to_webhookÚ_email_valuesÚ_email_env_varsÚ_ms_teams_valuesÚ_ms_teams_env_varsÚms_teams_alerting_entryÚ_router_settingsr  s                               rˆ   rÓ  rÓ   C  sÈ  è ø€ ð~
Ü)5«Ðä#/×#:Ñ#:Ó#<×<ˆØ#.§?¡?Ð3EÀrÓ#JÐØ#.§?¡?Ð3EÀrÓ#JÐØ'2§¡Ð7NÐPRÓ'SÐà0×:Ñ:Ô>N×>ZÑ>ZÑZˆà.×2Ñ2Ð3EÀrÓJÐØ.×2Ñ2Ð3EÀrÓJÐØ):×)>Ñ)>¸{ÈBÓ)OÐ&ò	ñ 0Ð0BÓCÐÙ/Ð0BÓCÐÙ);Ð<ZÓ)[Ð&àˆð	ð ,ò 	bˆIØ×"Ñ"Ô#3°I¸yÐJ_Ó#`Õað	bð ,ò 	bˆIØ×"Ñ"Ô#3°I¸yÐJ_Ó#`Õað	bð 8ò 	nˆIØ×"Ñ"Ô#3°IÐ?TÐVkÓ#lÕmð	nô 4°OÀ]ÓSˆð -×0Ñ0°¸RÓ@ˆ	Ø!ˆØ�iÑÜ-Ü!Ð#8¼"¿*¹*ÐVZô ÑˆM˜1ô &CÀ=ÐR_Ó%`ˆOä%6×%NÑ%N×%ZÑ%ZˆOÜ&7×&OÑ&O×&iÑ&iÓ&kÐÜ(@Ü!×9Ñ9×NÑNÐP]ó)Ðð × Ñ à#Ø!0Ø%4Ø);ñ	ôô *Ô*;Ð=RÔTV×T^ÑT^ÐptÔuÑˆ�qÜ!>¸}ÈmÓ!\ˆà×ÑàØ,ñô	
ô -Ü Ð"7¼¿¹ÐUYô
ÑÐ˜!ô %BÐBRÐTaÓ$bÐð Ø+ñE
Ðð 	×ÑÐ4Ô5äÐØ!Ñä)×6Ñ6Ó8Ðð  Ø(Ø#Ü,1°)Ó,<Ø/Ø#:ñ
ð 	
ðG =úôV ò 
Ü×&Ñ&Ð'hÐjkÔlÜ�aœÔ'Ü Ü  8Ð/DÀQÀCÀqÐ-IÓJÜ$×/Ñ/Ü˜a ¨&Ó1Ü˜Q ¬v×/JÑ/JÓKô	ð ô ˜œ>Ô*ØˆGÜØ,¬s°1«vÑ5Ü ×+Ñ+Ü˜!˜W fÓ-Ü×,Ñ,ô	
ð 	
ûð
üs:   ‚N„!J< ¥J9¦JJ< Ê8NÊ9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_endpointr{  �C  s   è ø€ ð. �WÐÐùs   ‚z/reload/model_cost_mapc              ƒ   óÂ  K  — | j                   t        j                  k7  rt        dd| j                   › �¬«      ‚	 t        €t        dd¬«      ‚ddlm}m}  |t        j                  ¬	«      ƒ d{  –—† }t        ||«      rt        d
d|j                  › d�¬«      ‚t        |j                  «      }t        «       }|t        _        t#        t        t$        |«      ƒ d{  –—† t        _        t)        j*                  d|«       d|› d�d||j-                  «       dœS 7 Œª7 Œ># t        $ r ‚ t.        $ r+}t)        j0                  d|«       t        dd|› �¬«      ‚d}~ww xY w­w)zÊ
    ADMIN ONLY / MASTER KEY Only Endpoint

    Manually reload the model cost map from the remote source.
    This will fetch fresh pricing data from the model_prices_and_context_window.json file.
    rv  ú2Access denied. Admin role required. Current role: rc  Nrž  ú!Database connection not availabler   r	  r  iö  z!Failed to reload model cost map: z . Current pricing data was kept.zEModel cost map reloaded successfully in current pod. Models count: %sz"Price data reloaded successfully! z models updated.r  )r�   r±  r	  r/	  z#Failed to reload model cost map: %s)rj  rP   r  r¨  r÷  rf  r	  r	  r  r	  rÓ  rÜ  rR  rN  r  r~  rg  rþ   rú   rh  rŸ   r  r	  rÿ  r   )r*  r	  r	  r	  r	  r 	  r  s          rˆ   Úreload_model_cost_mapr  ªC  sq  è ø€ ð  ×"Ñ"Ô&6×&BÑ&BÒBÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð
(]äÐ Ü¨CÐ8[Ô\Ð\÷	
ñ
 5¼×9SÑ9SÔT×TˆÜ�mÐ%BÔCÜØØ:¸=×;OÑ;OÐ:PÐPpÐqôð ô
 /¨}×/KÑ/KÓLˆÜ“yˆØ0<ŒÔ-ô >RÜÔ;¸\ó>
÷ 8
ŒÔ4ô 	×!Ñ!Ð"iÐkwÔxð <¸L¸>ÐIYÐZØØ(Ø%×/Ñ/Ó1ñ	
ð 	
ð' Uøð8
ùô ò ØÜò ]Ü×&Ñ&Ð'LÈaÔPÜ¨Ð6WÐXYÐWZÐ4[Ô\Ð\ûð]üsM   ‚8E»5D Á0DÁ1A-D ÃDÃ;D ÄEÄD ÄD ÄEÄ1&EÅEÅEz/schedule/model_cost_map_reloadÚhoursc              ƒ   óÞ  K  — |j                   t        j                  k7  rt        dd|j                   › �¬«      ‚| dk  rt        dd¬«      ‚	 t        €t        dd	¬«      ‚t        t        t        | «      ƒ d{  –—†  t        j                  d
| «       d| › d�d| t        «       j                  «       dœS 7 Œ;# t        $ r+}t        j                  d|«       t        dd|› �¬«      ‚d}~ww xY w­w)zÁ
    ADMIN ONLY / MASTER KEY Only Endpoint

    Schedule periodic reload of the model cost map.
    This will create a background job that reloads the model cost map every specified hours.
    rv  r}  rc  r   rD  úHours must be greater than 0Nrž  r~  z2Model cost map reload scheduled for every %s hoursz*Model cost map reload scheduled for every ú hoursr  ©r�   r±  r
	  r/	  z,Failed to schedule model cost map reload: %sz*Failed to schedule model cost map reload: )rj  rP   r  r¨  r÷  r  rú   rŸ   r  r  r	  rÿ  r   ©r€  r*  r  s      rˆ   Úschedule_model_cost_map_reloadr†  ëC  s  è ø€ ð" ×"Ñ"Ô&6×&BÑ&BÒBÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð
 �‚zÜ¨Ð4RÔSÐSð
äÐ Ü¨CÐ8[Ô\Ð\ä#¤MÔ3SÐUZÓ[×[Ð[ä×!Ñ!Ð"VÐX]Ô^ð DÀEÀ7È&ÐQØØ#Ü ›×,Ñ,Ó.ñ	
ð 	
ð	 	\ùô ò 
Ü×&Ñ&Ð'UÐWXÔYÜØØ?À¸sÐCô
ð 	
ûð
üs<   ‚A
C-Á+B6 Á8B4Á9:B6 Â3C-Â4B6 Â6	C*Â?&C%Ã%C*Ã*C-c              ƒ   ó¬  K  — | j                   t        j                  k7  rt        dd| j                   › �¬«      ‚	 t        €t        dd¬«      ‚t        t        t        «      ƒ d{  –—†  t        j                  d«       ddt        «       j                  «       d	œS 7 Œ5# t        $ r+}t        j                  d
|«       t        dd|› �¬«      ‚d}~ww xY w­w)zp
    ADMIN ONLY / MASTER KEY Only Endpoint

    Cancel the scheduled periodic reload of the model cost map.
    rv  r}  rc  Nrž  r~  z(Model cost map reload schedule cancelledr  ©r�   r±  r/	  z*Failed to cancel model cost map reload: %sz(Failed to cancel model cost map reload: )rj  rP   r  r¨  r÷  rû   rú   rŸ   r  r  r	  rÿ  r   ©r*  r  s     rˆ   Úcancel_model_cost_map_reloadrŠ  D  sÜ   è ø€ ð ×"Ñ"Ô&6×&BÑ&BÒBÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð
däÐ Ü¨CÐ8[Ô\Ð\ä#¤MÔ3SÓT×TÐTä×!Ñ!Ð"LÔMð BØÜ ›×,Ñ,Ó.ñ
ð 	
ð	 	Uùô ò dÜ×&Ñ&Ð'SÐUVÔWÜ¨Ð6^Ð_`Ð^aÐ4bÔcÐcûðdüs:   ‚8C»*B Á%BÁ&4B ÂCÂB Â	CÂ&&CÃCÃCz&/schedule/model_cost_map_reload/statusc              ƒ   ó^  K  — t        | «      st        dd| j                  › �¬«      ‚	 t        € t	        j
                  d«       t        d«      S t        t        t        t        «      ƒ d{  –—† «      S 7 Œ# t        $ r+}t	        j                  d|«       t        dd|› �¬«      ‚d}~ww xY w­w)	zo
    ADMIN ONLY / MASTER KEY Only Endpoint

    Get the status of the scheduled model cost map reload job.
    rv  r}  rc  Nú/No database connection, returning not scheduledz.Failed to get model cost map reload status: %srž  z,Failed to get model cost map reload status: )r1  r¨  rj  r÷  rŸ   r  r   rý   rú   rÿ  r   r‰  s     rˆ   Ú get_model_cost_map_reload_statusr�  DD  s¯   è ø€ ô  Ð 1Ô2ÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð

ô Ð Ü ×%Ñ%Ð&WÔXÜ)¨$Ó/Ð/ä%Ô,@ÄÔPpÓ,q×&qÓrÐrÐ&qùÜò 
Ü×&Ñ&Ð'WÐYZÔ[ÜØØAÀ!ÀÐEô
ð 	
ûð
üsF   ‚&B-©%A6 ÁB-ÁA6 Á+A4Á,A6 Á3B-Á4A6 Á6	B*Á?&B%Â%B*Â*B-z/model/cost_map/sourcec              ƒ   óD  K  — t        | «      st        dd| j                  › �¬«      ‚	 ddlm}  |«       }t
        j                  rt        t
        j                  «      nd}i |¥d|i¥S # t        $ r+}t        j                  d|«       t        dd	|› �¬«      ‚d
}~ww xY w­w)a  
    ADMIN ONLY / MASTER KEY Only Endpoint

    Returns information about where the current model cost/pricing data was loaded from.

    Response fields:
    - source: "local" (bundled backup) or "remote" (fetched from URL)
    - url: the remote URL that was attempted (null when env-forced local)
    - is_env_forced: true if LITELLM_LOCAL_MODEL_COST_MAP=True forced local usage
    - fallback_reason: human-readable reason why remote failed (null on success)
    - model_count: number of models in the currently loaded cost map
    rv  r}  rc  r   )Úget_model_cost_map_source_infoÚmodel_countz,Failed to get model cost map source info: %srž  z*Failed to get model cost map source info: N)r1  r¨  rj  rf  r�  r  rO  rÈ  rÿ  rŸ   r   )r*  r�  Úsource_infor�  r  s        rˆ   Úget_model_cost_map_sourcer’  iD  s»   è ø€ ô,  Ð 1Ô2ÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð

õ	
ñ <Ó=ˆÜ8?×8JÒ8JœS¤×!3Ñ!3Ô4ÐPQˆð
Øð
à˜;ñ
ð 	
øô ò 
Ü×&Ñ&Ð'UÐWXÔYÜØØ?À¸sÐCô
ð 	
ûð
üs(   ‚&B ©?A) Á(B Á)	BÁ2&BÂBÂB z/reload/anthropic_beta_headersc           
   ƒ   ót  K  — | j                   t        j                  k7  rt        dd| j                   › �¬«      ‚	 t        €t        dd¬«      ‚ddlm}  |«       }t        j                  «       }|j                  «       a
t        t        «      j                  d	d
i¬«      ƒ d{  –—† }d}|r'|j                  r|j                  j                  d«      }t        t        «      j                   j#                  d	d
id
t%        dddœ«      dœdt%        |ddœ«      idœ¬«      ƒ d{  –—†  t'        d
«      ƒ d{  –—†  t)        d„ |D «       «      }t+        j,                  d|«       d|› d�d||j                  «       dœS 7 Œ×7 ŒZ7 ŒI# t.        $ r+}t+        j0                  d|«       t        dd|› �¬«      ‚d}~ww xY w­w)zß
    ADMIN ONLY / MASTER KEY Only Endpoint

    Manually reload the Anthropic beta headers configuration from the remote source.
    This will fetch fresh configuration from the anthropic_beta_headers_config.json file.
    rv  r}  rc  Nrž  r~  r   r	  rT  r�  r�  r
	  Tr	  r‘  rU  r’  r”  c              3   ó*   K  — | ]  }|d vsŒd–— Œ y­w))r	  rô  r8  Nrè  r	  s     rˆ   r”  z0reload_anthropic_beta_headers.<locals>.<genexpr>ÕD  s   è ø€ Ò#j¨!¸QÐFiÒ=i¤AÑ#jùs   ‚	ŒzQAnthropic beta headers config reloaded successfully in current pod. Providers: %sz<Anthropic beta headers configuration reloaded successfully! z providers updated.r  )r�   r±  Úproviders_countr/	  z+Failed to reload anthropic beta headers: %sz)Failed to reload anthropic beta headers: )rj  rP   r  r¨  r÷  r	  r	  r
   r	  r	  r	  rw  rÙ  rU  rp  rv  rH  r–  r5   rk  r£  rŸ   r  rÿ  r   )r*  r	  r  r 	  Úexisting_beta_configÚexisting_beta_intervalr	  r  s           rˆ   Úreload_anthropic_beta_headersr˜  œD  s÷  è ø€ ð  ×"Ñ"Ô&6×&BÑ&BÒBÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð
0eäÐ Ü¨CÐ8[Ô\Ð\õ 	Vá6Ó8ˆ
ô 'Ÿo™oÓ/ˆØ-9×-CÑ-CÓ-EÐ*ô EXÔXeÓDf×DrÑDrØÐ!GÐHð Esó E
÷ ?
Ðð "&ÐÙÐ$8×$DÒ$DØ%9×%EÑ%E×%IÑ%IÐJZÓ%[Ð"äœ}Ó-×3Ñ3×:Ñ:ØÐ!GÐHð #IÜ#-ÀÐW[Ñ.\Ó#]ñð )¬*ÐH^ÐptÑ5uÓ*vÐwñð ;ó 	
÷ 		
ð 		
ô &Ð&LÓM×MÐMä #Ñ#j¨zÔ#jÓ jˆÜ×!Ñ!Ø_Ðaoô	
ð
 VÐVdÐUeÐexÐyØØ-Ø%×/Ñ/Ó1ñ	
ð 	
ð1?
øð		
øð 	Nùô ò eÜ×&Ñ&Ð'TÐVWÔXÜ¨Ð6_Ð`aÐ_bÐ4cÔdÐdûðeüsa   ‚8F8»A(F Â#E;Â$A>F Ä"E=Ä#F Ä5E?Ä6AF Å:F8Å;F Å=F Å?F Æ	F5Æ
&F0Æ0F5Æ5F8z'/schedule/anthropic_beta_headers_reloadc           
   ƒ   óŠ  K  — |j                   t        j                  k7  rt        dd|j                   › �¬«      ‚| dk  rt        dd¬«      ‚	 t        €t        dd	¬«      ‚t        t        «      j                  j                  d
didt        | ddœ«      dœdt        | ddœ«      idœ¬«      ƒ d{  –—†  t        d«      ƒ d{  –—†  t        j                  d| «       d| › d�d| t        j                  «       j                  «       dœS 7 ŒX7 ŒG# t        $ r+}t        j                   d|«       t        dd|› �¬«      ‚d}~ww xY w­w)zÖ
    ADMIN ONLY / MASTER KEY Only Endpoint

    Schedule periodic reload of the Anthropic beta headers configuration.
    This will create a background job that reloads the configuration every specified hours.
    rv  r}  rc  r   rD  r‚  Nrž  r~  rT  r�  Fr	  r‘  rU  r’  r”  z:Anthropic beta headers reload scheduled for every %s hoursz2Anthropic beta headers reload scheduled for every rƒ  r  r„  z4Failed to schedule anthropic beta headers reload: %sz2Failed to schedule anthropic beta headers reload: )rj  rP   r  r¨  r÷  rv  rH  r–  r5   rk  rŸ   r  r
   r	  r	  rÿ  r   r…  s      rˆ   Ú&schedule_anthropic_beta_headers_reloadrš  åD  st  è ø€ ð" ×"Ñ"Ô&6×&BÑ&BÒBÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð
 �‚zÜ¨Ð4RÔSÐSð
äÐ Ü¨CÐ8[Ô\Ð\ô œ}Ó-×3Ñ3×:Ñ:ØÐ!GÐHð #IÜ#-ÀÐX]Ñ.^Ó#_ñð )¬*ÈÐ_dÑ5eÓ*fÐgñð ;ó 	
÷ 		
ð 		
ô &Ð&LÓM×MÐMä×!Ñ!Ð"^Ð`eÔfð LÈEÈ7ÐRXÐYØØ#Ü!Ÿ™Ó*×4Ñ4Ó6ñ	
ð 	
ð		
øð 	Nùô ò 
Ü×&Ñ&Ð']Ð_`ÔaÜØØGÈÀsÐKô
ð 	
ûð
üsP   ‚A
EÁA"D Â/DÂ0D ÃD
ÃAD ÄEÄD Ä
D Ä	E Ä&D;Ä;E Å Ec              ƒ   ó  K  — | j                   t        j                  k7  rt        dd| j                   › �¬«      ‚	 t        €t        dd¬«      ‚t        t        «      j                  j                  ddi¬	«      ƒ d{  –—†  t        d«      ƒ d{  –—†  t        j                  d
«       d
dt        j                  «       j                  «       dœS 7 ŒR7 ŒA# t        $ r+}t        j                  d|«       t        dd|› �¬«      ‚d}~ww xY w­w)z†
    ADMIN ONLY / MASTER KEY Only Endpoint

    Cancel the scheduled periodic reload of the Anthropic beta headers configuration.
    rv  r}  rc  Nrž  r~  rT  r�  r�  z0Anthropic beta headers reload schedule cancelledr  rˆ  z2Failed to cancel anthropic beta headers reload: %sz0Failed to cancel anthropic beta headers reload: )rj  rP   r  r¨  r÷  rv  rH  rÑ  rk  rŸ   r  r
   r	  r	  rÿ  r   r‰  s     rˆ   Ú$cancel_anthropic_beta_headers_reloadrœ  !E  s  è ø€ ð ×"Ñ"Ô&6×&BÑ&BÒBÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð

äÐ Ü¨CÐ8[Ô\Ð\ô œ}Ó-×3Ñ3×:Ñ:À,ÐPvÐAwÐ:Óx×xÐxÜ%Ð&LÓM×MÐMä×!Ñ!Ð"TÔUð JØÜ!Ÿ™Ó*×4Ñ4Ó6ñ
ð 	
ð 	yøØMùô ò 
Ü×&Ñ&Ð'[Ð]^Ô_ÜØØEÀaÀSÐIô
ð 	
ûð
üsM   ‚8D
»AC Á<CÁ=C ÂCÂ>C ÃD
ÃC ÃC Ã	DÃ&DÄDÄD
z./schedule/anthropic_beta_headers_reload/statusc              ƒ   óÌ  K  — t        | «      st        dd| j                  › �¬«      ‚	 t        j                  dt
        «       t        €t        j                  d«       dddddœS t        t        «      j                  d	d
i¬«      ƒ d{  –—† }|�|j                  €t        j                  d«       dddddœS |j                  }t        t        dz  |j                  d«      «      }|€t        j                  d«       dddddœS t        j                  «       }d}t
        �T	 t        j                  t
        «      }||z
  }|j!                  «       dz  }||k  r|t#        |¬«      z   j%                  «       }d|t
        |dœS 7 Œõ# t&        $ r }	t        j(                  d|	«       Y d}	~	Œ1d}	~	ww xY w# t&        $ r+}	t        j*                  d|	«       t        dd|	› �¬«      ‚d}	~	ww xY w­w)zw
    ADMIN ONLY / MASTER KEY Only Endpoint

    Get the status of the scheduled Anthropic beta headers reload job.
    rv  r}  rc  z>Checking anthropic beta headers reload status. Last reload: %sNrŒ  F)Ú	scheduledr
	  Úlast_runÚnext_runrT  r�  r�  z4No anthropic beta headers reload configuration foundr
	  z/No interval configured, returning not scheduledr+  )r€  r	  Tz6Failed to get anthropic beta headers reload status: %srž  z4Failed to get anthropic beta headers reload status: )r1  r¨  rj  rŸ   r  r	  r÷  rw  rÙ  rU  r   r"  rp  r
   r	  r	  r	  r   r	  rÿ  r/  r   )
r*  rÅ  r^  r
	  r 	  r   r	  r	  r	  r  s
             rˆ   Ú(get_anthropic_beta_headers_reload_statusr¡  NE  s.  è ø€ ô  Ð 1Ô2ÜØØGÐHY×HcÑHcÐGdÐeô
ð 	
ð
F
ô 	×!Ñ!ØLÔNpô	
ô Ð Ü ×%Ñ%Ð&WÔXà"Ø"&Ø Ø ñ	ð ô &9¼Ó%G×%SÑ%SØÐ!GÐHð &Tó &
÷  
ˆð Ð  M×$=Ñ$=Ð$EÜ ×%Ñ%Ð&\Ô]à"Ø"&Ø Ø ñ	ð ð &×1Ñ1ˆÜ $Ü�$‰J˜Ÿ
™
Ð#3Ó4ó!
ˆð Ð!Ü ×%Ñ%Ð&WÔXà"Ø"&Ø Ø ñ	ð ô 'Ÿo™oÓ/ˆØˆô .Ð9ðVÜ*2×*@Ñ*@ÔAcÓ*dÐ Ø0<Ð?OÑ0OÐ&Ø1G×1UÑ1UÓ1WÐZ^Ñ1^Ð'à*¨^Ò;Ø 0´9À>Ô3RÑ R×]Ñ]Ó_�Hð
 Ø,Ü:Ø ñ	
ð 	
ðU 
ùôN ò VÜ$×,Ñ,Ð-QÐST×UÑUûðVûô ò 
Ü×&Ñ&Ð'_ÐabÔcÜØØIÈ!ÈÐMô
ð 	
ûð
üsŠ   ‚&G$©;F- Á$G$Á%$F- Â	E?Â
-F- Â7G$Â8AF- ÄG$ÄF- Ä!AF Å4
F- Å>G$Å?F- Æ	F*Æ
F%Æ F- Æ%F*Æ*F- Æ-	G!Æ6&GÇG!Ç!G$)rŽ  c              ƒ   ó   K  — y­w)NzLiteLLM: RUNNINGrè  rÍ  s    rˆ   Úhomer£  ¬E  s	   è ø€ àùs   ‚z/adaptive_router/stateÚadaptive_routerc              ƒ   óx  K  — t        | «      s't        ddt        j                  j                  i¬«      ‚t
        �t
        j                  st        dddi¬«      ‚t
        j                  j                  «       D ��cg c]+  }|D ]$  }|j                  j                  «       ƒ d{  –—† ‘Œ& Œ- }}}d|iS 7 Œc c}}w ­w)uU  Return live bandit posteriors + queue depth for every configured adaptive router.

    Admin-only. Returns 404 if no adaptive router is configured.

    Response shape: `{"routers": [<snapshot>, ...]}` â€” one snapshot per
    adaptive-router deployment. Each snapshot's `router_name` field identifies
    which deployment it came from.
    rv  rz  rc  Nr»  z/No adaptive_router is configured on this proxy.Úrouters)
r1  r¨  r:   rø  r*  rU  rh  r¢  r£  Úget_state_snapshot)r*  r±  r²  Ú	snapshotss       rˆ   Úget_adaptive_router_stater©  ±E  sÌ   è ø€ ô"  Ð 1Ô2ÜØØÔ.×AÑA×GÑGÐHô
ð 	
ô Ð¤×!<Ò!<ÜØØÐNÐOô
ð 	
ô )×9Ñ9×@Ñ@ÓB÷àØ$òð ð �o‰o×0Ñ0Ó2×2Ñ2ðØ2ð€Iñ ð
 �yÐ!Ð!ð	 	3úóùs*   ‚A9B:Á;'B4Â"B2Â#B4Â+B:Â2B4Â4B: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)r¿  Úendpoint_router3  ry   )r¿  r  )	Ú%litellm.proxy.common_utils.get_routesr«  r3  r  rw  r|  Úget_app_routesr¬  Úget_routes_for_mounted_app)r«  r  r¿  r¬  s       rˆ   Ú
get_routesr°  ÔE  s›   è ø€ õ
 @à€FÜ—‘ò MˆÜ  ¨
°DÓ9ˆØÐ%Ø�M‰MØ×(Ñ(ØØ#1ð )ó õô �U˜EÕ"¤w¨u°fÕ'=Ø�M‰M˜)×>Ñ>ÀUÐ>ÓKÕLðMð �fÐÐùs   ‚ABÁBÁ*'Bc                  ó,   — t         j                  d«      S )NrÙ  r_  rè  rŠ   rˆ   rü  rü  ?F  s   € Ô$4×$8Ñ$8Ð9NÓ$O€ rŠ   c                  ó   — t         du S )NT)rÄ  rè  rŠ   rˆ   rü  rü  @F  s   € ¬,¸$Ð*>€ rŠ   )Úget_max_request_size_mbÚis_request_size_limit_enabledr»  c              ƒ   ó¼  ‡‡‡K  — ddl m} t        j                  «       j	                  «       Št        j
                  d¬«      Šˆˆfd„}t        j                   | |||«      «      Šdt        j                  ddfˆˆfd	„}‰j                  |«       	 t        j                  t        j                  ‰«      d
¬«      ƒ d{  –—† \  }}|D ��	ci c]&  \  }}	|j                  d«      |	j                  d«      “Œ( }
}}	ˆˆfd„} | |«       ||
|
j                  d«      ¬«      S 7 Œ`# t        j                  $ r ‰j                  «        t        dd¬«      ‚w xY wc c}	}w ­w)zû
    Call an ASGI MCP handler and return a StreamingResponse so SSE/streaming works.

    asyncio.create_task copies the current context, so any ContextVar set before
    this call (e.g. _mcp_active_toolset_id) is visible inside the handler task.
    r   )r»  r_  rF  c              “   ót  •K  — | d   dk(  rE‰j                  «       s4‰j                  | j                  dd«      | j                  dg «      f«       y y | d   dk(  rZ| j                  dd«      }|r‰j                  |«      ƒ d {  –—†  | j                  d	d
«      s‰j                  d «      ƒ d {  –—†  y y y 7 Œ27 Œ	­w)Nrw   zhttp.response.startr±  rÊ  r9  zhttp.response.bodyr	  rŠ   Ú	more_bodyF)rF
  Ú
set_resultrp  rÍ  )r�   rÍ	  Ú
body_queueÚheaders_readys     €€rˆ   Úbridging_sendz0_stream_mcp_asgi_response.<locals>.bridging_sendPF  sµ   øè ø€ Ø�6‰?Ð3Ò3Ø ×%Ñ%Ô'Ø×(Ñ(¨'¯+©+°hÀÓ*DÀgÇkÁkÐR[Ð]_ÓF`Ð)aÕbð (à�V‰_Ð 4Ò4Ø"Ÿ;™; v¨sÓ3ˆEÙØ —n‘n UÓ+×+Ð+Ø—;‘;˜{¨EÔ2Ø —n‘n TÓ*×*Ñ*ð 3ð	 5ð ,øà*ús$   ƒA>B8ÂB4Â*B8Â,B6Â-B8Â6B8ÚtaskrÐ  Nc                 óÔ   •— | j                  «       r‰j                  d «       y | j                  «       }|�3‰j                  «       s‰j	                  |«       ‰j                  d «       y y rn  )Ú	cancelledÚ
put_nowaitr   rF
  Úset_exception)r¼  Útask_exceptionr¹  rº  s     €€rˆ   Ú_ensure_eofz._stream_mcp_asgi_response.<locals>._ensure_eofbF  s]   ø€ Ø�>‰>ÔØ×!Ñ! $Ô'Øà $§¡Ó 0ˆØÐ%Ø ×%Ñ%Ô'Ø×+Ñ+¨NÔ;Ø×!Ñ! $Õ'ð &rŠ   g      >@rA
  iø  z#MCP handler did not respond in timerc  zlatin-1c                 óö  •K  — 	 	 ‰j                  «       ƒ d {  –—† } | €n| ­–— Œ!	 ‰j                  «       sG‰j                  «        t        j                  t
        j                  «      5  ‰ƒ d {  –—†  d d d «       y y 7 Œf7 Œ# 1 sw Y   y xY w# ‰j                  «       sT‰j                  «        t        j                  t
        j                  «      5  ‰ƒ d {  –—†7   d d d «       w # 1 sw Y   w xY ww xY w­wrn  )rp  rF
  rG
  Ú
contextlibÚsuppressrP  r°  )rÍ	  r¹  Úhandler_tasks    €€rˆ   Ú	body_iterz,_stream_mcp_asgi_response.<locals>.body_iterwF  sè   øè ø€ ð
	'ØØ(Ÿn™nÓ.×.�Ø�=ØØ“ð	 ð ð  ×$Ñ$Ô&Ø×#Ñ#Ô%Ü×(Ñ(¬×)?Ñ)?Ó@ñ 'Ø&×&Ð&÷'ð 'ð 'ð /øð 'ø÷'ð 'ûð  ×$Ñ$Ô&Ø×#Ñ#Ô%Ü×(Ñ(¬×)?Ñ)?Ó@ñ 'Ø&×&Ñ&÷'÷ 'ñ 'úð 'üs{   ƒC9…B ™B šB ¨AC9Á+BÁ1BÁ2BÁ6
C9Â B ÂBÂBÂ	C9ÂAC6ÃC)ÃC
ÃC)Ã 	C6Ã)C2Ã.C6Ã6C9zcontent-type)r7  r9  ræ  )Ústarlette.responsesr»  rP  Úget_running_loopÚcreate_futureÚQueuer‡  ÚTaskÚadd_done_callbackÚwait_forÚshieldÚTimeoutErrorrG
  r¨  r
  rp  )Ú	handle_fnr”  Úreceiver»  r»  rÂ  r±  Úraw_headersrF  rG  Úheaders_dictrÇ  r¹  rÆ  rº  s               @@@rˆ   Ú_stream_mcp_asgi_responserÕ  DF  s=  úè ø€ õ 6ä+2×+CÑ+CÓ+E×+SÑ+SÓ+U€MÜ'.§}¡}¸TÔ'B€Jõ	+ô "×-Ñ-©i¸¸wÈÓ.VÓW€Lð	(œ'Ÿ,™,ð 	(¨4ö 	(ð ×"Ñ" ;Ô/ð[Ü$+×$4Ñ$4´W·^±^ÀMÓ5RÐ\`Ô$a×aÑˆ�ð
 Q\×\ÉÈÈ1˜1Ÿ8™8 IÓ.°·±¸Ó0CÑCÐ\€LÑ\õ'ñ Ù‹ØØØ×#Ñ# NÓ3ô	ð ð) bùÜ×Ñò [Ø×ÑÔÜ¨Ð4YÔZÐZð[üó ]ùs<   …BEÂ-D" Â?D Ã D" ÃEÃ+EÃ7)EÄ D" Ä"1EÅ	E)ÚGETrv   ÚPUTÚDELETEÚPATCHÚOPTIONSÚHEAD)rÇ  c              ƒ   óò   K  — ddl m}  |«       st        dd¬«      ‚ddlm} t        | j                  «      }|j                  dd«      |d	<   t        |d<   t        ||| j                  «      ƒ d
{  –—† S 7 Œ­w)zÁServe the aggregate MCP endpoint on the bare ``/mcp`` spelling: the
    ``/mcp`` mount cannot match its bare prefix, and the resulting 307 breaks
    MCP clients behind TLS-terminating proxies.r   rl	  r»  z	Not Foundrc  ©Úhandle_streamable_http_mcpry   r6  Ú_original_pathN)rp	  rm	  r¨  Ú-litellm.proxy._experimental.mcp_server.serverrÞ  rÔ  r”  rp  r*   rÕ  rÒ  )r3  rm	  rÞ  r”  s       rˆ   Úaggregate_mcp_routerá  ‘F  sm   è ø€ õ NáÔÜ¨°KÔ@Ð@õô �—‘Ó€EØ#Ÿi™i¨°Ó3€EÐ
ÑÜ"€Eˆ&�MÜ*Ð+EÀuÈgÏoÉoÓ^×^Ð^Ð^ús   ‚A.A7Á0A5Á1A7z/toolset/{toolset_name}/mcpÚtoolset_namec              ƒ   óH  K  — 	 ddl m} ddlm}m} t
        €t        dd¬«      ‚|j                  t
        | «      ƒ d{  –—† }|€t        dd	| › d
�¬«      ‚t        |j                  «      }d|d<   |j                  |j                  «      }	 t        |||j                  «      ƒ d{  –—† |j                  |«       S 7 Œ}7 Œ# |j                  |«       w xY w# t        $ r}|‚d}~wt        $ r2}t!        j"                  d| t%        |«      «       t        dd¬«      ‚d}~ww xY w­w)a?  
    Namespace a toolset as its own MCP endpoint.

    Connecting to /toolset/<name>/mcp exposes exactly the tools defined in
    the toolset. Access is enforced: non-admin API keys must have the toolset
    listed in their object_permission.mcp_toolsets grant list, or the request
    will be rejected with a 403.
    r   rž  ©Ú_mcp_active_toolset_idrÞ  Nr²  zDatabase not availablerc  r»  z	Toolset 'ú' not foundú/mcpry   z+Error handling toolset MCP route for %s: %srž  rŸ  )r§  rŸ  rà  rå  rÞ  r÷  r¨  Úget_toolset_by_name_cachedrÔ  r”  rð  Ú
toolset_idrÕ  rÒ  Úresetrÿ  rŸ   r   r‚  )	râ  r3  rŸ  rå  rÞ  Útoolsetr”  r”  r  s	            rˆ   Útoolset_mcp_routerì  ªF  s!  è ø€ ð Mõ	
÷	
ô
 Ð Ü¨CÐ8PÔQÐQà8×SÑSÔTaÐcoÓp×pˆØˆ?ÜØØ" < .°Ð<ôð ô
 ˜GŸM™MÓ*ˆØˆˆf‰à-×1Ñ1°'×2DÑ2DÓEˆð	0Ü2Ð3MÈuÐV]×VeÑVeÓf×fà"×(Ñ(¨Õ/ð qøð gùà"×(Ñ(¨Õ/ûäò ØˆûÜò MÜ×&Ñ&Ð'TÐVbÔdgÐhiÓdjÔkÜ¨Ð4KÔLÐLûðMüso   ‚D"„:C ¾B<¿AC ÂC  Â&B>Â'C  Â*C Â;D"Â<C Â>C  Ã CÃC Ã	DÃC!Ã!DÃ--DÄDÄD"Úpath_segmentc              ƒ   ó¼   K  — ddl m} t        |j                  «      }|j	                  dd«      |d<   d| › �|d<   t        |||j                  «      ƒ d{  –—† S 7 Œ­w)z<Rewrite path to /mcp/{path_segment} and stream the response.r   rÝ  ry   r6  rß  z/mcp/N)rà  rÞ  rÔ  r”  rp  rÕ  rÒ  )rí  r3  rÞ  r”  s       rˆ   Ú_mcp_forward_as_pathrï  ÚF  s[   è ø€ õô ˜Ÿ™Ó&€Eà#Ÿi™i¨°Ó3€EÐ
ÑØ˜L˜>Ð*€Eˆ&�MÜ*Ð+EÀuÈgÏoÉoÓ^×^Ð^Ð^ús   ‚AAÁAÁAÚcsv_segmentÚ	client_ipc              ƒ   ó¦  K  — ddl m} ddlm} t	        «       }g }| j                  d«      D ]K  }|j                  «       }|r||v rŒ|j                  |«       |j                  |«       t        |«      |k\  sŒK n g }|D ]L  }|j                  ||¬«      r|j                  |«       Œ(t        |«      ƒ d{  –—† sŒ<|j                  |«       ŒN |S 7 Œ­w)u´  Validate a comma-separated ``/{name1,name2,...}/mcp`` segment.

    For each token, check (in order) whether it is a registered MCP server
    alias / name or an MCP access group tag (cached). Tokens are stripped,
    deduped (exact-match, keeping first occurrence in original order), and
    capped at ``DEFAULT_MCP_NAMESPACE_CSV_MAX_TOKENS`` to bound the
    per-request DB / cache fan-out an authenticated caller can trigger by
    stuffing the path with tokens. Dedup is case-sensitive on purpose:
    downstream resolvers may treat names case-sensitively, so collapsing
    ``MyGroup`` and ``mygroup`` would risk dropping a valid distinct token.

    Toolset names are intentionally NOT resolved here â€” toolsets bind a single
    toolset id into request scope and have no defined semantics inside a
    comma-separated server list.

    Returns the subset of resolved tokens in original order. An empty list
    means the segment did not resolve to any known server / group; the caller
    should treat that as a 404 instead of forwarding it downstream (where an
    all-unmatched server filter falls back to the full ``allowed_mcp_servers``
    list and silently broadens the request scope).
    r   )Ú$DEFAULT_MCP_NAMESPACE_CSV_MAX_TOKENSrž  r7  ©rñ  N)r3  ró  r§  rŸ  rð  rq  rr  rä  rã  rÈ  Úget_mcp_server_by_nameÚ_is_mcp_access_group_cached)	rð  rñ  ró  rŸ  ÚseenÚdedupedrZ
  r”  rK  s	            rˆ   Ú_resolve_mcp_csv_tokensrù  çF  sÕ   è ø€ õ, Gõô “u€DØ "€GØ× Ñ  Ó%ò ˆØ—	‘	“ˆÙ˜ ™ØØ�‰�ŒØ�‰�uÔÜˆw‹<Ð?Ó?Ùðð "$€HØò #ˆØ$×;Ñ;¸EÈYÐ;ÔWØ�O‰O˜EÔ"ØÜ,¨UÓ3×3Ñ3Ø�O‰O˜EÕ"ð#ð €Oð 4ús   ‚A4CÁ7=CÂ4CÂ5CÂ:CrÄ  c              ƒ   ó:  K  — ddl m} ddlm} d| › �}t        j                  |¬«      ƒ d{  –—† }|�t        |«      S t        |j                  | g«      ƒ d{  –—† «      }t        j                  |||rt        t        «      n|¬«      ƒ d{  –—†  |S 7 Œg7 Œ=7 Œ
­w)a   Return True if *name* is a known MCP access group tag.

    Positive results are cached for the configured management-object TTL
    (``get_management_object_ttl(user_api_key_cache)``). Negative results are
    cached for a short
    ``DEFAULT_MCP_ACCESS_GROUP_NEGATIVE_CACHE_TTL`` window so unauthenticated
    callers cannot force a fresh DB lookup per request for unknown names, while
    bounding staleness so a transient DB error (which surfaces as an empty
    list) cannot hide a real group for long.
    r   )Ú+DEFAULT_MCP_ACCESS_GROUP_NEGATIVE_CACHE_TTL)ÚMCPRequestHandlerzmcp_access_group_exists:ry  NrŠ  )
r3  rû  ÚAlitellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcprü  rA  r�  r#  Ú#_get_mcp_servers_from_access_groupsrI  r  )rÄ  rû  rü  r	  r�  rC  s         rˆ   rö  rö  G  s®   è ø€ õ Nõð 2°$°Ð8€IÜ"4×"DÑ"DÈÐ"DÓ"S×S€FØÐÜ�F‹|ÐÜÐ0×TÑTÐVZÐU[Ó\×\Ó]€FÜ
×
,Ñ
,ØØÙ>DÔ&Ô'9Ô:ÐJuð -ó ÷ ð ð
 €Mð Tøð ]øðús3   ‚+B­B®+BÁBÁ4BÂBÂBÂBÂBz/{mcp_server_name}/mcpÚmcp_server_namec              ƒ   óÖ  K  — 	 ddl m} ddlm} |j	                  |«      }|j                  | |¬«      rt        | |«      ƒ d{  –—† S d| v rJt        | |«      ƒ d{  –—† }|st        dd| › d	�¬
«      ‚t        dj                  |«      |«      ƒ d{  –—† S t        �£ddlm}m} |j                  t        | «      ƒ d{  –—† }|�{t        |j                   «      }	|	j#                  dd«      |	d<   d|	d<   |j%                  |j&                  «      }
	 t)        ||	|j*                  «      ƒ d{  –—† |j-                  |
«       S t/        | «      ƒ d{  –—† rt        | |«      ƒ d{  –—† S t        dd| › d�¬
«      ‚7 �Œ47 �Œ7 Œë7 ŒÁ7 ŒW# |j-                  |
«       w xY w7 ŒK7 Œ9# t        $ r}|‚d}~wt0        $ r2}t3        j4                  d| t7        |«      «       t        dd¬
«      ‚d}~ww xY w­w)aD  Handle /{name}/mcp for MCP server aliases, toolsets, MCP access group tags, and comma-separated lists.

    Resolution order:
    1. Registered MCP server alias / name
    2. Comma-separated list (short-circuits before any DB call)
    3. Toolset name (DB lookup, cached)
    4. MCP access group tag (DB lookup, cached)
    r   rž  )ÚIPAddressUtilsrô  Nr7  r»  z,No MCP server, toolset, or access group in 'z' resolved to a known targetrc  rä  ry   r6  rß  rç  z&MCP server, toolset, or access group 'ræ  z+Error handling dynamic MCP route for %s: %srž  rŸ  )r§  rŸ  Ú#litellm.proxy.auth.ip_address_utilsr  Úget_mcp_client_iprõ  rï  rù  r¨  r–  r÷  rà  rå  rÞ  rè  rÔ  r”  rp  rð  ré  rÕ  rÒ  rê  rö  rÿ  rŸ   r   r‚  )rÿ  r3  rŸ  r  rñ  Úresolved_tokensrå  rÞ  rë  r”  r”  r  s               rˆ   Údynamic_mcp_router  5G  s   è ø€ ð:Mõ	
õ 	Gà)×;Ñ;¸GÓDˆ	ð %×;Ñ;¸OÐW`Ð;ÔaÜ-¨o¸wÓG×GÐGð �/Ñ!Ü+BÀ?ÐT]Ó+^×%^ˆOÙ"Ü#Ø #àFÀÐFWÐWsÐtôð ô .¨c¯h©h°Ó.GÈÓQ×QÐQô Ð$÷ð
 $=×#WÑ#WÔXeÐgvÓ#w×wˆGØÐ"Ü# G§M¡MÓ2�Ø*/¯)©)°F¸BÓ*?�Ð&Ñ'Ø &��f‘Ø5×9Ñ9¸'×:LÑ:LÓM�ð8Ü!:Ð;UÐW\Ð^e×^mÑ^mÓ!n×nà*×0Ñ0°Õ7ô -¨_Ó=×=Ð=Ü-¨o¸wÓG×GÐGäØØ;¸OÐ;LÈKÐXô
ð 	
ðO Hùð &_ùð Røð xøð oùà*×0Ñ0°Õ7úð >øØGùô ò ØˆûÜò MÜ×&Ñ&Ð'TÐVeÔgjÐklÓgmÔnÜ¨Ð4KÔLÐLûðMüsé   ‚G)„?F ÁE7ÁF ÁG)ÁF ÁE:Á5F ÂE=ÂF ÂG)Â'F Â=E?Â>AF ÄF Ä)FÄ*F Ä-F Ä>G)Ä?F ÅFÅF Å!FÅ"F Å%G)Å&F Å:F Å=F Å?F ÆF ÆFÆF ÆF Æ	G&Æ&F(Æ(G&Æ4-G!Ç!G&Ç&G)rl  rn  r£	  )NNNNNF)NNNN)NNNNNNN)NNNNFFNNr¾  NFTTNFFN)rè  )FN)Nr8  r9  NN)rS  )r   (Ž  rP  rÆ  Úenumru  rx  r:  rn  r”   rÂ  rG  rÐ  r$  rY  rd  rÁ  r}  r2  ÚwarningsÚcollections.abcr   r   r   r   r   r   r	   r
   r   r   Útypesr   r   Útypingr   r   r   r   r   r   r   r   r   r   r   r   r   r   Úanyior\  Úwebsockets.exceptionsÚpydanticr   r   r   r<  r    r!   r"   Úlitellm._uuidr#   r3  r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r�  r4   Ú*litellm.litellm_core_utils.safe_json_dumpsr5   Ú*litellm.litellm_core_utils.safe_json_loadsr6   Úlitellm.proxy._typesr7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   Ú/litellm.proxy.common_utils.cache_pydantic_utilsr[   Ú)litellm.proxy.common_utils.callback_utilsr\   r]   r^   r_   Ú)litellm.proxy.common_utils.realtime_utilsra   Ú/litellm.router_utils.add_retry_fallback_headersrb   rc   Ú-litellm.router_utils.auto_router_model_namingrd   re   rf   r[  rg   rh   ri   rj   rk   r  rl   rm   rn   r,  ro   Úfastapi.routingrp   rF  rq   Ú_SpanÚprismars   Úprisma_modelsÚ"litellm.integrations.opentelemetryrt   rz   rÔ  r‚  r\  r!  r‰   ÚfilterwarningsÚUserWarningrŒ   r•  ry   Úinsertrw  rº	  ÚbackoffÚfastapir
  ro  Úapscheduler.schedulers.asyncior�   Úapscheduler.triggers.intervalrŽ   r…  r  r�   r™   rÄ  Úcollectionsrš   r›   Ú	functoolsrœ   r  Úlitellm._redisr�   r»	  rž   rŸ   r    rV  r¡   r¢   Ú#litellm.caching.redis_cluster_cacher£   r¤   r¥   r¦   r§   r¨   r©   rª   r«   r¬   r­   r®   r¯   r°   r±   r²   r³   r´   rµ   r¶   r·   r¸   r¹   Úlitellm.exceptionsrº   Ú%litellm.integrations.custom_guardrailr»   Ú"litellm.integrations.custom_loggerr¼   Ú1litellm.integrations.SlackAlerting.slack_alertingr½   Ú0litellm.litellm_core_utils.agentic_loop_settingsr¾   Ú#litellm.litellm_core_utils.asyncifyr¿   Ú'litellm.litellm_core_utils.core_helpersrÀ   rÁ   Ú.litellm.litellm_core_utils.credential_accessorrÂ   rÃ   ÚLiteLLMLoggingObjÚ*litellm.litellm_core_utils.realtime_errorsrÄ   rÅ   Ú0litellm.litellm_core_utils.sensitive_data_maskerrÆ   rÇ   r-  rÈ   rÉ   Ú&litellm.llms.vertex_ai.vertex_llm_baserÊ   r%  rË   Ú5litellm.proxy.analytics_endpoints.analytics_endpointsrÎ   Úanalytics_routerÚlitellm.proxy.auth.auth_checksrÏ   rÐ   rÑ   rÒ   Úlitellm.proxy.auth.auth_utilsrÓ   rÔ   rÕ   Ú(litellm.proxy.auth.fallback_model_accessrÖ   Úlitellm.proxy.auth.handle_jwtr×   Ú"litellm.proxy.auth.litellm_licenserØ   rª  rÙ   rÚ   rÛ   rÜ   rÝ   rÞ   Ú$litellm.proxy.auth.user_api_key_authrß   rà   rá   Ú)litellm.proxy.batches_endpoints.endpointsÚbatches_routerÚlitellm.proxy.caching_routesÚcaching_routerÚ'litellm.proxy.common_request_processingrâ   rã   rä   rå   ræ   rç   Ú9litellm.proxy.common_utils.auth_cache_invalidation_pubsubrè   ré   Ú-litellm.proxy.common_utils.config_sync_pubsubrê   Ú&litellm.proxy.common_utils.debug_utilsrë   Údebugging_endpoints_routerÚ0litellm.proxy.common_utils.encrypt_decrypt_utilsrì   rí   Ú/litellm.proxy.common_utils.healthy_model_filterrî   rï   Ú.litellm.proxy.common_utils.html_forms.ui_loginrð   Ú-litellm.proxy.common_utils.http_parsing_utilsrñ   rò   ró   rô   Ú,litellm.proxy.common_utils.load_config_utilsrõ   rö   Ú,litellm.proxy.common_utils.model_deprecationr÷   Ú.litellm.proxy.common_utils.model_listing_utilsrø   Ú0litellm.proxy.common_utils.openai_endpoint_utilsrù   Ú3litellm.proxy.common_utils.periodic_reload_schedulerú   rû   rü   rý   rþ   rÿ   r   r  r  Ú&litellm.proxy.common_utils.proxy_stater  Ú+litellm.proxy.common_utils.reset_budget_jobr  Ú0litellm.proxy.common_utils.scheduled_job_staggerr  r  r  r  Ú(litellm.proxy.common_utils.swagger_utilsr	  rf  r
  r  Ú-litellm.proxy.common_utils.user_api_key_cacher  r  r  r  r  r  Úlitellm.proxy.config_resolversr  Ú'litellm.proxy.config_resolvers.alertingr  r  r  Ú+litellm.proxy.container_endpoints.endpointsÚcontainer_routerÚ,litellm.proxy.credential_endpoints.endpointsÚcredential_routerrS  r  r  Ú?litellm.proxy.db.db_transaction_queue.window_spend_update_queuer  Ú"litellm.proxy.db.exception_handlerr  r  Ú)litellm.proxy.db.gateway_request_trackingr  r  Ú'litellm.proxy.db.proxy_worker_heartbeatr  r  Ú%litellm.proxy.db.spend_counter_reseedr  Ú!litellm.proxy.discovery_endpointsr   Ú-litellm.proxy.fine_tuning_endpoints.endpointsÚfine_tuning_routerr!  Ú(litellm.proxy.google_endpoints.endpointsÚgoogle_routerÚ(litellm.proxy.guardrails.init_guardrailsr"  r#  rœ  r$  r%  r&  r'  r~  Ú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.list_api.commonr+  r,  r-  Ú$litellm.proxy.litellm_pre_call_utilsr.  Ú7litellm.proxy.logging_endpoints.callback_logs_endpointsr/  Ú8litellm.proxy.management_endpoints.auto_router_endpointsÚauto_router_management_routerÚ>litellm.proxy.management_endpoints.budget_management_endpointsÚbudget_management_routerr¾  Úcache_settings_routerÚ@litellm.proxy.management_endpoints.callback_management_endpointsÚ$callback_management_endpoints_routerr¥  r0  r1  r2  Ú?litellm.proxy.management_endpoints.coordination_redis_endpointsr3  Ú"coordination_redis_settings_routerÚ9litellm.proxy.management_endpoints.cost_tracking_settingsÚcost_tracking_settings_routerÚ5litellm.proxy.management_endpoints.customer_endpointsÚcustomer_routerÚ@litellm.proxy.management_endpoints.fallback_management_endpointsÚfallback_management_routerÚ<litellm.proxy.management_endpoints.gateway_request_endpointsÚgateway_request_routerÚ:litellm.proxy.management_endpoints.internal_user_endpointsÚinternal_user_routerr4  Ú;litellm.proxy.management_endpoints.key_management_endpointsr5  r6  r7  Úkey_management_routerÚ0litellm.proxy.management_endpoints.management_v1Úmanagement_v1_routerÚ7litellm.proxy.management_endpoints.management_v1.commonr8  ÚJlitellm.proxy.management_endpoints.model_access_group_management_endpointsÚ$model_access_group_management_routerÚ=litellm.proxy.management_endpoints.model_management_endpointsr9  r:  r;  r<  Úmodel_management_routerÚ9litellm.proxy.management_endpoints.organization_endpointsÚorganization_routerÚ<litellm.proxy.management_endpoints.router_settings_endpointsÚrouter_settings_routerÚ;litellm.proxy.management_endpoints.tag_management_endpointsÚtag_management_routerÚ:litellm.proxy.management_endpoints.team_callback_endpointsÚteam_callback_routerÚ1litellm.proxy.management_endpoints.team_endpointsÚteam_routerr=  r>  r2  r?  Úui_sso_routerÚAlitellm.proxy.management_endpoints.user_agent_analytics_endpointsÚuser_agent_analytics_routerÚ@litellm.proxy.management_endpoints.workflow_management_endpointsÚworkflow_management_routerrb  r@  rA  Ú9litellm.proxy.management_helpers.team_metadata_validationrB  rC  rD  Ú%litellm.proxy.memory.memory_endpointsÚmemory_routerÚ<litellm.proxy.middleware.billable_request_metrics_middlewarerE  rF  Úlitellm.proxy.plugin_routesrG  Úplugin_routerÚ6litellm.types.proxy.management_endpoints.management_v1rH  Ú0litellm.proxy.enterprise_billing.billing_metricsrI  Ú_build_billing_metrics_recorderrJ  Ú"_shutdown_billing_metrics_recorderÚ6litellm.proxy.middleware.in_flight_requests_middlewarerK  Ú3litellm.proxy.middleware.prometheus_auth_middlewarerL  Ú6litellm.proxy.middleware.request_size_limit_middlewarerM  Ú4litellm.proxy.middleware.security_headers_middlewarerN  Ú%litellm.proxy.ocr_endpoints.endpointsÚ
ocr_routerÚ4litellm.proxy.openai_files_endpoints.files_endpointsÚopenai_files_routerrO  Ú>litellm.proxy.pass_through_endpoints.llm_passthrough_endpointsrP  rQ  rR  Úllm_passthrough_routerr’	  rS  Úpass_through_routerÚlitellm.proxy.public_endpointsÚpublic_endpoints_routerÚ(litellm.proxy.public_endpoints.public_v1Úpublic_v1_routerÚ%litellm.proxy.rag_endpoints.endpointsÚ
rag_routerÚ(litellm.proxy.rerank_endpoints.endpointsÚrerank_routerÚ.litellm.proxy.response_api_endpoints.endpointsÚresponse_routerr§
  rT  Ú(litellm.proxy.search_endpoints.endpointsÚsearch_routerÚ0litellm.proxy.shutdown.graceful_shutdown_managerrU  ræ  rV  Ú7litellm.proxy.spend_tracking.spend_management_endpointsÚspend_management_routerÚ1litellm.proxy.spend_tracking.spend_tracking_utilsrW  Úlitellm.proxy.types_utils.utilsrX  rÃ
  Úui_crud_endpoints_routerÚ5litellm.proxy.ui_crud_endpoints.user_banner_endpointsÚuser_banner_endpoints_routerrþ  rY  rZ  r[  r\  r]  r^  r_  r`  ra  rb  rc  rd  re  rf  rg  rh  ri  rj  rk  rl  rm  rn  ro  rp  Ú'litellm.proxy.video_endpoints.endpointsÚvideo_routerÚ$litellm.repositories.base_repositoryrq  Ú+litellm.repositories.credentials_repositoryrr  Ú%litellm.repositories.prisma_protocolsrs  Úlitellm.routerrt  ru  rv  rw  Úlitellm.schedulerrx  ry  Ú*litellm.secret_managers.aws_secret_managerrz  Ú"litellm.secret_managers.google_kmsr{  r«
  r|  r}  r~  r  r€  r�  Ú)litellm.types.integrations.slack_alertingr‚  rƒ  Úlitellm.types.llms.anthropicr„  r…  r†  r‡  Úlitellm.types.llms.openairˆ  r‰  rŠ  r‹  Ú+litellm.types.proxy.control_plane_endpointsrŒ  ÚClitellm.types.proxy.management_endpoints.model_management_endpointsr�  Ú/litellm.types.proxy.management_endpoints.ui_ssorŽ  r�  Ú%litellm.types.proxy.model_deprecationr�  r‘  Úlitellm.types.realtimer’  r\  r“  r”  r•  r–  r—  r˜  r™  rç  Úlitellm.types.schedulerrš  Ú"litellm.types.secret_managers.mainr›  rœ  r�  rž  rŸ  r   ÚModelMapInfor¡  Úlitellm._versionr¢  rÿ  Úsuppress_debug_inform  r£  r¤  r¥  r¦  r§  r¨  r©  rª  r«  r¬  r­  r®  r¯  r°  r±  Úfastapi.encodersr²  Úfastapi.exceptionsr³  Úfastapi.middleware.corsr´  Úfastapi.openapi.docsrµ  Úfastapi.openapi.utilsr¶  r  r·  r¸  r¹  rº  r»  r¼  Úfastapi.securityr½  Úfastapi.security.api_keyr¾  Úfastapi.staticfilesr¿  Úenterprise_routerÚlitellm.proxyrÀ  Ú*litellm_enterprise.proxy.enterprise_routesÚ_enterprise_routerÚ%litellm_enterprise.proxy.proxy_serverrÁ  rÂ  rÃ  r{  r|  rÄ  r#  rû  rÅ  r¨  rÇ  rÈ  rÉ  r@  rÎ  r×  rÙ  r"  rÛ  rÜ  r   rÝ  rÞ  rß  Ú
ui_messagerá  rã  ræ  rø  r  r  rŒ  ÚAddressFamilyÚ
SocketKindr  r  r2  r¾  rÌ  rÓ  rÖ  rð  rÜ  rï  r3  Úlitellm.integrations.otel.mountrù  rú  rû  r  r&  r,  ÚopenapiÚEnumr1  Úexception_handlerr?  r=  rQ  rS  rW  rZ  r^  ra  rh  rl  rs  rw  ry  r�  r„  r‰  rœ  r¡  r®  ÚoriginsÚallow_cors_credentialsrv  r   r  r–  r±  r¹  r²  r¸  r¿  rÈ  rÒ  rÉ  rÔ  Údefault_runtime_ui_pathrÖ  rz  r×  Úis_pre_restructuredrØ  r  r/  r  ÚaccessÚW_OKÚis_writableræ  ÚrootÚdirsrì  rƒ   rï  ré  rW  Úfr9  r8  r  Úmodified_contentr€   ÚUnicodeDecodeErrorrÃ  rÄ  r  rñ  r   Úadd_middlewarer  rð  r  rp  r  r¾	  r¸	  r¹	  rÙ  rÀ	  r¿	  rÂ	  r  r½	  rê  r  rÁ	  rU  r�  ÚLockr   rW  r!  r"  rÏ  ré  rë  r÷  r©  r2  r*  rA  r$  r%  r'  rX  rY  rX  r)  r*  r,  rì  rî  r-  r.  rï  rñ  rò  ró  rô  rÇ	  rõ  rö  rÀ  r/  r¿  rÄ  r0  r1  r  r3  re  rf  r:  rg  r;  rj  r<  r  r™  r4  r‘  r	  rý  r5  r6  r7  rQ  r	  rü  r@  rD  rS  r[  r\  r`  rf  rw  rr  r†  rq  rp  rÞ  rÕ  rÖ  r×  rØ  ré  r¬  r®  r­  rö  r  rÿ  r  r  r÷  r  rQ  r\  rf  rk  Úcompilerl  rv  rƒ  r‰  rª  r¬  r¦  r¡  r×  rß  rã  ræ  rí  r  r  r	  rŠ  r  r  r  r  r$  r0  r:  r=  rC  rH  r7  rR  rY  r[  r~  r§	  rƒ  rÎ	  rÝ	  rá	  rã	  rè	  rî	  rô	  rþ	  r)
  r
  r
  r 
  r
  r'
  r*
  r+
  r,
  r8
  r9
  r:
  r;
  r<
  rJ
  rL
  rY
  r\
  rd
  re
  rm
  rŒ
  r�
  r–
  r™
  rœ
  r…  rm  r¸  rÉ  rÏ  rõ  rÿ  r   r  r&  r4  r?  r@  rE  rK  rd  rj  rm  rÑ  rq  ru  rz  r}  r€  r‹  Ú litellm.llms.base_llm.base_utilsrŒ  Ú'litellm.proxy.db.routing_prisma_wrapperrˆ  Ú&litellm.repositories.config_repositoryrv  Ú%litellm.repositories.model_repositoryr‡  Ú'litellm.repositories.table_repositoriesr�  rë  rŽ  r9	  rØ  rÉ
  Ú$litellm.repositories.team_repositoryr�  Ú$litellm.repositories.user_repositoryr¼
  rž  rª  r¬  r¸  rÁ  rÇ  rÌ  rÑ  rÔ  rß  rê  rñ  rù  rÿ  r  r
  r  r  r  r!  r"  r8  rH  rR  rb  rd  rl  rn  rp  rt  rw  ry  r|  rŒ  r¨  r°  r²  r¶  r‰  rº  r¼  r‹  rÂ  rÌ  rÏ  rÚ  rØ  rã  r  r  r   r;  r?  rK  rO  rr  rw  r{  r~  r‡  r�  r•  r«  r²  rº  r¾  rÀ  rÅ  rÖ  rØ  ré  rñ  r÷  rú  rû  rÕ  r�  r]  r  ÚLitellmTableNamesÚCONFIG_TABLE_NAMEÚAUDIT_ACTIONSrÍ  r  r  r  r  r  r  r"  ÚGeneralSettingsUILiteLLMValuer$  rõ  r1  r3  rö  r;  rK  rM  rU  rÓ  r{  r  r†  rŠ  r�  r’  r˜  rš  rœ  r¡  r£  r©  r°  Úinclude_routerrÕ  Ú	api_routerá  rì  rï  rù  rö  r  rè  rŠ   rˆ   ú<module>r     s\V  ðÜ Û Û Û Û Û 	Û 	Û Û 	Û Û Û Û Û 
Û Û Û Û ß r× rÑ rß 2Ñ 2ß -÷÷ ÷ ÷ ó" Û Û ß /Ñ /ß AÑ Aå ÷÷ ÷ ÷ ó õ$õ BÝ F÷%÷ %÷ %÷ %÷ %÷ %÷ %÷ %÷ %ó %õL G÷ó õ M÷÷ñ ÷
õ ÷ñ ñ Ý%Ý(Ý1Ý.å@à�3‰;�Dà€DØ€Mð ØØñ=Ð   t¨C°¨KÑ'8Ñ!9ó ó#ð #€Ô Ø €× Ò ˜	¨KÕ 8ð
 €ˆ%�‰+Ó Ø ‡‚‡‚��2—7’7—?’? 7Ó+Ô ,ð
UÛãÛÛÛÝ?Ý=ò	Ð �%ó 	òó6 Ý #Ý *Ý ã Û Ý ß XÑ Xß 9Ý A÷÷ ÷ ÷ ÷ ÷ õ0 4Ý IÝ ;Ý Kõõ 9÷õ NÝ S÷÷÷ QÝ =Ý =Ü "÷ð ÷÷ ô ÷÷ ð ÷
 RÐ Qß 4Ð 4ß ;Ð ;÷÷ ÷ ô ÷÷ ð ÷
 OÐ N÷ BÐ A÷÷ ÷ ô ÷ð ÷ Tß NÐ Nß GÐ Gß WÐ W÷ô ÷ô ÷ OÐ N÷÷ ô ÷ô ÷ TÐ Sß RÐ R÷ð ÷
÷ 
÷ 
÷ 
÷ 
ð 
÷ >Ð =ß FÐ F÷÷ ô ÷ EÐ D÷ô ÷÷ ÷ ô ÷ :Ð 9÷÷ ð ÷
 SÐ Rß TÐ T÷ô ÷ð ÷ô ÷ô ÷ô ÷ EÐ Dß KÐ Kß VÐ Vß PÐ Pß LÐ L÷ô ÷÷ ô ÷ UÐ T÷ð ÷ð ÷ IÐ Hß JÐ J÷÷ ð ÷
 MÐ L÷ð ÷ð ÷ð ÷ð ÷ð ÷÷ ð ÷
ð ÷ð ÷ð ÷ð ÷ð ÷ð ÷ð ÷ð ÷÷ ð ÷
ð ÷ð ÷ YÐ X÷ð ÷÷ ô ÷ð ÷ð ÷ð ÷ð ÷ð ÷ TÐ S÷ô ÷ð ÷ NÐ M÷ð ÷ð ÷ô ÷÷ ð ÷
 JÐ I÷ô ÷ð ÷ð ÷ QÐ Pð-÷ð ÷ð ñ TsÑ" H¨S±/ÀDÑ2HÐ-HÑ$IÈDÑ$PÓrÙCeÑ% x°°D°Ñ'9¸DÑ'@Óe÷ð ÷ YÐ X÷ð ÷ð ÷ GÐ F÷ð ÷ð ÷÷ ð ÷
ð ÷ð ÷ð ÷ MÐ Lß OÐ Oß FÐ Fß LÐ Lß TÐ Tß 9Ð 9ß LÐ Lß TÐ Tß SÐ S÷ð ÷ RÐ Qß ;Ð ;÷ð ÷ð ÷÷ ÷ ÷ ÷ ÷ ÷ ÷ ÷ ÷ ÷ ÷ ô ÷4 KÐ Jß BÐ Bß MÐ Mß >Ð >÷÷ ô ÷ 2Ô 1ß CÐ Cß >Ð >÷÷ ÷ ô ÷ SÔ R÷÷ ô ÷÷ ô ÷ LÐ K÷ð ÷ô ÷ô ÷ 7Ð 6÷÷ ÷ ô ÷ >Ð =ß 5Ð 5÷ô ÷ x× wÓ wß 9ß Gðß(Ð(ð #€Õ Ý ÷÷ ÷ ÷ ÷ ÷ ÷ ÷ ÷" .Ð -ß 5Ð 5ß 2Ð 2ß 4Ð 4ß -Ð -÷÷ ÷ ð ÷ &ß 1Ð 1ß 1Ð 1ß +Ð +ò “KÑ ðç(Ð(ð#ßWÐWßKÐKá*ÑÚ<QÓ<SÑÑ2°TÑ9ÓSò
 /Ó0Ñ �%Ó 0Ú“�Ý#×.Ò.Ó0�‰dÓ 0Ý7E×7\Ò7\Ñ �8Ð3Ñ4Ó \Ø=F¸R¿YºYÐGtÓ=uÑ '¨¨s°T©zÑ):Ó uÚ“\�ˆUÓ !Ù2Ó4Ñ �uÓ 4ò 09òó0Ñ % uó ð°S¸4ÀÀYÀÑ;OÑ5OÐRVÑ5Vð Ð[dô ñ* +Ð2Ø/0Ñ'©Ô0â*-Ñ.UÓ*VÑ'àCLÀ2Ç9Â9Ø7óDÑ -¨u°S¸4±ZÑ/@ó ñ 1Ð8Ø7;Ñ-©uÔ;â05Ñ6cÓ0dÑ-á$Ð% SÐ)�ˆÓ )Ù 0Ð1°ÐAÑ �UÓ AÙ+Ð,Ð,?Ð@��Ó @Ø7¹°yð  AJñ  K^ð  J_ð  _`ð  a�
Ù 
ÐTÑ T�
á 
Ð3±NÐ3Cð  D_ð  `ñ  `�
ð yñ ˜ó ö
 ;G�	�—	’	˜,¨Ô6ÈM�ˆÓ Yö ð	 €B‡I‚IØØ
VÑWmÐVnÐnrÑs}Ðr~Ðôð
 AÑAWÐ@XÐX\Ñ]gÐ\hÐ	iñ ˆeó ó!õH]ò (&Ñ1EÈÑ1Lð (&ÐX\ô (&ñV $¡C¨&×*>Ò*>Ñ$>ÁÀf×FWÒFWÑ@WÑY\Ð^aÑchÐioÐqtÐitÑcuÐ$uÑvÑ �)Ó vô@˜i¨uö @ó%ðP ðEB¡7ð EB¨~¸jÑ/Iò EBó ñEBðP
¨ð ¸ô ò	 Ñ �uó 	ð$ .AÀ/Ð,RÑ ˜%¡ C¡™/Ó Rð°Cð ¸Cô ð /3ò,Ø˜˜c˜‘Nð,á ™H t™Oð,ð 
ˆ#ˆsˆ(�^ô,ò^ Ú‹_ÚÓÚ Ó"Ù
ÙÙÙÙ Ù =Øô�÷& CÐ Bâ ‘sÔ á-7«\Ñ # UÓ 9÷
 .ð)Àð )ÐX\ð )Ðaeô )óX(ôVð@ €2‡9‚9‰_™gÓ&©&Ò0¶\Ù �C†Kñ %�C…Kö˜TŸYšYõ ñ ×Ò�~Ó&ñ
©Gñ 
¸.ó 
ó 'ñ
ó#2©gñ #2ÁCñ #2ÉiÐZ^ÑN^ð #2Ðjnõ #2ñL ×ÒÑ(Ó)ñ)¹ñ )ÑFWó )ó *ñ)ö
0�hõ 0ö
1˜(õ 1ö.�Hõ .ö3�Xõ 3ö˜õ ö�Hõ ö*�Hõ *ñ
 D��	Ô Cñ¡¨tÑ 3ð ¹Á_Ñ8Uõ öˆyõ ö!�)õ !ö(�I Uö (ö˜Yõ ñ
 ×ÒÑ-Ó.ñ¹Wñ ÑKaó ó /ññ, ×Ò‘yÓ!ñ±Gñ Á)ó ó "ñò  “�ˆÔ ð $(Ø'+ò$2Ø˜D‘jñ$2à ™*õ$2òN #3Ó"4Ñ �Ñ	ðf	Ø—'’'—/’/ "§'¢'§/¢/±(Ó";Ó<�KØ ŸgšgŸlšl©;¹ÉÓOÑ�eÔOÙ�GÙ"9Ñ˜%Ô9ñ˜sð ¡tõ ñ¨ð ±õ ñ2+¨ð +±õ +ñZ!°ñ !À#ð !É%ÑPTÐVYÐPYÑJZõ !ð0 #˜ŸšÑ#5±rÓ:×@Ò@ÓBÁfÑL�K�ÔLò Ù"7Òá"2Ñà&˜RŸYšYÑ'8Ñ:QÓR�O�UÔRò "Ñ"2Ô3Ø"Ð×"Ò"ÙXÑZjô	
ñ &5Ñ8HÑ%HÑ˜UÔHâÚ5±oÓFÑÚ-©oÓ>‰�UÔ>ò Ò.Ø%Ð ×%Ò%Ñ&GÉÔYÙ%ŠGò Ò!4Ø(Ð ×(Ò(ÙnÙôñ &ŠGð &Ð ×%Ò%Ñ&dÑfuÔvâ7Ñ8HÉ/ÓZ‰N‰G‘Uâá)’ð -Ð$×,Ò,ñ FÙ#ÙÙ$ô	ñ +’ð 	"Ð×!Ò!Ñ"CÑEUÔVÙ"‰ò "¡'Ô*Ø"Ð×"Ò"Ñ#mÑovÔwó Ñ,±Ó3à�b—i’i¡¨¯ªÓ1‰âØ(Ð ×(Ò(ñ CÙõð &- R§W¢W©WÓ%5ò &!Ñ!‘‘d™EÙ %ò %!‘HØ "§¢§¢©T±8Ó <‘Iá×(Ò(ñ
ôð !ð!Ú!¡)©S¹7ÕCð /ÁqÙ&'§f¢f£h™G÷/ñ ,3¯?ª?Ù3Ð4Ù/Ð0ó,Ñ(ñ ,<×+CÒ+CÙDÙ/Ð0Ñ0NÐOó,Ñ(ò
 "¡)©S¹7ÕCð 6ÁqÙŸGšGÑ$4Ô5÷6øñC%!ð&!ñR ‡I‚IÙÚ˜bŸgšgŸlšl©7±GÓ<Õ=Ùñ ô ñ
 ‡I‚IÙÐ
 ¡Ð'Ú˜bŸgšgŸlšl©7±GÓ<Õ=Ùñ ô ñ ‡I‚Iˆe’[©7¸Õ>ÁT�IÔJñ¨Cð °Dõ ð<dÚ5±gÓ>ÑØ�b—i’i¡¨¯ªÓ1‰âØ%Ð ×%Ò%Ñ&aÑcjÕkÚØ(Ð ×(Ò(ñ Ùõò
 '¡wÔ/Ø%Ð ×%Ò%Ñ&EÁwÔOð �gŠg�oŠo˜bŸgšgŸošo©hÓ7Ó8�ñ × Ò ÙÙÙ,Ù�%Ù�%Ø+ñ ô ñ × Ò Ñ+Ô ,ñ × Ò Ù$òò  \ñ/ ô ñ2 × Ò Ñ-Ô .Ù × Ò Ñ,Ô -ôQ<òh Ô â“/�ˆ%Ô !Ø'0 r§y¢yÑ1DÓ'EÑ �5˜˜t™Ñ$Ô EÙ‰s‚?Ñ(Ð4á‡W‚W‰S E�WÓ*ò7ó +ñ7ð �Ø�
Ø�
Ø�ØÑ ØÑ Ø�Ø�ˆUÔ Ø�Ø$(Ñ �s˜T‘zÔ (Ø�ˆuÔ Ø�à �
ˆF�T‰MÔ  Ø"���t‘Ô "ð +˜gŸlšl›nÑ �eÔ ,ØÑ �$Ô Ø<@Ñ ˜d 4¨¨S¨¡>Ñ2°TÑ9Ô @Ù �ˆ%Ô  Ø�ˆuÓ Ø�
ˆC�$‰JÔ Ø�Ø%)�‰|˜dÑ"Ô )Ø48Ñ ˜¡Ñ1Ô 8Ú&5Ù0×DÒD×JÒJõ'Ñ ‘Oô ñ 'Ñ=S×=gÒ=g×=mÒ=mÕnÑ �UÔ nÙ(Ð?ZÕ[Ñ �uÔ [Ú"HÕTfÕ"gÑ ˜%Ô gØ ×  Ò  × 5Ò 5Ñ6NÔ OØ'+Ñ �: Ñ$Ô +Ø?DÑ ˜7¡5™>¨D°©IÑ5¹Ñ<Ô DØ$&Ñ ˜˜S™	Ô &ÙÑ ‘3Ô ØÑ ØÑ ð (-Ñ ¡Ô ,Ø%*Ñ ™dÔ *ØÑ Ø�Ø%)Ñ "Ø#Ñ ØÑ Ø�	ØÑ ØÑ ØÑ Ø>@Ñ �d˜3¡ d¨4°°S°©>Ñ&:Ñ :Ð:Ñ;Ô @Ø&+Ñ #Ø$%Ñ !Ø�€uˆT�{Ô Ø#<Ñ ˜5Ô <Ø3Ñ Ù16��™Ñ'¨$Ñ.Ô 6Ø$EÑ !Ø$EÑ !Ø;Ñ Ø+Ñ Ø'KÑ $ØÑ ØÑ Ú“\�ˆUÔ !ØLPÑ Ñ BÀTÑ IÔ PØÑ ‘4Ô Ø.2Ñ �} tÑ+Ô 2ò &?Ó%@Ñ ˜UÔ @â".ÕBTÕcoÕ"pÑ ‘<Ô pà�ˆeÔ Ø��Ô Ø�	ˆ5Ô à�	ð &*Ñ "ð -1Ñ Ð" TÑ)Ô 0ñ &õ ñ ð ¨4õ ó
±4õ 
ô:Rñ +,Ñ   %Ô +ðJ©õ Jñ¨Cð °Dõ ð,  $Ø%)Ø#'Ø"&Ø$(Ø#(óMØñMáñMñ ˜‘ñMð ˜d™
ñ	Mð
 ˜D‘jñMð ˜4‘ZñMð ˜T‘/ñMñ !ðMñ õMñ`°3ñ Á%ð ÈDõ ñBR°Cð R¸Dõ Rð0 &*Ø#'Ø"&Ø$(ó(Øñ(à˜d™
ñ(ð ˜D‘jñ(ð ˜4‘Zñ	(ð
 ˜T‘/ð(ñ ˆT�\õ(ñV&!°Cñ &!Éð &!ÑSXÑY^Ñ`dÐYdÑSeõ &!ð\ Ø&*Ø"Ø!Ø!Ø*.Ø04óB/Ø�‰:ñB/à�4‰ZñB/ð �4‰ZñB/ñ ˜4‘<ñ	B/ð
 �$‰JñB/ð ˜t™ñB/ð �t‘ñB/ð ˆs‰)�dÑ
ñB/ð �d‘
ñB/ð ! 4™ñB/ð " #™¨Ñ-õB/ñJ !Ø˜t™ñ !á˜4‘<ð !ñ 	ˆ�Xõ !ñF
Ø�t‘ñ
à
ˆs‰)�dÑ
ñ
ñ ñ
ñ ˜s™8ð	
ð
 
õ
ñ<
Ø! &Ñ)ñ
áñ
ñ ˜s™8ð
ð 
õ	
ñ6Ø�$‰Jñáññ ˜s™8ðð 
õ	ñ Øñà˜D ™I‘oññ ññ ˜s™8ð	ð
 
õñ WØñWà˜D ™I‘oñWñ õWñ80
Ø#ñ0
àñ0
ð ˜‰n˜tÑ#ñ0
ð ñ	0
ð
 ˜T‘/ñ0
ñ ñ0
ð �d‘
ñ0
ð ! 4™ð0
ð 
õ0
ñfWØñWàñWð ñWð ˜4‘Zñ	Wð
 ˜T‘/ñWñ õWñ6dØñdà˜D ™I‘oõdñ(Ø˜D ™I‘oðá
õñØñàñð ñð ˜4‘Zñ	ð
 ðñ 
õñ:V°Cð V¹Dõ Vñ.^¨sñ ^¹uõ ^ñ°cñ Áeõ ñ0
°õ 
ð( "óf
Ø�‰:ñf
à�4‰Zñf
ð �t‘ñf
ð �4‰Zñ	f
ñ
 ˜4‘<ñf
ð ˜T‘kñf
ð ˆs‰)�dÑ
õf
ôR	

ð™U T™\õ ð ˜õ ð &˜2Ÿ:š:Ñ&VÓWÑ �5Ô Wñ RØñ Rá�D‰[ñ Rñ ˜4‘Zñ Rð "õ	 RñFð ñð ñ	ð
 õñ<1¨Tñ 1¸tð 1Éõ 1ð" +/óUaØñUaàñUað ! 4™KðUað 
õ	Uañp 24Ñ '¨Ô 3ôWô>m3ö`	™Yõ 	ñ -ñò
KÑ $ e¨D°±e¸CÀ¸H±oÐ1EÑ,FÑ&Gô 
ñ ñ ðLÑ % u¨T°#±u¸SÀ#¸X±Ð2FÑ-GÑ'Hô ñ` ð `©Dõ `ñ" $ s¨I ~Ñ"6ð "¸4õ "ñ(a°3ñ aÀ)ð aÐPYõ añH¨&ð ±T¸D±[õ ñ
¨7°3¸°;Ñ+?ð 
ÀDõ 
ñ1°ZÀ$Ñ5Fð 1È4õ 1ñ°W¸SÀ&¸[Ñ5Ið ÈdÐSVÐX^ÐS^ÑN_õ ñ)¨7°3¸°;Ñ+?ð )ÀJõ )ð&±$õ ð U°:ÀÑ3Dõ Uñ $3¨:ñ $3ÑPTð $3ÐY]õ $3ñN#Øñ#à˜D‘jñ#ð ð#ð 
õ	#ñLLØñLà"ñLð ˜D‘jðLð 
õ	Lñ8°¸¸f¸Ñ1Eð È$õ ñ.P¸7À3ÈÀ;Ñ;Oð PÐTXõ Pñ,
¨$ð 
°4õ 
ñ,Øñà˜D‘jñð ðñ õ	ñ.°ð ¹õ ñ"L sÐ-BÑ'Bð LÁtõ L÷2]6ô ]6ò@m ‹}�ô3ð Ø
ØØØ
ØØØØØØØØØØ	ØØö#FôT3ñ3,À~ñ 3,Ðeiõ 3,ñlG¸Dð GÀSõ Gñ ¡u¡¨tÑ!3ð ¹õ ñ?°$°s¸F°{Ñ2Cð ?Éõ ?ñ'Øð'á
‰4��t‘˜T $ s¨F {Ñ"3Ñ4Ð4Ñ5õ'ñ".à˜$‘Jñ.ð ˜$˜s F˜{Ñ+Ñ,ð.ð 	õ	.ð6 $)Ø/3ô?(àñ?(ð "%ñ?(ð ñ	?(ñ
  ñ?(ñ !ñ?(ð #&¨¡*ð?(ñ ˆ3‘ˆ9Ñõ?(ñDJ!ØðJ!á
ˆT�\õJ!ñZH ið H°C¹%±Kõ HñU¨fð U¹õ UñGÐ'7ð G¹Dõ Gñàñð &ñð ñ	ð
 ðñ ˆ3�ˆ8�_õñ*  s©U¡{ð  °s¹U±{õ  ñ  <Ñ �uÔ ;Ù#2Ñ ˜5Ô 2ñ	2 Cð 	2©E°#¸±*¸c°/Ñ,Bõ 	2ñ "›8Ñ �5Ô #á #Ñ ˜Ô #Ù %Ñ ˜Ô %Ù.>¸rÓ.B���g˜c 6˜kÑ*Ñ+Ô Bñ0Ø˜Ññ0à'¨¨±%¨Ñ8ñ0ñ ð0ð �C˜�IÑõ	0öf  õ  ñ
*Ø˜#˜s˜(Ñ#ñ*Ø/5ð*á $Ñ&õ*ñZ¨ð ±4õ ó)¨W°S¸&°[Ñ-Añ )ÈVð )Ñ_dõ )ñX '*Ñ ˜eÔ )ñ$¨7°3¸°;Ñ+?ð $ÀHÈfÈXÑW\È_ÑD]õ $ðV #ó	h
à%ñh
ð ñh
ñ �t‰^õ	h
ð^ #ó	à%ñð ññ �t‰^õ	ð *,ò  $õ ôYô
÷ lô lñ`% ‡‚‰LªÑ0AÓ(BÐ'CÑK]ÐJ^�Ó_Ù‡‚ÙšWÑ%6Ó7Ð8Ñ@RÐ?Sñ ó ð Ú(/Ñ0AÓ(BØ*/ØØ/4Ø,1Ø$)Ø $ØØ %ò}Ùñ}à%ñ}ñ ! 4™Kñ}ð �4‰Zñ	}ñ
 "&¨¡ñ}ñ # T™kñ}ñ ˜T‘kñ}ð ˜‘:ñ}ð �‰:ñ}ñ ˜‘+ó}óó `ñ}ñ@ ‡‚ÙÚÑ+Ó,Ð-Ù
Ð	ñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
Ð	ñ ó ò )0Ñ0AÓ(BØØ %ò	WØñWà%ñWð �4‰ZñWñ ˜‘+ó	WóóñWñtO¨v¸©}ð OÁõ Oñ  ‡‚ÙÚÑ+Ó,Ð-Ù
Ð	ñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
Ð	ñ ó ñ
 ‡‚Ù,ÚÑ+Ó,Ð-Ù
Ð	ñ ó ñ
 ‡‚Ù7ÚÑ+Ó,Ð-Ù
Ð	Ù‘]Ñ$9Ð:ÐN¹oÐNñ	 ó ð Ú(/Ñ0AÓ(Bò	V
ÙñV
áñV
ð �‰:ñV
ð &ó	V
óóóóñ*V
ñr ‡‚ÑªgÑ6GÓ.HÐ-IÑQ^ÐP_�Ó`Ù‡‚‰^ª7Ñ3DÓ+EÐ*FÉmÈ_�Ó]Ù‡‚Ù'ÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚Ù2ÚÑ+Ó,Ð-Ù
ˆñ ó ð Ú(/Ñ0AÓ(Bò	Y
ÙñY
áñY
ð �‰:ñY
ð &ó	Y
óóó ^ó añY
ñx ‡‚ÙÚÑ+Ó,Ð-Ù!Ù
ˆñ	 ó ñ ‡‚ÙÚÑ+Ó,Ð-Ù!Ù
ˆñ	 ó ñ ‡‚Ù&ÚÑ+Ó,Ð-Ù!Ù
ˆñ	 ó ñ ‡‚Ù1ÚÑ+Ó,Ð-Ù!Ù
ˆñ	 ó ð Ú(/Ñ0AÓ(Bò	`
Ùñ`
áñ`
ð �‰:ñ`
ð &ó	`
óóóóñ0`
ñF ‡‚ÙÚÑ+Ó,Ð-Ù!Ù
ˆñ	 ó ñ ‡‚ÙÚÑ+Ó,Ð-Ù!Ù
ˆñ	 ó ò )0Ñ0AÓ(BòfÙñfáñfð &ófóóñfñR	Ù)ð	à‘E˜4�KÑ õ	ñ ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(BòlÙñláñlð &ólóóñlñ^ ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ò ˜C“yÚ(/Ñ0AÓ(Bò	OÙñOáñOñ ñOð &ó	OóóñOñr ‡‚Ñ Ó!ð &˜ŸšØÙ]õð "/ §¢ØÙYõ"ð #0 '§-¢-ØÙQõ#ò )0Ñ0KÓ(LòÙñà�‰:ñð ˜$‘Jñð ˜4‘Zñð &óó "ññJ Ð,Õ-ñ
¨3°©:ñ 
¸sÀT¹zð 
ÉeÑTYÐZ]Ð_bÐZbÑTcÐehÐThÑNió 
ó .ñ
ñ ‡‚Ñ$Ó%Ù‡‚ˆ~ÓÙ‡‚‰{Óð &˜Ÿš dÑ8hÕiØ&˜Ÿš tÑ9bÕcØ*˜WŸ]š]ØÙWõò )0Ñ0KÓ(LòGhÙñGhà�‰:ñGhð �$‰JñGhð �d‘
ñ	Ghð &óGhó ó ó &ñGhñd ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(BòMÙñMáñMð &óMóóñMñ` ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(BòMÙñMáñMð &óMóóñMñ` ‡‚Ù(ÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚Ù%ÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(Bò	LÙñLàñLñ ñLð &ó	LóóñLñ^ ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(BòLÙñLáñLð &óLóóñLñ^ ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(Bò	JÙñJàñJñ ñJð &ó	JóóñJñZ ‡‚Ù&ÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚Ù#ÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(Bò	NÙñNàñNñ ñNð &ó	NóóñNñb ‡‚Ù&ÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚Ù#ÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(Bò	JÙñJàñJñ ñJð &ó	JóóñJñZ ‡‚Ù"ÚÑ+Ó,Ð-Ù
ˆñ ó ñ
 ‡‚ÙÚÑ+Ó,Ð-Ù
ˆñ ó ò )0Ñ0AÓ(Bò	mÙñmàñmñ ñmð &ó	móóñm÷p >Ñ =ß FÑ Fß CÑ Cß AÑ A÷÷ ÷ õ ÷ @Ñ ?ß ?Ñ ?ñ4Øñ4Ø$'ð4á
Ñ˜dÑ" C¨$¡J°°d±
Ð:Ñ;õ4ð~ Øò/Ù(ñ/à˜t™ñ/ð ð/ð �T‰kñ	/ð
 �T‰kñ/ð �S˜#�X‘ Ñ%ñ/ð ñ/ð �$‰;ñ/ð �$‰Jð/ð Ñ"Ñ#õ/ñd˜Fð Ñ'BÀTÑ'Iõ ñ ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Ø%ñ	 ó órÐ!2ñ rÁ4ó róñrñj ‡‚Ù$Ù
ˆÚÑ+Ó,Ð-ñ ó ñ
_¨ó _óñ
_ñ. ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Ù&ñ	 ó ñWÐ%9ó WóñWñ Ø�‰Jñà%ññ   $Ñ&ðð 
ˆ$�Zõ	ñ:¨$Ñ/BÑ*Cñ É}ð ÐaeÐfjÑakõ ñ$+Ø�T‘
ñ+àñ+ð &ñ+ñ   $Ñ&õ	+ñ\+ØÐ 1Ñ2ñ+àð+ð 
ˆ#‰s�3‰xˆ-Ñõ+ñ\8ØÐ 1Ñ2ñ8àñ8ñ  ñ8ð �c™3˜s™8�mÑ$ð	8ð
 
ˆ#‰s�3‰xˆ-Ñõ8ñv- Ø�S‘	˜G¡C™LÑ(ñ- áñ- ð ð- ð 
ˆ#ˆt�C‰yˆ.Ñõ	- ñ`Ø�S‰Mñàðñ ˆ3�ˆ8�_õð: !#óWØ%ñWàñWð ˜‘ðWñ ˆ3�ˆ8�_õ	Wñ.°$°t±*ð ÀÀdÁõ ñ5Ø%ñ5áñ5ð ñ5ð �T‘
ð	5ð
 
ˆ$�Zõ5ñp9Ø%ñ9áñ9ð ñ9ð �T‘
ð	9ð
 
ˆ$�Zõ9ð& MQó;Ø��S�‰>ñ;Ù"&ñ;Ø<BÀT¹Mð;à	ˆ#ˆsˆ(�^õ;ñ|"6Ø%¨Ñ,ñ"6á $Ñ&ð"6ñ 	ˆ�X��_õ"6ñJ+°D¸¸i¸Ñ4Hñ +Ñ\_Ð`cÑ\dÐgkÑ\kð +Ñptõ +ñ$ &)Ñ ˜UÔ (ð "ó@,Ùñ@,áñ@,ð ñ@,ñ   ™Hñ	@,ñ
 ñ@,ñ ñ@,ñ ñ@,ð �4‰Zñ@,ð #+¨D°°i°Ñ,@Ð+AÁ4Ð+GÑ"Hñ@,ð �d‘
ð@,ñ ˆ4��S˜#�X‘Ñ¡Ð$Ñ%õ@,ðP 04ØØØØ!órBØ�T˜#˜s˜(‘^Ñ$ñrBàñrBñ   $Ñ&ñrBñ ñ	rBð
 &¨Ñ,ñrBñ ñrBñ ñrBð �4‰ZñrBð �d‘
ðrBñ ˆ4��S˜#�X‘Ñ¡ t¡Ð+Ñ,õrBñj'¨ð '°8¸d±?õ 'ðZ óVØ�T˜#˜s˜(‘^Ñ$ñVà�4‰ZñVð ðVð 
ˆ$ˆs�Cˆx‰.Ñõ	VñrW ¨¨f¨Ñ!5ð W¹$õ Wñ *Ø�T˜#˜s˜(‘^Ñ$ñ*á
ñ*ñ ñ*ñ �t‘ñ	*ð
 �$‰Jð*ð 
ˆ#ˆvˆ+Ñõ*ñZ¨t°C©yñ ÈÐQTÐV^Ð_bÑVcÐQcÑIdð ÐimÐnqÑirõ ñ°cñ É,ð Ð[lÐosÑ[sõ ñ0%Ø"ñ0%àñ0%ñ  ñ0%ð ð	0%ñ
 	ˆ�Xõ0%ñf%
Øñ%
à%ñ%
ñ  ð%
ð 
õ	%
ðZ 04ó@Ø�T˜#˜s˜(‘^Ñ$ñ@àñ@ñ  ñ@ð ñ	@ð
 &¨Ñ,ð@ð 
ˆ$ˆs�Cˆx‰.Ñõ@ñF(*Øñ(*à�$‰Jñ(*ð ˜‘ñ(*ñ   $Ñ&ñ	(*ñ
  ð(*ñ ˆ4‘�t‘ÐÑõ(*ñV ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(BØ%˜Ÿš dÑ8[Õ\Ø$1 G§M¢M°%ÑElÕ$mØ'4 w§}¢}ØÑKõ(ð Ú‘a¡]±qÕ9Ú‘b¡k±aÕ8Ø&˜Ÿš tÑ9nÕoØ'˜'Ÿ-š-¨Ñ:hÕiØ&˜ŸšØÙwõð '˜ŸšØÙbõð *˜GŸMšMÙÙ4õð )6¨¯ªØñ.õ)ò1ZØ%ñZà�‰:ñZñ ˜T‘kñZñ  ™ñ	Zñ �$‰;ñZñ ñZñ ñZð �$‰JñZð �4‰ZñZð �$‰JñZð  �$‰Jñ!Zð( �T‰zñ)Zñ0  ™+ó1Zóñ
Zñz ‡‚ÙÙCÙ
Ð	ØÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(BØ(,Ø!%Ø#ò	z
Ø%ñz
à ™:ñz
ð ˜$‰ñz
ð ˜‰_ó	z
óñz
ñz ‡‚ÙÙPÙ
Ð	ØÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(BÙ(3Ø!%Ø#ØØòi
Ø%ñi
à ™:ñi
ð ˜$‰ñi
ð ˜‰_ñ	i
ð
 �4‰Zñi
ð �D‰jói
óñi
ñX ‡‚Ù#ÙAÙ
Ð	ØÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(BÙ(3Ø!%Ø#ØØòOØ%ñOà ™:ñOð ˜$‰ñOð ˜‰_ñ	Oð
 �4‰ZñOð �D‰jóOóñOñd ‡‚ÙÙIÙ
Ð	ØÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(BØ(,Ø!%Ø#ØØòNHØ%ñNHà ™:ñNHð ˜$‰ñNHð ˜‰_ñ	NHð
 �4‰ZñNHð �D‰jóNHóñNHñbe°4¸¸Y¸Ñ3Gñ eÐ^hÐilÑ^mð eÑrvõ eñ Ø%ñàðñ 	ˆ�X��_õñ@rØ�T‘
ñrá˜S™ D™ðrð 
ˆ$�Zõrñ0¨dð 0°tõ 0ñ6$5 ð $5¨$õ $5ñN ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-ñ ó ñ
 ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(BØ#'Ø'4 w§}¢}ØÙoõ(ð '˜ŸšØÙwõð !&òL$Ø%ñL$à˜D‘jñL$ñ  ™ñL$ð �$‰JñL$ñ ˜‘+óL$óóñL$ñ^ ‡‚ÙÙ	ÚÑ+Ó,Ð.Ù+ñ	 ó ñ ‡‚ÙÙ	ÚÑ+Ó,Ð.Ù+ñ	 ó ñ :ò`Ùð`áó`óóñ`ñ<ØñØ(,¨S©	ñØ@CÀdÁ
ðà	Ñ
ÑõñD ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(BØ"ò~"Ø%ñ~"à�t‘ó~"óñ
~"ñB ‡‚ÙÙ_Ù
Ð	ÚÑ+Ó,Ð-Øñ ó òóññ4 ‡‚ÙÙXÙ
ˆÚÑ+Ó,Ð-Øñ ó ò )0Ñ0AÓ(Bò^Ø%ó^óñ^ñD ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-Øñ	 ó ð Ú(/Ñ0AÓ(Bò	i
Ùñi
áñi
ð �‰:ñi
ð &ó	i
óñi
ñX ‡‚Ð	¡.Ð!1ÀU�ÓKñ¡'ó ó Lññ< ‡‚‰X¨�Ó/ñF™ó Fó 0ñFñR ‡‚‰[¨E�Ó2ñ8™Gó 8ó 3ñ8ñv ‡‚Ù 5ñ ó ñD™Gó DóñDñN ‡‚Ñ!°U�Ó;ñ:
¡Wó :
ó <ñ:
ñz ‡‚Ñ	 °E�Ó:ñ\ #ñ \±ó \ó ;ñ\ñ~"
±ð "
¸Tõ "
ñJsØñsàðsð 
õsñ.(¹-ð (ÈCõ (ñV ‡‚Ñ
#°u�Ó=ñx oñ xÁó xó >ñxñv ‡‚‰¨E�Ó2òó 3ññ"? Sð ?©X¸©_õ ?ñ. ‡‚‰¨�Ó/óCE˜7¡?Ñ3°dÑ:ó CEó 0ñCEñL ‡‚‰¨5�Ó1òIó 2ñIñF ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-Ø"Øñ ó ò SZÑZkÓRlò =+˜}ñ =+Àó =+óñ=+ñ@ ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-Ø"Øñ ó ò SZÑZkÓRlò #¨ñ #Àó #óñ#ñL ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-Ø"Øñ ó ò )0Ñ0AÓ(Bò/Ø
ñ/à%ó/óñ/ñd ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-Ø"Øñ ó ò )0Ñ0AÓ(Bò?Ø
ñ?à%ó?óñ?ñF ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(BòV
ØñV
à%óV
óñV
ðtñ $Ñ �eÔ #áFVðÙ¡ðá&©	ðñ 	™yðñ 	!¡)ð	ñ
 	¡	ðñ 	/±	ðñ 	!¡/ðñ 	™Yðñ 	&¡yðñ 	.©xðñ 	0±ðñ 	0±ðñ 	1±)ðñ 	0±ðñ 	3±Hðñ  	!¡&ð!ñ" 	#¡Fð#ñ$ %.Ù'0Ù-6Ù%Ù )Ù1:Ù*3ó1óGÑ )¨5°¸¸c¸Ñ1BÑ+Cô ñ<*¨Vñ *¸vð *È&õ *ñB ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(BòWØ
ñWà%óWóñWñtu°ð u¹õ uñ #%Ñ ˜%Ô $ó¨	ñ ¹#ð Àiõ ñ$°s¸T±zñ ÐPYð Ð^gõ ñ¨cñ ¸)ñ ÑTXð Ð]fõ ð QVô 	H ¨TÑ!1ñ 	HÉð 	HÐZ]Ð`dÑZdõ 	Hñ$ %6×$GÒ$GòØñáñð ˜dÑ"ñð ˜TÑ!ñ	ð
 &ññ "ðð 
õò: *3óó*Ñ  ô ñ¨¨S°#¸±*¨_Ñ(=ð À$ÀsÈCÐRVÉJÀÑBWõ ñr tñ r¹Dð rÀTõ rö2 	õ 2ñ
/¨Dñ /Áð /È$õ /ñB¹õ Bñ ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Ø"Øñ ó ò )0Ñ0AÓ(Bò<Øñ<à%ó<óñ<ñ~ !&©¡¨sÑ 2°TÑ 9Ñ ö ¨	õ  ñ ñ ò,ñ Ùñnò	(ñ ÙÙÙtò	%ñ ñdòñ ÙñBò	ò='\Ñ # U¨4°Ñ5VÐ0VÑ+WÑ%Xô 'ñT8Ù
+ð8á"õ8ñ$%¸Cñ $%Èð $%ÑSpõ $%ñNKØñKØ"ñKØ7EðKà	õKñ	I¸sñ 	IÐWeð 	IÐjnõ 	Iñ ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò^ØÑ+Ñ,ñ^à%ð^ð 
ˆ*Ñó^óñ^ñB ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(BòHØ
ñHà%óHóñHñV ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(BòQ
Ø
ñQ
à%óQ
óñQ
ñh ‡‚ÙÙ
ˆØÚÑ+Ó,Ð-ñ	 ó ò )0Ñ0AÓ(BòG
Ø%óG
óñG
ñT ‡‚ÙÙ
ˆÚÑ+Ó,Ð-Øñ	 ó ñ¨Jó óññ( ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò8]Ø%ó8]óñ8]ñv ‡‚Ù%Ù
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò(
Ùñ(
à%ó(
óñ(
ñV ‡‚Ù%Ù
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(BòdØ%ódóñdñD ‡‚Ù,Ù
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò
Ø%ó
óñ
ñ> ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò'
Ø%ó'
óñ'
ñZ ‡‚Ù$Ù
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò@eØ%ó@eóñ@eñF ‡‚Ù-Ù
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò3
Ùñ3
à%ó3
óñ3
ñl ‡‚Ù-Ù
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(Bò$
Ø%ó$
óñ$
ñN ‡‚Ù4Ù
Ð	ÚÑ+Ó,Ð-Øñ	 ó ò )0Ñ0AÓ(BòU
Ø%óU
óñU
ñp ‡‚‰CšwÑ'8Ó9Ð:�Ó;ñ™ó ó <ññ ‡‚ÙÙ
Ð	ÚÑ+Ó,Ð-ñ ó ò )0Ñ0AÓ(Bò"Ø%ó"óñ
"ñ< ‡‚‰I¢WÑ->Ó%?Ð$@�ÓAòó Bññ` × Ò ‘6Ô Ù × Ò ‘?Ô #Ù × Ò Ñ*Ô +Ù × Ò Ñ#Ô $Ù × Ò ‘=Ô !Ù × Ò ‘:Ô Ù × Ò ‘:Ô Ù × Ò ‘<Ô  Ù × Ò Ñ#Ô $Ù × Ò ‘=Ô !Ù × Ò ‘<Ô  Ù × Ò Ñ%Ô &Ù × Ò Ñ$Ô %Ù × Ò Ñ,Ô -Ù × Ò ‘>Ô "Ù × Ò Ñ&Ô 'Ù × Ò Ñ)Ô *Ù × Ò Ñ&Ô 'Ù × Ò ‘=Ô !Ù × Ò Ñ(Ô )Ù × Ò Ñ'Ô (Ù × Ò ‘;Ô Ù × Ò ‘=Ô !Ù × Ò Ñ&Ô 'Ù × Ò ‘?Ô #Ù × Ò Ñ'Ô (Ù × Ò Ñ*Ô +Ù × Ò ‘>Ô "Ù × Ò Ñ#Ô $Ù × Ò Ñ7Ô 8Ù × Ò Ñ-Ô .Ù × Ò Ñ,Ô -Ù × Ò Ñ+Ô ,Ù × Ò Ñ/Ô 0Ù × Ò Ñ'Ô (Ù × Ò Ñ+Ô ,Ù × Ò Ñ*Ô +Ù × Ò Ñ7Ô 8Ù × Ò Ñ0Ô 1Ù × Ò Ñ(Ô )Ù × Ò Ñ-Ô .Ù × Ò ‘=Ô !Ù × Ò ‘=Ô !Ù × Ò Ñ0Ô 1Ù × Ò Ñ)Ô *Ù × Ò Ñ-Ô .Ù × Ò Ñ(Ô )Ù × Ò Ñ5Ô 6Ù × Ò Ñ.Ô /Ù × Ò Ñ)Ô *Ù × Ò Ñ$Ô %Ù × Ò Ñ0Ô 1á × Ò ‘=Ô !á ‘SÔ Ù × Ò ÙÚOÚ">ñ ô ñE°dð EÑH[õ EñZ ‡‚ØÛHñ ó ñ_¡wó _ó	ñ_ñ* ‡‚Ù!ÛHñ ó ñ)M¨#ñ )M¹ó )Mó	ñ)MñX
_¨Sñ 
_¹7õ 
_ñ-¨sñ -¸sÀT¹zð -ÈdÐSVÉiõ -ñ`¨Cð ±Dõ ñ< ‡‚ÙÛHñ ó ñCM¨Sñ CM¹7ó CMó	òCMøðIt ò UÙ
Ð+¨A¨3Ð.RÐSÓ
TÐTûðUûðP ò -Ø%)Ñ"Ø(,Ô%ð-ûñf ò Ø„GðûñX ò ðÞøÙò Ùðýð	ûð ò #Ø"Ôð#ú÷X&/ñ /ú÷6ñ 6ûá.±ÁÐIò !â ð!ûñ~ ò oØ&Ð×&Ò&Ñ'aÑcjÐlm×nÒnûÙò dØ&Ð×&Ò&Ñ'VÑX_Ðab×cÒcûðdûñ ò 	Úð	ús~  È DC% Ý8DC> è	DD ë 	DD  ë*(DE þ=J<DG ÁI:DE*ÁJ
DEÁJADE*ÁK+DEÁLDE*ÁL	B6DG ÁO B DE< ÄC%DC;ÄC*DC6ÄC6DC;ÄC>DDÄDDDÄD	DDÄDDDÄD DD>ÄD'DD.ÄD-DD>ÄD.DD7ÄD4DD>ÄD6DD7ÄD7DD>ÄD=DD>ÄEDEÄEDEÄEDEÄEDE*ÄEDE'ÄE"DE*ÄE*DE9ÄE5DG ÄE8DE9ÄE9DG ÄE<DG
ÄFDFÄFDG ÄF	DG
ÄF(DGÄF?DG ÄGDG
ÄG
DG ÄGDGÄGDG