
    AHj`;                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	Z	 ej                  e      Zd dlmZmZ g dZddgZdee   fdZdefd	Zd
 Zd!dedee   fdZdedefdZd ZdefdZdededeeef   fdZ 	 	 	 d"dedee   dee   dee   fdZ!dededefdZ"dededefdZ#	 	 	 	 	 	 d#dedee   dee   dee   dee   dee   dee   fd Z$y)$    N)ListOptional)DEFAULT_HEALTH_CHECK_PROMPTHEALTH_CHECK_TIMEOUT_SECONDS)messagesapi_keypromptinputvertex_credentialsaws_access_key_idaws_secret_access_keymodel
mode_errorreturnc                      	 ddl } | j                  | j                        j                  }t        j
                  dk(  rt        |      dz  S t        |      dz  S # t        $ r Y yw xY w)zj
    Get process RSS memory in MB.
    On Linux, ru_maxrss is in KB. On macOS, ru_maxrss is in bytes.
    r   Ndarwini   i   )resource	getrusageRUSAGE_SELF	ru_maxrsssysplatformfloat	Exception)r   r   s     R/root/tools/cai/cai_env/lib/python3.12/site-packages/litellm/proxy/health_check.py_get_process_rss_mbr      sd    
&&x';';<FF	<<8##{33Y$&& s   A	A A 	A&%A&c                  $    t               } | y| dS )Nunknownz.2f)r   )rss_mbs    r   _rss_mb_for_logr    -   s     "F~S\    c                  <    ddg} dt        j                  |       dgS )z,
    Get a random message from the LLM.
    zHey how's it going?zWhat's 1 + 1?user)rolecontent)randomchoice)r   s    r   _get_random_llm_messager(   4   s%     &7Hh(?@AAr!   endpoint_datadetailsc                     | j                  dd       |dur-| j                         D ci c]  \  }}|t        vs|| c}}S | j                         D ci c]  \  }}|t        v s|| c}}S c c}}w c c}}w )z7
    Clean the endpoint data for display to users.
    litellm_logging_objNF)popitemsILLEGAL_DISPLAY_PARAMSMINIMAL_DISPLAY_PARAMS)r)   r*   kvs       r   _clean_endpoint_datar3   =   s     +T2 % (--/S$!Q1<R3RAS  -224Ttq!=S8SadTSTs   A1A1A7(A7
model_listc                     t               }g }| D ]V  }|j                  d      xs i }|j                  d      xs d }|0||vs5|j                  |       |j                  |       X |S )N
model_infoid)setgetaddappend)r4   seen_idsfiltered_deployments
deployment_model_info_ids         r   filter_deployments_by_idrA   I   sx     uH  4
 nn\28bood#+t;hLL ''
34  r!   c                    K   	 t        j                  | |       d {   S 7 # t         j                  $ r ddicY S w xY ww)NerrorzTimeout exceeded)asynciowait_forTimeoutError)tasktimeouts     r   run_with_timeoutrI   \   sF     -%%dG4444 - +,,-s,   A$ "$ A$ >A>Ac                 
  K   | d   }| j                  di       }|j                  dd       }t        ||      }|j                  d      xs t        }t        t	        j
                  ||t        dg      |       d {   S 7 w)Nlitellm_paramsr6   modehealth_check_timeoutztest from litellm)rL   r	   r
   )r9   '_update_litellm_params_for_health_checkr   rI   litellmahealth_checkr   )r   rK   r6   rL   rH   s        r   _run_model_health_checkrQ   e   s     +,N<,J>>&$'D<ZXNnn34T8TG!.&'		
 	   s   A:B<B=Bmodelsconcurrency_limitc                   	
K   dgt        |       z  }i t        t        |             	d
dt        f	
fd}t	        t        |t        |                   D ]	  } |         r}t        j                  t        j                               t        j                         d{   \  }}|D ].  }j                  |      }	 |j                         ||<    |        0 r}|
fS 7 A# t        $ r}|||<   Y d}~%d}~ww xY ww)z{
    Run health checks with at most `concurrency_limit` active tasks.
    Preserves result ordering to match `models`.
    Nr   r   c                      	 t              \  } }t        j                  t	        |            }| |<   t        t                    y# t        $ r Y yw xY w)NFT)nextStopIterationrD   create_taskrQ   maxlen)idx
next_modelrG   
model_iterpeak_in_flighttasks_to_indexs      r   _schedule_nextzC_run_health_checks_with_bounded_concurrency.<locals>._schedule_next   s`    	":.OC ""#::#FG"t^S-@A  		s   A
 
	AA)return_when)rZ   iter	enumerateboolrangeminrD   waitr8   keysFIRST_COMPLETEDr-   resultr   )rR   rS   resultsr`   _donerG   r[   er]   r^   r_   s            @@@r   +_run_health_checks_with_bounded_concurrencyro   w   s
     FS[(G.0Ni'(JN	D 	 3(#f+67  ##%&//
 
a  	D $$T*C!#{{} 	  N""
  ! !sB   B!D&C('DC*D$D*	D3C=8D=DDmax_concurrencyinstrumentation_contextc                   K   |xs i }t        |j                  dd            }|j                  dd      }|j                  dd      }d}d}t        |t              r|dkD  rd}t	        | |       d	{   \  }	}nS| D 
cg c]   }
t        j                  t        |
            " }}
t        |      }t        j                  |d
di d	{   }	|r@t        j                  d|||t        |       ||t        j                         t               	       g }g }t        |	|       D ]  \  }}
|
d   }|
j                  d      xs i j                  d      }t        |t               r-d|vr)t#        i |||      }|r||d<   |j%                  |       lt        |t               r)t#        i |||      }|r||d<   |j%                  |       t#        ||      }|r||d<   |j%                  |        ||fS 7 }c c}
w 7 .w)z
    Perform a health check for each model in the list.

    max_concurrency: Optional limit on concurrent health check requests.
    enabledFcycle_idr   source	unboundedr   boundedNreturn_exceptionsTzhealth_check_dispatch_summary source=%s cycle_id=%s mode=%s model_count=%d max_concurrency=%s peak_in_flight=%d thread_count=%d rss_mb=%srK   r6   r7   rC   model_id)rd   r9   
isinstanceintro   rD   rX   rQ   rZ   gatherloggerdebug	threadingactive_countr    zipdictr3   r;   )r4   r*   rp   rq   instrumentation_enabledrt   ru   dispatch_moder^   rk   r   taskshealthy_endpointsunhealthy_endpoints
is_healthyrK   	_model_idcleaneds                     r   _perform_health_checkr      s-     6;"#:#>#>y%#PQ&**:yAH$((9=FMN/3'Oa,?!(S)
 #

 NX
DIG 7 >?
 
 UFFF X
O""$
	
  *5 0
E/0YY|,277=	j$'G:,E*+Kn+K
+KWUG&/
#$$W-
D)*+Kn+K
+KWUG&/
#&&w/*>7CG&/
#&&w/%0( 111]#

 Gs1   A0G:2G/3G:?%G2$%G:	G7
D&G:2G:r   r   c                     t        j                          }i }| D ]  }|j                  d      }|sd|dd||<   ! |D ]  }|j                  d      }|sd|dd||<   ! |S )a  
    Build a dict mapping deployment_id -> DeploymentHealthStateValue from
    health check endpoint results.

    Each endpoint dict includes a 'model_id' field (added by _perform_health_check)
    that maps back to the deployment's model_info.id.

    Used by the background health check loop to feed health state into
    the router's DeploymentHealthCache for health-check-driven routing.
    ry   T )r   	timestampreasonFbackground_health_check_failed)timer9   )r   r   nowstatesepry   s         r   build_deployment_health_statesr      s     ))+CF 66*%"  F8 " 66*%# : F8 Mr!   r6   rK   c                 B   t               |d<   | j                  dd      }|||d<   n/d| j                  d      xs |j                  d      xs dvrd	|d<   | j                  dd      }|||d<   | j                  d
d      dk(  r| j                  dd      |d<   |d   j                  d      rqddlm} |d   }|j                  d      r|dd }|j                  d      }g }|D ]"  }||j                  vs|j                  |       $ dj                  |      }||d<   |S )a  
    Update the litellm params for health check.

    - gets a short `messages` param for health check
    - updates the `model` param with the `health_check_model` if it exists Doc: https://docs.litellm.ai/docs/proxy/health#wildcard-routes
    - updates the `voice` param with the `health_check_voice` for `audio_speech` mode if it exists Doc: https://docs.litellm.ai/docs/proxy/health#text-to-speech-models
    - for Bedrock models with region routing (bedrock/region/model), strips the litellm routing prefix but preserves the model ID
    r   health_check_max_tokensN
max_tokens*health_check_modelr   r      rL   audio_speechhealth_check_voicealloyvoicezbedrock/r   )BedrockModelInfo   /)	r(   r9   
startswith!litellm.llms.bedrock.common_utilsr   splitall_global_regionsr;   join)	r6   rK   _health_check_max_tokens_health_check_modelr   r   partsfiltered_partsparts	            r   rN   rN     sP    "9!:N:)~~.GN+'?|$	+,Q0B0B70KQr
 ()|$$..)=tD&"5w~~fd#~5",..1Ew"Ow g))*5Fw'J'!"IE C  	,D+>>>%%d+	,
 ("'wr!   	cli_modelry   c                   K   |xs i }t        |j                  dd            }|j                  dd      }|j                  dd      }	| s(|r	|d|idg} n|rt        j                  d|	|       g g fS t	        j
                         }
t        |       }|<| D cg c],  }|j                  d
      xs i j                  d      |k(  s+|. }}|r?|} n<|:| D cg c]  }|d   d   |k(  s| }}|g k(  r| D cg c]  }|d   |k(  s| }}|} t        |       }t        |       } t        |       }|r7t        j                  d|	|||||t        j                         t               	       	 t        | |||       d	{   \  }}|rat        j                  d|	||t        |      t        |      t	        j
                         |
z
  dz  t        j                         t               	       ||fS c c}w c c}w c c}w 7 }# t        $ rQ |rMt        j                  d|	||t	        j
                         |
z
  dz  t        j                         t                       w xY ww)av  
    Perform a health check on the system.

    When model_id is provided, only the deployment with that id is checked
    (so models that share the same name but have different ids are checked separately).
    When model (name) is provided, all deployments matching that name are checked.

    Returns:
        (bool): True if the health check passes, False otherwise.
    rs   Frt   r   ru   r   )
model_namerK   zAhealth_check_cycle_skipped source=%s cycle_id=%s reason=no_modelsNr6   r7   rK   r   )r4   zhealth_check_cycle_start source=%s cycle_id=%s requested_model_count=%d post_model_filter_count=%d deduped_model_count=%d max_concurrency=%s thread_count=%d rss_mb=%s)rp   rq   zihealth_check_cycle_failed source=%s cycle_id=%s model_count=%d duration_ms=%.2f thread_count=%d rss_mb=%si  zhealth_check_cycle_complete source=%s cycle_id=%s model_count=%d healthy_count=%d unhealthy_count=%d duration_ms=%.2f thread_count=%d rss_mb=%s)rd   r9   r}   r~   r   	monotonicrZ   rA   r   r   r    r   r   	exception)r4   r   r   r*   ry   rp   rq   r   rt   ru   cycle_start_timerequested_model_countx_by_id_new_model_listpost_filter_model_countdeduped_model_countr   r   s                      r   perform_health_checkr   M  s    & 6;"#:#>#>y%#PQ&**:yAH$((9=F(Wi<PQJ 'W
 r6M~~'
O !
aeeL&9&?R%D%DT%Jh%VA
 
 J		!
Q'7%8%AU%JA
 
 b *4QQ,58PqQOQ$
!*o)J j/ u!#""$
	
7L+$;	8
 2
..&  ^!"#$^^ 00D8""$
	
 111C

 R.2
  "{#!$44<&&(! 	si   BI,G(G(IG-&G-*I5G2G2AI'G9 9G7:G9 A6I7G9 9AII)T)TNN)NNTNNN)%rD   loggingr&   r   r   r   typingr   r   rO   	getLogger__name__r}   litellm.constantsr   r   r/   r0   r   r   strr    r(   r   rd   r3   rA   rI   rQ   listr{   tuplero   r   r   rN   r    r!   r   <module>r      s      
   ! 			8	$ W  "<0 Xe_   B	 	x~ 	  	 &- $'#'#%('#
49'#X #%).2	C2C2d^C2 c]C2 &d^	C2L### 
#L==&*=	=D  #""%).2l2l2C=l2 }l2 d^	l2
 sml2 c]l2 &d^l2r!   