Ë
    tPêjÐW  ã                   óò  — U d dl Z d dlmZmZmZmZmZ d dlmZm	Z	 d dl
mZ dedz  ddfd„Zdedz  ddfd	„Zd d
lmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZm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mZ d dl$m(Z(m)Z) dedefd„Z*ddœdedededdfd„Z+dedede,fd„Z-dedede,fd„Z.dededede,fd„Z/	 	 	 dBdeded    d!ed"   d#ed$   de,f
d%„Z0d&ed'ede,fd(„Z1ded&ed'edd de,f
d)„Z2	 	 	 dBd*ededed    d!ed"   d#ed$   de,fd+„Z3d,eeeeed-d.f   d/ed0eddfd1„Z4d2Z5ee6d3<   d0ede,fd4„Z7d5e8eef   de,fd6„Z9dd7œd8ed9ed:edz  ded;e8eef   d<edz  fd=„Z:d>e8d/eddfd?„Z;d0ede,fd@„Z<d>e8ddfdA„Z=y)Cé    N)ÚTYPE_CHECKINGÚAnyÚFinalÚOptionalÚUnion)ÚHTTPExceptionÚstatus)Ú	BaseModelÚspendÚreturnc                 óX   — | �(t        j                  | «      st        ddd| › �i¬«      ‚yy)u"  Reject NaN/Â±inf spend before it reaches the DB / spend counter.

    A non-finite spend would otherwise slip past `spend >= max_budget`
    enforcement, since any comparison with NaN (and `-inf >= max_budget`)
    is False, letting the entity keep spending past its configured budget.
    Né�  Úerrorz)spend must be a finite number. Received: ©Ústatus_codeÚdetail)ÚmathÚisfiniter   )r   s    út/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/management_endpoints/common_utils.pyÚvalidate_finite_spendr      s=   € ð Ð¤§¡¨uÔ!5ÜØØÐHÈÈÐPÐQô
ð 	
ð "6Ðó    Úbudget_durationc                 ó®   — | €yddl m} ddlm} 	  || «      dk  rt	        d«      ‚ || ¬«       y# t        t
        f$ r t        ddd	| › d
�i¬«      ‚w xY w)a£  Reject budget durations that can't be parsed, are non-positive, or
    overflow date math, so a bad value can't be persisted and later crash the
    budget reset job.

    A non-positive duration also resolves to a reset time of "now", which leaves
    the row permanently due: the reset job re-reads it every tick and, once
    enough of them exist, they fill each batch and starve every other tenant's
    reset.
    Nr   )Úduration_in_seconds©Úget_budget_reset_timez budget_duration must be positive©r   r   r   zInvalid budget_duration 'z1'. Use a format like '1h', '24h', '7d', or '30d'.r   )Ú*litellm.litellm_core_utils.duration_parserr   Ú)litellm.proxy.common_utils.timezone_utilsr   Ú
ValueErrorÚOverflowErrorr   )r   r   r   s      r   Úvalidate_budget_durationr"      ss   € ð ÐØåNÝOð

Ù˜Ó/°1Ò4ÜÐ?Ó@Ð@Ù¨oÖ>øÜœÐ&ò 
ÜØàÐ4°_Ð4EÐEvÐwðô
ð 	
ð
ús	   ‘1 ±#A)Úverbose_proxy_logger©Ú	DualCache)ÚKeyRequestBaseÚ)LiteLLM_ManagementEndpoint_MetadataFieldsÚ1LiteLLM_ManagementEndpoint_MetadataFields_PremiumÚLiteLLM_OrganizationTableÚLiteLLM_ProjectTableÚLiteLLM_TeamTableÚLiteLLM_UserTableÚLitellmUserRolesÚNewProjectRequestÚUpdateProjectRequestÚUserAPIKeyAuth)Úuser_api_key_has_admin_viewr   )Ú_premium_user_check)ÚTeamRepository)r.   r/   )ÚPrismaClientÚProxyLoggingÚuser_api_key_dictc                 ól   — | j                   €t        t        j                  ddi¬«      ‚| j                   S )a5  Return the caller's user_id, or raise 403 if missing.

    Non-admin analytics endpoints scope queries by the caller's own user_id.
    Service-account keys are deliberately created with user_id=None
    (key_management_endpoints.py forces ``data.user_id = None`` at key
    creation). Without this guard, that None value flows through to the
    daily-activity builder, which treats ``entity_id is None`` as "no filter"
    and returns every tenant's data.

    Callers must check is_admin first; this helper is only valid on the
    non-admin scoping branch.
    r   zaService-account keys cannot query user analytics. Use a user-bound key, or call as a proxy admin.r   )Úuser_idr   r	   ÚHTTP_403_FORBIDDEN)r6   s    r   Ú$require_caller_user_id_for_non_adminr:   Q   s?   € ð × Ñ Ð(ÜÜ×1Ñ1àØwðô
ð 	
ð ×$Ñ$Ð$r   Úkey)ÚentityÚdatar<   c                ó  — |j                   t        j                  j                  k(  ryt	        | dd«      rt        ddd|› d�i¬«      ‚t	        | dd«      }t        |t        «      r%|j                  d«      rt        ddd	|› d�i¬«      ‚yy)
uÆ   
    Only proxy admins may set `allowed_passthrough_routes` (top-level or under
    `metadata`) â€” it short-circuits the role-based route gate, so keys and teams
    must be gated identically.
    NÚallowed_passthrough_routesi“  r   z<Only proxy admins can set `allowed_passthrough_routes` on a ú.r   ÚmetadatazEOnly proxy admins can set `metadata.allowed_passthrough_routes` on a )	Ú	user_roler-   ÚPROXY_ADMINÚvalueÚgetattrr   Ú
isinstanceÚdictÚget)r=   r6   r<   rA   s       r   Ú+_check_passthrough_routes_caller_permissionrI   l   s¨   € ð ×"Ñ"Ô&6×&BÑ&B×&HÑ&HÒHØÜˆtÐ1°4Ô8ÜØØÐ[Ð\bÐ[cÐcdÐeÐfô
ð 	
ô ˜d J°Ó5€HÜ�(œDÔ! h§l¡lÐ3OÔ&PÜØØÐdÐekÐdlÐlmÐnÐoô
ð 	
ð 'QÐ!r   Úteam_objc                 ó–   — |j                   D ]:  }|j                  €Œ|j                  | j                  k(  sŒ*|j                  dk(  sŒ: y y)NÚadminTF)Úmembers_with_rolesr8   Úrole)r6   rJ   Úmembers      r   Ú_is_user_team_adminrP   ‡   sJ   € Ø×-Ñ-ò ˆØ�N‰NÑ&¨6¯>©>Ð=N×=VÑ=VÓ+VÐ\b×\gÑ\gÐkrÓ\rÙðð r   c              ƒ   óV  K  — |j                   r| j                  syddlm} ddlm}m}m}  || j                  ||d|¬«      ƒ d{  –—† }|€y|j                  xs g D ]E  }|j                   |j                   k(  sŒ|j                  t        j                  j                  k(  sŒE y y7 Œ`­w)zÀ
    Check if user is an org admin for the team's organization.

    Returns True if:
    - The team belongs to an organization, AND
    - The user has org_admin role in that organization
    Fr   ©Úget_user_object)Úprisma_clientÚproxy_logging_objÚuser_api_key_cache©r8   rT   rV   Úuser_id_upsertrU   NT)Úorganization_idr8   Úlitellm.proxy.auth.auth_checksrS   Úlitellm.proxy.proxy_serverrT   rU   rV   Úorganization_membershipsrB   r-   Ú	ORG_ADMINrD   )r6   rJ   rS   rT   rU   rV   Úcaller_userÚms           r   Ú_is_user_org_admin_for_teamr`   �   s®   è ø€ ð ×#Ò#Ð+<×+DÒ+DØå>÷ñ ñ  /Ø!×)Ñ)Ø#Ø-ØØ+ô ÷ €Kð ÐØà×1Ñ1Ò7°Rò ˆØ×Ñ × 8Ñ 8Ó8¸Q¿[¹[ÔL\×LfÑLf×LlÑLlÓ=lÙðð ðús   ‚AB)ÁB'Á3B)Á;'B)Â#B)Ú
permissionc                 ó®   — |j                   sy||j                   vry|j                  D ]*  }|j                  €Œ|j                  | j                  k(  sŒ* y y)zECheck if a non-admin team member has a specific permission on a team.FT)Úteam_member_permissionsrM   r8   )r6   rJ   ra   rO   s       r   Ú_team_member_has_permissionrd   ²   sZ   € ð ×+Ò+ØØ˜×9Ñ9Ñ9ØØ×-Ñ-ò ˆØ�>‰>Ñ%¨&¯.©.Ð<M×<UÑ<UÓ*UÙðð r   rT   r4   rV   r%   rU   r5   c              ƒ   ó  K  — | j                   t        j                  k(  ry|�| j                  €yddlm} ddlm} 	  || j                  ||xs  |«       d|¬«      ƒ d{  –—† }|€y|j                  �:|j                  D ]+  }|j                   t        j                  j                  k(  sŒ+ y |j                  �Œt        |j                  «      dkD  rtt        |«      j                  j                  dd	|j                  ii¬
«      ƒ d{  –—† }|D ]4  }	t!        j"                  |	j%                  «       «      }
t'        | |
¬«      sŒ4 y y7 Œæ7 Œ@# t(        $ r+}t+        j,                  d| j                  |«       Y d}~yd}~ww xY w­w)a­  
    Check if user has admin privileges (proxy admin, team admin, or org admin).

    Args:
        user_api_key_dict: User API key authentication object
        prisma_client: Prisma client for database operations
        user_api_key_cache: Cache for user API keys
        proxy_logging_obj: Proxy logging object

    Returns:
        True if user is proxy admin, team admin for any team, or org admin for any organization
    TNFr   r$   rR   rW   Úteam_idÚin©Úwhere©r6   rJ   z/Error checking admin privileges for user %s: %s)rB   r-   rC   r8   Úlitellm.cachingr%   rZ   rS   r\   r]   rD   ÚteamsÚlenr3   ÚtableÚ	find_manyr+   Úmodel_validateÚ
model_dumprP   Ú	Exceptionr#   Údebug)r6   rT   rV   rU   ÚDualCacheImportrS   Úuser_objÚ
membershiprl   ÚteamrJ   Úes               r   Ú_user_has_admin_privilegesry   Â   s�  è ø€ ð& ×"Ñ"Ô&6×&BÑ&BÒBØð ÐÐ 1× 9Ñ 9Ð AØõ =Ý>ðÙ /Ø%×-Ñ-Ø'Ø1ÒF±_Ó5FØ Ø/ô!
÷ 
ˆð ÐØð ×,Ñ,Ð8Ø&×?Ñ?ò  �
Ø×'Ñ'Ô+;×+EÑ+E×+KÑ+KÓKÙð ð
 �>‰>Ð%¬#¨h¯n©nÓ*=ÀÒ*Aä(¨Ó7×=Ñ=×GÑGÈyÐ[_Ðai×aoÑaoÐZpÐNqÐGÓr×rˆEàò  �Ü,×;Ñ;¸D¿O¹OÓ<MÓN�Ü&Ð9JÐU]Ö^Ùð ð ðA
øð( sùô ò ä×"Ñ"Ð#TÐVg×VoÑVoÐqrÔsÜûðüs„   ‚:F½#E Á EÁ!E Á'FÁ(AE Â+E Â,FÂ-AE ÄE	Ä	9E ÅE ÅFÅE ÅFÅE Å	E Å	E?Å!E:Å5FÅ:E?Å?FÚadmin_user_objÚtarget_user_objc                 óF  — | j                   €y| j                   D �ch c]5  }|j                  t        j                  j                  k(  r|j
                  ’Œ7 }}|sy|j                   €y|j                   D �ch c]  }|j
                  ’Œ }}t        ||z  «      S c c}w c c}w )a†  
    Check if an org admin can invite the target user.
    Target user must be in at least one org where the admin has org admin role.

    Args:
        admin_user_obj: The admin user's full object (from get_user_object)
        target_user_obj: The target user's full object (from get_user_object)

    Returns:
        True if target user is in an org where admin has org admin role
    F)r\   rB   r-   r]   rD   rY   Úbool)rz   r{   r_   Úadmin_org_idsÚtarget_org_idss        r   Ú_org_admin_can_invite_userr€     s¨   € ð ×.Ñ.Ð6Øð  ×8Ñ8öàØ�;‰;Ô*×4Ñ4×:Ñ:Ò:ð 	
×Óð€Mð ñ
 ØØ×/Ñ/Ð7ØØ8G×8`Ñ8`Öa°1˜Q×.Ó.Ða€NÐaÜ� Ñ.Ó/Ð/ùòùò bs   œ:BÁ6Bc           
   ƒ   ó  K  — |j                   rt        |j                   «      dk(  ry|j                   rt        |j                   «      dk(  ryt        |«      j                  j	                  dd|j                   ii¬«      ƒ d{  –—† }|D �cg c]<  }t        | t        j                  |j                  «       «      ¬«      r|j                  ‘Œ> }}|syt        |j                   «      }t        t        |«      |z  «      S 7 Œzc c}w ­w)a  
    Check if a team admin can invite the target user.
    Target user must be in at least one team where the admin has team admin role.

    Args:
        user_api_key_dict: The admin user's API key auth object
        admin_user_obj: The admin user's full object (from get_user_object)
        target_user_obj: The target user's full object (from get_user_object)
        prisma_client: Prisma client for database operations

    Returns:
        True if target user is in a team where admin has team admin role
    r   Frf   rg   rh   Nrj   )rl   rm   r3   rn   ro   rP   r+   rp   rq   rf   Úsetr}   )r6   rz   r{   rT   rl   rw   Úadmin_team_idsÚtarget_team_idss           r   Ú_team_admin_can_invite_userr…   "  sò   è ø€ ð& ×Ò¤3 ~×';Ñ';Ó#<ÀÒ#AØØ× Ò ¤C¨×(=Ñ(=Ó$>À!Ò$CØä'¨Ó6×<Ñ<×FÑFÈiÐZ^Ð`n×`tÑ`tÐYuÐMvÐFÓw×w€Eð öàÜØ/Ü&×5Ñ5°d·o±oÓ6GÓHõ
ð 	�‹ð€Nð ñ ØÜ  ×!6Ñ!6Ó7€OÜ”�NÓ# oÑ5Ó6Ð6ð xúòùs%   ‚BDÂC>ÂDÂAD Ã2DÄ DÚtarget_user_idc              ƒ   óÎ  K  — |j                   t        j                  k(  ry|�|j                  €yddlm} ddlm} 	 |xs  |«       } ||j                  ||d|¬«      ƒ d{  –—† }|€y || ||d|¬«      ƒ d{  –—† }	|	€yt        ||	«      ryt        |||	|¬«      ƒ d{  –—† ryy7 ŒE7 Œ/7 Œ
# t        $ r+}
t        j                  d	|j                  |
«       Y d}
~
yd}
~
ww xY w­w)
a•  
    Check if the admin can create an invitation for the target user.
    - Proxy admins: can invite any user
    - Org admins: can only invite users in their org(s)
    - Team admins: can only invite users in their team(s)

    Uses get_user_object for caching of both admin and target user objects.

    Args:
        target_user_id: The user_id of the user to invite
        user_api_key_dict: The admin user's API key auth object
        prisma_client: Prisma client for database operations
        user_api_key_cache: Cache for user API keys
        proxy_logging_obj: Proxy logging object

    Returns:
        True if user can invite the target user
    TNFr   r$   rR   rW   )r6   rz   r{   rT   z0Error checking invite permission for user %s: %s)rB   r-   rC   r8   rk   r%   rZ   rS   r€   r…   rr   r#   rs   )r†   r6   rT   rV   rU   rt   rS   Úcacherz   r{   rx   s              r   Úadmin_can_invite_userr‰   I  s  è ø€ ð2 ×"Ñ"Ô&6×&BÑ&BÒBØàÐÐ 1× 9Ñ 9Ð AØå<Ý>ð$Ø)Ò>©_Ó->ˆÙ&5Ø%×-Ñ-Ø'Ø$Ø Ø/ô'
÷ !
ˆð Ð!Øá'6Ø"Ø'Ø$Ø Ø/ô(
÷ "
ˆð Ð"Øä% n°oÔFØä,Ø/Ø)Ø+Ø'ô	
÷ 
ð 
ð àð?!
øð"
øð
ùô ò Ü×"Ñ"Ð#UÐWh×WpÑWpÐrsÔtÜûðüsˆ   ‚:C%½%B. Á"B(Á#B. Á)C%Á*B. Á:B*Á;B. ÂC%ÂB. ÂC%ÂB. Â!B,Â"B. Â&C%Â(B. Â*B. Â,B. Â.	C"Â7!CÃC%ÃC"Ã"C%Úobject_datar.   r/   Ú
field_namerD   c                 óv   — |t         v r|rt        |«       | j                  xs i | _        || j                  |<   y)a	  
    Helper function to set metadata fields that require premium user checks

    Args:
        object_data: The team/key/organization/project data object to modify
        field_name: Name of the metadata field to set
        value: Value to set for the field
    N)r(   r2   rA   )rŠ   r‹   rD   s      r   Ú_set_object_metadata_fieldr�   ’  s:   € ð( ÔFÑFÉ5Ü˜JÔ'à&×/Ñ/Ò5°2€KÔØ',€K×Ñ˜Ò$r   )Ú
max_budgetÚsoft_budgetÚmax_parallel_requestsÚ	tpm_limitÚ	rpm_limitÚmodel_max_budgetr   Úallowed_modelsÚ _TEAM_MEMBER_BUDGET_LIMIT_FIELDSc                 óH   — | €yt        | t        «      rt        | «      dk(  ryy)NFr   T)rF   Úlistrm   ©rD   s    r   Ú_is_set_budget_valuer™   ¹  s$   € Ø€}ØÜ�%œÔ¤3 u£:°¢?ØØr   Úbudget_valuesc                 ó4   ‡ — t        ˆ fd„t        D «       «      S )z„A budget is meaningful if at least one limit is actually set; an empty
    list (no model restriction) and None both count as unset.c              3   óR   •K  — | ]  }t        ‰j                  |«      «      –— Œ  y ­w)N)r™   rH   )Ú.0Úfieldrš   s     €r   ú	<genexpr>z/_has_meaningful_budget_limit.<locals>.<genexpr>Ä  s"   øè ø€ ÒlÀ%Ô# M×$5Ñ$5°eÓ$<×=Ñlùs   ƒ$')Úanyr•   )rš   s   `r   Ú_has_meaningful_budget_limitr¡   Á  s   ø€ ô ÓlÔKkÔlÓlÐlr   )Úteam_default_budget_idrf   r8   Úexisting_budget_idÚbudget_patchr¢   c             ƒ   óÆ  ‡ ‡‡K  — |syt        |«      }d|v r|d   }|�t        |¬«      nd|d<   |duxr |duxr ||k(  }	ˆˆ ˆfd„}
|�¢|	s ‰ j                  j                  d|i¬«      ƒ d{  –—† }|�|j	                  «       ni }|j                  |«       t        |«      s |
«       ƒ d{  –—†  y‰ j                  j                  d|id|j                  xs d	i|¥¬
«      ƒ d{  –—†  y|j                  xs d	|j                  xs d	dœ}|	re‰ j                  j                  d|i¬«      ƒ d{  –—† }|�=|j	                  «       }t        D ]$  }|j                  |«      }t        |«      sŒ |||<   Œ& |j                  |«       |j                  d«      �t        |d   ¬«      |d<   n|j                  dd«       t        |«      s|� |
«       ƒ d{  –—†  y‰ j                  j                  |ddi¬«      ƒ d{  –—† }‰ j                  j                  d‰‰dœi‰‰dd|j                  iidœddd|j                  iiidœ¬
«      ƒ d{  –—†  y7 �Œâ7 �Œ¦7 �Œo7 �Œ(7 Œˆ7 Œb7 Œ­w)aì  
    Apply a merge-patch of per-member budget fields to a team membership.

    ``budget_patch`` holds only the budget columns the caller explicitly sent
    (RFC 7396 semantics): a value sets the column, ``None`` clears it, and a
    column that is absent from the dict is left untouched. Once the patch is
    applied, if the budget has no meaningful limit left the member's private
    budget is disconnected so they fall back to the team default.

    ``team_default_budget_id`` is the team's shared default member budget id
    (from team metadata.team_member_budget_id). When the membership still
    points at it, we clone-on-write so editing one member's budget does not
    mutate the shared default that every other member points at.
    Nr   r   Úbudget_reset_atc               “   ón   •K  — ‰j                   j                  d‰‰ dœidddii¬«      ƒ d {  –—†  y 7 Œ­w)NÚuser_id_team_id©r8   rf   Úlitellm_budget_tableÚ
disconnectT©ri   r=   )Úlitellm_teammembershipÚupdate)rf   Útxr8   s   €€€r   Ú_disconnectz2_upsert_budget_and_membership.<locals>._disconnectï  sD   øè ø€ Ø×'Ñ'×.Ñ.Ø$°'ÀgÑ&NÐOØ(¨<¸Ð*>Ð?ð /ó 
÷ 	
ò 	
ús   ƒ*5­3®5Ú	budget_idrh   Ú
updated_byÚ r¬   )Ú
created_byr²   Úteam_membershipT)r=   Úincluder¨   r©   Úconnect)r8   rf   rª   rª   )Úcreater®   )rG   r   Úlitellm_budgettableÚfind_uniquerq   r®   r¡   r8   r•   rH   r™   Úpopr¸   r­   Úupsertr±   )r¯   rf   r8   r£   r6   r¤   r¢   Ú
write_dataÚdurationÚis_shared_defaultr°   Úexisting_budgetÚmergedÚcreate_dataÚdefault_budget_rowÚdefault_budget_dictrž   rD   Ú
new_budgets   ```                r   Ú_upsert_budget_and_membershiprÆ   Ç  sñ  úè ø€ ñ0 Øä˜\Ó*€JØ˜JÑ&Ø$Ð%6Ñ7ˆà?GÐ?SÔ!°(Õ;ÐY]ð 	Ð$Ñ%ð
 	 $Ð&ò 	9Ø"¨$Ð.ò	9àÐ"8Ñ8ð ö
ð Ð%Ñ.?Ø')×'=Ñ'=×'IÑ'IÐQ\Ð^pÐPqÐ'IÓ'r×!rˆØ8GÐ8S˜×2Ñ2Ô4ÐY[ˆØ�‰�jÔ!Ü+¨FÔ3Ù“-×ÐØØ×$Ñ$×+Ñ+ØÐ 2Ð3ØÐ 1× 9Ñ 9Ò ?¸RÐNÀ:ÐNð ,ó 
÷ 	
ð 	
ð 	ð (×/Ñ/Ò5°2Ø'×/Ñ/Ò5°2ñ*€Kñ
 Ø*,×*@Ñ*@×*LÑ*LÐT_ÐasÐStÐ*LÓ*u×$uÐØÐ)Ø);×)FÑ)FÓ)HÐÜ9ò /�Ø+×/Ñ/°Ó6�Ü'¨Õ.Ø).�K Ò&ð/ð
 ×Ñ�zÔ"à‡�Ð(Ó)Ð5Ü)>È{Ð[lÑOmÔ)nˆÐ%Ò&à�‰Ð)¨4Ô0ä'¨Ô4ØÐ)Ù“-×ÐØà ×4Ñ4×;Ñ;ØØ" DÐ)ð <ó ÷ €Jð ×
#Ñ
#×
*Ñ
*àØ"Ø"ñ ð
ð #Ø"à ¨Z×-AÑ-AÐBð)ñð 'Ø ¨Z×-AÑ-AÐBð)ðñ
ð +ó ÷ ñ ðU "sùð  ùð	
ùð %vùð"  øðøðús‡   …A(I!Á-IÁ.>I!Â,IÂ-9I!Ã&IÃ'A	I!Ä0IÄ1;I!Å-A%I!ÇIÇ'I!Ç:IÇ;AI!É	IÉ
I!ÉI!ÉI!ÉI!ÉI!ÉI!ÉI!Ú
updated_kvc                 ó´   — |t         v r| j                  |«      r
t        «        || v r1| |   �+| j                  |«      }d| v r| d   �	|| d   |<   y||i| d<   yyy)zô
    Helper function to update metadata fields that require premium user checks in the update endpoint

    Args:
        updated_kv: The key-value dict being used for the update
        field_name: Name of the metadata field being updated
    NrA   )r(   rH   r2   r»   )rÇ   r‹   Ú_values      r   Ú_update_metadata_fieldrÊ   8  sz   € ð ÔFÑFð
 �>‰>˜*Ô%ÜÔ!à�ZÑ J¨zÑ$:Ð$Fà"Ÿ™ zÓ2ˆØ˜Ñ#¨
°:Ñ(>Ð(JØ17ˆJ�zÑ" :Ò.à&0°&Ð%9ˆJ�zÒ"ð %GÐr   c                 ó�   — | €yt        | t        «      rt        | «      dk(  ryt        | t        «      r| j	                  «       dk(  ryy)zOCheck if a value has real content (not None, not empty list, not blank string).Fr   r³   T)rF   r—   rm   ÚstrÚstripr˜   s    r   Ú_has_non_empty_valuerÎ   Q  s>   € à€}ØÜ�%œÔ¤3 u£:°¢?ØÜ�%œÔ %§+¡+£-°2Ò"5ØØr   c                 ó�   — t         D ]  }|| v sŒ| |   €Œt        | |¬«       Œ t        D ]  }|| v sŒ| |   €Œt        | |¬«       Œ y)z 
    Helper function to update all metadata fields (both premium and standard).

    Args:
        updated_kv: The key-value dict being used for the update
    N)rÇ   r‹   )r(   rÊ   r'   )rÇ   rž   s     r   Ú_update_metadata_fieldsrÐ   \  sa   € ô Cò LˆØ�JÒ :¨eÑ#4Ñ#@Ü"¨jÀUÖKðLô ;ò LˆØ�JÒ :¨eÑ#4Ñ#@Ü"¨jÀUÖKñLr   )NNN)>r   Útypingr   r   r   r   r   Úfastapir   r	   Úpydanticr
   Úfloatr   rÌ   r"   Úlitellm._loggingr#   rk   r%   Úlitellm.proxy._typesr&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   Ú_user_has_admin_viewr   r   Úlitellm.proxy.utilsr2   Ú$litellm.repositories.team_repositoryr3   r4   r5   r:   rI   r}   rP   r`   rd   ry   r€   r…   r‰   r�   r•   Ú__annotations__r™   rG   r¡   rÆ   rÊ   rÎ   rÐ   © r   r   ú<module>rÜ      sE  ðÜ ß =Õ =ç )Ý ð
 ¨¡ð 
°$ó 
ð
¨c°D©jð 
¸Tó 
õ: 2Ý %÷÷ ÷ ñ õõ LÝ 3Ý ?áßLß>ð%Ø%ð%àó%ð> ò	
Ø
ð
à%ð
ð ð	
ð
 
ó
ð6¨>ð ÐEVð Ð[_ó ð ¸ð  ÐSdð  Ðimó  ðFØ%ðàðð ðð 
ó	ð$ /3Ø04Ø26ñ	?Ø%ð?à˜NÑ+ð?ð ! Ñ-ð?ð   Ñ/ð	?ð
 
ó?ðD0Ø%ð0à&ð0ð 
ó0ð<$7Ø%ð$7à%ð$7ð 'ð$7ð "ð	$7ð
 
ó$7ðT /3Ø04Ø26ñFØðFà%ðFð ˜NÑ+ðFð ! Ñ-ð	Fð
   Ñ/ðFð 
óFðR-ØØØØ!ØØØð	 ñð-ð ð-ð ð-ð 
ó-ð6	+Ð   %ó 	ð ð ¨ó ðm°°S¸#°X±ð mÀ4ó mð *.ònð ðnð ð	nð
 ˜d™
ðnð &ðnð �s˜C�x‘.ðnð   $™Jónðb: tð :¸ð :Àó :ð2 ð ¨ó ðL¨ð L°ô Lr   