
    hP                         d dl m Z  d dl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mZmZmZmZ d dlmZ d dlmZmZmZ  e       Z G d	 d
e      Zd Zy)    )datetime)AnyDictListLiteralOptionalTypeUnionget_args)verbose_logger)	DualCache)CustomLogger)DynamicGuardrailParamsGuardrailEventHooksLitellmParamsModePiiEntityType)GuardrailConfigModel)	CallTypesLLMResponseTypes#StandardLoggingGuardrailInformationc                       e Zd Z	 	 	 	 	 	 d2dee   deee      deeeee   ef      de	de	de	f fdZ
ed	eed
      fd       Zdeeeee   ef      dee   d	dfdZded	eee   eeeef      f   fdZdeee   eeeef      f   d	e	fdZdeeef   dee   d	ee   fdZdededee   d	ee   fdZded	e	fdZded	e	fdZded	efdZd	e	fdZ	 	 	 	 d3deeeeee   f   deded   dee   d ee   d!ee   d"eeee f      d	dfd#Z!	 	 d4d$ed%ee   d&eee"      d	efd'Z#	 	 	 d5dee   dedee   d ee   d!ee   f
d(Z$	 	 	 d5d)ededee   d ee   d!ee   f
d*Z%d+ed,ed-e d.e d	ef
d/Z&d0e'd	dfd1Z( xZ)S )6CustomGuardrailNguardrail_namesupported_event_hooks
event_hook
default_onmask_request_contentmask_response_contentc                     || _         || _        || _        || _        || _        || _        |r| j                  ||       t        |    di | y)a8  
        Initialize the CustomGuardrail class

        Args:
            guardrail_name: The name of the guardrail. This is the name used in your requests.
            supported_event_hooks: The event hooks that the guardrail supports
            event_hook: The event hook to run the guardrail on
            default_on: If True, the guardrail will be run by default on all requests
            mask_request_content: If True, the guardrail will mask the request content
            mask_response_content: If True, the guardrail will mask the response content
        N )	r   r   r   r   r   r   _validate_event_hooksuper__init__)	selfr   r   r   r   r   r   kwargs	__class__s	           a/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/integrations/custom_guardrail.pyr$   zCustomGuardrail.__init__   s`    . -%:"  	 !+*>!+@"  %%j2GH"6"    returnr   c                       y)zx
        Returns the config model for the guardrail

        This is used to render the config model in the UI.
        Nr!   r!   r)   r(   get_config_modelz CustomGuardrail.get_config_model?   s     r)   c                    dt         t        t           t        t           f   dt        t           dd fd}|y t	        |t              rt        |      }t	        |t
              r
 |||       y t	        |t              rL |t        |j                  j                               |       |j                  r ||j                  g|       y y t	        |t              r||vrt        d| d|       y y )Nr   r   r*   c                 r    | D ]2  }t        |t              rt        |      }||vs#t        d| d|        y )NEvent hook % is not in the supported event hooks )
isinstancestrr   
ValueError)r   r   hooks      r(   5_validate_event_hook_list_is_in_supported_event_hookszcCustomGuardrail._validate_event_hook.<locals>._validate_event_hook_list_is_in_supported_event_hooksP   sK     #dC(.t4D44$%dV+PQfPgh 	 #r)   r/   r0   )r
   r   r   r2   r1   listr   tagsvaluesdefaultr3   )r%   r   r   r5   s       r(   r"   z$CustomGuardrail._validate_event_hookH   s   
	d#67cBC
	#'(;#<
	 
	 j#&,Z8Jj$'A1 
D)AZ__++-.0E !!E''(*? " 
$78!66 !*-RShRij  7 9r)   datac                 t    d|v r|d   S |j                  d      xs i }|j                  d      xs g }|r|S |S )zN
        Returns the guardrail(s) to be run from the metadata or root
        
guardrailsmetadata)get)r%   r:   r=   requested_guardrailss       r(   get_guardrail_from_metadataz+CustomGuardrail.get_guardrail_from_metadatar   sM     4%%88J'-2'||L9?R''##r)   r?   c                     |D ]E  }t        |t              r| j                  |v s" yt        |t              s5| j                  |k(  sE y y)NTF)r1   dictr   r2   )r%   r?   
_guardrails      r(   %_guardrail_is_in_requested_guardrailsz5CustomGuardrail._guardrail_is_in_requested_guardrails   sI    
 /J*d+&&*4J,&&*4 / r)   r&   	call_typec                 \  K   ddl m} |j                  d      }|t        |t              s|S | j                  |t        j                        dur|S |t        j                  k(  s|t        j                  k(  r| j                   ||j                  d      |j                  d      |j                  d      |j                  d	      |j                  d
            t        ||j                  xs d       d {   }|(t        |t              r|j                  d      }|||d<   |S 7 0w)Nr   UserAPIKeyAuthr<   r:   
event_typeTuser_api_key_user_iduser_api_key_team_iduser_api_key_end_user_iduser_api_key_hashuser_api_key_request_routeuser_idteam_idend_user_idapi_keyrequest_routeacompletion)user_api_key_dictcacher:   rE   messages)litellm.proxy._typesrH   r>   r1   r6   should_run_guardrailr   pre_callr   
completionrV   async_pre_call_hookdcvaluerB   )r%   r&   rE   rH   litellm_guardrailsresultresult_messagess          r(   async_pre_call_deployment_hookz.CustomGuardrail.async_pre_call_deployment_hook   s0     	8 $ZZ5%Z8JD-QM %%(;(D(D &  
 M 	,,,	Y=R=R0R33"0"JJ'=>"JJ'=> &

+E F"JJ':;"(**-I"J# #//:] 4  F !j&>"(**Z"8".)8F:&%s   C7D,9D*:1D,request_dataresponsec                   K   ddl m} |j                  d      }|t        |t              s|S | j                  |t        j                        dur|S | j                   ||j                  d      |j                  d      |j                  d	      |j                  d
      |j                  d            ||       d{   }|t        |t        t                    s|S |S 7 #w)zh
        Allow modifying / reviewing the response just after it's received from the deployment.
        r   rG   r<   NrI   TrK   rL   rM   rN   rO   rP   )rW   r:   rf   )rZ   rH   r>   r1   r6   r[   r   	post_callasync_post_call_success_hookr   r   )r%   re   rf   rE   rH   ra   rb   s          r(   'async_post_call_success_deployment_hookz7CustomGuardrail.async_post_call_success_deployment_hook   s     	8 *--l;%Z8JD-QO %%!.A.K.K &  
 O 88,$(()?@$(()?@(,,-GH$(()<=*../KL  9 

 

 >FH=M4N!OO

s   B>C& C$$C&rJ   c                    | j                  |      }t        j                  d| j                  || j                  || j
                         | j
                  du rT| j                  |      rBt        | j                  t              r'	 ddl	m
} |j                  || j                        }||S yy| j                  r!| j                  |      s|j                  dk7  ry| j                  |      syt        | j                  t              r'	 ddl	m
} |j                  || j                        }||S y# t        $ r t        d      w xY w# t        $ r t        d      w xY w)zO
        Returns True if the guardrail should be run on the event_type
        zinside should_run_guardrail for guardrail=%s event_type= %s guardrail_supported_event_hooks= %s requested_guardrails= %s self.default_on= %sTr   )EnterpriseCustomGuardrailHelperzuSetting tag-based guardrails is only available in litellm-enterprise. You must be a premium user to use this feature.Flogging_only)r@   r   debugr   r   r   _event_hook_is_event_typer1   r   0litellm_enterprise.integrations.custom_guardrailrl   ImportError_should_run_if_mode_by_tagrD   r`   )r%   r:   rJ   r?   rl   rb   s         r(   r[   z$CustomGuardrail.should_run_guardrail   sm     $??E [OO OO	
 ??d"--j9doot4 =WWdooF )% OO>>?ST  N2--j9doot, 5OOdooF !K ' ) T 6  ! L s   D- E -EEc                 F   | j                   yt        | j                   t              r|j                  | j                   v S t        | j                   t              r0|j                  | j                   j
                  j                         v S | j                   |j                  k(  S )a  
        Returns True if the event_hook is the same as the event_type

        eg. if `self.event_hook == "pre_call" and event_type == "pre_call"` -> then True
        eg. if `self.event_hook == "pre_call" and event_type == "post_call"` -> then False
        T)r   r1   r6   r`   r   r7   r8   )r%   rJ   s     r(   ro   z)CustomGuardrail._event_hook_is_event_type%  s{     ??"doot,##t66doot,##t';';'B'B'DDD*"2"222r)   c                     | j                  |      }|D ]c  }t        |t              s| j                  |v s#t	        di || j                     }| j                         duri c S |j                  di       c S  i S )a  
        Returns `extra_body` to be added to the request body for the Guardrail API call

        Use this to pass dynamic params to the guardrail API call - eg. success_threshold, failure_threshold, etc.

        ```
        [{"lakera_guard": {"extra_body": {"foo": "bar"}}}]
        ```

        Will return: for guardrail=`lakera-guard`:
        {
            "foo": "bar"
        }

        Args:
            request_data: The original `request_data` passed to LiteLLM Proxy
        T
extra_bodyr!   )r@   r1   rB   r   r   _validate_premium_userr>   )r%   re   r?   	guardrailguardrail_configs        r(   )get_guardrail_dynamic_request_body_paramsz9CustomGuardrail.get_guardrail_dynamic_request_body_params5  s    $  $??M .I)T*t/B/Bi/O;Q < 3 34<  ..0<I (++L"== . 	r)   c                 v    ddl m}m} |dur-t        j                  d|j
                  j                          yy)z<
        Returns True if the user is a premium user
        r   )CommonProxyErrorspremium_userTz5Trying to use premium guardrail without premium user F)litellm.proxy.proxy_serverr{   r|   r   warningnot_premium_userr`   )r%   r{   r|   s      r(   rv   z&CustomGuardrail._validate_premium_userX  s>     	Ot#""GHYHjHjHpHpGqr r)   guardrail_json_responseguardrail_status)successfailure
start_timeend_timedurationmasked_entity_countc           
      z   t        |t              rt        |      }ddlm} t        | j                  t        | j                  t              r  |d	i | j                  j                         n| j                  ||||||      }	d|v r|d   i |d<   |	|d   d<   yd|v r	|	|d   d<   yt        j                  d       y)
z
        Builds `StandardLoggingGuardrailInformation` and adds it to the request metadata so it can be used for logging to DataDog, Langfuse, etc.
        r   )GuardrailMode)r   guardrail_modeguardrail_responser   r   r   r   r   r=   N&standard_logging_guardrail_informationlitellm_metadatazFunable to log guardrail information. No metadata found in request_datar!   )r1   	Exceptionr2   litellm.types.utilsr   r   r   r   r   
model_dumpr   r~   )
r%   r   re   r   r   r   r   r   r   slgs
             r(   :add_standard_logging_guardrail_information_to_request_datazJCustomGuardrail.add_standard_logging_guardrail_information_to_request_datae  s     -y9&)*A&B#51.. doot4 = : : <=__6-! 3
 %J'/+-Z(QTL$%MN</  +,8 ""Xr)   textlanguageentitiesc                    K   |S w)a  
        Apply your guardrail logic to the given text

        Args:
            text: The text to apply the guardrail to
            language: The language of the text
            entities: The entities to mask, optional

        Any of the custom guardrails can override this method to provide custom guardrail logic

        Returns the text with the guardrail applied

        Raises:
            Exception:
                - If the guardrail raises an exception

        r!   )r%   r   r   r   s       r(   apply_guardrailzCustomGuardrail.apply_guardrail  s     . s   c                 @    |i n|}| j                  ||d|||       |S )
        Add StandardLoggingGuardrailInformation to the request data

        This gets logged on downsteam Langfuse, DataDog, etc.
        r   r   re   r   r   r   r   r   )r%   rf   re   r   r   r   r   s          r(   _process_responsez!CustomGuardrail._process_response  s>     $,#3RGG$6%&! 	H 	
 r)   ec                 4    | j                  ||d|||       |)r   r   r   r   )r%   r   re   r   r   r   s         r(   _process_errorzCustomGuardrail._process_error  s1     	GG$%%&! 	H 	
 r)   content_stringmask_stringstart_index	end_indexc                 \    d|cxk  r|cxk  rt        |      k  s|S  |S |d| |z   ||d z   S )zS
        Mask the content in the string between the start and end indices.
        r   N)len)r%   r   r   r   r   s        r(   mask_content_in_stringz&CustomGuardrail.mask_content_in_string  sM     [C9CN0CC!! D!! l{+k9N9:<VVVr)   litellm_paramsc                      y)z@
        Update the guardrails litellm params in memory
        Nr!   )r%   r   s     r(   update_in_memory_litellm_paramsz/CustomGuardrail.update_in_memory_litellm_params  s     	r)   )NNNFFF)NNNN)NN)NNN)*__name__
__module____qualname__r   r2   r   r   r
   r   boolr$   staticmethodr	   r,   r"   rB   r   r   r@   rD   r   r   rd   r   rj   r[   ro   ry   rv   r   r   floatintr   r   r   r   r   r   r   r   __classcell__)r'   s   @r(   r   r      s    )-EI  %*&+$# $#  (-@(AB$# %t,?'@$FG
	$# $# #$#  $$#L ht,B'CD  (%t,?'@$FG
(
  $$78( 
(T$$	tCy$tC)?$?@AA	B$#DItD>T9T4U/V$VW 
"'38n'19)1D'	$'R(( #( I&	(
 
"	#(T? (? 
	?B34G 3D 3 !d !t !F $ '+$($(8<*!&y#tT$Z'G!H* * ""67	*
 UO* 5/* 5/* &d38n5* 
*^ #'26	 3- 4./	
 
: '+$($(4.  UO	
 5/ 5/: '+$($(  UO	
 5/ 5/.WW W 	W
 W 
W$m PT r)   r   c                      ddl ddl}|j                          fd       |j                          fd       |j                          fd       }|S )ad  
    Decorator to add standard logging guardrail information to any function

    Add this decorator to ensure your guardrail response is logged to DataDog, OTEL, s3, GCS etc.

    Logs for:
        - pre_call
        - during_call
        - TODO: log post_call. This is more involved since the logs are sent to DD, s3 before the guardrail is even run
    r   Nc            	      |  K   t        j                         }| d   }|j                  d      xs |j                  d      xs i }	  | i | d {   }|j                  |||j	                         t        j                         j	                         t        j                         |z
  j                               S 7 k# t        $ rq}|j                  |||j	                         t        j                         j	                         t        j                         |z
  j                               cY d }~S d }~ww xY ww)Nr   r:   re   )rf   re   r   r   r   )r   re   r   r   r   )r   nowr>   r   	timestamptotal_secondsr   r   argsr&   r   r%   re   rf   r   funcs          r(   async_wrapperz0log_guardrail_information.<locals>.async_wrapper  s    \\^
 $Q#ZZ/S6::n3MSQS	!42622H))!)%//1!113",,.:5DDF *   3  	&&)%//1!113",,.:5DDF '  	sJ   AD<B? B=A*B? <D<=B? ?	D9A&D4.D9/D<4D99D<c                     t        j                         }| d   }|j                  d      xs |j                  d      xs i }	  | i |}|j                  ||t        j                         |z
  j	                               S # t
        $ rA}|j                  ||t        j                         |z
  j	                               cY d }~S d }~ww xY w)Nr   r:   re   )rf   re   r   )r   re   r   )r   r   r>   r   r   r   r   r   s          r(   sync_wrapperz/log_guardrail_information.<locals>.sync_wrapper  s    \\^
 $Q#ZZ/S6::n3MSQS	T,V,H))!)",,.:5DDF *  
  	&&)",,.:5DDF '  	s   >B 	C6CCCc                  F    j                        r | i |S  | i |S )N)iscoroutinefunction)r   r&   r   asyncior   r   s     r(   wrapperz*log_guardrail_information.<locals>.wrapper+  s1    &&t, $1&11T,V,,r)   )r   	functoolswraps)r   r   r   r   r   r   s   `  @@@r(   log_guardrail_informationr     sg     __T , __T $ __T- -
 Nr)   N)r   typingr   r   r   r   r   r	   r
   r   litellm._loggingr   litellm.cachingr   "litellm.integrations.custom_loggerr   litellm.types.guardrailsr   r   r   r   r   3litellm.types.proxy.guardrails.guardrail_hooks.baser   r   r   r   r   r_   r   r   r!   r)   r(   <module>r      sQ     L L L + % ;  U  [Xl Xv>r)   