o
    ưi(                     @   sV   d Z ddlmZmZmZmZmZ ddlmZ ddl	m
Z
mZmZmZ G dd dZdS )z
Policy Resolver - Resolves final guardrail list from policies.

Handles:
- Inheritance chain resolution (inherit with add/remove)
- Applying add/remove guardrails
- Evaluating model conditions
- Combining guardrails from multiple matching policies
    )DictListOptionalSetTuple)verbose_proxy_logger)GuardrailPipelinePolicyPolicyMatchContextResolvedPolicyc                   @   sR  e Zd ZdZe	ddedeeef dee	e  de
e fddZe	ddedeeef d	ee defd
dZe		dd	edeeeef  dee
e  de
e fddZe		dd	edeeeef  dee
e  de
eeef  fddZede
eeef  de	e fddZe		ddeeeef  d	ee deeef fddZdS )PolicyResolverz
    Resolves the final list of guardrails from policies.

    Handles:
    - Inheritance chains with add/remove operations
    - Model-based conditions
    Npolicy_namepoliciesvisitedreturnc                 C   st   |du rt  }| |v rtd|  d g S || }|du r!g S ||  |jr7tj|j||d}|| g S | gS )aX  
        Get the inheritance chain for a policy (from root to policy).

        Args:
            policy_name: Name of the policy
            policies: Dictionary of all policies
            visited: Set of visited policies (for cycle detection)

        Returns:
            List of policy names from root ancestor to the given policy
        Nz*Circular inheritance detected for policy '')r   r   r   )setr   warninggetaddinheritr   resolve_inheritance_chain)r   r   r   policyZparent_chain r   b/home/app/Keep/.python/lib/python3.10/site-packages/litellm/proxy/policy_engine/policy_resolver.pyr      s"   



z(PolicyResolver.resolve_inheritance_chaincontextc           	      C   s   ddl m} tj| |d}t }|D ]A}||}|du rq|dur9|jdur9|j|j|ds9t	d| d q|j
 D ]}|| q>|j
 D ]}|| qKqt| t||dS )	a  
        Resolve the final guardrails for a single policy, including inheritance.

        This method:
        1. Resolves the inheritance chain
        2. Applies add/remove from each policy in the chain
        3. Evaluates model conditions (if context provided)

        Args:
            policy_name: Name of the policy to resolve
            policies: Dictionary of all policies
            context: Optional request context for evaluating conditions

        Returns:
            ResolvedPolicy with final guardrails list
        r   )ConditionEvaluator)r   r   N)	conditionr   Policy 'z.' condition did not match, skipping guardrails)r   
guardrailsinheritance_chain)Z/litellm.proxy.policy_engine.condition_evaluatorr   r   r   r   r   r   evaluater   debugr   Zget_addr   Z
get_removediscardr   list)	r   r   r   r   r    r   Zchain_policy_namer   	guardrailr   r   r   resolve_policy_guardrailsD   s8   

z(PolicyResolver.resolve_policy_guardrailspolicy_namesc                 C   s   ddl m} ddlm} |du r| }| sg S | }|dur#|n|j| d}|s>td| j	 d| j
 d| j  g S t }|D ]}tj||| d	}	||	j td
| d|	j  qCt|}
td|
  |
S )ax  
        Resolve the final list of guardrails for a request context.

        This:
        1. Finds all policies that match the context via policy_attachments (or policy_names if provided)
        2. Resolves each policy's guardrails (including inheritance)
        3. Evaluates model conditions
        4. Combines all guardrails (union)

        Args:
            context: The request context
            policies: Dictionary of all policies (if None, uses global registry)
            policy_names: If provided, use this list instead of attachment matching

        Returns:
            List of guardrail names to apply
        r   PolicyMatcherget_policy_registryNr   z&No policies match context: team_alias=z, key_alias=z, model=r   r   r   r   z' contributes guardrails: zFinal guardrails for context: )*litellm.proxy.policy_engine.policy_matcherr)   +litellm.proxy.policy_engine.policy_registryr+   is_initializedget_all_policiesget_matching_policiesr   r"   Z
team_aliasZ	key_aliasmodelr   r   r&   updater   r$   )r   r   r'   r)   r+   registrymatching_policy_namesZall_guardrailsr   resolvedresultr   r   r   resolve_guardrails_for_context   sH   

z-PolicyResolver.resolve_guardrails_for_contextc           
      C   s   ddl m} ddlm} |du r| }| sg S | }|dur#|n|j| d}|s-g S g }|D ])}||}	|	du r=q1|	jdurZ|	||	jf t
d| dt|	jj d q1|S )	aJ  
        Resolve pipelines from matching policies for a request context.

        Returns (policy_name, pipeline) tuples for policies that have pipelines.
        Guardrails managed by pipelines should be excluded from the flat
        guardrails list to avoid double execution.

        Args:
            context: The request context
            policies: Dictionary of all policies (if None, uses global registry)
            policy_names: If provided, use this list instead of attachment matching

        Returns:
            List of (policy_name, GuardrailPipeline) tuples
        r   r(   r*   Nr,   r   z' has pipeline with z steps)r.   r)   r/   r+   r0   r1   r2   r   pipelineappendr   r"   lensteps)
r   r   r'   r)   r+   r5   r6   	pipelinesr   r   r   r   r   resolve_pipelines_for_context   s6   



z,PolicyResolver.resolve_pipelines_for_contextr>   c                 C   s0   t  }| D ]\}}|jD ]}||j qq|S )z
        Get the set of guardrail names managed by pipelines.

        These guardrails should be excluded from normal independent execution.
        )r   r=   r   r%   )r>   ZmanagedZ_policy_namer:   stepr   r   r   get_pipeline_managed_guardrails   s   	
z.PolicyResolver.get_pipeline_managed_guardrailsc                 C   sT   ddl m} | du r| }| si S | } i }| D ]}tj|| |d||< q|S )a  
        Resolve all policies and return their final guardrails.

        Useful for debugging and displaying policy configurations.

        Args:
            policies: Dictionary of all policies (if None, uses global registry)
            context: Optional context for evaluating conditions

        Returns:
            Dictionary mapping policy names to ResolvedPolicy objects
        r   r*   Nr-   )r/   r+   r0   r1   r   r&   )r   r   r+   r5   r7   r   r   r   r   get_all_resolved_policies  s   z(PolicyResolver.get_all_resolved_policies)N)NN)__name__
__module____qualname____doc__staticmethodstrr   r	   r   r   r   r   r
   r   r&   r9   r   r   r?   rA   rB   r   r   r   r   r      s    

'
>
C
4
r   N)rF   typingr   r   r   r   r   Zlitellm._loggingr   Z!litellm.types.proxy.policy_enginer   r	   r
   r   r   r   r   r   r   <module>   s
    
