
    jZ                         d dl m Z  d dl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 d d	lmZmZmZmZ  e       Z G d
 de      Zd Z y)    )datetime)AnyDictListOptionalTypeUnionget_args)verbose_logger)	DualCache)CustomLogger)DynamicGuardrailParamsGuardrailEventHooksLitellmParamsModePiiEntityType)AllMessageValues)GuardrailConfigModel)	CallTypesGuardrailStatusLLMResponseTypes#StandardLoggingGuardrailInformationc                   &    e Zd Z	 	 	 	 	 	 d3d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	 	 	 	 	 d4deeeeee   f   dededee   dee   d ee   d!eeee f      d"ee   d	dfd#Z!	 	 	 d5d$ed%ee   d&eee"      d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(	 d6dedee   d	eee)      fd2Z* xZ+S )7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	           ~/Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/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_modelB   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_hooksR   sK     #dC(.t4D44$%dV+PQfPgh 	 #r*   r0   r1   )r	   r   r   r3   r2   listr   tagsvaluesdefaultr4   )r&   r   r   r6   s       r)   r#   z$CustomGuardrail._validate_event_hookK   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                     d|v r|d   S |j                  d      xs |j                  di       }|j                  d      xs g S )zN
        Returns the guardrail(s) to be run from the metadata or root
        
guardrailslitellm_metadatametadata)get)r&   r;   r?   s      r)   get_guardrail_from_metadataz+CustomGuardrail.get_guardrail_from_metadatat   sJ     4%%88./K488J3K||L)/R/r*   requested_guardrailsc                     |D ]E  }t        |t              r| j                  |v s" yt        |t              s5| j                  |k(  sE y y)NTF)r2   dictr   r3   )r&   rB   
_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;   rG   messages)litellm.proxy._typesrJ   r@   r2   r7   should_run_guardrailr   pre_callr   
completionrX   async_pre_call_hookdcvaluerD   )r&   r'   rG   rJ   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   rI   r=   NrK   TrM   rN   rO   rP   rQ   rR   )rY   r;   rh   )r\   rJ   r@   r2   r7   r]   r   	post_callasync_post_call_success_hookr
   r   )r&   rg   rh   rG   rJ   rc   rd   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&rL   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)rA   r   debugr   r   r   _event_hook_is_event_typer2   r   0litellm_enterprise.integrations.custom_guardrailrn   ImportError_should_run_if_mode_by_tagrF   rb   )r&   r;   rL   rB   rn   rd   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 !I ' ) 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   r2   r7   rb   r   r8   r9   )r&   rL   s     r)   rq   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"   )rA   r2   rD   r   r   _validate_premium_userr@   )r&   rg   rB   	guardrailguardrail_configs        r)   )get_guardrail_dynamic_request_body_paramsz9CustomGuardrail.get_guardrail_dynamic_request_body_params-  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_userrb   )r&   r}   r~   s      r)   rx   z&CustomGuardrail._validate_premium_userP  s>     	Ot#""GHYHjHjHpHpGqr r*   guardrail_json_responseguardrail_status
start_timeend_timedurationmasked_entity_countguardrail_providerc	                    t        |t              rt        |      }ddlm}	 t        | j                  |t        | j                  t              r  |	di | j                  j                         n| j                  ||||||	      dt        ddffd}
d|v r|d   i |d<    |
|d          yd	|v r |
|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   r   guardrail_modeguardrail_responser   r   r   r   r   	containerr+   Nc                     d}| j                  |      }|g| |<   y t        |t              r|j                         y |g| |<   y )N&standard_logging_guardrail_information)r@   r2   r7   append)r   keyexistingslgs      r)   _append_guardrail_infozjCustomGuardrail.add_standard_logging_guardrail_information_to_request_data.<locals>._append_guardrail_info  sL    :C }}S)H"%	#Hd+$ #+C	#r*   r?   r>   zFunable to log guardrail information. No metadata found in request_datar"   )r2   	Exceptionr3   litellm.types.utilsr   r   r   r   r   
model_dumprD   r   r   )r&   r   rg   r   r   r   r   r   r   r   r   r   s              @r)   :add_standard_logging_guardrail_information_to_request_datazJCustomGuardrail.add_standard_logging_guardrail_information_to_request_data]  s     -y9&)*A&B#51..1 doot4 = : : <=__6-! 3
 		1d 		1t 		1 %J'/+-Z("<
#;<</"<0B#CD""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
            request_data: The request data dictionary to store guardrail metadata

        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   rg   s        r)   apply_guardrailzCustomGuardrail.apply_guardrail  s     2 s   c                 @    |i n|}| j                  ||d|||       |S )
        Add StandardLoggingGuardrailInformation to the request data

        This gets logged on downsteam Langfuse, DataDog, etc.
        successr   rg   r   r   r   r   r   )r&   rh   rg   r   r   r   r   s          r)   _process_responsez!CustomGuardrail._process_response  s>     $,#3RGG$6%&! 	H 	
 r*   ec                 4    | j                  ||d|||       |)r   guardrail_failed_to_respondr   r   )r&   r   rg   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                 `    t        |      j                         D ]  \  }}t        | ||        y)z@
        Update the guardrails litellm params in memory
        N)varsitemssetattr)r&   r   r   rb   s       r)   update_in_memory_litellm_paramsz/CustomGuardrail.update_in_memory_litellm_params  s,     ~.446JCD#u% 7r*   c                    ||y|t         j                  j                  k(  s:|t         j                  j                  k(  s|t         j                  j                  k(  r|j                  d      S |t         j                  j                  k(  s|t         j                  j                  k(  rGddlm	} ddl
m} |j                  d      }|y|j                  ||      } |t        t           |      S y)zG
        Returns the messages for the given call type and data
        Nr[   r   )cast) LiteLLMCompletionResponsesConfiginput)r   responses_api_request)r   r_   rb   rX   anthropic_messagesr@   	responses
aresponsestypingr   Blitellm.responses.litellm_completion_transformation.transformationr   )transform_responses_api_input_to_messagesr   r   )r&   rG   r;   r   r   
input_datar[   s          r)   %get_guardrails_messages_for_call_typez5CustomGuardrail.get_guardrails_messages_for_call_type  s      --333I11777I88>>>88J'' ,,222I00666# '*J!7aa &* b H -.99r*   )NNNFFF)NNNNN)NNNN),__name__
__module____qualname__r   r3   r   r   r	   r   boolr%   staticmethodr   r-   r#   rD   r   r   rA   rF   r   r   rf   r   rl   r]   rq   r{   rx   r   r   floatintr   r   r   r   r   r   r   r   r   r   __classcell__)r(   s   @r)   r   r      s    )-EI  %*&+## ##  (-@(AB## %t,?'@$FG
	## ## ###  $##J ht,B'CD  '%t,?'@$FG
'
  $$78' 
'R	0	0	tCy$tC)?$?@AA	B	0#DItD>T9T4U/V$VW 
&38n&19)1D&	$&P(( #( I&	(
 
"	#(T< (< 
	<|34G 3D 3 !d !t !F $ '+$($(8<,06!&y#tT$Z'G!H6 6 *	6
 UO6 5/6 5/6 &d38n56 %SM6 
6v #'26'+ 3- 4./	
 tn 
> '+$($(4.  UO	
 5/ 5/: '+$($(  UO	
 5/ 5/.WW W 	W
 W 
W$&m &PT & <@,",*24.,	$'(	),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;   rg   )rh   rg   r   r   r   )r   rg   r   r   r   )r   nowr@   r   	timestamptotal_secondsr   r   argsr'   r   r&   rg   rh   r   funcs          r)   async_wrapperz0log_guardrail_information.<locals>.async_wrapper6  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;   rg   )rh   rg   r   )r   rg   r   )r   r   r@   r   r   r   r   r   s          r)   sync_wrapperz/log_guardrail_information.<locals>.sync_wrapperM  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 r   )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   r   r   r   r   r   r   r	   r
   litellm._loggingr   litellm.cachingr   "litellm.integrations.custom_loggerr   litellm.types.guardrailsr   r   r   r   r   litellm.types.llms.openair   3litellm.types.proxy.guardrails.guardrail_hooks.baser   r   r   r   r   r   ra   r   r   r"   r*   r)   <module>r      sV     C C C + % ;  U  [Il IX>r*   