
    g4                        d dl mZ d dlmZmZmZmZ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 er	d dlmZ eZneZded	ed
efdZdee   ded
eeee      ee   f   fdZdee   dedee   dedededed
efdZdedee   dee   deded
efdZdededefdZdededefdZdeee      d
efdZ de	ee   eeeef      f   defdZ!y)    )Enum)TYPE_CHECKINGAnyDictListOptionalTupleUnionN)verbose_router_logger)CustomLogger)LiteLLMParamsTypedDict)Routermodel_groupfallback_keyreturnc                     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
    / TF)litellmprovider_list
isinstancer   value
startswithreplace)r   r   provider	_providerstripped_model_groups        a/var/www/openai/venv/lib/python3.12/site-packages/litellm/router_utils/fallback_event_handlers.py_check_stripped_model_groupr      si     ))h% I I!!YKq/2#.#6#6)A#K #|3 *     	fallbacksc                    d}d}d}t        |       D ]  \  }}t        |t              rt        |j	                               d   |k(  r||   } nt        |t        |j	                               d         r |t        |j	                               d      }t        |j	                               d   dk(  s|}t        |t              s| j                  |      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   )r   r   *)	enumerater   dictlistkeysr   strpop)r!   r   generic_fallback_idxstripped_model_fallbackfallback_model_groupidxitems          r   get_fallback_model_groupr/   *   s    +/3704y)	TdD!DIIK #{2'+K'8$,'d499;6G6J +/tDIIK/@/C*D'diik"1%,'*$c"$-MM#$6#7  * #".#:   !555 "-#,-A#B3#G !555r    argslitellm_routerr,   original_model_grouporiginal_exceptionmax_fallbacksfallback_depthc                 x  K   ||k\  r||}|D ]  }	|	|k(  r		 | j                  ||      }t        j                  d|	        t        |	t              r|	|d<   n!t        |	t
              r|j                  |	       |j                  di       j                  d|j                  dd      i       |dz   |d<   ||d	<    | j                  |i | d{   }
t        j                  d
       t        |||       d{    |
c S  |7 67 # t        $ r$}|}t        |||       d{  7   Y d}~$d}~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.

    Returns:
        The response from the successful fallback model group.
    Raises:
        The most recent exception if all fallback model groups fail.
    kwargseFalling back to model_group = modelmetadatar   N   r5   r4   Successful fallback b/w models.r2   r8   r3   )	log_retryr   infor   r(   r%   update
setdefaultgetasync_function_with_fallbackslog_success_fallback_event	Exceptionlog_failure_fallback_event)r1   r,   r2   r3   r4   r5   r0   r8   error_from_fallbacksmgresponser9   s               r   run_async_fallbackrL   R   sr    @ &  -"%%	#--V?Q-RF!&&)Gt'LM"c""$wB%b!j"-44

7D 9: (6'9F#$&3F?#I^II H "&&'HI,%9#5  
 O5 #D %
  	#$ ,%9#5  	s_   D:B7D
D*D
:D;D
 D:D
D

	D7D2&D)'D2,D:2D77D:c                P   |}|D ]  }||k(  r		 | j                  ||      }t        j                  d|        ||d<   |j                  di       j	                  d|i        | j
                  |i |}t        j                  d       |c S  |# t        $ r}	|	}Y d}	~	d}	~	ww xY w)a  
    Synchronous version of run_async_fallback.
    Loops through all the fallback model groups and calls kwargs["original_function"] with the arguments and keyword arguments provided.

    If the call is successful, returns the response.
    If the call fails, 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.

    Returns:
        The response from the successful fallback model group.
    Raises:
        The most recent exception if all fallback model groups fail.
    r7   r:   r;   r<   r   r>   N)r@   r   rA   rC   rB   function_with_fallbacksrG   )
r1   r,   r2   r3   r0   r8   rI   rJ   rK   r9   s
             r   run_sync_fallbackrO      s    : ."%%	%#--V?Q-RF!&&)Gt'LM F7Oj"-44# >~==tNvNH!&&'HIO #    	%#$ 	%s   A;B	B%B  B%r8   c                   K   ddl m} t        j                  D ]  }t	        |t
              s|t        j                  v s&	 d}|t        j                  v r ||dd      }n,t	        |t
              r|}nt        j                  | d       s|t        j                  | d       |j                  | ||       d{     y7 # t        $ r+}t        j                  dt        |              Y d}~d}~ww xY ww)	a  
    Log a successful fallback event to all registered callbacks.

    This function iterates through all callbacks, initializing _known_custom_logger_compatible_callbacks  if needed,
    and calls the log_success_fallback_event method on CustomLogger instances.

    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   $_init_custom_logger_compatible_classNlogging_integration
llm_routerinternal_usage_cache( logger not found / initialized properlyz: logger not found / initialized properly, callback is Noner?   z%Error in log_success_fallback_event: )*litellm.litellm_core_utils.litellm_loggingrR   r   	callbacksr   r   )_known_custom_logger_compatible_callbacksr   	exceptionrF   rG   errorr(   r2   r8   r3   rR   	_callback_callback_custom_loggerr9   s          r   rF   rF      s      &&	i.JJJBF' Q QQ.R,5#'-1/+
  	<8.7+)33$+%MN *2)33$+%_` -HH)=!'9 I   5 '4
  %++;CF8D Z   <C? ACC?C&C?'C>C?CC?C	C<!C72C?7C<<C?c                   K   ddl m} t        j                  D ]  }t	        |t
              s|t        j                  v s&	 d}|t        j                  v r ||dd      }n,t	        |t
              r|}nt        j                  | d       s|t        j                  | d       |j                  | ||       d{     y7 # t        $ r+}t        j                  dt        |              Y d}~d}~ww xY ww)a  
    Log a failed fallback event to all registered callbacks.

    This function iterates through all callbacks, initializing _known_custom_logger_compatible_callbacks if needed,
    and calls the log_failure_fallback_event method on CustomLogger instances.

    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   rQ   NrS   rW   r?   z%Error in log_failure_fallback_event: )rX   rR   r   rY   r   r   rZ   r   r[   rH   rG   r\   r(   r]   s          r   rH   rH     s      &&	i.JJJBF' Q QQ.R,5#'-1/+
  	<8.7+)33$+%MN *2)33$+%MN -HH)=!'9 I   5 '4
  %++;CF8D r`   c                    | t        | t              rt        |       dk(  ryt        d | D              ryt        d | D              r:t        j
                  j                         D ]  }|| d   j                         v s y 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N)r   r(   .0r.   s     r   	<genexpr>z6_check_non_standard_fallback_format.<locals>.<genexpr>K  s     
7YT:dC Y   Tc              3   <   K   | ]  }t        |t                y wrd   )r   r%   re   s     r   rg   z6_check_non_standard_fallback_format.<locals>.<genexpr>M  s     :	Zd#	rh   )r   r&   lenallr   __annotations__r'   )r!   keys     r   #_check_non_standard_fallback_formatrn   ?  sx     
9d ;s9~QR?R

7Y
77	:	:	:)99>>@Cil'')) A r    c                      y rd    )r!   r   s     r    run_non_standard_fallback_formatrq   U  s     	r    )"enumr   typingr   r   r   r   r   r	   r
   r   litellm._loggingr   "litellm.integrations.custom_loggerr   litellm.types.routerr   litellm.routerr   _RouterLitellmRouterr(   boolr   intr/   rG   rL   rO   r%   rF   rH   rn   rq   rp   r    r   <module>r|      s    I I I  2 ; 70MMS   2%6Cy%6'*%6
8DI-.%6PG:G!G s)G 	G
 "G G G 	GT.!.:. s). 	.
 ". 	.b66'+6AJ6r66'+6AJ6r8DI3F 4 ,	T#YT#s(^ 445	DG	r    