
    g"                     |    d Z ddlZddl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  G d d      Z G d	 d
      Zy)zA
Class to handle llm wildcard routing and regex pattern matching
    N)Match)DictListOptionalTuple)get_llm_provider)verbose_router_loggerc            	       p    e Zd Zededeeef   fd       Zedeee	e   f   de	eee	e   f      fd       Z
y)PatternUtilspatternreturnc                 N     g d}t               t         fd|D              f}|S )z
        Calculate pattern specificity based on length and complexity.

        Args:
            pattern: Regex pattern to analyze

        Returns:
            Tuple of (length, complexity) for sorting
        )	*+?\^$|()c              3   @   K   | ]  }j                  |        y wN)count).0charr   s     c/var/www/openai/venv/lib/python3.12/site-packages/litellm/router_utils/pattern_match_deployments.py	<genexpr>z=PatternUtils.calculate_pattern_specificity.<locals>.<genexpr>   s      0@d#0@s   )lensum)r   complexity_charsret_vals   `  r   calculate_pattern_specificityz*PatternUtils.calculate_pattern_specificity   s6     JL 0@ 
     patternsc                 <    t        | j                         d d      S )z
        Cached property for patterns sorted by specificity.

        Returns:
            Sorted list of pattern-deployment tuples
        c                 2    t         j                  | d         S )Nr   )r   r#   )xs    r   <lambda>z.PatternUtils.sorted_patterns.<locals>.<lambda>/   s    ,DDQqTJr$   T)keyreverse)sorteditemsr%   s    r   sorted_patternszPatternUtils.sorted_patterns#   s!     NNJ
 	
r$   N)__name__
__module____qualname__staticmethodstrr   intr#   r   r   r/    r$   r   r   r      sm    s uS#X  & 
sDJ'
	eCdO$	%
 
r$   r   c            	           e Zd ZdZd ZdedefdZdedefdZde	d	e
e   de
e   fd
Z	 ddee   dee
e      dee
e      fdZede	dedefd       Z	 ddedee   dee
e      fdZ	 ddedee   de
e   fdZy)PatternMatchRouterz
    Class to handle llm wildcard routing and regex pattern matching

    doc: https://docs.litellm.ai/docs/proxy/configs#provider-specific-wildcard-routing

    This class will store a mapping for regex pattern: List[Deployments]
    c                     i | _         y r   r.   )selfs    r   __init__zPatternMatchRouter.__init__=   s	    )+r$   r   llm_deploymentc                     | j                  |      }|| j                  vrg | j                  |<   | j                  |   j                  |       y)z
        Add a regex pattern and the corresponding llm deployments to the patterns

        Args:
            pattern: str
            llm_deployment: str or List[str]
        N)_pattern_to_regexr%   append)r:   r   r<   regexs       r   add_patternzPatternMatchRouter.add_pattern@   sE     &&w/%#%DMM% e##N3r$   r   c                 L    t        j                  |      j                  dd      S )a0  
        Convert a wildcard pattern to a regex pattern

        example:
        pattern: openai/*
        regex: openai/.*

        pattern: openai/fo::*::static::*
        regex: openai/fo::.*::static::.*

        Args:
            pattern: str

        Returns:
            str: regex pattern
        z\*z(.*))reescapereplace)r:   r   s     r   r>   z$PatternMatchRouter._pattern_to_regexN   s     , yy!))%88r$   matched_patterndeploymentsc                     g }|D ]K  }t        j                  |      }t        j                  ||d   d         |d   d<   |j	                  |       M |S )Nlitellm_paramsmodel)rF    litellm_deployment_litellm_model)copydeepcopyr8   set_deployment_model_namer?   )r:   rF   rG   new_deployments
deploymentnew_deployments         r   #_return_pattern_matched_deploymentsz6PatternMatchRouter._return_pattern_matched_deploymentsf   sp     %J!]]:6N"<<$35?@P5Q6 =  +,W5 "">2 & r$   Nrequestfiltered_model_namesc                    	 |yt         j                  | j                        }||D cg c]  }| j                  |       c}ng }|D ]9  \  }}|||vrt	        j
                  ||      }|s&| j                  ||      c S  	 yc c}w # t        $ r+}	t        j                  dt        |	              Y d}	~	yd}	~	ww xY w)a  
        Route a requested model to the corresponding llm deployments based on the regex pattern

        loop through all the patterns and find the matching pattern
        if a pattern is found, return the corresponding llm deployments
        if no pattern is found, return None

        Args:
            request: str - the received model name from the user (can be a wildcard route). If none, No deployments will be returned.
            filtered_model_names: Optional[List[str]] - if provided, only return deployments that match the filtered_model_names
        Returns:
            Optional[List[Deployment]]: llm deployments
        N)rF   rG   z#Error in PatternMatchRouter.route: )r   r/   r%   r>   rC   matchrR   	Exceptionr	   debugr4   )
r:   rS   rT   r/   mregex_filtered_model_namesr   llm_deploymentspattern_matches
             r   routezPatternMatchRouter.routex   s     	X*::4==IO (3 5II4Hq''*4HI '
 -<((4'AA "' : CC(5? D   -< % J  	X!''*McRSfX(VWW	Xs9   B %B B,B /B B B 	C !B;;C rK   c                     d|vr|S |j                  d      }| j                         }t        |      |kD  r| j                  S |D ]  }|j	                  d|d      } |S )a  
        Set the model name for the matched pattern llm deployment

        E.g.:

        Case 1:
        model_name: llmengine/* (can be any regex pattern or wildcard pattern)
        litellm_params:
            model: openai/*

        if model_name = "llmengine/foo" -> model = "openai/foo"

        Case 2:
        model_name: llmengine/fo::*::static::*
        litellm_params:
            model: openai/fo::*::static::*

        if model_name = "llmengine/foo::bar::static::baz" -> model = "openai/foo::bar::static::baz"

        Case 3:
        model_name: *meta.llama3*
        litellm_params:
            model: bedrock/meta.llama3*

        if model_name = "hello-world-meta.llama3-70b" -> model = "bedrock/meta.llama3-70b"
        r      )r   groupsr   stringrE   )rF   rK   wildcard_countdynamic_segmentssegments        r   rN   z,PatternMatchRouter.set_deployment_model_name   s}    B 66339??D +113 >1&& (G/O/W/WWa0, (
 0/r$   rJ   custom_llm_providerc                     |	 t        |      \  }}}}| j                  |      xs | j                  | d|       S # t        $ r Y 4w xY w)z
        Check if a pattern exists for the given model and custom llm provider

        Args:
            model: str
            custom_llm_provider: Optional[str]

        Returns:
            bool: True if pattern exists, False otherwise
        )rJ   /)r   rW   r^   )r:   rJ   rf   _s       r   get_patternzPatternMatchRouter.get_pattern   sj     &	 %51'
 zz% PDJJ2E1Faw/O$PP  s   > 	A
	A
c                 2    | j                  ||      }|r|S g S )z
        Get the deployments by pattern

        Args:
            model: str
            custom_llm_provider: Optional[str]

        Returns:
            List[Dict]: llm deployments matching the pattern
        )rj   )r:   rJ   rf   r\   s       r   get_deployments_by_patternz-PatternMatchRouter.get_deployments_by_pattern   s%     ((0CD  	r$   r   )r0   r1   r2   __doc__r;   r4   r   rA   r>   r   r   rR   r   r^   r3   rN   rj   rl   r6   r$   r   r8   r8   4   s"   ,43 4 49 9 90$37:	d& SW(}(<DT#Y<O(	$t*	(T 2020*-20 
20 20j @DQQ/7}Q	$t*	Q6 @D/7}	dr$   r8   )rm   rL   rC   r   typingr   r   r   r   litellmr   litellm._loggingr	   r   r8   r6   r$   r   <module>rq      s8     	  . . $ 2#
 #
LM Mr$   