Ë
    uPêj]#  ã                   óp   — d Z 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	  G d„ d«      Z
 G d	„ d
«      Zy)zA
Class to handle llm wildcard routing and regex pattern matching
é    N)ÚMatch)ÚFinal)Úverbose_router_logger)Úget_llm_providerc            	       ó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     €ús/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/router_utils/pattern_match_deployments.pyú	<genexpr>z=PatternUtils.calculate_pattern_specificity.<locals>.<genexpr>   s   øè ø€ ÒA¨�—‘˜d×#ÑAùs   ƒ)ÚlenÚsum)r	   Úcomplexity_charsÚret_vals   `  r   Úcalculate_pattern_specificityz*PatternUtils.calculate_pattern_specificity   s0   ø€ ò #QÐä�‹LÜÓAÐ0@ÔAÓAð
ˆð ˆó    Ú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ÑDÀQÀqÁTÓJ€ r!   T)ÚkeyÚreverse)ÚsortedÚitems©r"   s    r   Úsorted_patternszPatternUtils.sorted_patterns!   s!   € ô Ø�N‰NÓÙJØô
ð 	
r!   N)Ú__name__Ú
__module__Ú__qualname__ÚstaticmethodÚstrÚtupleÚintr    ÚdictÚlistr,   © r!   r   r   r      sm   „ Øð¨sð °u¸SÀ#¸X±ò ó ðð" ð
Ø�s˜D ™J�Ñ'ð
à	ˆe�C˜˜d™�OÑ$Ñ	%ò
ó ñ
r!   r   c                   ó  — e Zd ZdZd„ Zdedefd„Zdeddfd	„Zdedefd
„Z	de
dee   dee   fd„Zddedz  dee   dz  dee   dz  fd„Zede
dedefd„«       Zddededz  dee   dz  fd„Zddededz  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   € ð ×-Ñ-¨gÓ6ˆØ˜Ÿ™Ñ%Ø#%ˆD�M‰M˜%Ñ Ø�‰�eÑ×#Ñ# NÕ3r!   Úmodel_idr
   Nc                 óú   — | j                   j                  «       D ���ci c]B  \  }}|D �cg c],  }|j                  d«      xs i j                  d«      |k7  sŒ+|‘Œ. c}x}r||“ŒD c}}}| _         yc c}w c c}}}w )zž
        Remove every deployment with the given model id from the pattern registry,
        dropping any pattern whose deployment list becomes empty.
        Ú
model_infoÚidN)r"   r*   Úget)r:   rB   r@   ÚdeploymentsÚdÚ	remainings         r   Úremove_deploymentz$PatternMatchRouter.remove_deploymentL   s}   € ð '+§m¡m×&9Ñ&9Ó&;÷
ð 
á"��{Ø)4Öj A¸¿¹¸|Ó9LÒ9RÐPR×8WÑ8WÐX\Ó8]ÐaiÓ8išaÒjÐj�	Ðjð �9Ñô
ˆ�ùò kùô
s   ŸA6«,A1ÁA1Á
A6Á1A6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_regexW   s    € ô, �y‰y˜Ó!×)Ñ)¨%°Ó8Ð8r!   Úmatched_patternrG   c                 óª   — g }|D ]K  }t        j                  |«      }t        j                  ||d   d   ¬«      |d   d<   |j	                  |«       ŒM |S )NÚlitellm_paramsÚmodel)rO   Ú litellm_deployment_litellm_model)ÚcopyÚdeepcopyr8   Úset_deployment_model_namer?   )r:   rO   rG   Únew_deploymentsÚ
deploymentÚnew_deployments         r   Ú#_return_pattern_matched_deploymentsz6PatternMatchRouter._return_pattern_matched_deploymentso   sn   € Ø!#ˆØ%ò 	3ˆJÜ!Ÿ]™]¨:Ó6ˆNÜ8J×8dÑ8dØ /Ø1;Ð<LÑ1MÈgÑ1Vð 9eó 9ˆNÐ+Ñ,¨WÑ5ð ×"Ñ" >Õ2ð	3ð Ðr!   ÚrequestÚfiltered_model_namesc                 óp  — 	 |€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|	«       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)rO   rG   z%Error in PatternMatchRouter.route: %s)
r   r,   r"   r>   rL   ÚmatchrZ   Ú	Exceptionr   Údebug)
r:   r[   r\   r,   ÚmÚregex_filtered_model_namesr	   Úllm_deploymentsÚpattern_matchÚes
             r   ÚroutezPatternMatchRouter.route{   sÚ   € ð	TØˆØä%1×%AÑ%AÀ$Ç-Á-Ó%PˆOàMaÐMmÐ4HÖI¨q�×'Ñ'¨Õ*ÓIÐsuð 'ð -<ò Ñ(�˜Ø'Ð3¸ÐGaÑ8aØÜ "§¡¨°'Ó :�Ú Ø×CÑCØ(5À?ð Dó ò ñð ùò Jøô ò 	TÜ!×'Ñ'Ð(OÐQR×SÐSàûð	Tús9   ‚B …%B ªBÁ,B Á/B ÂB ÂB Â	B5ÂB0Â0B5rS   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   ÚstringrN   )rO   rS   Úwildcard_countÚdynamic_segmentsÚsegments        r   rV   z,PatternMatchRouter.set_deployment_model_namež   s€   € ðB Ð6Ñ6Ø3Ð3à @× FÑ FÀsÓ Kˆð #2×"8Ñ"8Ó":ÐäÐÓ  >Ò1Ø"×)Ñ)Ð)à'ò 	iˆGØ/O×/WÑ/WÐX[Ð]dÐfgÓ/hÑ,ð	ið 0Ð/r!   rR   Ú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
        )rR   ú/)r   r_   rf   )r:   rR   rn   Ú_s       r   Úget_patternzPatternMatchRouter.get_patternÏ   sj   € ð Ð&ð	ô %¨5Ô1ñØØ'ØØð
 �z‰z˜%Ó ÒP D§J¡JÐ2EÐ1FÀaÈÀ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
        )rr   )r:   rR   rn   rd   s       r   Úget_deployments_by_patternz-PatternMatchRouter.get_deployments_by_patternç   s%   € ð  $×/Ñ/°Ð7JÓKˆÙØ Ð Øˆ	r!   r   )r-   r.   r/   Ú__doc__r;   r1   r4   rA   rJ   r>   r   r5   rZ   rf   r0   rV   rr   rt   r6   r!   r   r8   r8   2   s&  „ ñò,ð4 3ð 4¸ó 4ð	
¨#ð 	
°$ó 	
ð9¨ð 9°ó 9ð0
À5ð 
ÐW[Ð\`ÑWað 
ÐfjÐkoÑfpó 
ñ!˜S 4™Zð !¸tÀC¹yÈ4Ñ?Oð !Ð[_Ð`dÑ[eÐhlÑ[ló !ðF ð.0Øð.0à*-ð.0ð 
ò.0ó ð.0ñ`Q ð Q¸3À¹:ð QÐQUÐVZÑQ[Ð^bÑQbó Qñ0°ð È#ÐPTÉ*ð Ð`dÐeiÑ`jô r!   r8   )ru   rT   rL   r   Útypingr   Úlitellm._loggingr   Ú1litellm.litellm_core_utils.get_llm_provider_logicr   r   r8   r6   r!   r   ú<module>ry      s5   ðñó Û 	Ý Ý å 2Ý N÷!
ñ !
÷HCò Cr!   