Ë
    uPêj.  ã                   óh   — d 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 ee   ez  Z G d„ d«      Zy)	a  
Passthrough Guardrails Helper Module

Handles guardrail execution for passthrough endpoints with:
- Opt-in model (guardrails only run when explicitly configured)
- Field-level targeting using JSONPath expressions
- Automatic inheritance from org/team/key levels when enabled
é    )ÚAnyÚFinal)Úverbose_proxy_logger)ÚPassThroughGuardrailsConfigÚPassThroughGuardrailSettingsÚUserAPIKeyAuth)ÚJsonPathExtractorc                   ó~  — e Zd ZdZededz  dedz  fd„«       Zededz  defd„«       Z	ededz  de
e   fd„«       Zededz  dededz  fd	„«       Zed
ededz  defd„«       Zedededz  defd„«       Ze	 dd
edededz  dedef
d„«       Zedededz  deeef   dz  fd„«       Ze	 ddededededz  fd„«       Zy)ÚPassthroughGuardrailHandleraþ  
    Handles guardrail execution for passthrough endpoints.

    Passthrough endpoints use an opt-in model for guardrails:
    - Guardrails only run when explicitly configured on the endpoint
    - Supports field-level targeting using JSONPath expressions
    - Automatically inherits org/team/key level guardrails when enabled

    Guardrails can be specified as:
    - List format (simple): ["guardrail-1", "guardrail-2"]
    - Dict format (with settings): {"guardrail-1": {"request_fields": ["query"]}}
    Úguardrails_configNÚreturnc                 ó¸   — | €yt        | t        «      r| S t        | t        «      r| D �ci c]  }|d“Œ c}S t        j                  dt        | «      «       yc c}w )zø
        Normalize guardrails config to dict format.

        Accepts:
        - List of guardrail names: ["g1", "g2"] -> {"g1": None, "g2": None}
        - Dict with settings: {"g1": {"request_fields": [...]}}
        - None: returns None
        Nz<Passthrough guardrails config is not a dict or list, got: %s)Ú
isinstanceÚdictÚlistr   ÚdebugÚtype)r   Únames     ú€/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/pass_through_endpoints/passthrough_guardrails.pyÚnormalize_configz,PassthroughGuardrailHandler.normalize_config*   sf   € ð Ð$Øô Ð'¬Ô.Ø$Ð$ô Ð'¬Ô.Ø+<Ö= 4�D˜$‘JÒ=Ð=ä×"Ñ"ØJÜÐ"Ó#ô	
ð ùò >s   ª
Ac                 óN   — t         j                  | «      }|€yt        |«      dkD  S )zÙ
        Check if guardrails are enabled for a passthrough endpoint.

        Passthrough endpoints are opt-in only - guardrails only run when
        the guardrails config is set with at least one guardrail.
        Fr   )r   r   Úlen©r   Ú
normalizeds     r   Ú
is_enabledz&PassthroughGuardrailHandler.is_enabledG   s-   € ô 8×HÑHÐIZÓ[ˆ
ØÐØÜ�:‹ Ñ"Ð"ó    c                 óf   — t         j                  | «      }|€g S t        |j                  «       «      S )zFGet the list of guardrail names configured for a passthrough endpoint.)r   r   r   Úkeysr   s     r   Úget_guardrail_namesz/PassthroughGuardrailHandler.get_guardrail_namesV   s2   € ô
 8×HÑHÐIZÓ[ˆ
ØÐØˆIÜ�J—O‘OÓ%Ó&Ð&r   Úguardrail_namec                 ó”   — t         j                  | «      }|€y|j                  |«      }|€yt        |t        «      rt        di |¤ŽS |S )zBGet settings for a specific guardrail from the passthrough config.N© )r   r   Úgetr   r   r   )r   r    r   Úsettingss       r   Úget_settingsz(PassthroughGuardrailHandler.get_settings`   sR   € ô 8×HÑHÐIZÓ[ˆ
ØÐØà$Ÿ.™.¨Ó8ˆØÐØä�h¤Ô%Ü/Ñ;°(Ñ;Ð;àˆr   Úrequest_dataÚguardrail_settingsc                 ó|   — |�|j                   €ddlm}  || «      S t        j                  | |j                   ¬«      S )zà
        Prepare input text for guardrail execution based on field targeting settings.

        If request_fields is specified, extracts only those fields.
        Otherwise, uses the entire request payload as text.
        r   ©Ú
safe_dumps©ÚdataÚjsonpath_expressions)Úrequest_fieldsÚ*litellm.litellm_core_utils.safe_json_dumpsr*   r	   Úextract_fields)r&   r'   r*   s      r   Úprepare_inputz)PassthroughGuardrailHandler.prepare_inputs   sC   € ð Ð%Ð);×)JÑ)JÐ)RÝMá˜lÓ+Ð+ä ×/Ñ/ØØ!3×!BÑ!Bô
ð 	
r   Úresponse_datac                 ó|   — |�|j                   €ddlm}  || «      S t        j                  | |j                   ¬«      S )zã
        Prepare output text for guardrail execution based on field targeting settings.

        If response_fields is specified, extracts only those fields.
        Otherwise, uses the entire response payload as text.
        r   r)   r+   )Úresponse_fieldsr/   r*   r	   r0   )r2   r'   r*   s      r   Úprepare_outputz*PassthroughGuardrailHandler.prepare_outputˆ   sC   € ð Ð%Ð);×)KÑ)KÐ)SÝMá˜mÓ,Ð,ä ×/Ñ/ØØ!3×!CÑ!Cô
ð 	
r   Úuser_api_key_dictÚ
event_typec              ƒ   ó"  K  — t         j                  |«      st        j                  d«       | S t         j	                  |«      }t        j                  d|«       ddlm} d| vri | d<   |D �ci c]  }|d“Œ c}| d   d<    ||«       | S c c}w ­w)a/  
        Execute guardrails for a passthrough endpoint.

        This is the main entry point for passthrough guardrail execution.

        Args:
            request_data: The request payload
            user_api_key_dict: User API key authentication info
            guardrails_config: Passthrough-specific guardrails configuration
            event_type: "pre_call" for request, "post_call" for response

        Returns:
            The potentially modified request_data

        Raises:
            HTTPException if a guardrail blocks the request
        z@Passthrough guardrails not enabled, skipping guardrail executionz$Executing passthrough guardrails: %sr   )Ú!set_passthrough_guardrails_configÚmetadataTÚ
guardrails)r   r   r   r   r   Ú8litellm.proxy.pass_through_endpoints.passthrough_contextr9   )r&   r6   r   r7   Úguardrail_namesr9   r   s          r   Úexecutez#PassthroughGuardrailHandler.execute�   s    è ø€ ô0 +×5Ñ5Ð6GÔHÜ ×&Ñ&Ð'iÔjØÐä!<×!PÑ!PÐQbÓ!cˆÜ×"Ñ"Ð#IÈ?Ô[õ	
ð ˜\Ñ)Ø')ˆL˜Ñ$ð JYÖ1YÀ°$¸±*Ò1Yˆ�ZÑ  Ñ.ñ 	*Ð*;Ô<àÐùò 2Zùs   ‚A+BÁ-
B
Á7BÚpassthrough_guardrails_configc                 ó  — ddl m} t        j                  |«      }|€t	        j
                  d«       yt        |«      dk(  rt	        j
                  d«       yi }|D ]  }d||<   t	        j
                  d|«       Œ di i} || j                  | j                  |d¬	«       |d   j                  d
g «      }|D ]"  }||vsŒd||<   t	        j
                  d|«       Œ$ t	        j
                  dt        |j                  «       «      «       |r|S dS )a@  
        Collect guardrails for a passthrough endpoint.

        Passthrough endpoints are opt-in only for guardrails. Guardrails only run when
        the guardrails config is set with at least one guardrail.

        Accepts both list and dict formats:
        - List: ["guardrail-1", "guardrail-2"]
        - Dict: {"guardrail-1": {"request_fields": [...]}}

        When enabled, this function collects:
        - Passthrough-specific guardrails from the config
        - Org/team/key level guardrails (automatic inheritance when passthrough is enabled)

        Args:
            user_api_key_dict: User API key authentication info
            passthrough_guardrails_config: List or Dict of guardrail names/settings

        Returns:
            Dict of guardrail names to run (format: {guardrail_name: True}), or None
        r   )Ú)_add_guardrails_from_key_or_team_metadataNzDPassthrough guardrails not configured, skipping guardrail collectionz0Passthrough guardrails config is empty, skippingTz(Added passthrough-specific guardrail: %sr:   )Úkey_metadataÚteam_metadatar,   Úmetadata_variable_namer;   z.Added inherited guardrail (key/team level): %sz1Collected guardrails for passthrough endpoint: %s)Ú$litellm.proxy.litellm_pre_call_utilsrA   r   r   r   r   r   r:   rC   r#   r   r   )r6   r?   rA   Únormalized_configÚguardrails_to_runr    Ú	temp_dataÚinherited_guardrailss           r   Úcollect_guardrailsz.PassthroughGuardrailHandler.collect_guardrailsÌ   s=  € õ4	
ô
 $?×#OÑ#OÐPmÓ#nÐàÐ$Ü ×&Ñ&Ð'mÔnØäÐ Ó! QÒ&Ü ×&Ñ&Ð'YÔZØð 57Ðð 0ò 	cˆNØ04Ð˜nÑ-Ü ×&Ñ&Ð'QÐSaÕbð	cð
 -7¸Ð+;ˆ	Ù1Ø*×3Ñ3Ø+×9Ñ9ØØ#-õ		
ð '0°
Ñ&;×&?Ñ&?ÀÈbÓ&QÐØ2ò 	mˆNØÐ%6Ò6Ø48Ð! .Ñ1Ü$×*Ñ*Ð+[Ð]kÕlð	mô
 	×"Ñ"Ø?ÜÐ"×'Ñ'Ó)Ó*ô	
ñ
 %6Ð Ð?¸4Ð?r   r,   Ú
is_requestc                 ó  — ddl m}  |«       }|€yt        j                  ||«      }|€y|r-|j                  r t        j                  | |j                  «      S y|j                  r t        j                  | |j                  «      S y)aþ  
        Get the text to check for a guardrail, respecting field targeting settings.

        Called by guardrail hooks to get the appropriate text based on
        passthrough field targeting configuration.

        Args:
            data: The request/response data dict
            guardrail_name: Name of the guardrail being executed
            is_request: True for request (pre_call), False for response (post_call)

        Returns:
            The text to check, or None to use default behavior
        r   )Ú!get_passthrough_guardrails_configN)r<   rM   r   r%   r.   r	   r0   r4   )r,   r    rK   rM   Úpassthrough_configr$   s         r   Úget_field_targeted_textz3PassthroughGuardrailHandler.get_field_targeted_text  sŠ   € õ(	
ñ %FÓ$GÐØÐ%Øä5×BÑBÐCUÐWeÓfˆØÐØáØ×&Ò&Ü(×7Ñ7¸¸h×>UÑ>UÓVÐVð
 ð ×'Ò'Ü(×7Ñ7¸¸h×>VÑ>VÓWÐWàr   )Úpre_call)T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstaticmethodÚ PassThroughGuardrailsConfigInputr   r   Úboolr   r   Ústrr   r   r%   r   r1   r5   r   r>   rJ   rO   r"   r   r   r   r      s  „ ñð ðØ;¸dÑBðà	$ tÑ	+òó ðð8 ð#Ø;¸dÑBð#à	ò#ó ð#ð ð'Ø;¸dÑBð'à	ˆc‰ò'ó ð'ð ðØ;¸dÑBðàðð 
&¨Ñ	,òó ðð$ ð
Øð
à8¸4Ñ?ð
ð 
ò
ó ð
ð( ð
Øð
à8¸4Ñ?ð
ð 
ò
ó ð
ð( ð
 %ñ	,Øð,à)ð,ð 7¸Ñ=ð,ð ð	,ð
 
ò,ó ð,ð\ ðE@Ø)ðE@à'GÈ$Ñ'NðE@ð 
ˆc�4ˆi‰˜4Ñ	òE@ó ðE@ðN ð  ñ&Øð&àð&ð ð&ð 
ˆt‰ò	&ó ñ&r   r   N)rT   Útypingr   r   Úlitellm._loggingr   Úlitellm.proxy._typesr   r   r   Ú7litellm.proxy.pass_through_endpoints.jsonpath_extractorr	   r   rX   rV   r   r"   r   r   ú<module>r]      sD   ðñ÷ å 1÷ñ õ
 Vð
 	ˆ�IØ!ñ"ð !÷_ò _r   