Ë
    tPêjíG  ã                   ó°  — U d dl Z d dlmZ d dlmZmZmZmZmZm	Z	 d dl
Z
d dl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mZ d d
lmZ d dlm Z  erd dl!m"Z# d dl$m%Z%m&Z&m'Z' d dlm(Z( dZ)ee*d<   dZ+ee*d<    G d„ de«      Z, G d„ de«      Z- G d„ ded¬«      Z. G d„ de	«      Z/de/de,fd„Z0 G d „ d!e1«      Z2 G d"„ d#e1«      Z3 G d$„ d%e«      Z4y)&é    N)ÚMapping)ÚTYPE_CHECKINGÚAnyÚFinalÚLiteralÚOptionalÚProtocol)ÚNotRequiredÚReadOnlyÚ	TypedDict)Úverbose_proxy_logger)Úversion)ÚGuardrailRaisedExceptionÚTimeout)ÚCustomGuardrailÚlog_guardrail_information)Úget_async_httpx_clientÚhttpxSpecialProvider)ÚGuardrailEventHooks)ÚGenericGuardrailAPIInputs)ÚLogging)ÚAllMessageValuesÚChatCompletionToolCallChunkÚChatCompletionToolParam)ÚChatCompletionMessageToolCallÚdeepkeepÚGUARDRAIL_NAMEz+/v3/openai/beta/litellm_basic_guardrail_apiÚ_DEEPKEEP_GUARDRAIL_ENDPOINTc                   ó¬   — e Zd ZU dZeee      ed<   eee      ed<   eed      ed<   eed      ed<   eed      ed<   eed	      ed
<   eed      ed<   y)ÚDeepKeepFirewallResponsez0Body returned by the DeepKeep firewall endpoint.ÚactionÚblocked_reasonz	list[str]ÚtextsÚimageszlist[ChatCompletionToolParam]ÚtoolszGlist[ChatCompletionToolCallChunk] | list[ChatCompletionMessageToolCall]Ú
tool_callszlist[AllMessageValues]Ústructured_messagesN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r
   ÚstrÚ__annotations__© ó    ú/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/guardrails/guardrail_hooks/deepkeep/deepkeep.pyr    r    ,   sx   … Ù:à�[ Ñ%Ñ&Ó&Ø˜[¨Ñ-Ñ.Ó.Ø�K Ñ,Ñ-Ó-Ø�[ Ñ-Ñ.Ó.Ø�KÐ ?Ñ@ÑAÓAØ˜Ð%nÑoÑpÓpØ! +Ð.FÑ"GÑHÔHr/   r    c                   ó"   — e Zd ZU dZee   ed<   y)Ú_DeepKeepInitKwargsViewzNTyped read of the guardrail name carried in the untyped base-guardrail kwargs.Úguardrail_nameN)r(   r)   r*   r+   r   r,   r-   r.   r/   r0   r2   r2   8   s   … ÙXà˜S‘MÔ!r/   r2   c                   óF   — e Zd ZU dZeeeef      ed<   eeeef      ed<   y)Ú_DeepKeepMetadataSourcezFTyped read of the two untyped metadata mappings this guardrail merges.Úlitellm_metadataÚmetadataN)	r(   r)   r*   r+   r   r   r,   Úobjectr-   r.   r/   r0   r5   r5   >   s-   … ÙPà˜w s¨F {Ñ3Ñ4Ó4Ø�w˜s F˜{Ñ+Ñ,Ô,r/   r5   F)Útotalc                   ó   — e Zd Zdefd„Zy)Ú_FirewallResponseBodyÚreturnc                  ó   — y ©Nr.   )Úselfs    r0   Újsonz_FirewallResponseBody.jsonF   s   � r/   N)r(   r)   r*   r    r@   r.   r/   r0   r;   r;   E   s   „ Ø3Ð.Ô3r/   r;   Úresponser<   c                 ó"   — | j                  «       S r>   )r@   )rA   s    r0   Ú_firewall_response_bodyrC   I   s   € Ø�=‰=‹?Ðr/   c                   ó   — e Zd ZdZy)ÚDeepKeepGuardrailMissingSecretszAException raised when DeepKeep API key or firewall_id is missing.N©r(   r)   r*   r+   r.   r/   r0   rE   rE   M   s   „ ÚKr/   rE   c                   ó   — e Zd ZdZy)ÚDeepKeepGuardrailAPIErrorz@Exception raised when there's an error calling the DeepKeep API.NrF   r.   r/   r0   rH   rH   Q   s   „ ÚJr/   rH   c                   óš  ‡ — e Zd ZdZ	 	 	 	 	 d'dedz  dedz  dedz  ded   deeef   ee   z  dz  d	efˆ fd
„Z	de
deeef   fd„Zdeeef   fd„Zddœdeded   ded   dededz  defd„Z	 d(dededed   ded   dedefd„Zededee   ddddd d!d"d#defd$„«       Ze	 d)dededed   ded   def
d%„«       Zededz  fd&„«       Zˆ xZS )*ÚDeepKeepGuardrailaà  
    DeepKeep AI Firewall integration for LiteLLM.

    Provides content moderation, prompt injection detection, PII protection,
    and policy enforcement through the DeepKeep AI Firewall API.

    DeepKeep's firewall evaluates LLM inputs and outputs against a configurable
    set of guardrails (detectors + actions) managed via the DeepKeep platform.

    Configuration example (litellm config YAML):
        guardrails:
          - guardrail_name: deepkeep-firewall
            litellm_params:
              guardrail: deepkeep
              mode: pre_call
              api_key: os.environ/DEEPKEEP_API_KEY
              api_base: https://your-deepkeep-instance.example.com
              deepkeep_firewall_id: your-firewall-id
    NÚapi_keyÚapi_baseÚfirewall_idÚunreachable_fallback)Úfail_closedÚ	fail_openÚextra_headersÚkwargsc                 ó   •— t        t        j                  ¬«      | _        |xs t        j
                  j                  d«      }|st        d«      ‚|| _        |xs t        j
                  j                  d«      | _	        | j                  st        d«      ‚|xs t        j
                  j                  d«      }|st        d«      ‚|j                  d«      }|j                  t        j                  d«      «      r|| _        n|› t        › �| _        || _        |�9t        |t         «      s)t#        j$                  d	t'        |«      j(                  «       t        |t         «      rt+        |«      ni | _        d
|vr2t.        j0                  t.        j2                  t.        j4                  g|d
<   t7        ‰
| �p  di |¤Ž d|j                  dd«      i}	t#        j:                  d|	d   | j                  | j                  «       y )N)Úllm_providerÚDEEPKEEP_API_KEYzxDeepKeep API key is required. Set the `DEEPKEEP_API_KEY` environment variable or pass `api_key` in the guardrail config.ÚDEEPKEEP_FIREWALL_IDz�DeepKeep firewall_id is required. Set the `DEEPKEEP_FIREWALL_ID` environment variable or pass `deepkeep_firewall_id` in the guardrail config.ÚDEEPKEEP_API_BASEzDeepKeep API base URL is required. Set the `DEEPKEEP_API_BASE` environment variable or pass `api_base` in the guardrail config.ú/zËDeepKeep guardrail ignoring `extra_headers`: expected a mapping of header name to value, got %s. `litellm_params.extra_headers` is a list of header names to forward and is not supported by this guardrailÚsupported_event_hooksr3   ÚunknownzNDeepKeep guardrail initialized: guardrail_name=%s, api_base=%s, firewall_id=%sr.   )r   r   ÚGuardrailCallbackÚasync_handlerÚosÚenvironÚgetrE   Údeepkeep_api_keyrM   ÚrstripÚendswithr   rL   rN   Ú
isinstancer   r   ÚwarningÚtyper(   ÚdictrQ   r   Úpre_callÚ	post_callÚduring_callÚsuperÚ__init__Údebug)r?   rK   rL   rM   rN   rQ   rR   r`   Úbase_urlÚ	init_viewÚ	__class__s             €r0   rk   zDeepKeepGuardrail.__init__j   sÜ  ø€ ô 4ÔAU×AgÑAgÔhˆÔð #*Ò"O¬R¯Z©Z¯^©^Ð<NÓ-OÐÙÜ1ðFóð ð &6ˆÔð 'ÒP¬"¯*©*¯.©.Ð9OÓ*PˆÔØ×ÒÜ1ðSóð ð ÒBœrŸz™zŸ~™~Ð.AÓBˆÙÜ1ðGóð ð —?‘? 3Ó'ˆØ×ÑÔ9×@Ñ@ÀÓEÔFØ$ˆD�Mà'˜jÔ)EÐ(FÐGˆDŒMàI]ˆÔ!ØÐ$¬Z¸ÄwÔ-OÜ ×(Ñ(ð}ä�]Ó#×,Ñ,ôô
 EOÈ}Ô^eÔDf¬T°-Ô-@ÐlnˆÔð #¨&Ñ0ä#×,Ñ,Ü#×-Ñ-Ü#×/Ñ/ð/ˆFÐ*Ñ+ô 	‰ÑÑ"˜6Ò"à5EÀvÇzÁzÐRbÐdmÓGnÐ4oˆ	ä×"Ñ"Ø\ØÐ&Ñ'Ø�M‰MØ×Ñõ		
r/   Úrequest_datar<   c                 óè   — i }|j                  di «      }|j                  di «      }i |¥|¥}|s|S g d¢}|D ]  }|j                  |«      }|€Œ|||<   Œ |j                  d«      �d|vr|d   |d<   |S )zù
        Extract user API key metadata from request_data for the DeepKeep API.

        Args:
            request_data: Request data dictionary containing metadata.

        Returns:
            Dictionary with user API key metadata fields.
        r6   r7   )Úuser_api_key_hashÚuser_api_key_aliasÚuser_api_key_user_idÚuser_api_key_user_emailÚuser_api_key_team_idÚuser_api_key_team_aliasÚuser_api_key_end_user_idÚuser_api_key_org_idÚuser_api_key_tokenrr   )r_   )	r?   rp   Úresult_metadatar6   Útop_level_metadataÚmetadata_dictÚ_METADATA_KEYSÚkeyÚvalues	            r0   Ú_extract_user_api_key_metadataz0DeepKeepGuardrail._extract_user_api_key_metadata±   s¶   € ð 57ˆà".×"2Ñ"2Ð3EÀrÓ"JÐØ$0×$4Ñ$4°ZÀÓ$DÐØ5_Ð8JÐ5_ÐN^Ð5_ˆáØ"Ð"ò	!
ˆð "ò 	-ˆCØ!×%Ñ% cÓ*ˆEØÑ Ø',� Ò$ð	-ð ×ÑÐ1Ó2Ð>ÐCVÐ^mÑCmØ3@ÐAUÑ3VˆOÐ/Ñ0àÐr/   c                 ór   — d| j                   dœ}| j                  r|j                  | j                  «       |S )z0Build HTTP headers for the DeepKeep API request.zapplication/json)zContent-Typez	X-API-Key)r`   rQ   Úupdate)r?   Úheaderss     r0   Ú_build_request_headersz(DeepKeepGuardrail._build_request_headersÚ   s9   € ð /Ø×.Ñ.ñ*
ˆð ×ÒØ�N‰N˜4×-Ñ-Ô.Øˆr/   )Úhttp_status_codeÚinputsÚ
input_type)ÚrequestrA   Úlogging_objÚLiteLLMLoggingObjÚerrorr†   c                óà   — |rd|› �nd}t        j                  d|t        | dd«      t        | dd«      ||rt        |dd«      nd|rt        |dd«      nd|¬	«       i }|j                  |«       |S )
zPAllow the request to proceed when the guardrail is unreachable (fail-open mode).z http_status_code=Ú zžDeepKeep guardrail unreachable (fail-open). Proceeding without guardrail.%s guardrail_name=%s api_base=%s input_type=%s litellm_call_id=%s litellm_trace_id=%sr3   NrL   Úlitellm_call_idÚlitellm_trace_id)Úexc_info)r   ÚcriticalÚgetattrrƒ   )r?   r‡   rˆ   rŠ   rŒ   r†   Ústatus_suffixÚreturn_inputss           r0   Ú_fail_open_passthroughz(DeepKeepGuardrail._fail_open_passthroughä   s�   € ñ K[Ð!3Ð4DÐ3EÑFÐ`bˆÜ×%Ñ%ðaàÜ�DÐ*¨DÓ1Ü�D˜* dÓ+ØÙ=HŒG�KÐ!2°DÔ9ÈdÙ>IŒG�KÐ!3°TÔ:ÈtØõ
	
ð ;=ˆØ×Ñ˜VÔ$ØÐr/   Úis_unreachablec                 óì   — |rF| j                   dk(  r7t        t        |dd«      dd«      } | j                  d	||||dœ|rd|i¤ŽS i ¤ŽS t        j                  dt        |«      «       t        d|› �«      ‚)
zEHandle errors from the DeepKeep API with fail-open/fail-closed logic.rP   rA   NÚstatus_code)r‡   rˆ   rŠ   rŒ   r†   z DeepKeep guardrail API error: %szDeepKeep guardrail API failed: r.   )rN   r“   r–   r   rŒ   r,   rH   )r?   rŒ   r‡   rˆ   rŠ   r—   r†   s          r0   Ú_handle_guardrail_request_errorz1DeepKeepGuardrail._handle_guardrail_request_errorþ   s¤   € ñ ˜d×7Ñ7¸;ÒFÜ29¼'À%ÈÐUYÓ:ZÐ\iÐkoÓ2pÐØ.�4×.Ñ.ð ØØ%Ø'Øñ	ñ
 >NÐ&Ð(8Ð9ñð ð
 TVñð ô 	×"Ñ"Ð#EÄsÈ5ÃzÔRÜ'Ð*IÈ%ÈÐ(QÓRÐRr/   Úresponse_jsonr#   r$   zlist[str] | Noner%   z$list[ChatCompletionToolParam] | Noner&   zNlist[ChatCompletionToolCallChunk] | list[ChatCompletionMessageToolCall] | Noner'   zlist[AllMessageValues] | Nonec                 óP  — t        |¬«      }| j                  d«      }|�||d<   | j                  d«      }|�||d<   n|�||d<   | j                  d«      }	|	�|	|d<   n|�||d<   | j                  d«      }
|
�|
|d<   n|�||d<   | j                  d«      }|�||d<   |S |�||d<   |S )at  Merge original inputs with any guardrail-modified values from the API response.

        Presence is checked with ``is not None`` (not truthiness) so that an
        intentional empty-list replacement such as ``texts: []`` or
        ``tool_calls: []`` is honoured and forwarded downstream rather than
        silently discarded in favour of the original content.
        )r#   r#   r$   r%   r&   r'   )r   r_   )r›   r#   r$   r%   r&   r'   r•   Útexts_overrideÚimages_overrideÚtools_overrideÚtool_calls_overrideÚstructured_messages_overrides               r0   Ú_build_return_inputsz&DeepKeepGuardrail._build_return_inputs  s  € ô"  9¸uÔEˆØ -× 1Ñ 1°'Ó :ˆØÐ%Ø%3ˆM˜'Ñ"Ø!.×!2Ñ!2°8Ó!<ˆØÐ&Ø&5ˆM˜(Ò#ØÐØ&,ˆM˜(Ñ#Ø -× 1Ñ 1°'Ó :ˆØÐ%Ø%3ˆM˜'Ò"ØÐØ%*ˆM˜'Ñ"Ø%2×%6Ñ%6°|Ó%DÐØÐ*Ø*=ˆM˜,Ò'ØÐ#Ø*4ˆM˜,Ñ'Ø.;×.?Ñ.?Ð@UÓ.VÐ$Ø'Ð3Ø3OˆMÐ/Ñ0ð Ðð !Ð,Ø3FˆMÐ/Ñ0ØÐr/   c              ƒ   óâ  K  — t        j                  d|«       |j                  dg «      }|j                  d«      }|j                  d«      }|j                  d«      }|j                  d«      }	|j                  d«      }
|€i }|j                  d	«      xs i }d
| j                  i}| j	                  |«      }|r9|j                  |j                  «       D ��ci c]  \  }}|d
k7  sŒ||“Œ c}}«       | j                  |«      }|r|j                  nd|r|j                  nd||t        ||||	|||
dœ}| j                  «       }	 | j                  j                  | j                  ||¬«      ƒ d{  –—† }|j                  «        t!        |«      }t        j                  d|«       |j                  dd«      }|dk(  r>|j                  d«      xs d}t        j"                  d|«       t%        t&        |dd¬«      ‚| j)                  |||||	|¬«      S c c}}w 7 Œ§# t$        $ r ‚ t*        $ r}| j-                  ||||«      cY d}~S d}~wt.        j0                  $ r<}t3        t3        |dd«      dd«      }|dv }| j-                  |||||¬«      cY d}~S d}~wt.        j4                  $ r}| j-                  ||||«      cY d}~S d}~wt6        $ r }| j-                  ||||d¬«      cY d}~S d}~ww xY w­w)a'  
        Apply the DeepKeep AI Firewall guardrail to the given inputs.

        This is the main method called by the LiteLLM framework for guardrail evaluation.

        Args:
            inputs: Dictionary containing texts, images, tools, tool_calls, structured_messages.
            request_data: Request data dictionary containing metadata.
            input_type: Whether this is a "request" (pre-call) or "response" (post-call) guardrail.
            logging_obj: Optional logging object for tracking the guardrail execution.

        Returns:
            GenericGuardrailAPIInputs with original or modified content.

        Raises:
            GuardrailRaisedException: If the guardrail blocks the request.
            DeepKeepGuardrailAPIError: If the API call fails (in fail-closed mode).
        z5DeepKeep guardrail: applying guardrail, input_type=%sr#   r$   r%   r'   r&   ÚmodelNÚbodyrM   )r�   r�   r#   rp   Úlitellm_versionr$   r%   r'   r&   Ú#additional_provider_specific_paramsrˆ   r¤   )Úurlr@   r„   zDeepKeep guardrail response: %sr!   ÚNONEÚBLOCKEDr"   zContent violates policyz&DeepKeep guardrail blocked request: %sFT)r3   ÚmessageÚ should_wrap_with_default_messageÚblocked_content)r›   r#   r$   r%   r&   r'   rA   r™   )iö  i÷  iø  )r—   )r   rl   r_   rM   Ú)get_guardrail_dynamic_request_body_paramsrƒ   Úitemsr�   r�   r�   r¦   r…   r\   ÚpostrL   Úraise_for_statusrC   rd   r   r   r¢   r   rš   ÚhttpxÚHTTPStatusErrorr“   ÚRequestErrorÚ	Exception)r?   r‡   rp   rˆ   rŠ   r#   r$   r%   r'   r&   r¤   Úrequest_bodyÚadditional_paramsÚdynamic_paramsÚkÚvÚuser_metadataÚguardrail_requestr„   rA   r›   r!   Úerror_messageÚer™   r—   s                             r0   Úapply_guardrailz!DeepKeepGuardrail.apply_guardrail>  s  è ø€ ô4 	×"Ñ"Ð#ZÐ\fÔgà—z‘z '¨2Ó.ˆØŸ
™
 8Ó,ˆØ—z‘z 'Ó*ˆØ%+§Z¡ZÐ0EÓ%FÐØ"ŸJ™J |Ó4ˆ
Ø—z‘z 'Ó*ˆàÐØˆLà*×.Ñ.¨vÓ6Ò<¸"ˆð 8EÀd×FVÑFVÐ6WÐØ $× NÑ NÈ|Ó \ˆÙØ×$Ñ$°~×7KÑ7KÓ7M×%d©t¨q°!ÐQRÐVcÓQc a¨¡dÓ%dÔeð  $×BÑBÀ<ÓPˆñ @K × ;Ò ;ÐPTÙAL ×!=Ò!=ÐRVØØ)Ü.ØØØ#6Ø$Ø3DØ$Øñ7
Ðð ×4Ñ4Ó6ˆð.	rØ$(×$6Ñ$6×$;Ñ$;Ø—M‘MØ&Øð %<ó %÷ ˆHð ×%Ñ%Ô'Ü#:¸8Ó#DˆMä ×&Ñ&Ð'HÈ-ÔXà)×-Ñ-¨h¸Ó?ˆFà˜Ò"Ø'4×'8Ñ'8Ð9IÓ'JÒ'gÐNg�Ü$×,Ñ,Ð-UÐWdÔeÜ.Ü#1Ø)Ø5:Ø$(ô	ð ð ×,Ñ,Ø+ØØØØ%Ø$7ð -ó ð ùó_ &eð0ùô@ (ò 	ØÜò 	\Ø×7Ñ7¸¸6À:È{Ó[Õ[ûÜ×$Ñ$ò 	Ü!(¬°°JÀÓ)EÀ}ÐVZÓ![ˆKØ$/°?Ð$BˆNØ×7Ñ7Ø�6˜: {À>ð 8ó õ ûô ×!Ñ!ò 	\Ø×7Ñ7¸¸6À:È{Ó[Õ[ûÜò 	rØ×7Ñ7¸¸6À:È{ÐkpÐ7ÓqÕqûð	rüs¤   ‚CK/ÃH
Ã&H
Ã+AK/Å+H Å/HÅ0B H ÈK/ÈH ÈK,È+IÈ>K,È?K/ÉK,É1JÊK,ÊK/ÊK,Ê'K Ê:K,Ê;K/Ë K,ËK'Ë!K,Ë"K/Ë'K,Ë,K/c                  ó   — ddl m}  | S )Nr   ©ÚDeepKeepGuardrailConfigModel)Ú7litellm.types.proxy.guardrails.guardrail_hooks.deepkeeprÂ   rÁ   s    r0   Úget_config_modelz"DeepKeepGuardrail.get_config_model±  s   € õ	
ð ,Ð+r/   )NNNrO   N)Tr>   )r(   r)   r*   r+   r,   r   r   Úlistr   rk   r5   rf   r8   r�   r…   r   r   rµ   Úintr–   Úboolrš   Ústaticmethodr    r¢   r   r¿   re   rÄ   Ú__classcell__)ro   s   @r0   rJ   rJ   U   sN  ø„ ñð, #Ø#Ø"&ØDQØ>BñE
à�t‘ðE
ð ˜‘*ðE
ð ˜4‘Zð	E
ð
 &Ð&@ÑAðE
ð ˜s C˜xÑ(¨4°©9Ñ4°tÑ;ðE
ð õE
ðN'Ð;Rð 'ÐW[Ð\_ÐagÐ\gÑWhó 'ðR¨¨S°#¨X©ó ð" (,òð *ðð Ð1Ñ2ð	ð
 Ð1Ñ2ðð ðð  ™*ðð 
#óð@  $ñSàðSð *ðSð Ð1Ñ2ð	Sð
 Ð1Ñ2ðSð ðSð 
#óSð* ð(à/ð(ð �C‰yð(ð #ð	(ð
 6ð(ð eð(ð =ð(ð 
#ò(ó ð(ðT ð 6:ñprà)ðprð ðprð Ð1Ñ2ð	prð
 Ð1Ñ2ðprð 
#òpró ðprðd ð,˜d T™kò ,ó ô,r/   rJ   )5r]   Úcollections.abcr   Útypingr   r   r   r   r   r	   r²   Útyping_extensionsr
   r   r   Úlitellm._loggingr   Úlitellm._versionr   r¦   Úlitellm.exceptionsr   r   Ú%litellm.integrations.custom_guardrailr   r   Ú&litellm.llms.custom_httpx.http_handlerr   r   Úlitellm.types.guardrailsr   Úlitellm.types.utilsr   Ú*litellm.litellm_core_utils.litellm_loggingr   r‹   Úlitellm.types.llms.openair   r   r   r   r   r-   r   r    r2   r5   r;   rC   rµ   rE   rH   rJ   r.   r/   r0   ú<module>rÖ      sØ   ðô 
Ý #ß I× Iã ß >Ñ >å 1Ý 7ß @÷÷õ 9Ý 9áÝW÷ñ õ
 Bà"€�Ó "ð 'TÐ ˜eÓ Sô	I˜yô 	Iô"˜iô "ô-˜i¨uõ -ô4˜Hô 4ðÐ&;ð Ð@Xó ôL iô LôK 	ô Kôb,˜õ b,r/   