Ë
    tPêjÈJ  ã                   óþ   — U d dl 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
Z
d dl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 d d
lmZ d dlmZmZ d dlmZmZm Z m!Z! erd dl"m#Z$ dZ%ee&d<    G d„ de«      Z'y)é    N)ÚAsyncGenerator)Údatetime)ÚTYPE_CHECKINGÚAnyÚFinalÚLiteralÚOptional)Úverbose_proxy_logger)Ú	DualCache)ÚCustomGuardrailÚlog_guardrail_information)Úget_async_httpx_clientÚhttpxSpecialProvider)ÚUserAPIKeyAuth©ÚGuardrailEventHooks)ÚEnkryptAIProcessedResultÚEnkryptAIResponse)ÚCallTypesLiteralÚGenericGuardrailAPIInputsÚGuardrailStatusÚModelResponseStream)ÚLoggingÚ	enkryptaiÚGUARDRAIL_NAMEc                   óp  ‡ — e Zd Z	 	 	 	 d"dededz  dedz  dedz  fˆ fd„Z	 d#dededz  d	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dededed	eez  ez  dz  f
d„Zdededefd„Zdedefd„Ze	 d#dddeded   ded   d	df
d„«       Zdededed	eedf   fd„Zed „ «       Zed	ee    fd!„«       Z!ˆ xZ"S )$ÚEnkryptAIGuardrailsNÚguardrail_nameÚapi_keyÚapi_baseÚpolicy_namec                 ó  •— t        t        j                  ¬«      | _        |xs t	        j
                  d«      | _        | j                  st        d«      ‚|xs t	        j
                  dd«      | _        | j                  › d�| _	        || _
        || _        d| _        || _        |j                  dt        | j!                  «       «      «       t#        ‰| �H  dd	|i|¤Ž t'        j(                  d
| j                  | j                  «       y )N)Úllm_providerÚENKRYPTAI_API_KEYzdEnkryptAI API key is required. Set ENKRYPTAI_API_KEY environment variable or pass api_key parameter.ÚENKRYPTAI_API_BASEzhttps://api.enkryptai.comz/guardrails/policy/detectr   Úsupported_event_hooksr   zHEnkryptAI Guardrail initialized with guardrail_name: %s, policy_name: %s© )r   r   ÚGuardrailCallbackÚasync_handlerÚosÚgetenvr   Ú
ValueErrorr    Úapi_urlr!   r   Úguardrail_providerÚoptional_paramsÚ
setdefaultÚlistÚget_supported_event_hooksÚsuperÚ__init__r
   Údebug)Úselfr   r   r    r!   ÚkwargsÚ	__class__s         €ú�/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/guardrails/guardrail_hooks/enkryptai/enkryptai.pyr4   zEnkryptAIGuardrails.__init__.   só   ø€ ô 4ÔAU×AgÑAgÔhˆÔð Ò@¤"§)¡)Ð,?Ó"@ˆŒØ�|Š|ÜØvóð ð !Ò`¤B§I¡IÐ.BÐD_Ó$`ˆŒØŸ-™-˜Ð(AÐBˆŒð 'ˆÔØ,ˆÔØ"-ˆÔð  &ˆÔð 	×ÑÐ1´4¸×8VÑ8VÓ8XÓ3YÔZä‰ÑÑA¨ÐA¸&ÒAä×"Ñ"ØVØ×ÑØ×Ñõ	
ó    ÚpromptÚrequest_dataÚreturnc           
   ƒ   óH  K  — t        j                  «       }d|i}d| j                  dœ}| j                  r| j                  |d<   t	        j
                  d| j                  |«       	 t	        j
                  d| j                  |«       | j                  j                  | j                  ||¬«      ƒ d{  –—† }|j                  «        |j                  «       }t        j                  «       }||z
  j                  «       }	t	        j
                  d| j                  |«       |rO| j                  |«      }
| j                  | j                  |||
|j                  «       |j                  «       |	¬	«       |S 7 Œ¿# t         j"                  $ r—}t        j                  «       }||z
  j                  «       }	t	        j$                  d
t'        |«      «       |rI| j                  | j                  dt'        |«      i|d|j                  «       |j                  «       |	¬	«       ‚ d}~ww xY w­w)a_  
        Call Enkrypt AI Guardrails API to detect potential issues in the given prompt.

        Args:
            prompt (str): The text to analyze for potential violations
            request_data (dict): Optional request data for logging purposes

        Returns:
            EnkryptAIResponse: Response from the Enkrypt AI Guardrails API
        Útextzapplication/json)zContent-TypeÚapikeyzx-enkrypt-policyz(EnkryptAI request to %s with payload: %s)ÚurlÚjsonÚheadersNz+EnkryptAI response from %s with payload: %s)r.   Úguardrail_json_responser<   Úguardrail_statusÚ
start_timeÚend_timeÚdurationz EnkryptAI API request failed: %sÚerrorÚguardrail_failed_to_respond)r   Únowr   r!   r
   r5   r-   r)   ÚpostÚraise_for_statusrB   Útotal_secondsÚ_determine_guardrail_statusÚ:add_standard_logging_guardrail_information_to_request_datar.   Ú	timestampÚhttpxÚ	HTTPErrorrI   Ústr)r6   r;   r<   rF   ÚpayloadrC   ÚresponseÚresponse_jsonrG   rH   rE   Úes               r9   Ú_call_enkryptai_guardrailsz.EnkryptAIGuardrails._call_enkryptai_guardrailsU   s  è ø€ ô %ŸL™L›Nˆ
à  &Ð)ˆà*<ÈÏÉÑUˆð ×ÒØ*.×*:Ñ*:ˆGÐ&Ñ'ä×"Ñ"Ø6Ø�L‰LØô	
ð8	Ü ×&Ñ&Ø:Ø—‘Øôð
 %)×$6Ñ$6×$;Ñ$;Ø—L‘LØØð %<ó %÷ ˆHð
 ×%Ñ%Ô'Ø#+§=¡=£?ˆMä—|‘|“~ˆHØ  :Ñ-×<Ñ<Ó>ˆHä ×&Ñ&Ø=Ø—‘Øôñ Ø*.×*JÑ*JÈ=Ó*YÐ Ø×OÑOØ'+×'>Ñ'>Ø,9Ø!-Ø%5Ø)×3Ñ3Ó5Ø%×/Ñ/Ó1Ø%ð Pô ð !Ð ð=ùô@ �‰ò 	Ü—|‘|“~ˆHØ  :Ñ-×<Ñ<Ó>ˆHä ×&Ñ&Ð'IÌ3ÈqË6ÔRñ Ø×OÑOØ'+×'>Ñ'>Ø-4´c¸!³fÐ,=Ø!-Ø%BØ)×3Ñ3Ó5Ø%×/Ñ/Ó1Ø%ð Pô ð ûð%	üs?   ‚A$H"Á'AE5 Â3E3Â4B>E5 Å2H"Å3E5 Å5HÆBHÈHÈH"rV   c                 ó|  — |j                  di «      }|j                  di «      }g }i }|j                  «       D ]}  \  }}|dk(  rGt        |t        «      sŒt	        |«      dkD  sŒ+|j                  |«       |j                  |i «      ||<   ŒR|dk(  sŒX|j                  |«       |j                  |i «      ||<   Œ ||dœS )a  
        Process the response from the Enkrypt AI Guardrails API

        Args:
            response: The response from the API with 'summary' and 'details' keys

        Returns:
            EnkryptAIProcessedResult: Processed response with detected attacks and their details
        ÚsummaryÚdetailsÚtoxicityr   é   )Úattacks_detectedÚattack_details)ÚgetÚitemsÚ
isinstancer1   ÚlenÚappend)r6   rV   r[   r\   Údetected_attacksr`   ÚkeyÚvalues           r9   Ú&_process_enkryptai_guardrails_responsez:EnkryptAIGuardrails._process_enkryptai_guardrails_response®   sÀ   € ð "Ÿ™ i°Ó4ˆØ!Ÿ™ i°Ó4ˆà-/ÐØ02ˆà!Ÿ-™-›/ò 	?‰JˆC�ð �jÒ Ü˜e¤TÕ*¬s°5«z¸A«~Ø$×+Ñ+¨CÔ0Ø*1¯+©+°c¸2Ó*>�N 3Ò'à˜A“:Ø$×+Ñ+¨CÔ0Ø*1¯+©+°c¸2Ó*>�N 3Ò'ð	?ð %5ÈÑWÐWr:   rW   c                 óÄ   — 	 t        |t        «      sy| j                  |«      }|d   }|ryy# t        $ r)}t	        j
                  dt        |«      «       Y d}~yd}~ww xY w)a<  
        Determine the guardrail status based on EnkryptAI API response.

        Returns:
            "success": Content allowed through with no violations
            "guardrail_intervened": Content blocked due to policy violations
            "guardrail_failed_to_respond": Technical error or API failure
        rJ   r_   Úguardrail_intervenedÚsuccessz0Error determining EnkryptAI guardrail status: %sN)rc   Údictri   Ú	Exceptionr
   rI   rT   )r6   rW   Úprocessed_resultr_   rX   s        r9   rO   z/EnkryptAIGuardrails._determine_guardrail_statusÍ   sh   € ð	1Ü˜m¬TÔ2Ø4ð '+×&QÑ&QÐR_Ó&`ÐØ&6Ð7IÑ&JÐáØ-àøäò 	1Ü ×&Ñ&Ð'YÔ[^Ð_`Ó[aÔbÜ0ûð	1ús   ‚- “- ­	A¶AÁAro   c           
      óÄ  — |d   }|d   }dt        |«      › d�}|D �],  }|d|j                  «       › d�z  }|j                  |i «      }|dk(  r3|d|j                  d	d
«      › d�z  }|d|j                  dd
«      › d�z  }nÃ|dk(  r|d|j                  di «      › d�z  }n¤|dk(  rX|j                  «       D ��cg c]$  \  }}t	        |t
        t        f«      sŒ|dkD  sŒ#|‘Œ& }	}}|ddj                  |	«      › d�z  }nG|dk(  r|d|j                  dg «      › d�z  }n(|dk(  r|d|j                  dd«      › d�z  }n	|d|› d�z  }|dz  }�Œ/ |j                  «       S c c}}w )zø
        Create a detailed error message from processed guardrail results.

        Args:
            processed_result: Processed response with detected attacks and their details

        Returns:
            Formatted error message string
        r_   r`   zGuardrail failed: z violation(s) detected

z- z:
Úpolicy_violationz
  Policy: Úviolating_policyzN/Aú
z  Explanation: ÚexplanationÚpiiz  PII Detected: r]   g      à?z	  Types: z, Úkeyword_detectedz  Keywords: Údetected_keywordsÚbiasz  Bias Detected: Úbias_detectedFz  Details: )	rd   Úupperra   rb   rc   ÚintÚfloatÚjoinÚstrip)
r6   ro   r_   r`   Úerror_messageÚattack_typer\   ÚkÚvÚtoxic_typess
             r9   Ú_create_error_messagez)EnkryptAIGuardrails._create_error_messageç   sÅ  € ð #3Ð3EÑ"FÐØ 0Ð1AÑ Bˆà,¬SÐ1AÓ-BÐ,CÐC]Ð^ˆà+ó 	"ˆKØ˜r +×"3Ñ"3Ó"5Ð!6°cÐ:Ñ:ˆMØ$×(Ñ(¨°bÓ9ˆGð Ð0Ò0Ø :¨g¯k©kÐ:LÈeÓ.TÐ-UÐUWÐ!XÑX�Ø ?°7·;±;¸}ÈeÓ3TÐ2UÐUWÐ!XÑX‘Ø Ò%ØÐ#3°G·K±KÀÀrÓ4JÐ3KÈ2Ð!NÑN‘Ø 
Ò*Ø-4¯]©]«_×h¡T Q¨Ä
È1ÌsÔTYÈlÕ@[Ð`aÐdgÓ`gšqÐh�ÑhØ 9¨T¯Y©Y°{Ó-CÐ,DÀBÐ!GÑG‘ØÐ 2Ò2Ø <°·±Ð<OÐQSÓ0TÐ/UÐUWÐ!XÑX‘Ø Ò&ØÐ#4°W·[±[ÀÐRWÓ5XÐ4YÐY[Ð!\Ñ\‘à ;¨w¨i°rÐ!:Ñ:�Ø˜TÑ!ŠMð'	"ð* ×"Ñ"Ó$Ð$ùó is   Â8EÃEÃEÚuser_api_key_dictÚcacheÚdataÚ	call_typec              ƒ   ó   K  — t        j                  d«       ddlm} t        j
                  }| j                  ||¬«      dur|S |j                  d«      }|rŽ|D ]‰  }|j                  d«      }	t        |	t        «      sŒ%| j                  |	|¬«      ƒ d	{  –—† }
t        j                  d
|
«       | j                  |
«      }|d   }|sŒo| j                  |«      }t        |«      ‚  ||| j                  ¬«       |S 7 Œf­w)zz
        Runs before the LLM API call
        Runs on only Input
        Use this if you want to MODIFY the input
        zRunning EnkryptAI pre-call hookr   ©Ú*add_guardrail_to_applied_guardrails_header©r‡   Ú
event_typeTÚmessagesÚcontent©r;   r<   Nz)Guardrails async_pre_call_hook result: %sr_   ©r<   r   )r
   r5   Ú)litellm.proxy.common_utils.callback_utilsr‹   r   Úpre_callÚshould_run_guardrailra   rc   rT   rY   ri   r„   r,   r   )r6   r…   r†   r‡   rˆ   r‹   r�   Ú	_messagesÚmessageÚ_contentÚresultro   r_   r   s                 r9   Úasync_pre_call_hookz'EnkryptAIGuardrails.async_pre_call_hook  s  è ø€ ô 	×"Ñ"Ð#DÔEõ	
ô 2E×1MÑ1Mˆ
Ø×$Ñ$¨$¸:Ð$ÓFÈdÑRØˆKàŸ8™8 JÓ/ˆ	ÙØ$ò 8�Ø"Ÿ;™; yÓ1�Ü˜h¬Õ,Ø#'×#BÑ#BØ'Ø%)ð $Có $÷ �Fô
 )×.Ñ.Ð/ZÐ\bÔcð (,×'RÑ'RÐSYÓ'ZÐ$Ø'7Ð8JÑ'KÐ$ò (Ø(,×(BÑ(BÐCSÓ(T˜Ü(¨Ó7Ð7ð#8ñ( 	3ÀÐUY×UhÑUhÕiàˆð'ús   ‚A<C>Á?C>ÂC<Â2C>Ã	4C>c              ƒ   óÔ  K  — ddl m} t        j                  }| j	                  ||¬«      dury|j                  d«      }|rŽ|D ]‰  }|j                  d«      }t        |t        «      sŒ%| j                  ||¬«      ƒ d{  –—† }	t        j                  d	|	«       | j                  |	«      }
|
d
   }|sŒo| j                  |
«      }t        |«      ‚  ||| j                  ¬«       |S 7 Œf­w)z²
        Runs in parallel to LLM API call
        Runs on only Input

        This can NOT modify the input, only used to reject or accept a call before going to LLM API
        r   rŠ   rŒ   TNrŽ   r�   r�   z+Guardrails async_moderation_hook result: %sr_   r‘   )r’   r‹   r   Úduring_callr”   ra   rc   rT   rY   r
   r5   ri   r„   r,   r   )r6   r‡   r…   rˆ   r‹   r�   r•   r–   r—   r˜   ro   r_   r   s                r9   Úasync_moderation_hookz)EnkryptAIGuardrails.async_moderation_hook=  sÿ   è ø€ õ	
ô 2E×1PÑ1Pˆ
Ø×$Ñ$¨$¸:Ð$ÓFÈdÑRØàŸ8™8 JÓ/ˆ	ÙØ$ò 8�Ø"Ÿ;™; yÓ1�Ü˜h¬Õ,Ø#'×#BÑ#BØ'Ø%)ð $Có $÷ �Fô
 )×.Ñ.Ð/\Ð^dÔeð (,×'RÑ'RÐSYÓ'ZÐ$Ø'7Ð8JÑ'KÐ$ò (Ø(,×(BÑ(BÐCSÓ(T˜Ü(¨Ó7Ð7ð#8ñ( 	3ÀÐUY×UhÑUhÕiàˆð'ús   ‚A&C(Á)C(Á?C&Â 2C(Â34C(c              ƒ   óê  K  — ddl m} ddlm} | j	                  ||j
                  ¬«      duryt        j                  d|«       t        |t        j                  «      �r|d}|j                  D ]\  }t        |t        j                  «      sŒ|j                  j                  sŒ5t        |j                  j                  t        «      sŒZd} n |st        j                   d	«       y|j                  D ]è  }t        |t        j                  «      sŒt        j                  d
|«       |j                  j                  sŒKt        |j                  j                  t        «      sŒp| j#                  |j                  j                  |¬«      ƒ d{  –—† }t        j                  d|«       | j%                  |«      }	|	d   }
|
sŒÎ| j'                  |	«      }t)        |«      ‚  ||| j*                  ¬«       y7 Œe­w)zÍ
        Runs on response from LLM API call

        It can be used to reject a response

        Uses Enkrypt AI guardrails to check the response for policy violations, PII, and injection attacks
        r   rŠ   r   rŒ   TNz)async_post_call_success_hook response: %sFz<EnkryptAI: not running guardrail. No output text in responsez'async_post_call_success_hook choice: %sr�   z2Guardrails async_post_call_success_hook result: %sr_   r‘   )r’   r‹   Úlitellm.types.guardrailsr   r”   Ú	post_callr
   r5   rc   ÚlitellmÚModelResponseÚchoicesÚChoicesr–   r�   rT   ÚwarningrY   ri   r„   r,   r   )r6   r‡   r…   rV   r‹   r   Úhas_text_contentÚchoicer˜   ro   r_   r   s               r9   Úasync_post_call_success_hookz0EnkryptAIGuardrails.async_post_call_success_hookk  s°  è ø€ õ	
õ 	Aà×$Ñ$¨$Ð;N×;XÑ;XÐ$ÓYÐaeÑeØä×"Ñ"Ð#NÐPXÔYô �h¤× 5Ñ 5Õ6Ø$ÐØ"×*Ñ*ò �Ü˜f¤g§o¡oÕ6Ø—~‘~×-Ó-´*¸V¿^¹^×=SÑ=SÔUXÕ2YØ+/Ð(Ùð	ñ $Ü$×,Ñ,Ð-kÔlØà"×*Ñ*ò <�Ü˜f¤g§o¡oÕ6Ü(×.Ñ.Ð/XÐZ`ÔaØ—~‘~×-Ó-´*¸V¿^¹^×=SÑ=SÔUXÕ2YØ'+×'FÑ'FØ#)§>¡>×#9Ñ#9Ø)-ð (Gó (÷ "˜ô
 -×2Ñ2Ð3gÐioÔpð ,0×+VÑ+VÐW]Ó+^Ð(Ø+;Ð<NÑ+OÐ(ò ,Ø,0×,FÑ,FÐGWÓ,X˜MÜ",¨]Ó";Ð;ð%<ñ* 	3ÀÐUY×UhÑUhÖið#"ús=   ‚B	G3ÂG3Â#$G3ÃAG3Ä,G3Ä<$G3Å!*G3ÆG1Æ2G3Æ?3G3Úinputsr   Ú
input_type)ÚrequestrV   Úlogging_objÚLiteLLMLoggingObjc              ƒ   óâ   K  — |j                  dg «      }|D ]Q  }| j                  ||¬«      ƒ d{  –—† }| j                  |«      }|d   }	|	sŒ7| j                  |«      }
t	        |
«      ‚ |S 7 Œ<­w)a÷  
        Apply EnkryptAI guardrail to a batch of texts.

        Args:
            inputs: Dictionary containing texts and optional images
            request_data: Request data dictionary containing metadata
            input_type: Whether this is a "request" or "response"
            logging_obj: Optional logging object

        Returns:
            GenericGuardrailAPIInputs - texts unchanged if passed, images unchanged

        Raises:
            ValueError: If any attacks are detected
        Útextsr�   Nr_   )ra   rY   ri   r„   r,   )r6   r¨   r<   r©   r«   r®   r?   r˜   ro   r_   r   s              r9   Úapply_guardrailz#EnkryptAIGuardrails.apply_guardrail§  s•   è ø€ ð. —z‘z '¨2Ó.ˆð ò 	0ˆDØ×:Ñ:ØØ)ð ;ó ÷ ˆFð
  $×JÑJÈ6ÓRÐØ/Ð0BÑCÐò  Ø $× :Ñ :Ð;KÓ L�Ü  Ó/Ð/ð	0ð ˆðús   ‚.A/°A-±A/Á A/c                ó4   K  — |2 3 d{  –—† }|­–— Œ7 Œ
6 y­w)a†  
        Passes the entire stream to the guardrail

        This is useful for guardrails that need to see the entire response, such as PII masking.

        See Aim guardrail implementation for an example - https://github.com/BerriAI/litellm/blob/d0e022cfacb8e9ebc5409bb652059b6fd97b45c0/litellm/proxy/guardrails/guardrail_hooks/aim.py#L168

        Triggered by mode: 'post_call'
        Nr'   )r6   r…   rV   r<   Úitems        r9   Ú'async_post_call_streaming_iterator_hookz;EnkryptAIGuardrails.async_post_call_streaming_iterator_hookÑ  s$   è ø€ ð #÷ 	ð 	�$ØŒJð	ø™(ùs   ‚…‰Š�”–c                  ó   — ddl m}  | S )Nr   ©ÚEnkryptAIGuardrailConfigModel)Ú8litellm.types.proxy.guardrails.guardrail_hooks.enkryptairµ   r´   s    r9   Úget_config_modelz$EnkryptAIGuardrails.get_config_modelã  s   € õ	
ð -Ð,r:   c                 ó`   — t         j                  t         j                  t         j                  gS ©N)r   r“   rŸ   r›   )Úclss    r9   r2   z-EnkryptAIGuardrails.get_supported_event_hooksë  s)   € ô  ×(Ñ(Ü×)Ñ)Ü×+Ñ+ð
ð 	
r:   )Úlitellm_testNNNr¹   )#Ú__name__Ú
__module__Ú__qualname__rT   r4   rm   r   rY   r   ri   r   rO   r„   r   r   r   rn   r™   rœ   r§   r   r   r	   r¯   r   r   r   r²   Ústaticmethodr·   Úclassmethodr1   r   r2   Ú__classcell__)r8   s   @r9   r   r   -   sü  ø„ ð -Ø"Ø#Ø"&ñ%
àð%
ð �t‘ð%
ð ˜‘*ð	%
ð
 ˜4‘Zõ%
ðT %)ñWàðWð ˜T‘kðWð 
ó	WðrXÐ?Pð XÐUmó Xð>1Ð9Jð 1Èó 1ð4$%Ð6Nð $%ÐSVó $%ðL.à)ð.ð ð.ð ð	.ð
 $ð.ð 
�S‰˜4Ñ	 $Ñ	&ó.ð`,àð,ð *ð,ð $ó	,ð\:jàð:jð *ó:jðx ð 6:ñ'à+ð'ð ð'ð Ð1Ñ2ð	'ð
 Ð1Ñ2ð'ð 
%ò'ó ð'ðRà)ðð ðð ð	ð
 
Ð+¨TÐ1Ñ	2óð$ ñ-ó ð-ð ð
¨$Ð/BÑ*Cò 
ó ô
r:   r   )(r*   Úcollections.abcr   r   Útypingr   r   r   r   r	   rR   r    Úlitellm._loggingr
   Úlitellm.caching.cachingr   Ú%litellm.integrations.custom_guardrailr   r   Ú&litellm.llms.custom_httpx.http_handlerr   r   Úlitellm.proxy._typesr   rž   r   r¶   r   r   Úlitellm.types.utilsr   r   r   r   Ú*litellm.litellm_core_utils.litellm_loggingr   r¬   r   Ú__annotations__r   r'   r:   r9   ú<module>rÌ      sc   ðô 
Ý *Ý ß ?Õ ?ã ã Ý 1Ý -÷÷õ 0Ý 8÷÷ó ñ ÝWà#€�Ó #ôD
˜/õ D
r:   