Ë
    uPêjº_  ã                   ó.  — U d dl Z d dl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 d dlZd dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZmZmZmZ d dlmZ d dlm Z  e	r	d dl!m"Z# e#Z$ne
Z$ e%d«      Z&ee'd<   de$dee(e
f   de)ddfd„Z*de+de(dz  fd„Z, ed¬«       G d„ d«      «       Z-de(de(de.fd„Z/de0e
   de(de1e0e(   dz  e2dz  f   fd „Z3d!Z4ee'd"<    e%h d#£«      Z5ee'd$<    e%d%h«      Z6ee'd&<   d'e(ee(e+f   z  de(dz  fd(„Z7de$d'e(ee(e+f   z  d)e(dee(e+f   de.f
d*„Z8dee(e+f   de.fd+„Z9dee(e+f   de.fd,„Z:d-d.œd/e1e
   de$d0e0e(   d)e(d1e)d2e2d3e2d4e.de
fd5„Z;d)e(de<d1e)fd6„Z=d)e(de<d1e)fd7„Z>de0e
   dz  de.fd8„Z?de0e(   e0e<e(e
f      z  de(fd9„Z@y):é    N)ÚMapping)Ú	dataclass)ÚEnum)ÚTYPE_CHECKINGÚAnyÚFinal)Úverbose_router_logger)ÚCustomLogger)Úmask_sensitive_structure)Ú add_fallback_headers_to_responseÚget_fallback_error_info)Ú"_get_router_metadata_variable_name)Ú_first_presentÚ_set_cooldown_deploymentsÚcast_exception_status_to_intÚ is_advisor_orchestration_failure)Ú0increment_deployment_failures_for_current_minute)ÚLiteLLMParamsTypedDict)ÚRouter)i”  Ú_REQUEST_SCOPED_STATUS_CODESÚlitellm_routerÚkwargsÚ	exceptionÚreturnc                 ó¨  — 	 t        |«      rt        j                  d«       yt        |dd«      }|j	                  d«      �(t        |«      t        v rt        j                  d|«       y|j	                  d«      r$t        |«      dk(  rt        j                  d	«       yt        |d
d«      }|€t        j                  d«       y| j                  |¬«      }|�,t        |j	                  d«      |j	                  d«      d¬«      nd}t        j                  j                  j                  |¬«      }t        j                  j                  }|�	 ||¬«      nd}	|�|dk\  r|n|	�|	dk\  r|	n| j                  }
t!        | |¬«       t#        | ||||
¬«       t        j                  d|«       y# t$        $ r }t        j                  d|«       Y d}~yd}~ww xY w)ap  
    Trigger cooldown for a failed fallback deployment.

    In the fallback path the normal failure-callback cooldown is skipped because the
    Logging object sets has_logged_async_failure=True after the first failure and
    blocks all subsequent failure callbacks. This helper ensures every failed
    fallback deployment is evaluated for cooldown regardless.
    z|Not triggering cooldown for fallback deployment: failure originated from advisor orchestration, not the selected deployment.NÚstatus_codeÚ Úoriginal_generic_functionzˆNot triggering cooldown for fallback deployment: status %s on a generic API call is caller-attributable, not a deployment health signal.Úclient_side_timeouti˜  z|Not triggering cooldown for fallback deployment: a caller-supplied x-litellm-timeout caused this 408, not deployment health.Úfailed_deployment_idzJCannot trigger cooldown for fallback: no failed_deployment_id on exception)ÚidÚ
model_infoÚlitellm_paramsÚcooldown_time)Úkey)Úoriginal_exception)Úresponse_headersr   )Úlitellm_router_instanceÚdeployment_id)r(   Úexception_statusr&   Ú
deploymentÚtime_to_cooldownz-Triggered cooldown for fallback deployment %sz5Error triggering cooldown for fallback deployment: %s)r   r	   ÚdebugÚgetattrÚgetr   r   Úget_model_infor   ÚlitellmÚlitellm_core_utilsÚexception_mapping_utilsÚ_get_response_headersÚutilsÚ&_get_retry_after_from_exception_headerr$   r   r   Ú	Exception)r   r   r   r*   r)   Údeployment_dictÚdeployment_cooldownÚexception_headersÚ_get_retry_afterÚheader_cooldownr,   Úes               úq/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/router_utils/fallback_event_handlers.pyÚ'_trigger_cooldown_for_failed_deploymentr?   (   s  € ðZ`Ü+¨IÔ6Ü!×'Ñ'ðKôð ä-4°YÀÈrÓ-RÐð �J‰JÐ2Ó3Ð?Ü,Ð-=Ó>ÔB^Ñ^ä!×'Ñ'ðOà ôð
 ð �:‰:Ð+Ô,Ô1MÐN^Ó1_ÐcfÒ1fÜ!×'Ñ'ðLôð ô ,3°9Ð>TÐVZÓ+[ˆàÐ Ü!×'Ñ'Ð(tÔuØð "0×!>Ñ!>À-Ð!>Ó!Pˆð
 Ð*ô Ø×#Ñ# LÓ1°?×3FÑ3FÐGWÓ3XÐ^mõð ð 	ô $+×#=Ñ#=×#UÑ#U×#kÑ#kØ(ð $ló $
Ðô �M‰M×@Ñ@ð 	ð EVÐDaÑÐ.?Õ@Ðgkð 	ð
 #Ð.Ð3FÈ!Ò3Kñ  ð #Ð.°?ÀaÒ3Gñ  à#×1Ñ1ð 	ô 	9Ø$2Ø'õ	
ô 	"Ø$2Ø-Ø(Ø$Ø-õ	
ô 	×#Ñ#Ð$SÐUbÕcøÜò `Ü×#Ñ#Ð$[Ð]^×_Ñ_ûð`ús0   ‚ F( £AF( Á)4F( Â$F( ÃC$F( Æ(	GÆ1GÇGÚfallback_targetc                 óD  — t        | t        «      r| S t        | t        «      sy| j                  d«      }t	        | «      dk(  rt        |t        «      r|S t        j                  | dt        ¬«      }t        j                  |j                  «       «      j                  «       S )aß  
    Identity of one fallback attempt, so the same attempt is never made twice per request.

    A bare model group name and a `{"model": name}` entry describe the same attempt. An
    entry carrying anything else describes a different one and keeps its own identity: a
    client-side fallback list overrides request params such as `messages`, and the router
    re-targets the group that just failed by attaching `_target_order` or
    `_excluded_deployment_ids` to select a different set of deployments inside it. The
    payload is hashed rather than kept, so a large `messages` override does not make the
    request hold a second copy of itself.

    Returns None for a shape with no usable identity, which is never skipped.
    NÚmodel)rB   T)Ú	sort_keysÚdefault)Ú
isinstanceÚstrÚdictr/   ÚtupleÚjsonÚdumpsÚhashlibÚsha256ÚencodeÚ	hexdigest)r@   rB   Ú
serializeds      r>   Úfallback_attempt_keyrP   ’   s   € ô �/¤3Ô'ØÐÜ�o¤tÔ,ØØ"×&Ñ& wÓ/€EÜˆ_Ó Ò+´
¸5Ä#Ô0FØˆÜŸ
™
 ?¸dÌCÔP€JÜ�>‰>˜*×+Ñ+Ó-Ó.×8Ñ8Ó:Ð:ó    T)Úslotsc                   óP   — e Zd ZU dZ e«       Zee   ed<   dedefd„Z	deddfd„Z
y)ÚAttemptedFallbackTargetsañ  
    The fallback attempts a single request has already made.

    One instance is created on the first fallback hop and shared by reference for the rest
    of the walk, so an attempt made in one branch is not repeated in a sibling branch.
    Without it the walk enumerates paths rather than attempts: a fallback graph containing
    a cycle retries one deterministic failure once per path through the cycle, and a
    client-side fallback list is re-walked at every level of the recursion.
    Úkeysr%   r   c                 ó   — || j                   v S ©N)rU   ©Úselfr%   s     r>   Ú__contains__z%AttemptedFallbackTargets.__contains__¹   s   € Ø�d—i‘iÐÐrQ   Nc                 ó@   — | j                   t        |f«      z  | _         y rW   )rU   Ú	frozensetrX   s     r>   ÚrecordzAttemptedFallbackTargets.record¼   s   € Ø—I‘I¤	¨3¨&Ó 1Ñ1ˆ�	rQ   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r\   rU   rF   Ú__annotations__ÚboolrZ   r]   © rQ   r>   rT   rT   «   s?   … ññ %›;€Dˆ)�C‰.Ó&ð  ð  ¨ó  ð2˜#ð 2 $ô 2rQ   rT   Úmodel_groupÚfallback_keyc                 óÎ   — t         j                  D ]R  }t        |t        «      r|j                  }n|}| j                  |› d�«      sŒ7| j                  |› d�d«      }||k(  sŒR y y)zô
    Handles wildcard routing scenario

    where fallbacks set like:
    [{"gpt-3.5-turbo": ["claude-3-haiku"]}]

    but model_group is like:
    "openai/gpt-3.5-turbo"

    Returns:
    - True if the stripped model group == fallback_key
    ú/r   TF)r1   Úprovider_listrE   r   ÚvalueÚ
startswithÚreplace)re   rf   ÚproviderÚ	_providerÚstripped_model_groups        r>   Ú_check_stripped_model_grouprp   À   sn   € ô ×)Ñ)ò ˆÜ�h¤Ô%Ø Ÿ™‰Ià ˆIØ×!Ñ! Y K¨q /Õ2Ø#.×#6Ñ#6¸)¸ÀA°ÈÓ#KÐ Ø# |Ó3Ùðð rQ   Ú	fallbacksc                 óÌ  — d}d}d}t        | «      D ]¹  \  }}t        |t        «      r�t        |j	                  «       «      d   |k(  r||   } n€t        |t        |j	                  «       «      d   ¬«      r |t        |j	                  «       «      d      }Œƒt        |j	                  «       «      d   dk(  sŒ£|}Œ¦t        |t        «      sŒ·|g}Œ» |€|�|}||fS |�| |   d   }||fS )a)  
    Returns:
    - fallback_model_group: List[str] of fallback model groups. example: ["gpt-4", "gpt-3.5-turbo"]
    - generic_fallback_idx: int of the index of the generic fallback in the fallbacks list.

    Checks:
    - exact match
    - stripped model group match
    - generic fallback
    Nr   )re   rf   Ú*)Ú	enumeraterE   rG   ÚlistrU   rp   rF   )rq   re   Úgeneric_fallback_idxÚstripped_model_fallbackÚfallback_model_groupÚidxÚitems          r>   Úget_fallback_model_groupr{   Ù   s  € ð (,ÐØ04ÐØ-1Ðä˜yÓ)ò *‰	ˆˆTÜ�dœDÔ!Ü�D—I‘I“KÓ  Ñ# {Ò2Ø'+¨KÑ'8Ð$ÙÜ,Ø'´d¸4¿9¹9»;Ó6GÈÑ6Jõð +/¬t°D·I±I³KÓ/@ÀÑ/CÑ*DÑ'Ü�d—i‘i“kÓ" 1Ñ%¨Ó,Ø'*Ñ$Ü˜œcÕ"Ø$( 6Ñ ð*ð Ð#Ø"Ð.Ø#:Ð ð  Ð!5Ð5Ð5ð "Ð-Ø#,Ð-AÑ#BÀ3Ñ#GÐ àÐ!5Ð5Ð5rQ   )Úinput_file_idÚtraining_fileÚbatch_idÚfile_idÚfine_tuning_job_idÚPROVIDER_SCOPED_RESOURCE_KEYS>   Úafile_deleteÚafile_contentÚ_acancel_batchÚ_acreate_batchÚacancel_fine_tuning_jobÚacreate_fine_tuning_jobÚaretrieve_fine_tuning_jobÚ'PROVIDER_SCOPED_RESOURCE_FUNCTION_NAMESÚ_acreate_fileÚ'PROVIDER_SCOPED_CREATION_FUNCTION_NAMESÚfallback_entryc                 óp   — t        | t        «      r| S | j                  d«      }t        |t        «      r|S d S )NrB   )rE   rF   r/   )rŒ   Útargets     r>   Ú _get_fallback_target_model_groupr�     s6   € Ü�.¤#Ô&ØÐØ"×&Ñ& wÓ/€FÜ ¬Ô,ˆ6Ð6°$Ð6rQ   Úoriginal_model_groupc              ƒ   ó¸   K  — | j                   }t        |«      }|�|�||k(  ry |||| ¬«      ƒ d {  –—† ryt        j                  dt	        |«      «       y7 Œ%­w)NT)rB   Úrequest_kwargsÚ
llm_routerzJSkipping fallback to model_group = %s: caller is not authorized to call itF)Úfallback_access_checkr�   r	   Úinfor   )r   rŒ   r�   r   Úaccess_checkrŽ   s         r>   Ú_is_fallback_target_authorizedr—     sk   è ø€ ð )×>Ñ>€LÜ4°^ÓD€FØÐ˜v˜~°Ð;OÒ1OØÙ °vÈ.ÔY×YÐYØÜ×ÑØTÜ  Ó0ôð ð Zús   ‚0A²A³&Ac                 ó‚   ‡ — t        ˆ fd„dD «       «      }t        d„ |D «       «      ryt        ˆ fd„t        D «       «      S )a×  
    True when a file, batch, or fine-tuning job operation names an id that only exists
    under one provider's credentials.

    Each of those ids lives in the account of the deployment that issued it. Handing it to
    a different model group asks a provider about an id it never issued, which costs an
    extra round trip that can only answer not-found. Generic calls dispatched through
    `Router._ageneric_api_call_with_fallbacks` carry the real handler in
    `original_generic_function`, so both slots are checked. Gating on the handler name
    keeps completion-style requests eligible for cross-group fallback even when a caller
    passes a stray extra body field that happens to share one of these key names.
    c              3   óV   •K  — | ]   }t        ‰j                  |«      d d«      –— Œ" y­w)r^   N)r.   r/   )Ú.0Úfunction_keyr   s     €r>   ú	<genexpr>z6references_provider_scoped_resource.<locals>.<genexpr>5  s+   øè ø€ ò !àô 	�—
‘
˜<Ó(¨*°d×;ñ!ùs   ƒ&))Úoriginal_functionr   c              3   ó,   K  — | ]  }|t         v–— Œ y ­wrW   )r‰   )rš   Únames     r>   rœ   z6references_provider_scoped_resource.<locals>.<genexpr>9  s   è ø€ Ò
YÀ4ˆ4Ô>Ô>Ñ
Yùs   ‚Fc              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrW   )r/   )rš   r%   r   s     €r>   rœ   z6references_provider_scoped_resource.<locals>.<genexpr>;  s   øè ø€ ÒH 3ˆv�z‰z˜#�ÑHùs   ƒ)rH   ÚallÚanyr�   )r   Úhandler_namess   ` r>   Ú#references_provider_scoped_resourcer¤   (  sA   ø€ ô !ó !àNô!ó €Mô Ñ
YÈ=Ô
YÔYØÜÓHÔ*GÔHÓHÐHrQ   c                 óF   — t        | j                  d«      dd«      t        v S )a·  
    True when the request creates a resource that will live under one provider's credentials.

    A file uploaded for batches or fine-tuning is stored in the account of the deployment
    that handled it, and its id is only usable against the model group the caller named.
    Letting the upload fall back to a different model group silently stores the file with
    the wrong provider, and every later use of the returned id fails.
    r�   r^   N)r.   r/   r‹   )r   s    r>   Ú creates_provider_scoped_resourcer¦   >  s#   € ô �6—:‘:Ð1Ó2°JÀÓEÔIpÐpÐprQ   F)Úinclude_fallback_errorsÚargsrx   r&   Úmax_fallbacksÚfallback_depthr§   c              �   ó&  K  — ||k\  r|‚|}	t        |«      f}
t        t        |j                  d«      dd«      ¬«      }t	        |«      xs t        |«      }|j                  d«      }t        |t        «      r|n	t        «       }|j                  |«       |D �]ò  }||k(  rŒ
|r/t        |«      |k7  r!t        j                  dt        |«      |«       Œ;t        | |||«      ƒ d{  –—† sŒRt        |«      }|�5||v r t        j                  dt        |«      «       Œƒ|j                  |«       	 | j                  ||¬«      }t        j                  d	t        |«      «       t        |t         «      r||d
<   n!t        |t"        «      r|j%                  |«       |dz   }t#        |j                  |«      xs i «      }|j'                  d|«      }|j'                  dd«       |j'                  dd«       ||d<   |j                  d
d«      |d<   ||d<   |||<   ||d<   ||d<   ||d<   |r||d<    | j(                  |i |¤Žƒ d{  –—† }t        j                  d«       t+        |||rt-        |
«      nd¬«      }t/        |||¬«      ƒ d{  –—†  |c S  |	‚7 �Œ¬7 ŒT7 Œ# t0        $ rp}|}	|
t        |«      fz   }
t3        |||¬«      ƒ d{  –—†7   |j                  d«      }|�*|j4                  j                  dd«      rt7        | ||¬«       Y d}~�Œsd}~ww xY w­w)a  
    Loops through all the fallback model groups and calls kwargs["original_function"] with the arguments and keyword arguments provided.

    If the call is successful, it logs the success and returns the response.
    If the call fails, it logs the failure and continues to the next fallback model group.
    If all fallback model groups fail, it raises the most recent exception.

    Args:
        litellm_router: The litellm router instance.
        *args: Positional arguments.
        fallback_model_group: List[str] of fallback model groups. example: ["gpt-4", "gpt-3.5-turbo"]
        original_model_group: The original model group. example: "gpt-3.5-turbo"
        original_exception: The original exception.
        **kwargs: Keyword arguments. `attempted_targets` carries the fallback attempts
            already made for this request, created on the first hop and shared by reference
            for the rest of the walk. A target already in it is skipped, so neither a
            fallback graph that loops back on itself nor a client-side fallback list
            re-walked at each level can repeat an attempt that has already failed. Identity
            comes from `fallback_attempt_key`, so an entry that overrides request params or
            re-targets the failed group with a different deployment selection stays distinct
            from a bare name.

    Returns:
        The response from the successful fallback model group.
    Raises:
        The most recent exception if all fallback model groups fail.
    r�   r^   N)Úfunction_nameÚattempted_targetszYSkipping fallback to model_group = %s: request names a resource owned by model_group = %szISkipping fallback to model_group = %s, already attempted for this request)r   r=   z Falling back to model_group = %srB   é   r�   re   Úattempted_fallbacksrª   r©   r§   zSuccessful fallback b/w models.)Úresponser¯   Úfallback_errors©r�   r   r&   Úlitellm_logging_objÚhas_logged_async_failureF)r   r   r   )r   r   r.   r/   r¤   r¦   rE   rT   r]   r�   r	   r•   r   r—   rP   Ú	log_retryrF   rG   ÚupdateÚpopÚasync_function_with_fallbacksr   ru   Úlog_success_fallback_eventr7   Úlog_failure_fallback_eventÚmodel_call_detailsr?   )r   rx   r�   r&   r©   rª   r§   r¨   r   Úerror_from_fallbacksr±   Úmetadata_variable_nameÚsame_model_group_onlyÚcarried_targetsÚ	attemptedÚmgÚattempt_keyÚ_hop_metadataÚ_original_model_group_stampr°   r=   Úlogging_objs                         r>   Úrun_async_fallbackrÆ   J  sy  è ø€ ðP ˜Ò&Ø Ð à-ÐÜ.Ð/AÓBÐD€OÜ$FÜ˜fŸj™jÐ)<Ó=¸zÈ4ÓPô%Ðô $GÀvÓ#Nò $ÔRrØóSÐð $ŸZ™ZÐ(;Ó<€Oä% oÔ7OÔP‰ÔVnÓVpð ð ×ÑÐ)Ô*à"ó GˆØÐ%Ò%ØÙ Ô%EÀbÓ%IÐMaÒ%aÜ!×&Ñ&ØkÜ(¨Ó,Ø$ôð
 Ü3°NÀBÐH\Ð^dÓe×eÐeØÜ*¨2Ó.ˆØÐ"Ø˜iÑ'Ü%×*Ñ*Ø_Ü,¨RÓ0ôð Ø×Ñ˜[Ô)ð2	à#×-Ñ-°VÐ?QÐ-ÓRˆFÜ!×&Ñ&Ð'IÔKcÐdfÓKgÔhÜ˜"œcÔ"Ø"$��w’Ü˜B¤Ô%Ø—‘˜bÔ!Ø+¨aÑ/ˆNÜ  §¡Ð,BÓ!CÒ!IÀrÓJˆMØ*7×*;Ñ*;Ð<RÐThÓ*iÐ'Ø×Ñ˜m¨TÔ2Ø×ÑÐ3°TÔ:Ø4OˆMÐ0Ñ1Ø+1¯:©:°g¸tÓ+DˆM˜-Ñ(Ø3AˆMÐ/Ñ0Ø-:ˆFÐ)Ñ*Ø'5ˆFÐ#Ñ$Ø&3ˆF�?Ñ#Ø*3ˆFÐ&Ñ'Ù&Ø4K�Ð0Ñ1ØI˜^×IÑIÈ4ÐZÐSYÑZ×ZˆHÜ!×&Ñ&Ð'HÔIÜ7Ø!Ø$2Ù:Q¤ oÔ!6ÐW[ôˆHô -Ø%9ØØ#5ô÷ ð ð
 ŠOðqGðP Ðð} fùðB [øðùô ò 	Ø#$Ð Ø-Ô1HÈÓ1KÐ0MÑMˆOÜ,Ø%9ØØ#5ô÷ ñ ð
 !Ÿ*™*Ð%:Ó;ˆKØÐ&¨;×+IÑ+I×+MÑ+MÐNhÐjoÔ+pÜ7Ø#1Ø!Øõÿùð	üsp   ‚C LÃ"JÃ#ALÄ+DJÈ<JÈ=AJÊJÊJÊLÊJÊJÊ	LÊ"L	Ë KËAL	ÌLÌ	LÌLc              ƒ   óö   K  — t         j                  j                  t        «      }|D ]  }	 |j	                  | ||¬«      ƒ d{  –—†  Œ! y7 Œ# t
        $ r }t        j                  d|«       Y d}~ŒId}~ww xY w­w)a·  
    Log a successful fallback event to all registered callbacks.

    Uses LoggingCallbackManager.get_custom_loggers_for_type() to get deduplicated
    CustomLogger instances from all callback lists.

    Args:
        original_model_group (str): The original model group before fallback.
        kwargs (dict): kwargs for the request

    Note:
        Errors during logging are caught and reported but do not interrupt the process.
    r²   Nz'Error in log_success_fallback_event: %s)r1   Úlogging_callback_managerÚget_custom_loggers_for_typer
   r¹   r7   r	   Úerror©r�   r   r&   Úcustom_loggersÚ_callback_custom_loggerr=   s         r>   r¹   r¹   Ñ  ó‹   è ø€ ô $×<Ñ<×XÑXÔYeÓf€Nà#1ò VÐð	VØ)×DÑDØ%9ØØ#5ð Eó ÷ ñ ñVðùô
 ò 	VÜ!×'Ñ'Ð(QÐST×UÑUûð	Vüó@   ‚)A9¬AÁAÁAÁA9ÁAÁ	A6ÁA1Á,A9Á1A6Á6A9c              ƒ   óö   K  — t         j                  j                  t        «      }|D ]  }	 |j	                  | ||¬«      ƒ d{  –—†  Œ! y7 Œ# t
        $ r }t        j                  d|«       Y d}~ŒId}~ww xY w­w)a³  
    Log a failed fallback event to all registered callbacks.

    Uses LoggingCallbackManager.get_custom_loggers_for_type() to get deduplicated
    CustomLogger instances from all callback lists.

    Args:
        original_model_group (str): The original model group before fallback.
        kwargs (dict): kwargs for the request

    Note:
        Errors during logging are caught and reported but do not interrupt the process.
    r²   Nz'Error in log_failure_fallback_event: %s)r1   rÈ   rÉ   r
   rº   r7   r	   rÊ   rË   s         r>   rº   rº   í  rÎ   rÏ   c                 óþ   — | �t        | t        «      rt        | «      dk(  ryt        d„ | D «       «      ryt        d„ | D «       «      r7| D ]2  }t        j
                  D ]  }||v sŒt        ||   t        «      rŒ  y Œ4 y)ar  
    Checks if the fallbacks list is a list of strings or a list of dictionaries.

    If
    - List[str]: e.g. ["claude-3-haiku", "openai/o-1"]
    - List[Dict[<LiteLLMParamsTypedDict>, Any]]: e.g. [{"model": "claude-3-haiku", "messages": [{"role": "user", "content": "Hey, how's it going?"}]}]

    If [{"gpt-3.5-turbo": ["claude-3-haiku"]}] then standard format.
    r   Fc              3   ó<   K  — | ]  }t        |t        «      –— Œ y ­wrW   )rE   rF   ©rš   rz   s     r>   rœ   z6_check_non_standard_fallback_format.<locals>.<genexpr>  s   è ø€ Ò
7 TŒ:�dœC× Ñ
7ùó   ‚Tc              3   ó<   K  — | ]  }t        |t        «      –— Œ y ­wrW   )rE   rG   rÓ   s     r>   rœ   z6_check_non_standard_fallback_format.<locals>.<genexpr>  s   è ø€ Ò:¨ŒZ˜œd×#Ñ:ùrÔ   )rE   ru   Úlenr¡   r   rb   )rq   rz   r%   s      r>   Ú#_check_non_standard_fallback_formatr×   	  s„   € ð Ð¤
¨9´dÔ ;¼sÀ9»~ÐQRÒ?RØÜ
Ñ
7¨YÔ
7Ô7ØÜ	Ñ:°	Ô:Ô	:Øò 	$ˆDÜ-×=Ñ=ò $�Ø˜$’;ô & d¨3¡i´Õ6Ú#ñ$ð	$ð rQ   c                  ó   — y rW   rd   )rq   re   s     r>   Ú run_non_standard_fallback_formatrÙ   #  s   € ØrQ   )ArK   rI   Úcollections.abcr   Údataclassesr   Úenumr   Útypingr   r   r   r1   Úlitellm._loggingr	   Ú"litellm.integrations.custom_loggerr
   Ú0litellm.litellm_core_utils.sensitive_data_maskerr   Ú/litellm.router_utils.add_retry_fallback_headersr   r   Ú litellm.router_utils.batch_utilsr   Ú&litellm.router_utils.cooldown_handlersr   r   r   r   Ú>litellm.router_utils.router_callbacks.track_deployment_metricsr   Úlitellm.types.routerr   Úlitellm.routerr   Ú_RouterÚLitellmRouterr\   r   rb   rF   r7   r?   ÚobjectrP   rT   rc   rp   ru   rH   Úintr{   r�   r‰   r‹   r�   r—   r¤   r¦   rÆ   rG   r¹   rº   r×   rÙ   rd   rQ   r>   ú<module>rë      s  ðÜ Û Ý #Ý !Ý ß ,Ñ ,ã Ý 2Ý ;Ý U÷õ P÷ó õõ 8áÝ0à�Mà€Mñ '0°Ó&7Ð ˜eÓ 7ðg`Ø!ðg`à�C˜�HÑðg`ð ðg`ð 
ó	g`ðT;¨&ð ;°S¸4±Zó ;ñ2 �Ô÷2ð 2ó ð2ð(¨Sð Àð Èó ð2#6¨¨S©	ð #6Àð #6ÈÈdÐSVÉiÐZ^ÑN^Ð`cÐfjÑ`jÐNjÑHkó #6ðL (wÐ ˜uÓ vÙ1:òó
2Ð '¨ó 
ñ 2;¸OÐ;LÓ1MÐ '¨Ó Mð7°S¸7À3ÈÀ;Ñ;OÑ5Oð 7ÐTWÐZ^ÑT^ó 7ðØ!ðà˜' # v +Ñ.Ñ.ðð ðð �C˜�KÑ ð	ð
 
óð&I°¸¸V¸Ñ0Dð IÈó Ið,	q¨W°S¸&°[Ñ-Að 	qÀdó 	qð( %*òDØ�‰:ðDà!ðDð ˜s™)ðDð ð	Dð
 "ðDð ðDð ðDð "ðDð 	óDðNV¸3ð VÈð VÐbkó Vð8V¸3ð VÈð VÐbkó Vð8°4¸±9¸tÑ3Cð Èó ð4	°°S±	¸DÀÀcÈ3ÀhÁÑ<PÑ0Pð 	Ð_bô 	rQ   