Ë
    uPêjó*  ã                   óà   — d Z ddlZddlmZmZmZ ddl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  G d„ d«      Zdededefd„Zdedefd„Zy# e$ r dZY Œ&w xY w)zâ
Pipeline Executor - Executes guardrail pipelines with conditional step logic.

Runs guardrails sequentially per pipeline step definitions, handling
pass/fail actions (allow, block, next, modify_response) and data forwarding.
é    N)ÚAnyÚFinalÚLiteral)Úverbose_proxy_logger)ÚCustomGuardrailÚModifyResponseException)ÚCustomLogger)Úindependent_snapshot)ÚUnifiedLLMGuardrails)ÚPipelineExecutionResultÚPipelineStepÚPipelineStepResult)ÚHTTPExceptionc                   óÐ   — e Zd ZdZe	 ddee   dedede	deded	edz  d
e
fd„«       Ze	 ddededede	ded	edz  d
eed   edz  edz  edz  f   fd„«       Zeded
edz  fd„«       Zy)ÚPipelineExecutorzBExecutes guardrail pipelines with ordered, conditional step logic.NÚstepsÚmodeÚdataÚuser_api_key_dictÚ	call_typeÚpolicy_nameÚraw_request_snapshotÚreturnc              ƒ   ó
  K  — g }|j                  «       }d|v r|d   j                  «       |d<   t        | «      D �](  \  }	}
t        j                  «       }t        j                  |
|||||¬«      ƒ d{  –—† \  }}}}t        j                  «       |z
  }t        |
|«      }t        |
j                  ||||t        |d«      ¬«      }|j                  |«       t        j                  d||	|
j                  ||«       |
j                  r|�i |¥|¥}|dk(  rt        d|||k7  r|nd¬«      c S |d	k(  rt        d	|||¬
«      c S |dk(  s�Œt        d||
j                  xs |¬«      c S  t        d|||k7  r|¬«      S d¬«      S 7 �Œ­w)an  
        Execute pipeline steps sequentially with conditional actions.

        Args:
            steps: Ordered list of pipeline steps
            mode: Event hook mode (pre_call, post_call)
            data: Request data dict
            user_api_key_dict: User API key auth
            call_type: Type of call (completion, etc.)
            policy_name: Name of the owning policy (for logging)
            raw_request_snapshot: pristine pre-pipeline, pre-guardrail request
                (taken by the caller before any guardrail or pipeline ran), so a
                step whose guardrail opted into ``scan_raw_request`` evaluates
                the original request instead of whatever an earlier
                ``pass_data`` step in this same pipeline already rewrote.

        Returns:
            PipelineExecutionResult with terminal action and step results
        Úmetadata)Ústepr   r   r   r   r   Né   )Úguardrail_nameÚoutcomeÚaction_takenÚmodified_dataÚerror_detailÚduration_secondsz:Pipeline '%s' step %s: guardrail=%s, outcome=%s, action=%sÚallow)Úterminal_actionÚstep_resultsr!   Úblock)r%   r&   Úerror_messageÚoriginal_exceptionÚmodify_response)r%   r&   Úmodify_response_message)ÚcopyÚ	enumerateÚtimeÚperf_counterr   Ú	_run_stepÚ_pipeline_action_for_outcomer   Ú	guardrailÚroundÚappendr   ÚdebugÚ	pass_datar   r+   )r   r   r   r   r   r   r   r&   Úworking_dataÚir   Ú
start_timer   r!   r"   r)   ÚdurationÚactionÚstep_results                      úr/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/policy_engine/pipeline_executor.pyÚexecute_stepszPipelineExecutor.execute_steps%   sæ  è ø€ ð: 9;ˆØ—y‘y“{ˆØ˜Ñ%Ø'3°JÑ'?×'DÑ'DÓ'FˆL˜Ñ$ä  Ó'ó A	‰GˆAˆtÜ×*Ñ*Ó,ˆJô '×0Ñ0ØØØ!Ø"3Ø#Ø%9ð 1ó ÷ ñØØØØ"ô ×(Ñ(Ó*¨ZÑ7ˆHä1°$¸Ó@ˆFä,Ø#Ÿ~™~ØØ#Ø+Ø)Ü!& x°Ó!3ôˆKð ×Ñ Ô,ä ×&Ñ&ØLØØØ—‘ØØôð �~Š~ -Ð";Ø@ ,Ð@°-Ð@�ð ˜Ò Ü.Ø$+Ø!-Ø2>À$Ò2F¡,ÈDôò ð ˜Ò Ü.Ø$+Ø!-Ø".Ø'9ô	ò ð Ð*Ô*Ü.Ø$5Ø!-Ø,0×,HÑ,HÒ,XÈLôò ð{A	ôL 'Ø#Ø%Ø*6¸$Ò*>˜,ô
ð 	
ð EIô
ð 	
ð}ûs   ‚A1FÁ3F Á4CFÅ:Fr   )ÚpassÚfailÚerrorc              ƒ   óF  K  — t         j                  | j                  «      }|€4t        j                  d| j                  «       ddd| j                  › d�dfS 	 d|vri |d<   | j                  g|d   d<   |j
                  }|r|�t        |«      n|}||ur | j                  g|j                  di «      d<   |}	dt        |«      j                  v xr |j                   }
|
r||d	<   t        «       }	|d
k(  r`|	j                  |d||¬«      ƒ d{  –—† }t        |t        «      rm|j                  |«       t        |t         «      rL|j                  |«       n:|dk(  r,|	j#                  |||j%                  d«      ¬«      ƒ d{  –—† }n	ddd|› �dfS d}|�t        |t         «      r|s|}d|ddfS 7 ŒŸ7 Œ.# t&        $ re}t        j(                  |«      rt+        |«      }dd||fcY d}~S t        j,                  d| j                  |«       ddt/        |«      |fcY d}~S d}~ww xY w­w)a.  
        Run a single pipeline step's guardrail.

        Returns:
            Tuple of (outcome, modified_data, error_detail, original_exception):
            - outcome: "pass", "fail", or "error"
            - modified_data: dict if guardrail returned modified data, else None
            - error_detail: error message string if fail/error, else None
            - original_exception: the exception the guardrail raised, so the
              pipeline can re-raise it verbatim and match the direct-attachment
              response/trace, else None
        Nz/Pipeline: guardrail '%s' not found in callbacksrA   zGuardrail 'z' not foundr   Ú
guardrailsÚapply_guardrailÚguardrail_to_applyÚpre_call)r   Úcacher   r   Ú	post_callÚresponse)r   r   rI   zUnsupported pipeline mode: r?   r@   z2Pipeline: unexpected error from guardrail '%s': %s)r   Úfind_guardrail_callbackr2   r   ÚwarningÚscan_raw_requestr
   Ú
setdefaultÚtypeÚ__dict__Úuse_native_lifecycle_hooksr   Úasync_pre_call_hookÚ
isinstancer   Úmark_pre_call_hook_ranÚdictÚasync_post_call_success_hookÚgetÚ	ExceptionÚ_is_guardrail_interventionÚ_extract_error_messagerA   Ústr)r   r   r   r   r   r   ÚcallbackÚscans_raw_requestÚ
hook_inputÚtargetÚuse_unifiedrI   r!   ÚeÚ	error_msgs                  r=   r0   zPipelineExecutor._run_step“   si  è ø€ ô4 +×BÑBÀ4Ç>Á>ÓRˆØÐÜ ×(Ñ(Ð)ZÐ\`×\jÑ\jÔkØ˜T [°·±Ð0@ÀÐ#LÈdÐSÐSð@	2à Ñ%Ø#%��ZÑ Ø.2¯n©nÐ-=ˆD�Ñ˜\Ñ*ð (0×'@Ñ'@Ðñ %Ð)=Ð)Iô %Ð%9Ô:àð ð
  Ñ%ØGKÇ~Á~ÐFV�
×%Ñ% j°"Ó5°lÑCð $,ˆFà!¤T¨(£^×%<Ñ%<Ð<ÒhÀX×EhÑEhÐAhð ñ Ø3;�
Ð/Ñ0Ü-Ó/�à�zÒ!Ø!'×!;Ñ!;Ø&7ØØ#Ø'ð	 "<ó "÷ �ô ˜h¬Ô8Ø×3Ñ3°DÔ9Ü! (¬DÔ1Ø ×7Ñ7¸ÕAØ˜Ò$Ø!'×!DÑ!DØ&7ØØ!ŸX™X jÓ1ð "Eó "÷ ‘ð   Ð)DÀTÀFÐ'KÈTÐRÐRð !ˆMØÐ#¬
°8¼TÔ(BÑK\Ø (�Ø˜M¨4°Ð6Ð6ð7øðùô$ ò 	2Ü×9Ñ9¸!Ô<Ü#9¸!Ó#<�	Ø  i°Ð3Õ3ä$×*Ñ*Ð+_Ðae×aoÑaoÐqrÔsØ ¤s¨1£v¨qÐ1Õ1ûð	2üsz   ‚AH!ÁB3F0 ÄF,ÄA2F0 Å?F.Æ F0 ÆH!ÆF0 Æ+H!Æ,F0 Æ.F0 Æ0	HÆ9%HÇHÇH!Ç$/HÈHÈH!ÈHÈH!r   c                 óv   — t         j                  D ]&  }t        |t        «      sŒ|j                  | k(  sŒ$|c S  y)zILook up an initialized guardrail callback by name from litellm.callbacks.N)ÚlitellmÚ	callbacksrR   r   r   )r   r[   s     r=   rJ   z(PipelineExecutor.find_guardrail_callbackô   s;   € ô  ×)Ñ)ò 	$ˆHÜ˜(¤OÕ4Ø×*Ñ*¨nÓ<Ø#’Oð	$ð ó    )N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstaticmethodÚlistr   rZ   rT   r   r   r>   Útupler   rW   r0   r   rJ   © re   r=   r   r   "   s5  „ ÙLàð -1ñk
Ø�LÑ!ðk
àðk
ð ðk
ð ð	k
ð
 ðk
ð ðk
ð # T™kðk
ð 
!òk
ó ðk
ðZ ð -1ñ^2Øð^2àð^2ð ð^2ð ð	^2ð
 ð^2ð # T™kð^2ð 
ØÐ'Ñ(Øˆt‰Øˆd‰
Ø�DÑð	ñ
ò^2ó ð^2ð@ ð°ð ¸È$Ñ8Nò ó ñre   r   r   r   r   c                 óŽ   — |dk(  r| j                   S |dk(  r| j                  S | j                  �| j                  S | j                  S )zË
    Map pipeline step outcome to the configured action.

    - pass -> on_pass
    - fail -> on_fail (content/policy intervention)
    - error -> on_error if set, else on_fail (backward compatible)
    r?   r@   )Úon_passÚon_failÚon_error)r   r   s     r=   r1   r1   þ   sF   € ð �&ÒØ�|‰|ÐØ�&ÒØ�|‰|ÐØ‡}�}Ð Ø�}‰}ÐØ�<‰<Ðre   r`   c                 ó®   — t        | t        «      rt        | «      S t        �*t        | t        «      rt	        | dd«      }|rt        |«      S t        | «      S )zBExtract a human-readable error message from a guardrail exception.NÚdetail)rR   r   rZ   r   Úgetattr)r`   rs   s     r=   rY   rY     sI   € ä�!Ô,Ô-Ü�1‹vˆÜÐ ¤Z°´=Ô%AÜ  8¨TÓ2ˆÙÜ�v“;ÐÜˆq‹6€Mre   )ri   r.   Útypingr   r   r   rc   Úlitellm._loggingr   Ú%litellm.integrations.custom_guardrailr   r   Ú"litellm.integrations.custom_loggerr	   Ú'litellm.litellm_core_utils.core_helpersr
   ÚLlitellm.proxy.guardrails.guardrail_hooks.unified_guardrail.unified_guardrailr   Ú0litellm.types.proxy.policy_engine.pipeline_typesr   r   r   Úfastapi.exceptionsr   ÚImportErrorr   rZ   r1   rW   rY   rm   re   r=   ú<module>r~      s�   ðñó ß &Ñ &ã Ý 1÷õ <Ý Hõ÷ñ ðÝ0÷
Yñ Yðx |ð ¸cð Àcó ð"˜ið ¨Cô øðc ò Ø‚Mðús   Á A# Á#A-Á,A-