Ë
    tPêjãU  ã            	       ó:  — U d dl Z d dlZd dlmZ d dlmZmZ d dlZd dl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  ed
dh«      Zeee      ed<   dedefd„Zdedefd„Zdedefd„Zde	dz  defd„Zde	dz  dedz  fd„Z de	dz  defd„Z!de	dz  deddfd„Z"de	dz  defd„Z#dede
dee   defd„Z$de	deeef   fd„Z%deeef   deeef   fd„Z&de	deeef   fd „Z'd'deeef   d!edeeef   fd"„Z(d#ede)e   fd$„Z*dede	defd%„Z+dede	ddfd&„Z,y)(é    N)Ú
Collection)ÚAnyÚFinal)ÚRequestÚ
UploadFileÚstatus)Úverbose_proxy_logger)Ú"MAX_REQUEST_BODY_SIZE_TO_REPAIR_MB)ÚProxyException)Ú&get_metadata_variable_name_from_kwargs)Ú
Deploymentz!application/x-www-form-urlencodedzmultipart/form-dataÚ_FORM_CONTENT_TYPESÚcontent_typeÚreturnc                 ój   — | sy| j                  dd«      d   j                  «       j                  «       S )zGReturn the bare media type per RFC 7231: strip params, trim, lowercase.Ú ú;é   r   )ÚsplitÚstripÚlower©r   s    úr/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/common_utils/http_parsing_utils.pyÚ_normalize_media_typer      s2   € áØØ×Ñ˜c 1Ó% aÑ(×.Ñ.Ó0×6Ñ6Ó8Ð8ó    c                 ó$   — t        | «      t        v S )a9  
    True iff Starlette's ``request.form()`` will actually parse this body.

    Substring matching ``"form"`` is unsafe: ``request.form()`` returns empty
    ``FormData`` for non-canonical types without consuming the body, leaving
    the auth-time pre-read and the handler's read seeing different payloads.
    )r   r   r   s    r   Ú_is_form_content_typer      s   € ô ! Ó.Ô2EÐEÐEr   c                 ó   — t        | «      dk(  S )z+True iff the body should be parsed as JSON.zapplication/json)r   r   s    r   Ú_is_json_content_typer   &   s   € ä  Ó.Ð2DÑDÐDr   Úrequestc              ƒ   ó†  K  — 	 | €i S t        | ¬«      }|�|S t        | ¬«      }|j                  dd«      }t        |«      rW	 | j	                  «       ƒ d{  –—† }t        |«      }d
|v rbt        |d
   t        «      rOt        j                  |d
   «      |d
<   n3| j!                  «       ƒ d{  –—† }|si }n	 t#        j                  |«      }t3        | |¬«       |S 7 Œ„# t
        $ r;}t        j                  d|«       t        d|› �ddt        j                  ¬	«      ‚d}~ww xY w7 Œw# t"        j$                  $ �r}t&        dz  dz  }|dkD  rDt)        |«      |kD  r6t        j                  d|«       t        d|› �ddt        j                  ¬	«      ‚t        |t*        «      r|j-                  d«      n|}	t/        j0                  dd|	«      }	t/        j0                  dd|	«      }		 t        j                  |	«      }nM# t        j$                  $ r7 t        j                  d|«       t        d|› �ddt        j                  ¬	«      ‚w xY wY d}~�Œ~d}~ww xY w# t        j$                  t"        j$                  t        f$ r}t        j                  d|«       ‚ d}~wt
        $ r"}t        j4                  d|«       i cY d}~S d}~ww xY w­w)zë
    Safely read the request body and parse it as JSON.

    Parameters:
    - request: The request object to read the body from

    Returns:
    - dict: Parsed request data as a dictionary or an empty dictionary if parsing fails
    N)r    úcontent-typer   zInvalid form payload: %szInvalid form payload: Úinvalid_request_errorÚrequest_body)ÚmessageÚtypeÚparamÚcodeÚmetadatai   r   z!Invalid JSON payload received: %szInvalid JSON payload: zutf-8z"[\uD800-\uDBFF](?![\uDC00-\uDFFF])z#(?<![\uD800-\uDBFF])[\uDC00-\uDFFF])r    Úparsed_bodyz*Unexpected error reading request body - %s)Ú_safe_get_request_parsed_bodyÚ_safe_get_request_headersÚgetr   ÚformÚ	Exceptionr	   Úerrorr   r   ÚHTTP_400_BAD_REQUESTÚdictÚ
isinstanceÚstrÚjsonÚloadsÚbodyÚorjsonÚJSONDecodeErrorr
   ÚlenÚbytesÚdecodeÚreÚsubÚ_safe_set_request_parsed_bodyÚ	exception)
r    Ú_cached_request_bodyÚ_request_headersr   Ú	form_dataÚer*   r7   Úrepair_limit_bytesÚbody_strs
             r   Ú_read_request_bodyrG   +   s´  è ø€ ðYØˆ?ØˆIô 4QÐY`Ô3aÐØÐ+Ø'Ð'ä(AÈ'Ô(RÐØ.×2Ñ2°>À2ÓFˆä  Ô.ðØ)0¯©«×#7�	ô ˜y›/ˆKØ˜[Ñ(¬Z¸ÀJÑ8OÔQTÔ-UÜ*.¯*©*°[ÀÑ5LÓ*M�˜JÒ'ð !(§¡£×.ˆDñ Ø ‘ð$Ü"(§,¡,¨tÓ"4�KôL 	&¨gÀ;ÕOØÐðE $8ùÜò ô %×*Ñ*Ð+EÀqÔIÜ$Ø4°Q°CÐ8Ø0Ø(Ü×4Ñ4ô	ð ûðúð& /ùô ×-Ñ-ó "ô 1SÐUYÑ0YÐ\`Ñ0`Ð&Ø)¨AÒ-´#°d³)Ð>PÒ2PÜ,×2Ñ2Ð3VÐXYÔZÜ,Ø&<¸Q¸CÐ$@Ø!8Ø"0Ü!'×!<Ñ!<ô	ð ô 8BÀ$ÌÔ7N˜tŸ{™{¨7Ô3ÐTX�Hô  "Ÿv™vÐ&KÈRÐQYÓZ�Hä!Ÿv™vÐ&LÈbÐRZÓ[�Hð
Ü&*§j¡j°Ó&:™øÜ×/Ñ/ò ä,×2Ñ2Ð3VÐXYÔZÜ,Ø&<¸Q¸CÐ$@Ø!8Ø"0Ü!'×!<Ñ!<ô	ð ðúõ $ûð3"ûôP × Ñ ¤&×"8Ñ"8¼.ÐIò ä×"Ñ"Ð#FÈÔJØûÜò ä×&Ñ&Ð'SÐUVÔWØ�	ûðüsÛ   ‚K„I ‡KˆI —K˜)I ÁC ÁCÁC ÁAI Â+D#Â,	I Â6D% ÃI ÃKÃC Ã	D Ã%6DÄD Ä I Ä%IÄ9B&I	Ç G6Ç5I	Ç6A
I É I	ÉI É	IÉI É(J>É9JÊJ>ÊJ9Ê3J>Ê4KÊ9J>Ê>Kc                 óÎ   — | €y t        | d«      rQd| j                  v rCt        | j                  d   t        «      r&| j                  d   \  }}|D �ci c]  }|||   “Œ
 c}S y c c}w )NÚscoper*   )ÚhasattrrI   r3   Útuple)r    Úaccepted_keysr*   Úkeys       r   r+   r+   ‘   sm   € Ø€ØÜˆw˜Ô  ]°g·m±mÑ%CÌ
ÐSZ×S`ÑS`ÐanÑSoÔqvÔHwØ%,§]¡]°=Ñ%AÑ"ˆ�{Ø1>Ö?¨#��[ Ñ%Ñ%Ò?Ð?Øùò @s   ÁA"c                 ó®   — | €i S 	 t        | d«      rt        | j                  «      S i S # t        $ r"}t	        j
                  d|«       i cY d }~S d }~ww xY w)NÚquery_paramsz2Unexpected error reading request query params - %s)rJ   r2   rO   r/   r	   Údebug)r    rD   s     r   Ú_safe_get_request_query_paramsrQ   š   sX   € Ø€Øˆ	ðÜ�7˜NÔ+Ü˜×,Ñ,Ó-Ð-Øˆ	øÜò Ü×"Ñ"Ð#WÐYZÔ[Ø�	ûðús   † ) §) ©	A²AÁ	AÁAr*   c                 ó´   — 	 | €y t        |j                  «       «      |f| j                  d<   y # t        $ r }t	        j
                  d|«       Y d }~y d }~ww xY w)Nr*   z1Unexpected error setting request parsed body - %s)rK   ÚkeysrI   r/   r	   rP   )r    r*   rD   s      r   r?   r?   ¦   sX   € ð[Øˆ?ØÜ(-¨k×.>Ñ.>Ó.@Ó(AÀ;Ð'Oˆ�‰�mÒ$øÜò [Ü×"Ñ"Ð#VÐXY×ZÑZûð[ús   ‚. …(. ®	A·AÁAc                 ód  — | €i S t        | dd«      }t        |dd«      }t        |t        «      r|S |�t        j                  dt        |«      «       	 t        | j                  «      }	 |�||_        |S # t        $ r"}t        j                  d|«       i }Y d}~Œ2d}~ww xY w# t        $ r Y |S w xY w)u  
    [Non-Blocking] Safely get the request headers.
    Caches the result on request.state to avoid re-creating dict(request.headers) per call.

    Warning: Callers must NOT mutate the returned dict â€” it is shared across
    all callers within the same request via the cache.
    NÚstateÚ_cached_headersz+Unexpected cached request headers type - %sz-Unexpected error reading request headers - %s)	Úgetattrr3   r2   r	   rP   r&   Úheadersr/   rV   )r    rU   ÚcachedrX   rD   s        r   r,   r,   ²   sÆ   € ð €Øˆ	Ü˜7 G¨TÓ2€EÜ˜EÐ#4°dÓ;€FÜ�&œ$ÔØˆØÐÜ×"Ñ"Ð#PÔRVÐW]ÓR^Ô_ðÜ�w—‘Ó'ˆðØÐØ$+ˆEÔ!ð €Nøô ò Ü×"Ñ"Ð#RÐTUÔVØ�ûðûô ò ØØ€Nðús*   ÁA4 Á)	B" Á4	BÁ=BÂBÂ"	B/Â.B/Úrequest_dataÚfileÚrouter_model_namesc                 ól  — ddl m}m}m}m} |j
                  xs d}|dz  }d| vri | d<   || d   d<   d}	|�W| d   |v rP	 |j                  | d   ¬«      }
|
r8|
j                  �,|
j                  j                  �|
j                  j                  }	|	�pt        j                  d
||	«       |s1 |d|j                  j                  › �t         j"                  dd¬«      ‚||	kD  r! |d|› d|	› d�t         j"                  dd¬«      ‚y# t        $ r)}t        j                  d	t        |«      «       Y d}~Œ d}~ww xY w)zî
    Check if any files passed in request are under max_file_size_mb

    Returns True -> when file size is under max_file_size_mb limit
    Raises ProxyException -> when file size is over max_file_size_mb limit or not a premium_user
    r   )ÚCommonProxyErrorsr   Ú
llm_routerÚpremium_useri   r)   Úfile_size_in_mbNÚmodel)Úmodel_group_namez%Got error when checking file size: %sz=Checking file size, file content size=%s, max_file_size_mb=%sz:Tried setting max_file_size_mb for /audio/transcriptions. Úbad_requestr[   )r%   r(   r&   r'   zGFile size is too large. Please check your file size. Passed file size: z MB. Max file size: z MBT)Úlitellm.proxy.proxy_serverr^   r   r_   r`   ÚsizeÚ"get_deployment_by_model_group_nameÚlitellm_paramsÚmax_file_size_mbr/   r	   r0   r4   rP   Únot_premium_userÚvaluer   r1   )rZ   r[   r\   r^   r   r_   r`   Úfile_contents_sizeÚfile_content_size_in_mbri   Ú
deploymentrD   s               r   Úcheck_file_size_under_limitro   Ï   s™  € ÷ó ð !%§	¡	¢¨QÐØ%7¸;Ñ%GÐØ˜Ñ%Ø#%ˆ�ZÑ Ø2I€L�ÑÐ.Ñ/ØÐàÐ ,¨wÑ"7Ð;MÑ"Mð	ZØ3=×3`Ñ3`Ø!-¨gÑ!6ð 4aó 4ˆJñ Ø×-Ñ-Ð9Ø×-Ñ-×>Ñ>ÐJà#-×#<Ñ#<×#MÑ#MÐ ð Ð#Ü×"Ñ"ØKØ#Øô	
ñ
 Ù ØTÐUf×UwÑUw×U}ÑU}ÐT~ÐÜ×0Ñ0Ø"Øô	ð ð #Ð%5Ò5Ù ØaÐbyÐazð  {Oð  P`ð  Oað  adð  eÜ×0Ñ0Ø"Øô	ð ð øô1 ò 	ZÜ ×&Ñ&Ð'NÔQTÐUVÓQW×YÑYûð	Zús   ¿AD Ä	D3Ä
D.Ä.D3c              ƒ   óð   K  — | j                  «       ƒ d{  –—† }i }|j                  «       D ]B  \  }}|j                  d«      r'|dd }|j                  |g «      j	                  |«       Œ>|||<   ŒD |S 7 Œ]­w)z²
    Read form data from request

    Handles when OpenAI SDKs pass form keys as `timestamp_granularities[]="word"` instead of `timestamp_granularities=["word", "sentence"]`
    Nz[]éþÿÿÿ)r.   Úmulti_itemsÚendswithÚ
setdefaultÚappend)r    r.   Úparsed_form_datarM   rk   Ú	clean_keys         r   Úget_form_datarx     s‚   è ø€ ð  Ÿ™›×&€DØ.0ÐØ×&Ñ&Ó(ò *‰
ˆˆUØ�<‰<˜ÔØ˜C˜R˜ˆIØ×'Ñ'¨	°2Ó6×=Ñ=¸eÕDà$)Ð˜SÒ!ð*ð Ðð 'ús   ‚A6–A4—AA6rC   c              ƒ   óÄ  K  — i }| j                  «       D ]Â  \  }}t        |t        «      rf|r^t        |d   d«      rOg }|D ]B  }|j	                  «       ƒ d{  –—† }|j                  |j                  ||j                  f«       ŒD |||<   Œv|||<   Œ|t        |d«      r6|j	                  «       ƒ d{  –—† }|j                  ||j                  fg||<   Œ¾|||<   ŒÄ |S 7 Œ…7 Œ-­w)a‚  
    Convert FastAPI UploadFile objects to file data tuples for litellm.

    Converts UploadFile objects to tuples of (filename, content, content_type)
    which is the format expected by httpx and litellm's HTTP handlers.

    Args:
        form_data: Dictionary containing form data with potential UploadFile objects

    Returns:
        Dictionary with UploadFile objects converted to file data tuples

    Example:
        ```python
        form_data = await get_form_data(request)
        data = await convert_upload_files_to_file_data(form_data)
        # data["files"] is now [(filename, content, content_type), ...]
        ```
    r   ÚreadN)Úitemsr3   ÚlistrJ   rz   ru   Úfilenamer   )rC   ÚdatarM   rk   ÚfilesÚfÚfile_contents          r   Ú!convert_upload_files_to_file_datar‚     så   è ø€ ð, €DØ—o‘oÓ'ò ‰
ˆˆUÜ�eœTÔ"áœ  q¡¨6Ô2Ø�Øò M�AØ)*¯©«§>�Là—L‘L !§*¡*¨l¸A¿N¹NÐ!KÕLðMð "��S’	à!��S’	Ü�U˜FÔ#à!&§¡£×-ˆLØŸ.™.¨,¸×8JÑ8JÐKÐLˆD�ŠIð ˆD�ŠIð%ð& €Kð $2øð .ús%   ‚AC ÁCÁAC Â0CÂ1,C ÃC c              ƒ   ó   K  — | j                   dk(  rf| j                  j                  dd«      }t        |«      rt	        | «      ƒ d{  –—† S t        |«      rt        | «      ƒ d{  –—† S t        d|› �«      ‚i S 7 Œ27 Œ­w)z5
    Read the request body and parse it as JSON.
    ÚPOSTr"   r   NzUnsupported content type: )ÚmethodrX   r-   r   rG   r   rx   Ú
ValueError)r    r   s     r   Úget_request_bodyr‡   L  sw   è ø€ ð ‡~�~˜ÒØ%Ÿo™o×1Ñ1°.À"ÓEˆÜ  Ô.Ü+¨GÓ4×4Ð4Ü" <Ô0Ü& wÓ/×/Ð/äÐ9¸,¸ÐHÓIÐIØ€Ið 5øà/ús$   ‚AA>ÁA:ÁA>Á%A<Á&A>Á<A>Úprefixc                 óÀ  — | si S i }| j                  «       D �]  \  }}t        |t        «      r|j                  |«      sŒ)t        |t        «      rt        j                  d|«       ŒP	 |j                  |d«      j                  d«      }|j                  d«      }|r|d   st        j                  d|«       Œ¡|}|dd D ]<  }t        |t        «      st        j                  d	|«        nC|j                  |i «      }Œ> t        |t        «      r	|||d   <   nt        j                  d
|«       �Œ |S # t        $ r"}	t        j                  d||	«       Y d}	~	�ŒAd}	~	ww xY w)aK  
    Extract nested metadata from form data with bracket notation.

    Handles form data that uses bracket notation to represent nested dictionaries,
    such as litellm_metadata[spend_logs_metadata][owner] = "value".

    This is commonly encountered when SDKs or clients send form data with nested
    structures using bracket notation instead of JSON.

    Args:
        form_data: Dictionary containing form data (from request.form())
        prefix: The prefix to look for in form keys (default: "litellm_metadata[")

    Returns:
        Dictionary with nested structure reconstructed from bracket notation

    Example:
        Input form_data:
        {
            "litellm_metadata[spend_logs_metadata][owner]": "john",
            "litellm_metadata[spend_logs_metadata][team]": "engineering",
            "litellm_metadata[tags]": "production",
            "other_field": "value"
        }

        Output:
        {
            "spend_logs_metadata": {
                "owner": "john",
                "team": "engineering"
            },
            "tags": "production"
        }
    z6Skipping UploadFile in metadata extraction for key: %sr   ú]z][r   z,Invalid metadata key format (empty path): %sNéÿÿÿÿzCCannot create nested path - intermediate value is not a dict at: %sz3Cannot set value - parent is not a dict for key: %sz#Error parsing metadata key '%s': %s)r{   r3   r4   Ú
startswithr   r	   ÚwarningÚreplaceÚrstripr   r2   rt   r/   r0   )
rC   rˆ   r)   rM   rk   Úpath_stringÚpartsÚcurrentÚpartrD   s
             r   Úextract_nested_form_metadatar”   [  sg  € ñF Øˆ	à&(€Hà—o‘oÓ'ó )‰
ˆˆUä˜#œsÔ#¨3¯>©>¸&Ô+AØô �eœZÔ(Ü ×(Ñ(Ð)aÐcfÔgØð	àŸ+™+ f¨bÓ1×8Ñ8¸Ó=ˆKð  ×%Ñ% dÓ+ˆEá  a¢Ü$×,Ñ,Ð-[Ð]`ÔaØð ˆGØ˜c˜r˜
ò m�Ü! '¬4Ô0Ü(×0Ñ0Ø]Ð_côñ Ø!×,Ñ,¨T°2Ó6‘ðmô ˜g¤tÔ,Ø).�G˜E "™IÒ&ä(×0Ñ0Ð1fÐhkÔlùðK)ðV €Oøô	 ò 	Ü ×&Ñ&Ð'LÈcÐSTÔUÝûð	ús    Á(AD2Â8A5D2Ä2	EÄ;EÅEr$   c                 óà  — t        | «      }| j                  |«      }t        |t        «      r#ddlm}  ||«      }t        |t        «      r|ni }nt        |t        «      si }|j                  dg «      }| j                  dg «      }g }t        |t        «      r|j                  |«       t        |t        «      r|j                  |«       |D �cg c]  }t        |t        «      sŒ|‘Œ c}S c c}w )zÄ
    Extract tags from request body metadata.

    Args:
        request_body: The request body dictionary

    Returns:
        List of tag names (strings), empty list if no valid tags found
    r   )Úsafe_json_loadsÚtags)	r   r-   r3   r4   Ú*litellm.litellm_core_utils.safe_json_loadsr–   r2   r|   Úextend)	r$   Úmetadata_variable_namer)   r–   ÚparsedÚtags_in_metadataÚtags_in_request_bodyÚcombined_tagsÚtags	            r   Úget_tags_from_request_bodyr    ±  sÕ   € ô %KÈ<Ó$XÐØ×ÑÐ 6Ó7€Hô �(œCÔ ÝNá'¨Ó1ˆÜ'¨´Ô5‘6¸2‰Ü˜¤$Ô'ØˆØ#+§<¡<°¸Ó#;ÐØ'3×'7Ñ'7¸ÀÓ'CÐØ&(€Mô
 Ð"¤DÔ)Ø×ÑÐ-Ô.ÜÐ&¬Ô-Ø×ÑÐ1Ô2à(ÖA�C¬J°s¼CÕ,@ŠCÒAÐAùÒAs   ÃC+Ã$C+c                 ó  — t        |«      }|r*|j                  «       D ]  \  }}| j                  ||«       Œ t        |dd«      }t	        |t
        «      r¨|r¦|j                  «       D ]l  \  }}|dk(  rP| j                  d|«       | j                  d«      }t	        |t        «      r||vr|j                  |«       n|g| d<   Œ[| j                  ||«       Œn t        j                  d| j                  d«      «       | S t        | |¬«       | S )a  
    Copy FastAPI path params and query params into the request payload so downstream checks
    (e.g. vector store RBAC, organization RBAC) see them the same way as body params.

    Since path_params may not be available during dependency injection,
    we parse the URL path directly for known patterns.

    Args:
        request_data: The request data dictionary to populate
        request: The FastAPI Request object

    Returns:
        dict: Updated request_data with path parameters and query parameters added
    Úpath_paramsNÚvector_store_idÚvector_store_idszIpopulate_request_with_path_params: Found path_params, vector_store_ids=%s)rZ   r    )rQ   r{   rt   rW   r3   r2   r-   r|   ru   r	   rP   Ú_add_vector_store_id_from_path)rZ   r    rO   rM   rk   r¢   Úexisting_idss          r   Ú!populate_request_with_path_paramsr§   Õ  s  € ô  9¸ÓA€LÙØ&×,Ñ,Ó.ò 	0‰JˆC�à×#Ñ# C¨Õ/ð	0ô
 ! ¨-¸Ó>€KÜ�+œtÔ$©Ø%×+Ñ+Ó-ò 
	0‰JˆC�ØÐ'Ò'Ø×'Ñ'Ð(9¸5ÔAØ+×/Ñ/Ð0BÓC�Ü˜l¬DÔ1Ø LÑ0Ø$×+Ñ+¨EÕ2à8=°w�LÐ!3Ñ4ØØ×#Ñ# C¨Õ/ð
	0ô 	×"Ñ"ØWØ×ÑÐ/Ó0ô	
ð Ðô #°ÀgÕNàÐr   c                 ó¶  — ddl m}  ||«      }t        j                  d|«      }|r�|j	                  d«      }t        j                  d||«       | j                  d|«       | j                  d«      }t        |t        «      r||vr|j                  |«       n|g| d<   t        j                  d| j                  d«      «       y
t        j                  d	|«       y
)a  
    Parse the request path to find /vector_stores/{vector_store_id}/... segments.

    When found, ensure both vector_store_id and vector_store_ids are populated.

    Args:
        request_data: The request data dictionary to populate
        request: The FastAPI Request object
    r   )Úget_request_routez/vector_stores/([^/]+)/r   zLpopulate_request_with_path_params: Extracted vector_store_id=%s from path=%sr£   r¤   zPpopulate_request_with_path_params: Updated request_data with vector_store_ids=%szHpopulate_request_with_path_params: No vector_store_id present in path=%sN)Úlitellm.proxy.auth.auth_utilsr©   r=   ÚsearchÚgroupr	   rP   rt   r-   r3   r|   ru   )rZ   r    r©   ÚpathÚvector_store_matchr£   r¦   s          r   r¥   r¥     sÔ   € õ @á# GÓ,€DÜ "§	¡	Ð*DÀdÓ KÐÙØ!3×!9Ñ!9¸!Ó!<ˆÜ×"Ñ"ØZÐ\kÐmqô	
ð 	×ÑÐ 1°?ÔCØ*×.Ñ.Ð/AÓBˆÜ�l¤DÔ)Ø lÑ2Ø×#Ñ# OÕ4à0?Ð/@ˆLÐ+Ñ,Ü×"Ñ"Ø^Ø×ÑÐ/Ó0õ	
ô
 	×"Ñ"Ð#mÐosÕtr   )zlitellm_metadata[)-r5   r=   Úcollections.abcr   Útypingr   r   r8   Úfastapir   r   r   Úlitellm._loggingr	   Úlitellm.constantsr
   Úlitellm.proxy._typesr   Ú)litellm.proxy.common_utils.callback_utilsr   Úlitellm.types.routerr   Ú	frozensetr   r4   Ú__annotations__r   Úboolr   r   r2   rG   r+   rQ   r?   r,   ro   rx   r‚   r‡   r”   r|   r    r§   r¥   © r   r   ú<module>r»      s)  ðÜ Û 	Ý &ß ã ß /Ñ /å 1Ý @Ý /õõ ,á-6Ð8[Ð]rÐ7sÓ-tÐ �U˜9 S™>Ñ*Ó tð9¨ð 9°ó 9ðF¨ð F°ó FðE¨ð E°ó Eð
c g°¡nð c¸ó cðL¨7°T©>ð ¸dÀT¹kó ð	¨G°d©Nð 	¸tó 	ð	[Ø�t‰^ð	[àð	[ð 
ó	[ð w°¡~ð ¸$ó ð:<Øð<à
ð<ð # 3™ð<ð 
ó	<ð~ ð ¨T°#°s°(©^ó ð"*Ø�C˜�H‰~ð*à	ˆ#ˆsˆ(�^ó*ðZ Gð °°S¸#°X±ó ñS¨D°°c°©Nð SÀCð SÐbfÐgjÐloÐgoÑbpó Sðl!B¨Tð !B°d¸3±ió !BðH-°Dð -À7ð -Ètó -ð` u°ð  uÀð  uÈDô  ur   