Ë
    tPêj»F  ã                   óê   — U d dl Z d dlmZ d dlmZ d dl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 d dl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 d dlmZmZmZ dZ ee!d<    G d„ de«      Z"y)é    N)ÚAsyncGenerator)Údatetime)ÚAnyÚFinal)Úverbose_proxy_logger)Ú	DualCache)ÚCustomGuardrail)Úget_async_httpx_clientÚhttpxSpecialProvider)ÚUserAPIKeyAuth©ÚGuardrailEventHooks)ÚGuardrailConfigModel)ÚDynamoAIProcessedResultÚDynamoAIRequestÚDynamoAIResponse)ÚCallTypesLiteralÚGuardrailStatusÚModelResponseStreamÚdynamoaiÚGUARDRAIL_NAMEc                   óp  ‡ — e Zd ZdZddddg fdededz  dedz  ded	ee   f
ˆ fd
„Z	 	 d!deeeef      de	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dedededeedf   fd„Zedee   dz  fd„«       Zedee	   fd „«       Z ˆ xZ!S )"ÚDynamoAIGuardrailszŽ
    DynamoAI Guardrails integration for LiteLLM.

    Provides content moderation and policy enforcement using DynamoAI's guardrail API.
    Úlitellm_testNÚ Úguardrail_nameÚapi_keyÚapi_baseÚmodel_idÚ
policy_idsc                 ó®  •— t        t        j                  ¬«      | _        |xs t	        j
                  d«      | _        | j                  st        d«      ‚|xs t	        j
                  dd«      | _        | j                  › d�| _	        |xs t	        j
                  dd«      | _
        t	        j
                  d	d«      }|xs |r|j                  d
«      ng | _        || _        d| _        || _        |j!                  dt#        | j%                  «       «      «       t'        ‰| �P  dd|i|¤Ž t+        j,                  d| j                  | j                  «       y )N)Úllm_providerÚDYNAMOAI_API_KEYzbDynamoAI API key is required. Set DYNAMOAI_API_KEY environment variable or pass api_key parameter.ÚDYNAMOAI_API_BASEzhttps://api.dynamo.aiz/v1/moderation/analyze/ÚDYNAMOAI_MODEL_IDr   ÚDYNAMOAI_POLICY_IDSú,r   Úsupported_event_hooksr   zBDynamoAI Guardrail initialized with guardrail_name=%s, model_id=%s© )r
   r   ÚGuardrailCallbackÚasync_handlerÚosÚgetenvr   Ú
ValueErrorr   Úapi_urlr   Úsplitr    r   Úguardrail_providerÚoptional_paramsÚ
setdefaultÚlistÚget_supported_event_hooksÚsuperÚ__init__r   Údebug)	Úselfr   r   r   r   r    ÚkwargsÚenv_policy_idsÚ	__class__s	           €ú/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/guardrails/guardrail_hooks/dynamoai/dynamoai.pyr7   zDynamoAIGuardrails.__init__+   s0  ø€ ô 4ÔAU×AgÑAgÔhˆÔð Ò?¤"§)¡)Ð,>Ó"?ˆŒØ�|Š|ÜØtóð ð !Ò[¤B§I¡IÐ.AÐCZÓ$[ˆŒØŸ-™-˜Ð(?Ð@ˆŒð !ÒF¤B§I¡IÐ.AÀ2Ó$FˆŒô !#§	¡	Ð*?ÀÓ DˆØ$Ò]Án¨×)=Ñ)=¸cÔ)BÐZ\ˆŒØ,ˆÔØ",ˆÔð  &ˆÔð 	×ÑÐ1´4¸×8VÑ8VÓ8XÓ3YÔZä‰ÑÑA¨ÐA¸&ÒAä×"Ñ"ØPØ×ÑØ�M‰Mõ	
ó    ÚmessagesÚ
event_typeÚ	text_typeÚrequest_dataÚreturnc              ƒ   ó  K  — t        j                  «       }d|i}| j                  r| j                  |d<   | j                  r| j                  |d<   dd| j                  › �dœ}t        j                  d| j                  |«       	 | j                  j                  | j                  t        |«      |¬«      ƒ d	{  –—† }|j                  «        |j                  «       }	t        j                  «       }
|
|z
  j                  «       }|rP| j                  |	«      }| j                  | j                   |	|||j#                  «       |
j#                  «       ||¬
«       |	S 7 ŒŸ# t$        j&                  $ r˜}t        j                  «       }
|
|z
  j                  «       }t        j(                  dt+        |«      «       |rJ| j                  | j                   dt+        |«      i|d|j#                  «       |
j#                  «       ||¬
«       ‚ d	}~ww xY w­w)a‚  
        Call DynamoAI Guardrails API to analyze messages for policy violations.

        Args:
            messages: List of messages to analyze
            text_type: Type of text being analyzed ("input" or "output")
            request_data: Optional request data for logging purposes

        Returns:
            DynamoAIResponse: Response from the DynamoAI Guardrails API
        r?   Ú	policyIdsÚmodelIdzapplication/jsonzBearer )zContent-TypeÚAuthorizationz&DynamoAI request to %s with payload=%s)ÚurlÚjsonÚheadersN)r1   Úguardrail_json_responserB   Úguardrail_statusÚ
start_timeÚend_timeÚdurationr@   zDynamoAI API request failed: %sÚerrorÚguardrail_failed_to_respond)r   Únowr    r   r   r   r8   r/   r+   ÚpostÚdictÚraise_for_statusrI   Útotal_secondsÚ_determine_guardrail_statusÚ:add_standard_logging_guardrail_information_to_request_datar1   Ú	timestampÚhttpxÚ	HTTPErrorrP   Ústr)r9   r?   r@   rA   rB   rM   ÚpayloadrJ   ÚresponseÚresponse_jsonrN   rO   rL   Úes                 r=   Ú_call_dynamoai_guardrailsz,DynamoAIGuardrails._call_dynamoai_guardrailsW   s÷  è ø€ ô$ %ŸL™L›Nˆ
ð ˜ð+
ˆð
 �?Š?Ø#'§?¡?ˆG�KÑ Ø�=Š=Ø!%§¡ˆG�IÑð /Ø& t§|¡| nÐ5ñ
ˆô
 	×"Ñ"Ø4Ø�L‰LØô	
ð/	Ø$(×$6Ñ$6×$;Ñ$;Ø—L‘LÜ˜'“]Øð %<ó %÷ ˆHð
 ×%Ñ%Ô'Ø#+§=¡=£?ˆMä—|‘|“~ˆHØ  :Ñ-×<Ñ<Ó>ˆHñ Ø*.×*JÑ*JÈ=Ó*YÐ Ø×OÑOØ'+×'>Ñ'>Ø,9Ø!-Ø%5Ø)×3Ñ3Ó5Ø%×/Ñ/Ó1Ø%Ø)ð Pô 	ð !Ð ð3ùô6 �‰ò 	Ü—|‘|“~ˆHØ  :Ñ-×<Ñ<Ó>ˆHä ×&Ñ&Ð'HÌ#ÈaË&ÔQñ Ø×OÑOØ'+×'>Ñ'>Ø-4´c¸!³fÐ,=Ø!-Ø%BØ)×3Ñ3Ó5Ø%×/Ñ/Ó1Ø%Ø)ð Pô 	ð ûð'	üs>   ‚BH	Â4E Â9EÂ:BE ÅH	ÅE ÅHÅ.BHÈHÈH	r^   c                 óü  — |j                  dd«      }|j                  dg «      }g }i }|dk(  rË|D ]Æ  }|j                  di «      }|j                  di «      }|j                  dd«      }	|j                  d	«      xs |r|j                  d	«      nd
xs d}
|
dk(  sŒk|j                  |	«       |j                  d«      |
|j                  d«      |j                  d«      |r|j                  d«      nd
dœ||	<   ŒÈ ||dœS )a  
        Process the response from the DynamoAI Guardrails API

        Args:
            response: The response from the API with 'finalAction' and 'appliedPolicies' keys

        Returns:
            DynamoAIProcessedResult: Processed response with detected violations
        ÚfinalActionÚNONEÚappliedPoliciesÚBLOCKÚpolicyÚoutputsÚnameÚunknownÚactionNÚidÚmethodÚdescriptionÚmessage)ÚpolicyIdrk   rm   rn   ro   )Úviolations_detectedÚviolation_details)ÚgetÚappend)r9   r^   Úfinal_actionÚapplied_policiesrq   rr   Úapplied_policyÚpolicy_infoÚpolicy_outputsÚpolicy_nameÚpolicy_actions              r=   Ú%_process_dynamoai_guardrails_responsez8DynamoAIGuardrails._process_dynamoai_guardrails_response±   s#  € ð 'Ÿl™l¨=¸&ÓAˆØ"*§,¡,Ð/@À"Ó"EÐà02ÐØ35Ðð ˜7Ò"Ø"2ò �Ø,×0Ñ0°¸2Ó>�Ø!/×!3Ñ!3°I¸rÓ!B�ð *Ÿo™o¨f°iÓ@�ð #×&Ñ& xÓ0ÒxÑUc°^×5GÑ5GÈÔ5QÐimÒxÐrxð ð
 ! GÓ+Ø'×.Ñ.¨{Ô;à$/§O¡O°DÓ$9Ø"/Ø"-§/¡/°(Ó";Ø'2§¡°}Ó'EÙES N×$6Ñ$6°yÔ$AÐY]ñ6Ð% kÒ2ðð0 $7Ø!2ñ
ð 	
r>   r_   c                 óò   — 	 t        |t        «      sy|j                  d«      ry|j                  dd«      }|dk(  ry|dk(  ryy# t        $ r)}t	        j
                  dt        |«      «       Y d	}~yd	}~ww xY w)
aO  
        Determine the guardrail status based on DynamoAI API response.

        Returns:
            "success": Content allowed through with no violations (finalAction is NONE)
            "guardrail_intervened": Content blocked (finalAction is BLOCK)
            "guardrail_failed_to_respond": Technical error or API failure
        rQ   rP   rc   rd   Úsuccessrf   Úguardrail_intervenedz/Error determining DynamoAI guardrail status: %sN)Ú
isinstancerT   rs   Ú	Exceptionr   rP   r\   )r9   r_   ru   r`   s       r=   rW   z.DynamoAIGuardrails._determine_guardrail_statusß   s   € ð	1Ü˜m¬TÔ2Ø4ð × Ñ  Ô)Ø4à"/×"3Ñ"3°MÀ6Ó"JˆLà˜vÒ%Ø Ø Ò(Ø-ð øäò 	1Ü ×&Ñ&Ð'XÔZ]Ð^_ÓZ`ÔaÜ0ûð	1ús&   ‚A “A ¥A ½A Á	A6ÁA1Á1A6Úprocessed_resultc                 óà  — |d   }|d   }dt        |«      › d�}|D ]Á  }|d|j                  «       › d�z  }|j                  |i «      }|j                  d«      r|d|d   › d	�z  }|j                  d
«      r|d|d
   › d	�z  }|j                  d«      r|d|d   › d	�z  }|j                  d«      r|d|d   › d	�z  }|j                  d«      r|d|d   › d	�z  }|d	z  }ŒÃ |j                  «       S )zé
        Create a detailed error message from processed guardrail results.

        Args:
            processed_result: Processed response with detected violations

        Returns:
            Formatted error message string
        rq   rr   zGuardrail failed: z violation(s) detected

z- z:
rk   z
  Action: ú
rm   z
  Method: rn   z  Description: ro   z  Message: rp   z  Policy ID: )ÚlenÚupperrs   Ústrip)r9   r‚   rq   rr   Úerror_messagerz   Údetailss          r=   Ú_create_error_messagez(DynamoAIGuardrails._create_error_messageþ   sF  € ð &6Ð6KÑ%LÐØ#3Ð4GÑ#HÐà,¬SÐ1DÓ-EÐ,FÐF`Ðaˆà.ò 	"ˆKØ˜r +×"3Ñ"3Ó"5Ð!6°cÐ:Ñ:ˆMØ'×+Ñ+¨K¸Ó<ˆGð �{‰{˜8Ô$Ø :¨g°hÑ.?Ð-@ÀÐ!CÑC�Ø�{‰{˜8Ô$Ø :¨g°hÑ.?Ð-@ÀÐ!CÑC�Ø�{‰{˜=Ô)Ø ?°7¸=Ñ3IÐ2JÈ"Ð!MÑM�Ø�{‰{˜9Ô%Ø ;¨w°yÑ/AÐ.BÀ"Ð!EÑE�Ø�{‰{˜:Ô&Ø =°¸Ñ1DÐ0EÀRÐ!HÑH�Ø˜TÑ!‰Mð	"ð" ×"Ñ"Ó$Ð$r>   Ú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«      }|ru| j                  |d|t        j
                  ¬«      ƒ d	{  –—† }t        j                  d
|«       | j                  |«      }	|	d   }
|
r| j                  |	«      }t        |«      ‚ ||| j                  ¬«       |S 7 Œd­w)zz
        Runs before the LLM API call
        Runs on only Input
        Use this if you want to MODIFY the input
        zRunning DynamoAI pre-call hookr   ©Ú*add_guardrail_to_applied_guardrails_header©r�   r@   Tr?   Úinput©r?   rA   rB   r@   Nz(Guardrails async_pre_call_hook result=%srq   ©rB   r   )r   r8   Ú)litellm.proxy.common_utils.callback_utilsr‘   r   Úpre_callÚshould_run_guardrailrs   ra   r|   rŠ   r.   r   )r9   r‹   rŒ   r�   rŽ   r‘   r@   Ú	_messagesÚresultr‚   rq   rˆ   s               r=   Úasync_pre_call_hookz&DynamoAIGuardrails.async_pre_call_hook   s÷   è ø€ ô 	×"Ñ"Ð#CÔDõ	
ô 2E×1MÑ1Mˆ
Ø×$Ñ$¨$¸:Ð$ÓFÈdÑRØˆKàŸ8™8 JÓ/ˆ	ÙØ"&×"@Ñ"@Ø"Ø!Ø!Ü.×7Ñ7ð	 #Aó #÷ ˆFô !×&Ñ&Ð'QÐSYÔZð '+×&PÑ&PÐQWÓ&XÐØ)9Ð:OÑ)PÐñ #Ø'+×'AÑ'AÐBRÓ'S�Ü  Ó/Ð/ñ 	3ÀÐUY×UhÑUhÕiàˆð+ús   ‚A<C%Á>C#Á?A%C%c              ƒ   ó¢  K  — ddl m} t        j                  }| j	                  ||¬«      dury|j                  d«      }|ru| j                  |d|t        j                  ¬«      ƒ d{  –—† }t        j                  d	|«       | j                  |«      }|d
   }	|	r| j                  |«      }
t        |
«      ‚ ||| j                  ¬«       |S 7 Œd­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=%srq   r•   )r–   r‘   r   Úduring_callr˜   rs   ra   r   r8   r|   rŠ   r.   r   )r9   r�   r‹   rŽ   r‘   r@   r™   rš   r‚   rq   rˆ   s              r=   Úasync_moderation_hookz(DynamoAIGuardrails.async_moderation_hookO  sä   è ø€ õ	
ô 2E×1PÑ1Pˆ
Ø×$Ñ$¨$¸:Ð$ÓFÈdÑRØàŸ8™8 JÓ/ˆ	ÙØ"&×"@Ñ"@Ø"Ø!Ø!Ü.×:Ñ:ð	 #Aó #÷ ˆFô !×&Ñ&Ð'SÐU[Ô\ð '+×&PÑ&PÐQWÓ&XÐØ)9Ð:OÑ)PÐñ #Ø'+×'AÑ'AÐBRÓ'S�Ü  Ó/Ð/ñ 	3ÀÐUY×UhÑUhÕiàˆð+ús   ‚A&CÁ(CÁ)A%Cc              ƒ   ód  K  — ddl m} ddlm} | j	                  ||j
                  ¬«      duryt        j                  d|«       t        |t        j                  «      �r9d}g }|j                  D ]›  }t        |t        j                  «      sŒ|j                  j                  sŒ5t        |j                  j                  t        «      sŒZd}|j!                  |j                  j"                  xs d	|j                  j                  d
œ«       Œ� |st        j$                  d«       y|rq| j'                  |d||j
                  ¬«      ƒ d{  –—† }	t        j                  d|	«       | j)                  |	«      }
|
d   }|r| j+                  |
«      }t-        |«      ‚ ||| j.                  ¬«       y7 Œc­w)z¯
        Runs on response from LLM API call

        It can be used to reject a response

        Uses DynamoAI guardrails to check the response for policy violations
        r   r�   r   r’   TNz(async_post_call_success_hook response=%sFÚ	assistant)ÚroleÚcontentz;DynamoAI: not running guardrail. No output text in responseÚoutputr”   z1Guardrails async_post_call_success_hook result=%srq   r•   )r–   r‘   Úlitellm.types.guardrailsr   r˜   Ú	post_callr   r8   r€   ÚlitellmÚModelResponseÚchoicesÚChoicesro   r¢   r\   rt   r¡   Úwarningra   r|   rŠ   r.   r   )r9   r�   r‹   r^   r‘   r   Úhas_text_contentÚdynamoai_messagesÚchoicerš   r‚   rq   rˆ   s                r=   Úasync_post_call_success_hookz/DynamoAIGuardrails.async_post_call_success_hook|  s“  è ø€ õ	
õ 	Aà×$Ñ$¨$Ð;N×;XÑ;XÐ$ÓYÐaeÑeØä×"Ñ"Ð#MÈxÔXô �h¤× 5Ñ 5Õ6Ø$ÐØ=?Ðà"×*Ñ*ò 	�Ü˜f¤g§o¡oÕ6Ø—~‘~×-Ó-´*¸V¿^¹^×=SÑ=SÔUXÕ2YØ+/Ð(Ø)×0Ñ0à(.¯©×(;Ñ(;Ò(J¸{Ø+1¯>©>×+AÑ+Añõð		ñ $Ü$×,Ñ,Ð-jÔkØá Ø&*×&DÑ&DØ.Ø&Ø!%Ø2×<Ñ<ð	 'Eó '÷ !�ô %×*Ñ*Ð+^Ð`fÔgð +/×*TÑ*TÐU[Ó*\Ð Ø-=Ð>SÑ-TÐ#ñ 'Ø+/×+EÑ+EÐFVÓ+W�MÜ$ ]Ó3Ð3ñ 	3ÀÐUY×UhÑUhÖið'!ús&   ‚BF0ÂF0Â%$F0Ã
B F0Å
F.ÅA$F0c                ó4   K  — |2 3 d{  –—† }|­–— Œ7 Œ
6 y­w)zÅ
        Passes the entire stream to the guardrail

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

        Triggered by mode: 'post_call'
        Nr)   )r9   r‹   r^   rB   Úitems        r=   Ú'async_post_call_streaming_iterator_hookz:DynamoAIGuardrails.async_post_call_streaming_iterator_hook¾  s$   è ø€ ð #÷ 	ð 	�$ØŒJð	ø™(ùs   ‚…‰Š�”–c                  ó   — ddl m}  | S )Nr   ©ÚDynamoAIGuardrailConfigModel)Ú7litellm.types.proxy.guardrails.guardrail_hooks.dynamoair´   r³   s    r=   Úget_config_modelz#DynamoAIGuardrails.get_config_modelÎ  s   € õ	
ð ,Ð+r>   c                 ó`   — t         j                  t         j                  t         j                  gS )N)r   r—   r¥   r�   )Úclss    r=   r5   z,DynamoAIGuardrails.get_supported_event_hooksÖ  s)   € ô  ×(Ñ(Ü×)Ñ)Ü×+Ñ+ð
ð 	
r>   )r“   N)"Ú__name__Ú
__module__Ú__qualname__Ú__doc__r\   r4   r7   rT   r   r   r   ra   r   r|   r   rW   rŠ   r   r   r   r�   r›   rž   r®   r   r   r±   ÚstaticmethodÚtyper   r¶   Úclassmethodr5   Ú__classcell__)r<   s   @r=   r   r   $   sñ  ø„ ñð -Ø"Ø#ØØ "ñ*
àð*
ð �t‘ð*
ð ˜‘*ð	*
ð
 ð*
ð ˜‘Iõ*
ð` !Ø$(ñXà�t˜C ˜H‘~Ñ&ðXð (ðXð ð	Xð
 ˜T‘kðXð 
óXðt,
Ð>Nð ,
ÐSjó ,
ð\1Ð9Ið 1Èoó 1ð> %Ð6Mð  %ÐRUó  %ðD-à)ð-ð ð-ð ð	-ð
 $ð-ð 
�S‰˜4Ñ	 $Ñ	&ó-ð^+àð+ð *ð+ð $ó	+ðZ@jàð@jð *ó@jðDà)ðð ðð ð	ð
 
Ð+¨TÐ1Ñ	2óð  ð,˜dÐ#7Ñ8¸4Ñ?ò ,ó ð,ð ð
¨$Ð/BÑ*Cò 
ó ô
r>   r   )#r,   Úcollections.abcr   r   Útypingr   r   rZ   r¦   Úlitellm._loggingr   Úlitellm.caching.cachingr   Ú%litellm.integrations.custom_guardrailr	   Ú&litellm.llms.custom_httpx.http_handlerr
   r   Úlitellm.proxy._typesr   r¤   r   Ú3litellm.types.proxy.guardrails.guardrail_hooks.baser   rµ   r   r   r   Úlitellm.types.utilsr   r   r   r   Ú__annotations__r   r)   r>   r=   ú<module>rË      s]   ðô 
Ý *Ý ß ã ã Ý 1Ý -Ý A÷õ 0Ý 8Ý T÷ñ ÷
 WÑ Và"€�Ó "ôx
˜õ x
r>   