Ë
    tPêj   ã                   ó°   — U d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 dZ
eed<   d	edz  d
eeef   fd„Zd	ed
eeef   dz  fd„Zdee	z  dedz  d
efd„Zy)z2
Shared utility functions for rate limiter hooks.
é    )ÚFinalN)Úverbose_proxy_logger)ÚModelGroupInfo)ÚPriorityReservationDictÚlitellm_proxyÚPROXY_LLM_PROVIDER_FALLBACKÚmodelÚreturnc           	      ó  — | sdt         fS 	 t        j                  | ¬«      \  }}}}|xs | |xs t         fS # t        $ rK}t	        | «      }|�|cY d}~S t        j                  d| t         t        |«      «       | t         fcY d}~S d}~ww xY w)uw  
    Resolve ``(model, llm_provider)`` for a request being rejected by an
    internal proxy-side rate-limit hook.

    These hooks fire from ``async_pre_call_hook`` â€” well before
    :func:`litellm.get_llm_provider` is invoked anywhere else in the request
    lifecycle â€” so the raised 429 would otherwise have an empty
    ``llm_provider`` field, making the resulting Prometheus
    ``litellm_proxy_failed_requests_metric`` show up with
    ``exception_class="RateLimitError"`` and no provider attribution.

    Resolution order:

    1. ``litellm.get_llm_provider(model)`` â€” covers raw provider/model
       strings the SDK already understands (``"gpt-4o-mini"``,
       ``"anthropic/claude-3-5-sonnet"``, ``"bedrock/..."`` etc.).
    2. **Router alias fallback** â€” nearly every real proxy deployment
       routes through a router ``model_name`` alias (e.g.
       ``"tpm-locked"`` â†’ ``litellm_params.model: openai/gpt-4o-mini``).
       ``get_llm_provider`` doesn't know router aliases, so without this
       step every alias call ended up labeled ``"litellm_proxy"``,
       defeating the field's purpose for the most common case.
    3. Defensive fallback to ``("", "litellm_proxy")`` â€” used only when
       ``model`` is missing, malformed, or both lookups fail. We never let
       a secondary exception escape and mask the rate-limit error we're
       trying to surface.
    Ú ©r	   Nz{rate_limiter_utils.resolve_llm_provider_for_rate_limit: could not resolve provider for model=%s, falling back to %s. err=%s)r   ÚlitellmÚget_llm_providerÚ	ExceptionÚ#_resolve_provider_from_router_aliasr   ÚdebugÚstr)r	   Úresolved_modelÚcustom_llm_providerÚ_ÚeÚalias_resolutions         úk/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/hooks/rate_limiter_utils.pyÚ#resolve_llm_provider_for_rate_limitr      sª   € ñ< ØÔ.Ð.Ð.ð2Ü4;×4LÑ4LØô5
Ñ1ˆÐ+¨Q°ð Ò#˜eØÒ>Ô#>ð
ð 	
øô ò 2Ü"EÀeÓ"LÐØÐ'Ø#Õ#Ü×"Ñ"ðRàÜ'Ü�‹Fô	
ð Ô1Ð1Õ1ûð2ús'   Œ*7 ·	BÁ BÁBÁ,BÂ BÂBc                 óÊ  — 	 ddl m} |€y	 t        |dd«      }|sy|D ]–  }t	        |t
        «      sŒ|j                  d«      | k7  rŒ)|j                  d«      }t	        |t
        «      sŒK|j                  d«      }t	        |t        «      r|sŒo	 t        j                  |¬«      \  }}}}|sŒŽ|xs ||fc S  y# t        $ r Y yw xY w# t        $ r Y Œ´w xY w# t        $ r Y yw xY w)	uÙ  
    Resolve a router ``model_name`` alias to ``(underlying_model, provider)``
    by scanning the active router's ``model_list``.

    Returns ``None`` if the router isn't initialized, the alias isn't
    registered, the deployment has no usable ``litellm_params.model``, or
    any underlying lookup raises. Callers fall through to the defensive
    ``litellm_proxy`` fallback in that case â€” never raising secondary
    exceptions out of the rate-limit raise path.
    r   )Ú
llm_routerNÚ
model_listÚ
model_nameÚlitellm_paramsr	   r   )
Úlitellm.proxy.proxy_serverr   r   ÚgetattrÚ
isinstanceÚdictÚgetr   r   r   )	r	   r   r   Ú
deploymentÚparamsÚunderlying_modelr   r   r   s	            r   r   r   E   s  € ðÝ9ð ÐØð Ü# J°¸dÓCˆ
ÙØØ$ò 	ˆJÜ˜j¬$Ô/ØØ�~‰~˜lÓ+¨uÒ4ØØ—^‘^Ð$4Ó5ˆFÜ˜f¤dÔ+ØØ%Ÿz™z¨'Ó2ÐÜÐ.´Ô4Ñ<LØðÜ<C×<TÑ<TØ*ô=Ñ9�Ð 3°Q¸ñ
 'Øð
 Ò2Ð"2Ø#ðò ð-	ð4 øôE ò Ùðûô. ò Ùðûô ò ÙðúsR   ‚B8 ŒC œA1C ÂCÂ)C Â6C Â8	CÃCÃ	CÃC ÃCÃC Ã	C"Ã!C"ÚvalueÚ
model_infoc                 óÌ  — t        | t        t        f«      rt        | «      S t        | t        «      r³| j	                  dd«      }| j	                  dd«      }|dk(  rt        |«      S |dk(  r5|r3|j
                  r'|j
                  dkD  rt        |«      |j
                  z  S |dk(  r5|r3|j                  r'|j                  dkD  rt        |«      |j                  z  S t        |«      S y)	a1  
    Convert priority reservation value to percentage (0.0-1.0).

    Supports three formats:
    1. Plain float/int: 0.9 -> 0.9 (90%)
    2. Dict with percent: {"type": "percent", "value": 0.9} -> 0.9
    3. Dict with rpm: {"type": "rpm", "value": 900} -> 900/model_rpm
    4. Dict with tpm: {"type": "tpm", "value": 900000} -> 900000/model_tpm

    Args:
        value: Priority value as float or dict with type/value keys
        model_info: Model configuration containing rpm/tpm limits

    Returns:
        float: Percentage value between 0.0 and 1.0
    ÚtypeÚpercentr(   g      ð?Úrpmr   ÚtpmN)r"   ÚintÚfloatr#   r$   r-   r.   )r(   r)   Úval_typeÚval_nums       r   Úconvert_priority_to_percentr3   {   sÇ   € ô" �%œ#œu˜Ô&Ü�U‹|Ðä�%œÔØŸ)™) F¨IÓ6ˆØŸ™ 7¨CÓ0ˆà�yÒ Ü˜“>Ð!Ø˜Ò¡:°*·.².ÀZÇ^Á^ÐVWÒEWÜ˜“> J§N¡NÑ2Ð2Ø˜Ò¡:°*·.².ÀZÇ^Á^ÐVWÒEWÜ˜“> J§N¡NÑ2Ð2ô �W‹~Ðð ó    )Ú__doc__Útypingr   r   Úlitellm._loggingr   Úlitellm.types.routerr   Úlitellm.types.utilsr   r   Ú__annotations__r   Útupler   r   r0   r3   © r4   r   ú<module>r=      s“   ðòõ ã Ý 1Ý /Ý 7à%4Ð ˜UÓ 4ð32Ø�‰:ð32à
ˆ3�ˆ8�_ó32ðl3Øð3à
ˆ3�ˆ8�_�tÑó3ðl  uÐ/FÑ'Fð  ÐTbÐeiÑTið  Ðnsô  r4   