Ë
    tPêjû}  ã            
       ó†  — U d dl Z d dlZd dl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 d dlmZ d dlmZmZ d d	lmZ d d
lmZmZ d dlmZ d dlmZmZmZ d dl m!Z! d dl"m#Z# erd dl$m%Z% dZ&ee'd<   dede(fd„Z)e&fdede*de+ee(e,f   fd„Z-de.e(ef   de.e(e(f   fd„Z/ G d„ de0«      Z1 G d„ de0«      Z2 G d„ de«      Z3y) é    N)ÚTYPE_CHECKINGÚAnyÚFinalÚLiteral)Úquote)ÚHTTPException)Ú	DualCache)Úverbose_proxy_logger)Úversion)ÚCustomGuardrailÚlog_guardrail_information)Úget_llm_provider)Úget_async_httpx_clientÚhttpxSpecialProvider)ÚUserAPIKeyAuth)Ú,TRUSTED_PILLAR_RESPONSE_HEADERS_METADATA_KEYÚ*add_guardrail_to_applied_guardrails_headerÚ&get_metadata_variable_name_from_kwargs)ÚGuardrailEventHooks)ÚLLMResponseTypes)ÚGuardrailConfigModeli    ÚMAX_PILLAR_HEADER_VALUE_BYTESÚdataÚreturnc                 óL   — t        j                  | dd¬«      }t        |d¬«      S )zJ
    JSON-serialize and URL-encode data for safe header transmission.
    F)ú,ú:)Úensure_asciiÚ
separatorsÚ ©Úsafe)ÚjsonÚdumpsr   )r   Újson_payloads     ú{/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/guardrails/guardrail_hooks/pillar/pillar.pyÚ_encode_json_for_headerr'   -   s#   € ô Ÿ*™* T¸È*ÔU€LÜ� BÔ'Ð'ó    ÚevidenceÚ	max_bytesc                 ó’  — t        | t        «      s=t        | «      }t        |j	                  d«      «      |k  r| |dfS d}|t        |«      dfS g }t        |«      }d}| D �]a  }t        |t
        «      rt        |«      }n|}|j                  |«       t        |«      }t        |j	                  d«      «      |k  rŒ\d}t        |t
        «      rÙt        |j                  dd«      «      }|r¼t        dt        |«      dz  «      }	t        |j	                  d«      «      |kD  rh|rft        |«      |	kD  r|d	|	  n|d	d
 }t        d|	dz  «      }	|r|› d�nd}
|
|d<   d|d<   t        |«      }t        |j	                  d«      «      |kD  r|rŒft        |j	                  d«      «      |k  r�ŒG|j                  «        t        |«      }�Œd |||fS )a  
    Truncate evidence payload so the encoded header value stays within max_bytes.

    Returns:
        truncated_evidence: Evidence list/value after truncation
        encoded_value: URL-encoded JSON string for header
        was_truncated: Whether truncation occurred
    zutf-8Fz[truncated]Tr)   r    é   é   Néÿÿÿÿz...[truncated]Úevidence_truncated)Ú
isinstanceÚlistr'   ÚlenÚencodeÚdictÚappendÚstrÚgetÚmaxÚpop)r)   r*   ÚencodedÚtruncated_valueÚ	truncatedÚtruncated_flagÚentryÚworking_entryÚevidence_textÚstepÚtruncated_texts              r&   Ú_truncate_evidence_payloadrC   5   sÕ  € ô �h¤Ô%Ü)¨(Ó3ˆÜˆw�~‰~˜gÓ&Ó'¨9Ò4Ø˜W eÐ+Ð+Ø!.ˆØÔ 7¸Ó HÈ$ÐNÐNà"$€IÜ% iÓ0€GØ€Nàó 5ˆä�eœTÔ"Ü  ›K‰Mà!ˆMà×Ñ˜Ô'Ü)¨)Ó4ˆäˆw�~‰~˜gÓ&Ó'¨9Ò4ØàˆÜ�m¤TÔ*Ü × 1Ñ 1°*¸bÓ AÓBˆMÙÜ˜1œc -Ó0°AÑ5Ó6�Ü˜'Ÿ.™.¨Ó1Ó2°YÒ>Á=Ü=@ÀÓ=OÐRVÒ=V M°&°D°5Ñ$9Ð\iÐjmÐkmÐ\n�MÜ˜q $¨!¡)Ó,�DÙIV¨ °nÑ%EÐ\i�NØ0>�M *Ñ-Ø:>�MÐ"6Ñ7Ü5°iÓ@�Gô ˜'Ÿ.™.¨Ó1Ó2°YÒ>Â=ô �w—~‘~ gÓ.Ó/°9Ò<Ùà�‰ŒÜ)¨)Ó4Šð=5ð@ �g˜~Ð-Ð-r(   Úmetadata_storec                 ó(  — i }d| v rt        | d   «      j                  «       |d<   d| v rt        | d   «      |d<   d| v r#t        | d   «      \  }}}|| d<   |rd| d<   ||d<   d	| v rt	        t        | d	   «      d
¬«      |d<   |r|| d<   d| t
        <   |S )zP
    Create URL-safe Pillar response headers and apply truncation metadata.
    Úpillar_flaggedzx-pillar-flaggedÚpillar_scannerszx-pillar-scannersÚpillar_evidenceTÚpillar_evidence_truncatedzx-pillar-evidenceÚpillar_session_id_responser    r!   zx-pillar-session-idÚpillar_response_headers)r6   Úlowerr'   rC   r   r   )rD   ÚheadersÚtruncated_evidenceÚencoded_valuer=   s        r&   Úbuild_pillar_response_headersrP   l   sÛ   € ð &(€Gà˜>Ñ)Ü&)¨.Ð9IÑ*JÓ&K×&QÑ&QÓ&SˆÐ"Ñ#à˜NÑ*Ü'>¸~ÐN_Ñ?`Ó'aˆÐ#Ñ$à˜NÑ*Ü<VØÐ,Ñ-ó=
Ñ9Ð˜M¨>ð -?ˆÐ(Ñ)ÙØ:>ˆNÐ6Ñ7Ø'4ˆÐ#Ñ$à# ~Ñ5Ü).¬s°>ÐB^Ñ3_Ó/`ÐgiÔ)jˆÐ%Ñ&áØ4;ˆÐ0Ñ1ØGKˆÔCÑDà€Nr(   c                   ó   — e Zd ZdZy)ÚPillarGuardrailMissingSecretsz0Exception raised when Pillar API key is missing.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r(   r&   rR   rR   Œ   s   „ Ú:r(   rR   c                   ó   — e Zd ZdZy)ÚPillarGuardrailAPIErrorz>Exception raised when there's an error calling the Pillar API.NrS   rX   r(   r&   rZ   rZ   �   s   „ ÚHr(   rZ   c                   ó  ‡ — e Zd ZdZg d¢ZdZddgZdZdZdZ		 	 	 	 	 	 	 	 	 	 d8d	e
dz  d
e
dz  de
dz  de
dz  dedz  dedz  dedz  dedz  de
dz  dedz  ddfˆ fd„Zededededed   dee
z  ez  dz  f
d„«       Zedededed   dee
z  ez  dz  fd„«       Zededededefd„«       Zdededefd„Zd ededefd!„Zdedee
e
f   fd"„Zd#ee
e
f   d$e
d%edz  ddfd&„Zd'ee
z  ez  dz  d(e
dz  d)edz  d*e
dedz  f
d+„Zed%ee
z  ez  defd,„«       Zdede e
e
f   fd-„Z!dedee
e"f   fd.„Z#d#ee
e
f   d/ee
e"f   dee
e"f   fd0„Z$d1ee
e"f   d2eddfd3„Z%d1ee
e"f   ddfd4„Z&ede'd5   dz  fd6„«       Z(e)de*e+   fd7„«       Z,ˆ xZ-S )9ÚPillarGuardrailz«
    Pillar Security Guardrail for LiteLLM.

    Provides comprehensive AI security scanning for input prompts and output responses
    using the Pillar Security API.
    )ÚblockÚmonitorÚmaskr^   Úallowr]   zhttps://api.pillar.securityg      @NÚguardrail_nameÚapi_keyÚapi_baseÚon_flagged_actionÚ
async_modeÚpersist_sessionÚinclude_scannersÚinclude_evidenceÚfallback_on_errorÚtimeoutr   c                 óÆ  •— t        t        j                  ¬«      | _        |xs t        j
                  j                  d«      | _        | j                  €d}t        |«      ‚|xs# t	        j                  d«      xs | j                  | _        |xs t        j
                  j                  d«      }|r|| j                  v r|| _        n)|rt        j                  d|«       | j                   | _        t        j"                  d| j                  «       | j%                  |d	dd
¬«      | _        | j%                  |ddd¬«      | _        | j%                  |ddd¬«      | _        | j%                  |ddd¬«      | _        |	xs t        j
                  j                  d«      }|r|| j.                  v r|| _        n4|r!t        j                  d|| j2                  «       | j2                  | _        t        j"                  d| j0                  «       |
�|
| _        nB	 t7        t        j
                  j                  dt9        | j:                  «      «      «      | _        tA        ‰| �„  d|tE        | jG                  «       «      dœ|¤Ž y# t<        t>        f$ rR t        j                  dt        j
                  j                  d«      | j:                  «       | j:                  | _        Y ŒŠw xY w)a²  
        Initialize the Pillar guardrail.

        Args:
            guardrail_name: Name of the guardrail instance
            api_key: Pillar API key
            api_base: Pillar API base URL
            on_flagged_action: Action to take when content is flagged ('block' or 'monitor')
            fallback_on_error: Action when API errors occur ('allow' or 'block')
            timeout: Timeout for API calls in seconds
            **kwargs: Additional arguments passed to parent class

        Note:
            LiteLLM virtual key context (user_id, team_id, key_alias, etc.) is always
            automatically passed as X-LiteLLM-* headers to enable application/user tracking.
        )Úllm_providerÚPILLAR_API_KEYNú�Couldn't get Pillar API key, either set the `PILLAR_API_KEY` in the environment or pass it as a parameter to the guardrail in the config fileÚPILLAR_API_BASEÚPILLAR_ON_FLAGGED_ACTIONz"Invalid action '%s', using defaultz8Pillar Guardrail: Initialized with on_flagged_action: %sÚPILLAR_ASYNCre   )Úprovided_valueÚenv_varÚdefaultÚsetting_nameÚPILLAR_PERSISTrf   ÚPILLAR_INCLUDE_SCANNERSTrg   ÚPILLAR_INCLUDE_EVIDENCErh   ÚPILLAR_FALLBACK_ON_ERRORz0Invalid fallback action '%s', using default '%s'z8Pillar Guardrail: Initialized with fallback_on_error: %sÚPILLAR_TIMEOUTzPPillar Guardrail: Invalid PILLAR_TIMEOUT value '%s', falling back to default %ss)ra   Úsupported_event_hooksrX   )$r   r   ÚGuardrailCallbackÚasync_handlerÚosÚenvironr7   rb   rR   ÚgetenvÚBASE_API_URLrc   ÚSUPPORTED_ON_FLAGGED_ACTIONSrd   r
   ÚwarningÚDEFAULT_ON_FLAGGED_ACTIONÚdebugÚ_resolve_bool_configre   rf   rg   rh   ÚSUPPORTED_FALLBACK_ACTIONSri   ÚDEFAULT_FALLBACK_ACTIONrj   Úfloatr6   ÚDEFAULT_TIMEOUTÚ
ValueErrorÚ	TypeErrorÚsuperÚ__init__r1   Úget_supported_event_hooks)Úselfra   rb   rc   rd   re   rf   rg   rh   ri   rj   ÚkwargsÚmsgÚactionÚ	__class__s                 €r&   rŽ   zPillarGuardrail.__init__¤   s®  ø€ ô< 4ÔAU×AgÑAgÔhˆÔØÒB¤"§*¡*§.¡.Ð1AÓ"BˆŒà�<‰<ÐðMð ô 0°Ó4Ð4à ÒU¤B§I¡IÐ.?Ó$@ÒUÀD×DUÑDUˆŒð #ÒP¤b§j¡j§n¡nÐ5OÓ&PˆÙ�f × AÑ AÑAØ%+ˆDÕ"áÜ$×,Ñ,Ð-QÐSYÔZØ%)×%CÑ%CˆDÔ"ä×"Ñ"Ð#]Ð_c×_uÑ_uÔvà×3Ñ3Ø%Ø"ØØ%ð	 4ó 
ˆŒð  $×8Ñ8Ø*Ø$ØØ*ð	  9ó  
ˆÔð !%× 9Ñ 9Ø+Ø-ØØ+ð	 !:ó !
ˆÔð !%× 9Ñ 9Ø+Ø-ØØ+ð	 !:ó !
ˆÔð #ÒP¤b§j¡j§n¡nÐ5OÓ&PˆÙ�f × ?Ñ ?Ñ?Ø%+ˆDÕ"áÜ$×,Ñ,ØFÈÐPT×PlÑPlôð &*×%AÑ%AˆDÔ"ä×"Ñ"Ð#]Ð_c×_uÑ_uÔvð ÐØ"ˆD�Lð4Ü$¤R§Z¡Z§^¡^Ð4DÄcÈ$×J^ÑJ^ÓF_Ó%`Óa�”ô 	‰Ñð 	
Ø)Ü"& t×'EÑ'EÓ'GÓ"Hñ	
ð ó	
øô ¤	Ð*ò 4Ü$×,Ñ,ØfÜ—J‘J—N‘NÐ#3Ó4Ø×(Ñ(ôð
  $×3Ñ3�–ð4ús   ÈAI? É?AK ËK Úuser_api_key_dictÚcacher   Ú	call_type)
Ú
completionÚtext_completionÚ
embeddingsÚimage_generationÚ
moderationÚaudio_transcriptionÚpass_through_endpointÚrerankÚmcp_callÚanthropic_messagesc              ƒ   ó,  K  — t         j                  }| j                  ||¬«      dur"t        j                  d| j
                  «       |S t        j                  d«       | j                  ||«      ƒ d{  –—† }t        || j
                  ¬«       |S 7 Œ­w)aÕ  
        Pre-call hook to scan the request for security threats before sending to LLM.

        Args:
            user_api_key_dict: User API key authentication info
            cache: LiteLLM cache instance
            data: Request data
            call_type: Type of LLM call

        Returns:
            Original data if safe, raises HTTPException if blocked

        Raises:
            HTTPException: If request should be blocked due to security threats
        ©r   Ú
event_typeTz3Pillar Guardrail: Pre-call scanning disabled for %szPillar Guardrail: Pre-call hookN©Úrequest_datara   )r   Úpre_callÚshould_run_guardrailr
   r…   ra   Úrun_pillar_guardrailr   )r�   r•   r–   r   r—   r¤   Úresults          r&   Úasync_pre_call_hookz#PillarGuardrail.async_pre_call_hook  sŒ   è ø€ ôD 0×8Ñ8ˆ
Ø×$Ñ$¨$¸:Ð$ÓFÈdÑRÜ ×&Ñ&Ð'\Ð^b×^qÑ^qÔrØˆKä×"Ñ"Ð#DÔEØ"×7Ñ7¸Ð>OÓP×Pˆô 	3ÀÐUY×UhÑUhÕiàˆð Qúó   ‚A2BÁ4BÁ5B)r˜   rš   r›   rœ   r�   Ú	responsesr    r¡   c              ƒ   ó,  K  — t         j                  }| j                  ||¬«      dur"t        j                  d| j
                  «       |S t        j                  d«       | j                  ||«      ƒ d{  –—† }t        || j
                  ¬«       |S 7 Œ­w)a£  
        During-call hook to scan the request in parallel with LLM processing.

        Args:
            data: Request data
            user_api_key_dict: User API key authentication info
            call_type: Type of LLM call

        Returns:
            Original data if safe, raises HTTPException if blocked

        Raises:
            HTTPException: If request should be blocked due to security threats
        r£   Tz6Pillar Guardrail: During-call scanning disabled for %sz-Pillar Guardrail: During-call moderation hookNr¥   )r   Úduring_callr¨   r
   r…   ra   r©   r   )r�   r   r•   r—   r¤   rª   s         r&   Úasync_moderation_hookz%PillarGuardrail.async_moderation_hookF  s‹   è ø€ ô< 0×;Ñ;ˆ
Ø×$Ñ$¨$¸:Ð$ÓFÈdÑRÜ ×&Ñ&Ð'_Ðae×atÑatÔuØˆKä×"Ñ"Ð#RÔSØ"×7Ñ7¸Ð>OÓP×Pˆô 	3ÀÐUY×UhÑUhÕiàˆð Qúr¬   Úresponsec              ƒ   ót  K  — t         j                  }| j                  ||¬«      dur"t        j                  d| j
                  «       |S t        j                  d«       t        |d«      r|j                  «       ni }|j                  dg «      D �cg c]%  }|j                  d«      sŒ|j                  d«      ‘Œ' }}|st        j                  d«       |S |j                  «       }|j                  d	g «      |z   |d	<   | j                  ||«      ƒ d
{  –—†  t        || j
                  ¬«       |S c c}w 7 Œ"­w)a­  
        Post-call hook to scan LLM responses before returning to user.

        Args:
            data: Original request data
            user_api_key_dict: User API key authentication info
            response: LLM response to scan

        Returns:
            Original response if safe, raises HTTPException if blocked

        Raises:
            HTTPException: If response should be blocked due to security threats
        r£   Tz4Pillar Guardrail: Post-call scanning disabled for %sz Pillar Guardrail: Post-call hookÚ
model_dumpÚchoicesÚmessagezJPillar Guardrail: No response content to scan, skipping post-call analysisÚmessagesNr¥   )r   Ú	post_callr¨   r
   r…   ra   Úhasattrr³   r7   Úcopyr©   r   )	r�   r   r•   r±   r¤   Úresponse_dictÚchoiceÚresponse_messagesÚpost_call_datas	            r&   Úasync_post_call_success_hookz,PillarGuardrail.async_post_call_success_hookq  s0  è ø€ ô* 0×9Ñ9ˆ
Ø×$Ñ$¨$¸:Ð$ÓFÈdÑRÜ ×&Ñ&Ð']Ð_c×_rÑ_rÔsØˆOä×"Ñ"Ð#EÔFô 29¸À<Ô1P˜×+Ñ+Ô-ÐVXˆà0=×0AÑ0AÀ)ÈRÓ0Pö$
Ø&,ÐTZ×T^ÑT^Ð_hÕTiˆF�J‰J�yÕ!ð$
Ðð $
ñ !Ü ×&Ñ&Ð'sÔtØˆOð !%§	¡	£ˆØ%)§X¡X¨j¸"Ó%=Ð@QÑ%Qˆ�zÑ"ð ×'Ñ'¨Ð8IÓJ×JÐJô 	3ÀÐUY×UhÑUhÕiàˆùò%$
ð 	Kús%   ‚BD8ÂD1Â(D1Â;AD8ÄD6Ä#D8c              ƒ   ó¢  K  — |j                  d«      st        j                  d«       |S 	 | j                  |«      }| j	                  |«      }| j                  ||¬«      ƒ d{  –—† }| j                  ||«       |S 7 Œ# t        $ rD}t        |t        «      r|‚t        j                  d|«       | j                  ||«      cY d}~S d}~ww xY w­w)a¶  
        Core method to run the Pillar guardrail scan.

        Args:
            data: Request data containing messages and metadata
            user_api_key_dict: User API key authentication info containing key context

        Returns:
            Original data if safe or in monitor mode

        Raises:
            HTTPException: If content is flagged and action is 'block', or if API fails and fallback_on_error is 'block'
        r¶   z?Pillar Guardrail: No messages detected, bypassing security scan)rM   ÚpayloadNz/Pillar Guardrail: API communication failed - %s)r7   r
   r…   Ú_prepare_headersÚ_prepare_payloadÚ_call_pillar_apiÚ_process_pillar_responseÚ	Exceptionr0   r   ÚerrorÚ_handle_api_error)r�   r   r•   rM   rÀ   r±   Úes          r&   r©   z$PillarGuardrail.run_pillar_guardrail§  sÑ   è ø€ ð �x‰x˜
Ô#Ü ×&Ñ&Ð'hÔiØˆKð	3Ø!×2Ñ2Ð3DÓEˆGØ!×2Ñ2°4Ó8ˆGà$(×$9Ñ$9ØØð %:ó %÷ ˆHð ×)Ñ)¨(°DÔ9ØˆKðùô ò 	3ä˜!œ]Ô+Ø�ô !×&Ñ&Ð'XÐZ[Ô\à×)Ñ)¨!¨TÓ2Õ2ûð	3üsF   ‚)C¬8A? Á$A=Á%A? Á<CÁ=A? Á?	CÂ9CÃCÃCÃCÃCrÆ   c                 ó¬   — | j                   dk(  rt        j                  d«       |S t        j                  d«       t        dddt	        |«      dœ¬«      ‚)	ad  
        Handle API errors based on fallback_on_error configuration.

        Args:
            error: The exception that occurred during API communication
            data: Original request data

        Returns:
            Original data if fallback_on_error is 'allow'

        Raises:
            HTTPException: If fallback_on_error is 'block'
        r`   zXPillar Guardrail: API unavailable, proceeding without scanning (fallback_on_error=allow)zMPillar Guardrail: API unavailable, blocking request (fallback_on_error=block)i÷  z%Pillar Security Guardrail UnavailablezQSecurity scanning service is temporarily unavailable and fallback is set to block)rÆ   rµ   Úoriginal_error©Ústatus_codeÚdetail)ri   r
   rƒ   r   r6   )r�   rÆ   r   s      r&   rÇ   z!PillarGuardrail._handle_api_errorÕ  s_   € ð ×!Ñ! WÒ,Ü ×(Ñ(Øjôð ˆKä ×(Ñ(Ø_ôô  ØàDØrÜ&)¨%£jñôð r(   c                 ó6  — | j                   sd}t        |«      ‚d| j                   › �ddœ}| j                  |d| j                  «       | j                  |d| j                  «       | j                  |d| j
                  «       | j                  |d| j                  «       |j                  |j                  |j                  |j                  |j                  |j                  |j                  d	œ}|j                  «       D ]  \  }}|sŒ	t        |«      ||<   Œ |S )
zí
        Prepare headers for the Pillar API request.

        Args:
            user_api_key_dict: User API key authentication info containing key context

        Returns:
            Dictionary of headers to send to Pillar API
        rn   zBearer zapplication/json)ÚAuthorizationzContent-TypeÚplr_scannersÚplr_evidenceÚ	plr_asyncÚplr_persist)zX-LiteLLM-Key-NamezX-LiteLLM-Key-AliaszX-LiteLLM-User-IdzX-LiteLLM-User-EmailzX-LiteLLM-Team-IdzX-LiteLLM-Team-NamezX-LiteLLM-Org-Id)rb   rR   Ú_set_bool_headerrg   rh   re   rf   Úkey_nameÚ	key_aliasÚuser_idÚ
user_emailÚteam_idÚ
team_aliasÚorg_idÚitemsr6   )r�   r•   r’   rM   Úcontext_mappingÚheader_nameÚvalues          r&   rÁ   z PillarGuardrail._prepare_headersõ  s  € ð �|Š|ðMð ô 0°Ó4Ð4ð  ' t§|¡| nÐ5Ø.ñ*
ˆð 	×Ñ˜g ~°t×7LÑ7LÔMØ×Ñ˜g ~°t×7LÑ7LÔMØ×Ñ˜g {°D·O±OÔDØ×Ñ˜g }°d×6JÑ6JÔKð #4×"<Ñ"<Ø#4×#>Ñ#>Ø!2×!:Ñ!:Ø$5×$@Ñ$@Ø!2×!:Ñ!:Ø#4×#?Ñ#?Ø 1× 8Ñ 8ñ"
ˆð #2×"7Ñ"7Ó"9ò 	2ÑˆK˜ÚÜ'*¨5£z�˜Ò$ð	2ð ˆr(   rM   rÞ   rß   c                 ó$   — |€y|rd||<   yd||<   y)zFApply a boolean value as a lowercase string HTTP header when provided.NÚtrueÚfalserX   )r�   rM   rÞ   rß   s       r&   rÔ   z PillarGuardrail._set_bool_header!  s!   € ð ˆ=ØÙ).˜vˆ�Ò°Gˆ�Òr(   rr   rs   rt   ru   c                 ó$  — |�	 | j                  |«      S |r)t	        j
                  |«      }|�	 | j                  |«      S |S # t        $ r t        j                  d||«       |cY S w xY w# t        $ r t        j                  d||«       |cY S w xY w)zKResolve configuration precedence: explicit value -> environment -> default.zMPillar Guardrail: Invalid boolean value '%s' for %s, falling back to default.zQPillar Guardrail: Invalid boolean env value '%s' for %s, falling back to default.)Ú_parse_bool_valuer‹   r
   rƒ   r~   r€   )r�   rr   rs   rt   ru   Ú	env_values         r&   r†   z$PillarGuardrail._resolve_bool_config(  s³   € ð Ð%ðØ×-Ñ-¨nÓ=Ð=ñ Ü!Ÿy™y¨Ó1ˆIØÐ$ð#Ø×1Ñ1°)Ó<Ð<ð ˆøô+ ò Ü$×,Ñ,ØcØ"Ø ôð
 ’ðûô "ò #Ü(×0Ñ0ØkØ!Øôð
 #’Nð#ús"   „A ¯A* Á"A'Á&A'Á*"BÂBc                 óÚ   — t        | t        «      r| S t        | t        «      rt        | «      S t        | «      j	                  «       j                  «       }|dv ry|dv ryt        d| › �«      ‚)z;Normalise various truthy/falsey inputs to a strict boolean.>   Ú1ÚyÚonÚyesrá   T>   Ú0ÚnÚnoÚoffrâ   FzUnrecognised boolean value: )r0   ÚboolÚintr6   ÚstriprL   r‹   )rß   Ú	value_strs     r&   rä   z!PillarGuardrail._parse_bool_valueK  sm   € ô �eœTÔ"ØˆLÜ�eœSÔ!Ü˜“;Ðä˜u›:×+Ñ+Ó-×3Ñ3Ó5ˆ	ØÐ7Ñ7ØØÐ8Ñ8ØÜÐ7¸°wÐ?Ó@Ð@r(   c                 ó@  — |j                  d«      }|sy	 t        ||j                  d«      |j                  d«      |j                  d«      ¬«      \  }}}}|xs d|xs dfS # t        $ r1 |xs d|j                  d«      xs |j                  d«      xs dfcY S w xY w)	z¸
        Extract the model and provider from the request data.

        Args:
            data: Request data

        Returns:
            Tuple of (model_name, provider_name)
        Úmodel)Úunknownrõ   Úcustom_llm_providerrc   rb   )rô   rö   rc   rb   rõ   Úprovider)r7   r   rÅ   )r�   r   rô   Úclean_modelr÷   Ú_s         r&   Ú_extract_model_and_providerz+PillarGuardrail._extract_model_and_provider[  s²   € ð —x‘x Ó(ˆÙØ'ð	Ü*:ØØ$(§H¡HÐ-BÓ$CØŸ™ *Ó-ØŸ™ Ó+ô	+Ñ'ˆK˜ 1 að Ò+ )¨XÒ-B¸ÐBÐBøÜò 	ð Ò"˜Ø—‘Ð.Ó/ÒT°4·8±8¸JÓ3GÒTÈ9ðò ð	ús   –AA# Á#7BÂBc                 óZ  — |j                  dg «      }|j                  dg «      }dt        dœ}|||dœ}|j                  d«      }|r||d<   |j                  di «      j                  d	«      }|r||d
<   | j                  |«      \  }}	||d<   |	|d<   t        j                  d||||	«       |S )ah  
        Prepare the payload for the Pillar API request following the /api/v1/protect contract.

        This method supports multi-modal content (images, files, audio, video, etc.) as messages
        are passed through without modification. The messages array can contain any OpenAI-compatible
        message structure including:
        - Text content (string)
        - Multi-modal content blocks (image_url, image_file, audio, video, document, file)
        - Attachments
        - Tool calls

        Args:
            data: Request data

        Returns:
            Formatted payload for Pillar API
        r¶   ÚtoolsÚlitellm)Úsourcer   )r¶   rü   ÚmetadataÚuserr×   rÿ   Úpillar_session_idÚ
session_idrô   r÷   zNPillar Guardrail: Request context - user=%s, session=%s, model=%s, provider=%s)r7   Úlitellm_versionrú   r
   r…   )
r�   r   r¶   rü   rÿ   rÀ   r×   r  rô   r÷   s
             r&   rÂ   z PillarGuardrail._prepare_payloady  sÙ   € ð$ Ÿ(™( :¨rÓ2ˆØ—x‘x ¨Ó,ˆàÜ&ñ
ˆð !ØØ ñ
ˆð Ÿ™ &Ó)ˆÙØ!(ˆG�IÑð !ŸH™H Z°Ó4×8Ñ8Ð9LÓMˆ
ÙØ$.ˆG�LÑ!ð ×:Ñ:¸4Ó@‰ˆˆxØ ˆ�ÑØ&ˆ�
Ñä×"Ñ"Ø\ØØØØô	
ð ˆr(   rÀ   c           	   ƒ   óž  K  — t        j                  dt        |j                  dg «      «      «       | j                  j                  | j                  › d�||| j                  ¬«      ƒ d{  –—† }|j                  «        |j                  «       }|j                  d«      }|j                  d«      }t        j                  d||«       |S 7 Œ_­w)	zä
        Call the Pillar API and return the response.

        Args:
            headers: HTTP headers for the request
            payload: Request payload

        Returns:
            Pillar API response as dictionary
        z;Pillar Guardrail: Scanning %s messages for security threatsr¶   z/api/v1/protect)ÚurlrM   r#   rj   NÚflaggedr  z<Pillar Guardrail: Analysis complete - flagged=%s, session=%s)
r
   r…   r2   r7   r}   Úpostrc   rj   Úraise_for_statusr#   )r�   rM   rÀ   r±   Úresr  r  s          r&   rÃ   z PillarGuardrail._call_pillar_api±  s¾   è ø€ ô 	×"Ñ"ØIÌ3ÈwÏ{É{Ð[eÐgiÓOjÓKkô	
ð !%× 2Ñ 2× 7Ñ 7Ø—=‘=�/ Ð1ØØØ—L‘Lð	 !8ó !
÷ 
ˆð 	×!Ñ!Ô#Ø—]‘]“_ˆàŸ™ Ó+ˆØŸG™G LÓ1ˆ
Ü×"Ñ"Ð#aÐcjÐlvÔwØˆ
ð
ús   ‚A)CÁ+CÁ,A CÚpillar_responseÚoriginal_datac                 ój  — |sy|j                  dd«      }t        |«      }||vst        |j                  |«      t        «      si ||<   ||   }|dk7  r(d|vst        |j                  d«      t        «      s||d<   |j                  d«      }|r$t	        j
                  d|«       d|vr||d<   ||d<   ||d	<   | j                  r|j                  d
i «      |d<   | j                  r|j                  dg «      |d<   |r®t	        j                  d«       | j                  dk(  r| j                  |«       nx| j                  dk(  rEt	        j                  d«       |j                  dg «      }|r||d<   n:t	        j                  d«       n$| j                  dk(  rt	        j                  d«       t        |«       y)aS  
        Process the Pillar API response and handle detections based on configuration.

        Args:
            pillar_response: Response from Pillar API
            original_data: Original request data (modified in-place with session info)

        Raises:
            HTTPException: If content is flagged and action is 'block'
        Nr  Frÿ   r  z5Pillar Guardrail: Received session_id from server: %sr  rJ   rF   ÚscannersrG   r)   rH   z!Pillar Guardrail: Threat detectedr]   r_   z8Pillar Guardrail: Masking mode - masking flagged contentÚmasked_session_messagesr¶   zNPillar Guardrail: Masking requested but no masked_session_messages in responser^   zGPillar Guardrail: Monitoring mode - allowing flagged content to proceed)r7   r   r0   r4   r
   r…   rg   rh   rƒ   rd   Ú!_raise_pillar_detection_exceptionÚinforP   )r�   r
  r  r  Úmetadata_fieldrD   r  Úmasked_messagess           r&   rÄ   z(PillarGuardrail._process_pillar_responseÍ  sÅ  € ñ Øà(×,Ñ,¨Y¸Ó>ˆä FÀ}Ó UˆØ Ñ.´jÀ×ARÑARÐSaÓAbÔdhÔ6iØ,.ˆM˜.Ñ)Ø -¨nÑ =ˆð ˜ZÒ'Ø Ñ.´jÀ×ARÑARÐS]ÓA^Ô`dÔ6eØ,:�˜jÑ)ð $3×#6Ñ#6°|Ó#DÐÙÜ ×&Ñ&Ð'^Ð`qÔrà"¨.Ñ8Ø6G�Ð2Ñ3Ø;LˆNÐ7Ñ8ð ,3ˆÐ'Ñ(Ø× Ò Ø0?×0CÑ0CÀJÐPRÓ0SˆNÐ,Ñ-Ø× Ò Ø0?×0CÑ0CÀJÐPRÓ0SˆNÐ,Ñ-áÜ ×(Ñ(Ð)LÔMØ×%Ñ%¨Ò0Ø×6Ñ6°ÕGØ×'Ñ'¨6Ò1Ü$×)Ñ)Ð*dÔeØ)8×)<Ñ)<Ð=VÐXZÓ)[�Ù"Ø0?�M *Ò-ä(×0Ñ0Øhõð ×'Ñ'¨9Ò4Ü$×)Ñ)Ð*sÔtä% nÕ5r(   c                 óü   — d|j                  d«      i}| j                  r|j                  di «      |d<   | j                  r|j                  dg «      |d<   dd|dœ}t        j                  d«       t        d|¬	«      ‚)
a  
        Raise an HTTPException for Pillar security detections.

        Args:
            pillar_response: Response from Pillar API containing detection details

        Raises:
            HTTPException: Always raises with security detection details
        r  r  r)   z$Blocked by Pillar Security GuardrailzSecurity threats detected)rÆ   Údetection_messager
  z=Pillar Guardrail: Request blocked - Security threats detectedi�  rË   )r7   rg   rh   r
   rƒ   r   )r�   r
  Úpillar_response_dictÚerror_details       r&   r  z1PillarGuardrail._raise_pillar_detection_exception	  s�   € ð ˜/×-Ñ-¨lÓ;ð'
Ðð
 × Ò Ø/>×/BÑ/BÀ:ÈrÓ/RÐ  Ñ,Ø× Ò Ø/>×/BÑ/BÀ:ÈrÓ/RÐ  Ñ,ð <Ø!<Ø3ñ
ˆô 	×$Ñ$Ð%dÔeä¨°LÔAÐAr(   r   c                  ó   — ddl m}  | S )z�
        Get the configuration model for this guardrail.

        Returns:
            Pydantic model class for guardrail configuration
        r   ©ÚPillarGuardrailConfigModel)Ú5litellm.types.proxy.guardrails.guardrail_hooks.pillarr  r  s    r&   Úget_config_modelz PillarGuardrail.get_config_model+  s   € õ	
ð *Ð)r(   c                 óœ   — t         j                  t         j                  t         j                  t         j                  t         j
                  gS )N)r   r§   r¯   r·   Úpre_mcp_callÚduring_mcp_call)Úclss    r&   r�   z)PillarGuardrail.get_supported_event_hooks9  s;   € ô  ×(Ñ(Ü×+Ñ+Ü×)Ñ)Ü×,Ñ,Ü×/Ñ/ð
ð 	
r(   )
zpillar-securityNNNNNNNNN).rT   rU   rV   rW   r‚   r„   r‡   rˆ   r�   rŠ   r6   rï   r‰   rŽ   r   r   r	   r4   r   rÅ   r«   r°   r   r¾   r©   rÇ   rÁ   rÔ   rð   r†   Ústaticmethodrä   Útuplerú   r   rÂ   rÃ   rÄ   r  Útyper  Úclassmethodr1   r   r�   Ú__classcell__)r”   s   @r&   r\   r\   •   sá  ø„ ñò $@Ð Ø )ÐØ")¨7Ð!3ÐØ%ÐØ0€LØ€Oð &7Ø"Ø#Ø(,Ø"&Ø'+Ø(,Ø(,Ø(,Ø $ñm
à˜d™
ðm
ð �t‘ðm
ð ˜‘*ð	m
ð
  ™:ðm
ð ˜4‘Kðm
ð  ™ðm
ð  ™+ðm
ð  ™+ðm
ð  ™:ðm
ð ˜‘ðm
ð 
õm
ðf ð,à)ð,ð ð,ð ð	,ð
 ð	"ñ
ð,ð" 
�S‰˜4Ñ	 $Ñ	&ò#,ó ð,ð\ ð(àð(ð *ð(ð ð"ñ	
ð	(ð 
�S‰˜4Ñ	 $Ñ	&ò(ó ð(ðT ð/àð/ð *ð/ð #ð	/ð
 
ò/ó ð/ðj(3¨tð (3Èð (3Ð[_ó (3ð\ yð ¸ð Àó ð@*°.ð *ÀTÈ#ÈsÈ(Á^ó *ðX<¨¨S°#¨X©ð <ÀSð <ÐQUÐX\ÑQ\ð <Ðaeó <ð!à˜s™
 SÑ(¨4Ñ/ð!ð �t‘ð!ð ˜‘ð	!ð
 ð!ð 
�‰ó!ðF ðA ¨¡¨cÑ!1ð A°dò Aó ðAð°ð ¸¸sÀC¸x¹ó ð<6 Tð 6¨d°3¸°8©nó 6ðp¨d°3¸°8©nð ÀtÈCÐQTÈHÁ~ð ÐZ^Ð_bÐdgÐ_gÑZhó ð8:6¸¸SÀ#¸X¹ð :6ÐW[ð :6Ð`dó :6ðxBÀÀcÈ3ÀhÁð BÐTXó BðD ð*˜dÐ#9Ñ:¸TÑAò *ó ð*ð ð
¨$Ð/BÑ*Cò 
ó ô
r(   r\   )4r#   r~   Útypingr   r   r   r   Úurllib.parser   Úfastapir   rý   r	   Úlitellm._loggingr
   Úlitellm._versionr   r  Ú%litellm.integrations.custom_guardrailr   r   Ú1litellm.litellm_core_utils.get_llm_provider_logicr   Ú&litellm.llms.custom_httpx.http_handlerr   r   Úlitellm.proxy._typesr   Ú)litellm.proxy.common_utils.callback_utilsr   r   r   Úlitellm.types.guardrailsr   Úlitellm.types.utilsr   Ú3litellm.types.proxy.guardrails.guardrail_hooks.baser   r   Ú__annotations__r6   r'   rð   r!  rï   rC   r4   rP   rÅ   rR   rZ   r\   rX   r(   r&   ú<module>r3     sï   ðô Û 	ß 5Ó 5Ý õ "õ Ý 1Ý 7÷õ O÷õ 0÷ñ õ
 9Ý 0áÝXà'/Ð ˜uÓ /ð( #ð (¨#ó (ð @]ñ 4.¨ð 4.¸ð 4.ÐafÐgjÐloÐquÐguÑavó 4.ðn°$°s¸C°x±.ð ÀTÈ#ÈsÈ(Á^ó ô@; Iô ;ôI˜iô Iô
l

�oõ l

r(   