o
    ưi$                     @   sl  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 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dZdee d	edeeee  ee f fddZdee dedee dededededefddZdededefddZdededefddZ deee  defdd Z!de	ee eeeef  f d	efd!d"Z"dS )#    )Enum)TYPE_CHECKINGAnyDictListOptionalTupleUnionN)verbose_router_logger)CustomLogger) add_fallback_headers_to_response)LiteLLMParamsTypedDict)Routermodel_groupfallback_keyreturnc                 C   sV   t jD ]%}t|tr|j}n|}| | dr(| | dd}||kr( dS qdS )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)litellmZprovider_list
isinstancer   value
startswithreplace)r   r   provider	_providerZstripped_model_group r   c/home/app/Keep/.python/lib/python3.10/site-packages/litellm/router_utils/fallback_event_handlers.py_check_stripped_model_group   s   

r   	fallbacksc                 C   s   d}d}d}t | D ]H\}}t|trGt| d |kr#|| } n0t|t| d dr:|t| d  }q
t| d dkrF|}q
t|trR| |g}q
|du rk|dura|}||fS |durk| | 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   Zgeneric_fallback_idxZstripped_model_fallbackfallback_model_groupidxitemr   r   r   get_fallback_model_group-   s2   

r)   argslitellm_routerr&   original_model_grouporiginal_exceptionmax_fallbacksfallback_depthc                    s,  ||kr||}|D ]}	|	|krqzc| j ||d}td|	  t|	tr,|	|d< n
t|	tr6||	 |di d|ddi |d }||d< ||d	< | j	|i |I dH }
td
 t
|
|d}
t|||dI dH  |
W   S  ty } z|}t|||dI dH  W Y d}~qd}~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ezFalling back to model_group = modelmetadatar   N   r/   r.   zSuccessful fallback b/w models.)responseZattempted_fallbacksr,   r0   r-   )Z	log_retryr
   infor   r$   r!   update
setdefaultgetZasync_function_with_fallbacksr   log_success_fallback_event	Exceptionlog_failure_fallback_event)r+   r&   r,   r-   r.   r/   r*   r0   Zerror_from_fallbacksZmgr5   r1   r   r   r   run_async_fallbackU   s\    





r>   r0   c                    n   t jt}|D ]+}z|j| ||dI dH  W q	 ty4 } ztdt|  W Y d}~q	d}~ww dS )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.
    r6   Nz%Error in log_success_fallback_event: )	r   logging_callback_managerget_custom_loggers_for_typer   r;   r<   r
   errorr$   r,   r0   r-   Zcustom_loggersZ_callback_custom_loggerr1   r   r   r   r;      $   r;   c                    r?   )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.
    r6   Nz%Error in log_failure_fallback_event: )	r   r@   rA   r   r=   r<   r
   rB   r$   rC   r   r   r   r=      rD   r=   c                 C   st   | du st | trt| dkrdS tdd | D rdS tdd | D r8tj D ]}|| d  v r7 dS q*dS )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.
    Nr   Fc                 s       | ]}t |tV  qd S N)r   r$   .0r(   r   r   r   	<genexpr>       z6_check_non_standard_fallback_format.<locals>.<genexpr>Tc                 s   rE   rF   )r   r!   rG   r   r   r   rI      rJ   )r   r"   lenallr   __annotations__r#   )r   keyr   r   r   #_check_non_standard_fallback_format   s   
rO   c                 C   s   d S rF   r   )r   r   r   r   r    run_non_standard_fallback_format   s   rP   )#enumr   typingr   r   r   r   r   r   r	   r   Zlitellm._loggingr
   Z"litellm.integrations.custom_loggerr   Z/litellm.router_utils.add_retry_fallback_headersr   Zlitellm.types.routerr   Zlitellm.routerr   Z_RouterZLitellmRouterr$   boolr   intr)   r<   r>   r!   r;   r=   rO   rP   r   r   r   r   <module>   sp    $
(	
O
"
"