Ë
    uPêjä/  ã                   óR  — U d dl Z d dlZd dlmZ d dlmZ d dlmZmZ erd dl	m
Z
 d dlmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ deeef   dz  defd„Zdedededz  fd„Zdedefd„Zdedefd„Zde e   ez  de d   defd„Z!	 d&de e   ez  dedz  de e   ez  fd„Z"dedefd„Z#	 d&de e   ez  dedz  de e   ez  fd„Z$ e%d„ eD «       «      Z&ee'd<    e%d „ eD «       «      Z(ee'd!<    ee&e&e&e&e&e&e&e&e(e(e(d"œ«      Z)eeee%e   f      e'd#<   d$edeeef   dedz  fd%„Z*y)'é    N)ÚMapping)ÚMappingProxyType)ÚTYPE_CHECKINGÚFinal)ÚOpenAIFileObject)Úverbose_loggerÚverbose_router_logger)Ú&ROUTER_FALLBACK_ERROR_DETAIL_MAX_CHARS)ÚBadRequestError)Úget_llm_provider)ÚCredentialLiteLLMParams)ÚLlmProvidersÚrequest_kwargsÚreturnc                 ó  — | €y| j                  d«      }| j                  d«      }t        |t        «      r|ni }t        |t        «      r|ni }|j                  d«      xs |j                  d«      }t        |dd «      dk(  S )NFÚmetadataÚlitellm_metadataÚuser_api_key_authÚ	user_roleÚproxy_admin)ÚgetÚ
isinstancer   Úgetattr)r   Úmetadata_valueÚlitellm_metadata_valuer   r   r   s         úf/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/router_utils/common_utils.pyÚ_is_proxy_admin_requestr      sŠ   € ØÐØØ*×.Ñ.¨zÓ:€NØ$2×$6Ñ$6Ð7IÓ$JÐÜ(2°>Ä7Ô(K‘nÐQS€HÜ8BÐCYÔ[bÔ8cÑ4ÐikÐØ'Ÿ|™|Ð,?Ó@ÒmÐDT×DXÑDXÐYlÓDmÐÜÐ$ k°4Ó8¸MÑIÐIó    Úmodel_group_aliasÚmodelc                 ó¶   — t        | t        «      sy| j                  |«      }t        |t        «      r|j                  d«      n|}t        |t        «      r|sy|S )aÛ  
    Resolve ``model`` through a ``model_group_alias`` map.

    Handles both supported entry shapes, the plain string form
    ``{"alias": "target"}`` and the item form
    ``{"alias": {"model": "target", "hidden": true}}``, and tolerates malformed
    entries: the map can come from a key or team row rather than from validated
    config, so a bad value must not raise mid-request.

    Returns the target model group, or None when the map does not rewrite ``model``.
    Nr    )r   r   r   Ústr)r   r    ÚentryÚtargets       r   Úresolve_model_group_aliasr%      sO   € ô Ð'¬Ô1ØØ$×(Ñ(¨Ó/€EÜ*4°U¼GÔ*D�E—I‘I˜gÔ&È%€FÜ�fœcÔ"©&ØØ€Mr   Údetailc                 ól   — t        | «      t        k  r| S t        | «      t        z
  }| dt         › d|› d�S )a  
    Bound a fallback failure detail before it is logged or appended to an exception message.

    Each level of the fallback walk records the failure of the level below it, so an
    untruncated detail carries every nested failure with it and grows superlinearly with
    the number of attempted model groups. One deterministic pre-network failure walked
    through a small fallback graph is enough to turn that into hundreds of megabytes of
    output on the event-loop thread, which starves the process that produced it.
    Nz... [truncated z characters])Úlenr
   )r&   Údroppeds     r   Útruncate_fallback_error_detailr*   2   sC   € ô ˆ6ƒ{Ô<Ò<ØˆÜ˜“[Ô#IÑI€GØÐ<Ô<Ð=Ð>¸oÈgÈYÐVbÐcÐcr   Úlitellm_paramsc                 ó¼   — t        di | ¤Ž}t        j                  t        j                  |j                  «       «      j                  «       «      j                  «       S )zX
    Hash of the credential params, used for mapping the file id to the right model
    © )r   ÚhashlibÚsha256ÚjsonÚdumpsÚ
model_dumpÚencodeÚ	hexdigest)r+   Úsensitive_paramss     r   Ú,get_litellm_params_sensitive_credential_hashr6   B   sF   € ô 6ÑG¸ÑGÐÜ�>‰>œ$Ÿ*™*Ð%5×%@Ñ%@Ó%BÓC×JÑJÓLÓM×WÑWÓYÐYr   Úhealthy_deploymentsÚ	responsesr   c                 óÂ   — i }t        | t        «      r| n| g}t        ||«      D ]8  \  }}|j                  di «      j                  d«      }|€Œ*|j                  ||<   Œ: |S )aÈ  
    Create a mapping of model id to file id
    {
        "model_id": "file_id",
        "model_id": "file_id",
    }

    `healthy_deployments` may be either a list of deployment dicts (multiple
    matched deployments) or a single deployment dict (when the router resolved
    a specific deployment, e.g. because the requested model matched a
    `model_info.id`). Both shapes must be handled by extracting
    `model_info.id` from each deployment.
    Ú
model_infoÚid)r   ÚlistÚzipr   r;   )r7   r8   Úmodel_file_id_mappingÚdeployments_listÚ
deploymentÚresponseÚmodel_ids          r   Úadd_model_file_id_mappingsrC   J   sy   € ð 46Ðä)Ð*=¼tÔDÑÐK^ÐJ_ð ô !$Ð$4°iÓ @ò :Ñˆ
�HØ—>‘> ,°Ó3×7Ñ7¸Ó=ˆØÑØ.6¯k©kÐ! (Ò+ð:ð !Ð r   c                 óž  ‡— |€| S |j                  d«      xs i }|j                  d«      xs i }|j                  d«      xs |j                  d«      }|€Ït        |«      rÄt        | t        «      r´|j                  d«      xs$ |j                  d«      xs |j                  d«      Št	        d„ | D «       «      }t        d„ |D «       «      }t        ‰t        «      xr! t        |«      xr t        ˆfd„|D «       «      }|r t        |«      d	kD  rt        d
‰› d�‰d¬«      ‚|r| S t        «       }t        | t        «      r| S | D ]Q  }	|	j                  d«      xs i }
|
j                  d«      }|€Œ,||k7  sŒ2|j                  |
j                  d«      «       ŒS | D �	cg c]'  }	|	j                  di «      j                  d«      |vr|	‘Œ) c}	S c c}	w )zM
    If a model has a team_id

    Only use if request is from that team
    r   r   Úuser_api_key_team_idr    Úmodel_groupc              3   óh   K  — | ]*  }|j                  d «      |j                  d«      xs i f–— Œ, y­w)Ú
model_namer:   N©r   )Ú.0r@   s     r   ú	<genexpr>z+filter_team_based_models.<locals>.<genexpr>v   s1   è ø€ ò -
ØS]ˆZ�^‰^˜LÓ)¨:¯>©>¸,Ó+GÒ+MÈ2ÔNñ-
ùs   ‚02c              3   óL   K  — | ]  \  }}|j                  d «      }|�|–— Œ y­w)Úteam_idNrI   )rJ   Ú_r:   rM   s       r   rK   z+filter_team_based_models.<locals>.<genexpr>y   s0   è ø€ ò $
á��:Ø&ŸN™N¨9Ó5�ØÐ"ô ñ$
ùs   ‚"$c              3   ó„   •K  — | ]7  \  }}|j                  d «      duxr |‰k(  xs |j                  d«      ‰k(  –— Œ9 y­w)rM   NÚteam_public_model_namerI   )rJ   rH   r:   Úrequested_models      €r   rK   z+filter_team_based_models.<locals>.<genexpr>‚   sV   øè ø€ ò ñ +�J 
ð —‘˜yÓ)°Ð5ò sØ ?Ñ2Òq°j·n±nÐE]Ó6^ÐbqÑ6qósñùs   ƒ=A é   zModel name 'z^' matches deployments from multiple teams. Specify the deployment ID directly to disambiguate.Ú )Úmessager    Úllm_providerr:   rM   r;   )r   r   r   r<   ÚtupleÚ	frozensetr"   ÚboolÚallr(   r   ÚsetÚdictÚadd)r7   r   r   r   Úrequest_team_idÚcandidate_deploymentsÚteam_idsÚmatches_requested_modelÚids_to_remover@   Ú_model_infoÚmodel_team_idrQ   s               @r   Úfilter_team_based_modelsrd   c   s  ø€ ð ÐØ"Ð"à$×(Ñ(¨Ó4Ò:¸€HØ,×0Ñ0Ð1CÓDÒJÈÐØ%Ÿ\™\Ð*@ÓAÒqÐEU×EYÑEYÐZpÓEq€OØÐÔ#:¸>Ô#JÌzÐZmÔosÔOtà×Ñ˜wÓ'Òm¨8¯<©<¸Ó+FÒmÐJZ×J^ÑJ^Ð_lÓJmð 	ô (-ñ -
Øatô-
ó (
Ðô $ñ $
à!6ô$
ó 
ˆô �¬Ó,ò ÜÐ*Ó+òäó ð /Dôó ð 	 ñ #¤s¨8£}°qÒ'8Ü!à" ?Ð"3ð 4Jð Jð &Øôð ñ #Ø&Ð&ä›5€MÜÐ%¤tÔ,Ø"Ð"Ø)ò 5ˆ
Ø —n‘n \Ó2Ò8°bˆØ#Ÿ™¨	Ó2ˆØÐ ØØ˜OÓ+Ø×Ñ˜kŸo™o¨dÓ3Õ4ð5ð .öàØ�>‰>˜,¨Ó+×/Ñ/°Ó5¸]ÑJò 	òð ùò s   Æ,G
r@   c                 ó:   — | j                  di «      }d|v r|d   S y)a›  
    Check if a deployment supports web search.

    Priority:
    1. Check config-level override in model_info.supports_web_search
    2. Default to True (assume supported unless explicitly disabled)

    Note: Ideally we'd fall back to litellm.supports_web_search() but
    model_prices_and_context_window.json doesn't have supports_web_search
    tags on all models yet. TODO: backfill and add fallback.
    r:   Úsupports_web_searchTrI   )r@   r:   s     r   Ú_deployment_supports_web_searchrg   ¦   s+   € ð #Ÿ™ |°RÓ8€Jà 
Ñ*ØÐ/Ñ0Ð0àr   c                 óp  — |€| S t        | t        «      r| S d}|j                  d«      xs g }|D ].  }|j                  d«      dk(  s|j                  d«      dk(  sŒ,d} n |s| S | D �cg c]  }t        |«      sŒ|‘Œ }}t	        | «      dkD  r#t	        |«      dk(  rt        j                  d«       |S c c}w )	z[
    If the request is websearch, filter out deployments that don't support web search
    FÚtoolsÚtypeÚ
web_searchÚweb_search_previewTr   z-No deployments support web search for request)r   r[   r   rg   r(   r   Úwarning)r7   r   Úis_web_search_requestri   ÚtoolÚdÚfinal_deploymentss          r   Úfilter_web_search_deploymentsrr   º   sØ   € ð ÐØ"Ð"ô Ð%¤tÔ,Ø"Ð"à!ÐØ!×%Ñ% gÓ.Ò4°"€EØò ˆà�8‰8�FÓ˜|Ò+¨t¯x©x¸Ó/?ÐCWÓ/WØ$(Ð!Ùð	ñ !Ø"Ð"ð ,?Öe aÔBaÐbcÕBd¢ÐeÐÐeÜ
ÐÓ !Ò#¬Ð,=Ó(>À!Ò(CÜ×ÑÐNÔOØÐùò  fs   Á)B3Á:B3c              #   ól   K  — | ],  }|j                   j                  d «      sŒ|j                   –— Œ. y­w))ÚbedrockÚ	sagemakerN©ÚvalueÚ
startswith©rJ   Úproviders     r   rK   rK   ß   s+   è ø€ ò "Ø°8·>±>×3LÑ3LÐMeÕ3f€H‡N…Nñ"ùó   ‚ 4£4Ú_AWS_PROVIDERSc              #   ól   K  — | ],  }|j                   j                  d «      sŒ|j                   –— Œ. y­w)Ú	vertex_aiNrv   ry   s     r   rK   rK   â   s*   è ø€ ò %Ø°8·>±>×3LÑ3LÈ[Õ3Y€H‡N…Nñ%ùr{   Ú_VERTEX_PROVIDERS)Úaws_access_key_idÚaws_profile_nameÚaws_region_nameÚaws_role_nameÚaws_secret_access_keyÚaws_session_nameÚaws_session_tokenÚaws_web_identity_tokenÚvertex_credentialsÚvertex_locationÚvertex_projectÚ!PROVIDER_SCOPED_CREDENTIAL_PARAMSrH   c                 ó  ‡‡— ‰j                  d«      }t        |t        «      r|syt        ˆfd„t        D «       «      }|sy‰j                  d«      }	 t        |t        |t        «      r|nd¬«      \  }Š}}t        ˆfd„|D «       «      }|syt        |D ��ch c]  }t        |   D ]  }|’Œ Œ c}}«      }	d| › d|› d	|› d
‰› d|	› d|	d   › d|› d‰› d�}
t        j                  |
«       |
S # t        $ r Y yw xY wc c}}w )aQ  
    Warn when a deployment carries one provider's credentials but resolves to another.

    Returns the warning text (for tests), or None when the deployment is consistent
    or its provider cannot be resolved. Never raises: a deployment litellm cannot
    classify is left alone rather than blocking router startup.

    Only inline credential params are examined. A deployment that sources them
    through ``litellm_credential_name`` resolves them after registration, so it
    carries none of these keys here and is left alone rather than warned about
    on incomplete information.
    r    Nc              3   óF   •K  — | ]  }‰j                  |«      €Œ|–— Œ y ­w©NrI   )rJ   Úparamr+   s     €r   rK   z7warn_on_provider_credential_mismatch.<locals>.<genexpr>  s#   øè ø€ Òx EÐR`×RdÑRdÐejÓRkÑRwœ%Ñxùs   ƒ!š!Úcustom_llm_provider)r    r�   c              3   ó:   •K  — | ]  }‰t         |   vsŒ|–— Œ y ­wrŽ   )r‹   )rJ   r�   Úresolved_providers     €r   rK   z7warn_on_provider_credential_mismatch.<locals>.<genexpr>  s%   øè ø€ ò ØÐ%6Ô>_Ð`eÑ>fÒ%fŒñùs   ƒ”zDeployment 'z' sets z but 'model=z' resolves to provider 'z0', which ignores them. Those params are read by z3, so this is usually a missing route prefix (e.g. 'r   ú/z$'); as written the request goes to 'z/' and will fail on that provider's credentials.)
r   r   r"   rV   r‹   r   r   Úsortedr	   rm   )rH   r+   r    Úscopedr�   rN   Ú
mismatchedr�   rz   Úexpectedrm   r’   s    `         @r   Ú$warn_on_provider_credential_mismatchr˜   ÷   sL  ù€ ð "×%Ñ% gÓ.€EÜ�eœSÔ!©ØÜÓxÔ-NÔxÓx€FÙØØ!/×!3Ñ!3Ð4IÓ!JÐðÜ%5ØÜ7AÐBUÔWZÔ7[Ñ 3Ðaeô&
Ñ"ˆÐ˜a ô ó Ø!ôó €Jñ ØÜØ)×c�eÔ:[Ð\aÑ:bÒc¨hŠÐcˆÓcó€Hð �z�l '¨*¨°\À%Àð IØÐÐNÈxÈjð Y1Ø19¸!±°¸Q¸u¸gð FØÐÐMð	Oð ô ×!Ñ! 'Ô*Ø€Nøô# ò Ùðüó 	ds   Á$C- ÂC<
Ã-	C9Ã8C9rŽ   )+r.   r0   Úcollections.abcr   Útypesr   Útypingr   r   Úlitellm.types.llms.openair   Úlitellm._loggingr   r	   Úlitellm.constantsr
   Úlitellm.exceptionsr   Ú1litellm.litellm_core_utils.get_llm_provider_logicr   Úlitellm.types.routerr   Úlitellm.types.utilsr   r"   ÚobjectrX   r   r%   r*   r[   r6   r<   rC   rd   rg   rr   rW   r|   Ú__annotations__r   r‹   r˜   r-   r   r   ú<module>r¥      s  ðÜ Û Ý #Ý "ß 'áÝ:ç BÝ DÝ .Ý NÝ 8Ý ,ðJ¨G°C¸°KÑ,@À4Ñ,Gð JÈDó Jð°ð Àð ÈÈdÉ
ó ð*d¨3ð d°3ó dð ZÀð ZÈ#ó Zð!°D¸±JÀÑ4Eð !ÐRVÐWiÑRjð !Ðosó !ð6 #'ñ@Ø˜d™ dÑ*ð@à˜4‘Kð@ð 
ˆ$�Z�$Ñó@ðF°ð ¸ó ð, #'ñØ˜d™ dÑ*ðà˜4‘Kðð 
ˆ$�Z�$ÑóñJ "ñ "Ø#/ô"ó €�ó ñ %ñ %Ø#/ô%ó Ð �5ó ñ JZà+Ø*Ø)Ø'Ø!/Ø*Ø+Ø"0Ø/Ø,Ø+ñóJÐ ! 5¨°°iÀ±nÐ1DÑ)EÑ#Fó ð"*°Sð *È'ÐRUÐW]ÐR]ÑJ^ð *ÐcfÐimÑcmô *r   