
    h:                         d Z ddl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mZ ddlmZmZ ddl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m Z   G d dee      Z!y)z5
OpenAI Moderation Guardrail Integration for LiteLLM
    )	TYPE_CHECKINGAnyAsyncGeneratorDictListLiteralOptionalTypeUnion)HTTPException)verbose_proxy_logger)CustomGuardraillog_guardrail_information)get_async_httpx_clienthttpxSpecialProvider   )OpenAIGuardrailBase)UserAPIKeyAuth)AllMessageValuesOpenAIModerationResponse)GuardrailConfigModel)ModelResponseModelResponseStreamc                       e Zd ZdZ	 	 	 d dedee   dee   deed      f fdZdee   fd	Zd
eddfdZ	d!dZ
edddedeeef   ded   deeeef      f
d       Zedeeef   ddded   deeeef      fd       Zedeeef   ddddddfd       Zedddedeeef   ded   fd       Zdddee   fdZedeed      fd       Z xZS )"OpenAIModerationGuardraila  
    LiteLLM Built-in Guardrail for OpenAI Content Moderation.

    This guardrail scans prompts and responses using the OpenAI Moderation API to detect
    harmful content, including violence, hate, harassment, self-harm, sexual content, etc.

    Configuration:
        guardrail_name: Name of the guardrail instance
        api_key: OpenAI API key
        api_base: OpenAI API endpoint
        model: OpenAI moderation model to use
        default_on: Whether to enable by default
    guardrail_nameapi_keyapi_basemodel)omni-moderation-latestztext-moderation-latestc                    ddl m} |j                  |j                  |j                  g}t        |   d||d| t        t        j                        | _
        |xs | j                         | _        |xs d| _        |xs d| _        | j                  st        d      t!        j"                  d| d	| j                          y
)z/Initialize OpenAI Moderation guardrail handler.r   )GuardrailEventHooks)r   supported_event_hooks)llm_providerzhttps://api.openai.com/v1r    zlOpenAI Moderation: api_key is required. Set OPENAI_API_KEY environment variable or pass it in configuration.z)Initialized OpenAI Moderation Guardrail: z with model: N )litellm.types.guardrailsr"   pre_callduring_call	post_callsuper__init__r   r   GuardrailCallbackasync_handler_get_api_keyr   r   r   
ValueErrorr   info)	selfr   r   r   r   kwargsr"   r#   	__class__s	           w/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/guardrails/guardrail_hooks/openai/moderations.pyr+   z"OpenAIModerationGuardrail.__init__6   s     	A  ((++))!

 	 	
)"7	
 	
 4-??

 5$"3"3"5 ?$?RWRs[s
||  L  M  M!!77G}UYU_U_T`a	
    returnc                     ddl }ddl}ddlm} |j                  j                  d      xs$ |j                  xs |j                  xs  |d      S )z?Get API key from environment variables or litellm configurationr   N)get_secret_strOPENAI_API_KEY)oslitellmlitellm.secret_managers.mainr8   environgetr   
openai_key)r1   r:   r;   r8   s       r4   r.   z&OpenAIModerationGuardrail._get_api_key]   sM    ? JJNN+, 00!!0 ./		
r5   
input_textr   c                   K   | j                   |d}t        j                  d|       | j                  j	                  | j
                   dd| j                   dd|       d{   }t        j                  d	|j                                |j                  d
k7  r$t        |j                  d|j                  d      ddlm}  |di |j                         S 7 ww)z>
        Make a request to the OpenAI Moderation API.
        )r   inputz#OpenAI Moderation guard request: %sz/moderationszBearer zapplication/json)AuthorizationzContent-Type)urlheadersjsonNz$OpenAI Moderation guard response: %s   z$OpenAI Moderation API request failed)errordetailsstatus_codedetailr   )r   r%   )r   r   debugr-   postr   r   rF   rK   r   textlitellm.types.llms.openair   )r1   r@   request_bodyresponser   s        r4   async_make_requestz,OpenAIModerationGuardrail.async_make_requestk   s      ZZ

 	""1<	
 ++00==/.#*4<<.!9 2  1 
 
 	""2HMMO	
 3&$00C'}}  	G':(--/::/
s   A$C &C'A8C c                 N   |j                   sy|j                   d   }|j                  r}g }|j                  r6|j                  j                         D ]  \  }}|s	|j	                  |        ||j
                  xs i d}t        j                  d|       t        dd|d      y)	zk
        Check if the moderation response indicates harmful content and raise exception if needed.
        Nr   )violated_categoriescategory_scoresz5OpenAI Moderation: Content flagged for violations: %si  z!Violated OpenAI moderation policy)rH   moderation_resultrJ   )	resultsflagged
categoriesitemsappendrV   r   warningr   )r1   moderation_responseresultrU   categoryis_violatedviolation_detailss          r4   _check_moderation_resultz2OpenAIModerationGuardrail._check_moderation_result   s     #**$,,Q/>>"$  -3->->-D-D-F)Hk"+228< .G
 (;#)#9#9#?R!
 !((G!
  @): % r5   user_api_key_dictr   cachedata	call_type)
completiontext_completion
embeddingsimage_generation
moderationaudio_transcriptionpass_through_endpointrerankc                   K   t        j                  d|       |dk(  r|S |j                  d      }|t        j                  d       |S | j	                  |      }|rIt        j                  d|dd  d       | j                  |	       d{   }| j                  |       |S t        j                  d
       |S 7 .w)z
        Pre-call hook to scan user prompts before sending to LLM.

        Raises HTTPException if content should be blocked.
        zAOpenAI Moderation: Running pre-call prompt scan, on call_type: %srl   messagesN=OpenAI Moderation: not running guardrail. No messages in dataz OpenAI Moderation: User prompt: d   ...r@   z'OpenAI Moderation: No user prompt foundr   r0   r>   r]   get_user_promptrS   rc   )r1   rd   re   rf   rg   new_messagesuser_promptr^   s           r4   async_pre_call_hookz-OpenAIModerationGuardrail.async_pre_call_hook   s     , 	!!O	
 $K;?88J;O ((O K**<8 %%2;t3D2ESI )-(?(?& )@ ) #
 ))*=> 	 !((9 #s   BB?B=/B?)rh   rj   rk   rl   rm   	responsesc                   K   t        j                  d|       |dk(  r|S |j                  d      }|t        j                  d       |S | j	                  |      }|r+| j                  |       d{   }| j                  |       |S 7 w)z
        Moderation hook to scan user prompts during call processing.

        Raises HTTPException if content should be blocked.
        z<OpenAI Moderation: Running moderation hook, on call_type: %srl   rq   Nrr   ru   rv   )r1   rf   rd   rg   rx   ry   r^   s          r4   async_moderation_hookz/OpenAIModerationGuardrail.async_moderation_hook   s     & 	!!J	
 $K;?88J;O ((O K**<8(,(?(?& )@ ) #
 ))*=>#s   A0B2B
3BrR   r   c                    K   t        j                  d       | j                  |      }|rGt        j                  d|dd  d       | j                  |       d{   }| j	                  |       |S 7 w)z
        Post-call hook to scan LLM responses before returning to user.

        Raises HTTPException if response should be blocked.
        z2OpenAI Moderation: Running post-call response scanz"OpenAI Moderation: Response text: Nrs   rt   ru   )r   r0   _extract_response_textrS   rc   )r1   rf   rd   rR   response_textr^   s         r4   async_post_call_hookz.OpenAIModerationGuardrail.async_post_call_hook  s      	!!@	

 33H= %%4]4C5H4IM )-(?(?( )@ ) #
 ))*=>#s   AA6A4A6request_data)r   Nc                  K   ddl m} ddlm} ddlm} t        j                  d       g }|2 3 d{   }|j                  |       7 6  ||      }	t        |	t        d      |f      r"t        j                  d       |D ]  }| 	 y| j                  |	      }
|
rHt        j                  d	|
dd
  d       | j                  |
       d{  7  }| j                  |        ||	      }|2 3 d{  7  }| 6 yw)a  
        Process streaming response chunks for OpenAI moderation.

        Collects all chunks from the stream, assembles them into a complete response,
        and applies moderation check. If content violates moderation policy, raises HTTPException.
        r   )MockResponseIterator)stream_chunk_builder)TextCompletionResponsez2OpenAI Moderation: Running streaming response scanN)chunkszTOpenAI Moderation: Could not assemble ModelResponse from chunks, skipping moderationz,OpenAI Moderation: Streaming response text: rs   rt   ru   )model_response))litellm.llms.base_llm.base_model_iteratorr   litellm.mainr   litellm.types.utilsr   r   r0   r\   
isinstancetyper]   r   rS   rc   )r1   rd   rR   r   r   r   r   
all_chunkschunkassembled_model_responser   r^   mock_responses                r4   'async_post_call_streaming_iterator_hookzAOpenAIModerationGuardrail.async_post_call_streaming_iterator_hook<  s9     	S5>!!@	

 35
# 	% 	%%e$	%8 !
 	! .d=S0TU !((f $ $ 334LM %%>}Tc?R>SSVW
 )-(?(?( )@ ) # #
 ))*=> -3

 ) 	 	%K )sJ   ,DAA	AD	ABDC!D4D8C;9D=	Dc                    t        |d      r|j                  syg }|j                  D ]  }	 t        |dd      }|r1t        |dd      }|r"t        |t              r|j                  |       Dt        |dd      }|r"t        |t              r|j                  |       ut        |dd      }|r1t        |dd      }|r"t        |t              r|j                  |        |rdj                  |      S dS # t        t        f$ r Y w xY w)zN
        Extract text content from the model response for moderation.
        choicesNmessagecontentrO   delta
)	hasattrr   getattrr   strr\   AttributeError	TypeErrorjoin)r1   rR   response_textschoicer   r   rO   r   s           r4   r   z0OpenAIModerationGuardrail._extract_response_text  s    x+83C3C&&F!&)T:%gy$?G:gs#;&--g6  vvt4JtS1"))$/  6%eY=G:gs#;&--g6 - '8 -;tyy(DD	 #I. s   ?C4,0C4?C44DDr   c                      ddl m}  | S )zK
        Get the config model for the OpenAI Moderation guardrail.
        r   $OpenAIModerationGuardrailConfigModel)Glitellm.types.proxy.guardrails.guardrail_hooks.openai.openai_moderationr   r   s    r4   get_config_modelz*OpenAIModerationGuardrail.get_config_model  s    
	
 43r5   )NNN)r^   r   r6   N)__name__
__module____qualname____doc__r   r	   r   r+   r.   rS   rc   r   r   r   rz   r}   r   r   r   r   staticmethodr
   r   __classcell__)r3   s   @r4   r   r   '   s   " "&"&W[%
%
 #%
 3-	%

  RST%
N
hsm 
&;&;	#&;P D 6+6 6 38n	6
 	
6 
$sCx.	!6 6p +38n+ ,+ 
	+ 
$sCx.	!+ +Z 38n , "	
 
 > A+A A 38n	A
 
3	4A AF$E $E8C= $EL 4ht,B'CD 4 4r5   r   N)"r   typingr   r   r   r   r   r   r	   r
   r   fastapir   litellm._loggingr   %litellm.integrations.custom_guardrailr   r   &litellm.llms.custom_httpx.http_handlerr   r   baser   litellm.proxy._typesr   rP   r   r   3litellm.types.proxy.guardrails.guardrail_hooks.baser   r   r   r   r   r%   r5   r4   <module>r      sP   
 
 
 " 1
 &3TXFH4 3_ H4r5   