Ë
    uPêj¿¤  ã                   óž  — U d Z ddlZddlmZmZ ddlmZmZ ddlmZm	Z	m
Z
mZmZ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mZmZmZmZmZmZmZm Z m!Z! erdd
l"m#Z# dZ$e
e%d<    G d„ de«      Z& G d„ ded¬«      Z' G d„ de«      Z( G d„ de«      Z) G d„ de«      Z*ddde*fd„Z+d$d„Z,de(defd„Z- G d „ d!«      Z.da/e.dz  e%d"<   de.fd#„Z0y)%zß
Policy Registry - In-memory storage for policies.

Handles storing, retrieving, and managing policies.

Policies define WHAT guardrails to apply. WHERE they apply is defined
by policy_attachments (see AttachmentRegistry).
é    N)ÚMappingÚSequence)ÚdatetimeÚtimezone)	ÚTYPE_CHECKINGÚAnyÚFinalÚLiteralÚOptionalÚProtocolÚ	TypedDictÚUnionÚcast)Úverbose_proxy_logger)ÚTableActions)ÚPolicyRepository)
ÚGuardrailPipelineÚPipelineStepÚPolicyÚPolicyConditionÚPolicyCreateRequestÚPolicyDBResponseÚPolicyGuardrailsÚPolicyUpdateRequestÚPolicyVersionCompareResponseÚPolicyVersionListResponse)ÚPrismaClientÚpolicy_ÚPOLICY_VERSION_ID_PREFIXc                   ó   — e Zd ZU eed<   y)Ú_RawPipelineStepÚ	guardrailN)Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__© ó    úp/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/policy_engine/policy_registry.pyr!   r!   0   s   … Ø„Nr)   r!   c                   ó2   — e Zd ZU eed<   eeedf      ed<   y)Ú_RawPipelineConfigÚmoder!   ÚstepsN)r#   r$   r%   r&   r'   r   r   r   r(   r)   r*   r,   r,   4   s   … Ø
ƒIØ�E˜,Ð(:Ð:Ñ;Ñ<Ô<r)   r,   F)Útotalc                   ó$  — e Zd ZU eed<   eed<   eed<   eed<   edz  ed<   eed<   edz  ed<   edz  ed	<   edz  ed
<   edz  ed<   ee   dz  ed<   ee   dz  ed<   e	ee
f   dz  ed<   e	ee
f   dz  ed<   eed<   eed<   edz  ed<   edz  ed<   y)Ú
_PolicyRowÚ	policy_idÚpolicy_nameÚversion_numberÚversion_statusNÚparent_version_idÚ	is_latestÚpublished_atÚproduction_atÚinheritÚdescriptionÚguardrails_addÚguardrails_removeÚ	conditionÚpipelineÚ
created_atÚ
updated_atÚ
created_byÚ
updated_by)r#   r$   r%   r&   r'   ÚintÚboolr   ÚlistÚdictÚobjectr(   r)   r*   r1   r1   9   s¶   … ØƒNØÓØÓØÓØ˜T‘zÓ!ØƒOØ˜T‘/Ó!Ø˜d‘?Ó"Ø�4‰ZÓØ�t‘ÓØ˜‘I Ñ$Ó$Ø˜C‘y 4Ñ'Ó'Ø�C˜�KÑ  4Ñ'Ó'Ø�3˜�;Ñ $Ñ&Ó&ØÓØÓØ�d‘
ÓØ�d‘
Ôr)   r1   c                   ó"  — e Zd Zedefd„«       Zedefd„«       Zedefd„«       Zededz  fd„«       Z	ededz  fd„«       Z
edee   dz  fd„«       Zedee   dz  fd	„«       Zedeeef   ez  dz  fd
„«       Zedeeef   ez  dz  fd„«       Zy)Ú_PolicyVersionSourceRowÚreturnc                  ó   — y ©Nr(   ©Úselfs    r*   r2   z!_PolicyVersionSourceRow.policy_idO   s   € Ø #r)   c                  ó   — y rM   r(   rN   s    r*   r3   z#_PolicyVersionSourceRow.policy_nameR   s   € Ø"%r)   c                  ó   — y rM   r(   rN   s    r*   r4   z&_PolicyVersionSourceRow.version_numberU   ó   € Ø%(r)   Nc                  ó   — y rM   r(   rN   s    r*   r:   z_PolicyVersionSourceRow.inheritX   rR   r)   c                  ó   — y rM   r(   rN   s    r*   r;   z#_PolicyVersionSourceRow.description[   s   € Ø),r)   c                  ó   — y rM   r(   rN   s    r*   r<   z&_PolicyVersionSourceRow.guardrails_add^   s   € Ø69r)   c                  ó   — y rM   r(   rN   s    r*   r=   z)_PolicyVersionSourceRow.guardrails_removea   s   € Ø9<r)   c                  ó   — y rM   r(   rN   s    r*   r>   z!_PolicyVersionSourceRow.conditiond   s   € Ø>Ar)   c                  ó   — y rM   r(   rN   s    r*   r?   z _PolicyVersionSourceRow.pipelineg   s   € Ø=@r)   )r#   r$   r%   Úpropertyr&   r2   r3   rD   r4   r:   r;   r   r<   r=   r   rH   r>   r?   r(   r)   r*   rJ   rJ   N   sí   „ ØØ#˜3Ò#ó Ø#àØ%˜SÒ%ó Ø%àØ( Ò(ó Ø(àØ(˜˜t™Ò(ó Ø(àØ,˜S 4™ZÒ,ó Ø,àØ9 ¨¡°Ñ 4Ò9ó Ø9àØ< 8¨C¡=°4Ñ#7Ò<ó Ø<àØA˜7 3¨ ;Ñ/°#Ñ5¸Ñ<ÒAó ØAàØ@˜' # v +Ñ.°Ñ4°tÑ;Ò@ó Ù@r)   rJ   c                   ó  — e Zd Zdeeef   defd„Zdeeef   dedz  fd„Z	 	 ddeeef   dz  deeef   dz  de	e   fd„Z
deeef   deeef   defd	„Zdeeef   deeef   defd
„Zdeeef   dedz  fd„Zdeeef   defd„Zy)Ú_PolicyTableClientÚdatarK   c              ƒ   ó   K  — y ­wrM   r(   )rO   r\   s     r*   Úcreatez_PolicyTableClient.createl   ó   è ø� ùó   ‚ÚwhereNc              ƒ   ó   K  — y ­wrM   r(   ©rO   ra   s     r*   Úfind_uniquez_PolicyTableClient.find_uniquen   r_   r`   Úorderc              ƒ   ó   K  — y ­wrM   r(   )rO   ra   re   s      r*   Ú	find_manyz_PolicyTableClient.find_manyp   s   è ø€ ð  #ùr`   c              ƒ   ó   K  — y ­wrM   r(   ©rO   ra   r\   s      r*   Úupdatez_PolicyTableClient.updatev   r_   r`   c              ƒ   ó   K  — y ­wrM   r(   ri   s      r*   Úupdate_manyz_PolicyTableClient.update_manyx   r_   r`   c              ƒ   ó   K  — y ­wrM   r(   rc   s     r*   Údeletez_PolicyTableClient.deletez   r_   r`   c              ƒ   ó   K  — y ­wrM   r(   rc   s     r*   Údelete_manyz_PolicyTableClient.delete_many|   r_   r`   ©NN)r#   r$   r%   r   r&   rH   r1   r^   rd   r   rg   rj   rD   rl   rn   rp   r(   r)   r*   r[   r[   k   sü   „ ØI ¨¨f¨Ñ!5ÐI¸*ÓIàV w¨s°F¨{Ñ';ÐVÀ
ÈTÑ@QÓVð .2Ø*.ñ#à�s˜F�{Ñ# dÑ*ð#ð �s˜C�xÑ  4Ñ'ð#ð 
�*Ñ	ó	#ð g '¨#¨v¨+Ñ"6Ðf¸gÀcÈ6ÀkÑ>RÐfÐWaÓfàd w¨s°F¨{Ñ';ÐdÀ7È3ÐPVÈ;ÑCWÐdÐ\_ÓdàQ '¨#¨v¨+Ñ"6ÐQ¸:ÈÑ;LÓQàH w¨s°F¨{Ñ';ÐHÀÔHr)   r[   Úprisma_clientr   rK   c                 óD   — t        | «      j                  }t        d|«      S )Nr[   )r   Útabler   ©rr   rt   s     r*   Ú_policy_tablerv      s$   € Ü# MÓ2×8Ñ8€EÜØ˜eóð r)   c                 ó0   — t        | «      j                  }|S rM   )r   rt   ru   s     r*   Ú_policy_version_source_tablerx   †   s   € Ü:JÈ=Ó:Y×:_Ñ:_€EØ€Lr)   Úrowc           
      ó  — t        di d| j                  “d| j                  “dt        | dd«      “dt        | dd«      “dt        | dd«      “d	t        | d	d
«      “dt        | dd«      “dt        | dd«      “d| j                  “d| j
                  “d| j                  xs g “d| j                  xs g “d| j                  “d| j                  “d| j                  “d| j                  “d| j                  “d| j                  “ŽS )z=Build PolicyDBResponse from a Prisma LiteLLM_PolicyTable row.r2   r3   r4   é   r5   Ú
productionr6   Nr7   Tr8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   r(   )r   r2   r3   Úgetattrr:   r;   r<   r=   r>   r?   r@   rA   rB   rC   )ry   s    r*   Ú_row_to_policy_db_responser~   ‹   s8  € äò Ø—-’-ðà—O’Oðô ˜sÐ$4°aÔ8ðô ˜sÐ$4°lÔCð	ô
 " #Ð':¸DÔAðô ˜#˜{¨DÔ1ðô ˜S .°$Ô7ðô ˜c ?°DÔ9ðð —’ðð —O’Oðð ×)Ñ)Ò/¨Røðð ×/Ñ/Ò5°2øðð —-’-ðð —’ðð —>’>ðð  —>’>ð!ð" —>’>ð#ð$ —>’>ð%ð r)   c                   óÎ  — e Zd ZdZd„ Zdeeeeef   f   ddfd„Z	dedeee
f   defd	„Zed
ed   dedz  fd„«       Zdededz  fd„Zdeeef   fd„Zdee   fd„Zdedefd„Zdefd„Zd2d„Zdeded   dz  fd„Zdeeef   fd„Zd3dededed   ddfd„Zdedefd„Z	 d4dedddedz  defd„Z 	 d4dede!ddd edz  def
d!„Z"dedddeeef   fd"„Z#dedddedz  fd#„Z$dede%eef   dz  fd$„Z&	 d4ddd%edz  dee   fd&„Z'	 	 	 	 d5d'„Z(dedddee   fd(„Z)deddde*fd)„Z+	 	 d6deddd*edz  dedz  def
d+„Z,	 d4ded,eddd edz  def
d-„Z-d.ed/eddde.fd0„Z/dedddeeef   fd1„Z0y)7ÚPolicyRegistryaT  
    In-memory registry for storing and managing policies.

    This is a singleton that holds all loaded policies and provides
    methods to access them.

    Policies define WHAT guardrails to apply:
    - Base guardrails via guardrails.add/remove
    - Inheritance via inherit field
    - Conditional guardrails via condition.model
    c                 óJ   — i | _         i | _        i | _        i | _        d| _        y )NF)Ú	_policiesÚ_config_policiesÚ_sourcesÚ_policies_by_idÚ_initializedrN   s    r*   Ú__init__zPolicyRegistry.__init__°   s(   € Ø,.ˆŒØ68ˆÔØ?AˆŒØ>@ˆÔØ"'ˆÕr)   Úpolicies_configrK   Nc                 ó.  — i | _         i | _        i | _        i | _        |j	                  «       D ]=  \  }}	 | j                  ||«      }|| j                   |<   t        j                  d|«       Œ? t        | j                   «      | _        | j                   D �ci c]  }|d“Œ c}| _        d| _        t        j                  dt        | j                   «      «       y# t        $ r.}t        j                  d||«       t        d|› d|› �«      |‚d}~ww xY wc c}w )	zê
        Load policies from a configuration dictionary.

        Args:
            policies_config: Dictionary mapping policy names to policy definitions.
                            This is the raw config from the YAML file.
        zLoaded policy: %szError loading policy '%s': %szInvalid policy 'z': NÚconfigTzLoaded %s policies)r‚   rƒ   r„   r…   ÚitemsÚ_parse_policyr   ÚdebugÚ	ExceptionÚerrorÚ
ValueErrorrG   r†   ÚinfoÚlen)rO   rˆ   r3   Úpolicy_dataÚpolicyÚes         r*   Úload_policieszPolicyRegistry.load_policies·   s  € ð ˆŒØ "ˆÔØˆŒØ!ˆÔà(7×(=Ñ(=Ó(?ò 	PÑ$ˆK˜ðPØ×+Ñ+¨K¸ÓE�Ø.4�—‘˜{Ñ+Ü$×*Ñ*Ð+>ÀÕLð		Pô !% T§^¡^Ó 4ˆÔØBFÇ.Á.ÖQ°;˜ hÑ.ÒQˆŒØ ˆÔÜ×!Ñ!Ð"6¼¸D¿N¹NÓ8KÕLøô ò PÜ$×*Ñ*Ð+JÈKÐYZÔ[Ü Ð#3°K°=ÀÀAÀ3Ð!GÓHÈaÐOûðPüò
 Rs   ´7CÂ
DÃ	DÃ!)D
Ä
Dr3   r“   c                 óÂ  — |j                  di «      }t        |t        «      r,t        |j                  d«      |j                  d«      ¬«      }nt        |r|nd¬«      }d}|j                  d«      }|rt	        |j                  d«      ¬	«      }t
        j                  |j                  d
«      «      }t        |j                  d«      |j                  d«      |||¬«      S )zÝ
        Parse a policy from raw configuration data.

        Args:
            policy_name: Name of the policy
            policy_data: Raw policy configuration

        Returns:
            Parsed Policy object
        Ú
guardrailsÚaddÚremove©r™   rš   N)r™   r>   Úmodel)rœ   r?   r:   r;   ©r:   r;   r˜   r>   r?   )ÚgetÚ
isinstancerG   r   r   r€   Ú_parse_pipeliner   )rO   r3   r“   Úguardrails_datar˜   r>   Úcondition_datar?   s           r*   rŒ   zPolicyRegistry._parse_policyÒ   sË   € ð "-§¡°¸rÓ!BˆÜ�o¤tÔ,Ü)Ø#×'Ñ'¨Ó.Ø&×*Ñ*¨8Ó4ô‰Jô *Á©oÐVZÔ[ˆJð ˆ	Ø +§¡°Ó <ˆÙÜ'¨n×.@Ñ.@ÀÓ.IÔJˆIô )×8Ñ8¸¿¹ÈÓ9TÓUˆäØ—O‘O IÓ.Ø#Ÿ™¨Ó6Ø!ØØô
ð 	
r)   Úpipeline_datar,   c                 óÄ   — | €y| j                  dg «      }|D �cg c]  }t        |t        «      rt        di |¤Žn|‘Œ! }}t	        | j                  dd«      |¬«      S c c}w )z-Parse a pipeline configuration from raw data.Nr.   r-   Úpre_call)r-   r.   r(   )rž   rŸ   rG   r   r   )r£   Ú
steps_dataÚ	step_datar.   s       r*   r    zPolicyRegistry._parse_pipelineù   sq   € ð
 Ð ØàGT×GXÑGXÐY`ÐbdÓGeˆ
ØjtÖuÐ]f¬j¸ÄDÔ.I”Ñ* 	Ò*ÈyÑXÐuˆÐuä Ø×"Ñ" 6¨:Ó6Øô
ð 	
ùò vs   š$Ac                 ó8   — | j                   j                  |«      S )z³
        Get a policy by name.

        Args:
            policy_name: Name of the policy to retrieve

        Returns:
            Policy object if found, None otherwise
        )r‚   rž   ©rO   r3   s     r*   Ú
get_policyzPolicyRegistry.get_policy	  s   € ð �~‰~×!Ñ! +Ó.Ð.r)   c                 ó6   — | j                   j                  «       S )zz
        Get all loaded policies.

        Returns:
            Dictionary mapping policy names to Policy objects
        )r‚   ÚcopyrN   s    r*   Úget_all_policieszPolicyRegistry.get_all_policies  s   € ð �~‰~×"Ñ"Ó$Ð$r)   c                 óH   — t        | j                  j                  «       «      S )zb
        Get list of all policy names.

        Returns:
            List of policy names
        )rF   r‚   ÚkeysrN   s    r*   Úget_policy_nameszPolicyRegistry.get_policy_names  s   € ô �D—N‘N×'Ñ'Ó)Ó*Ð*r)   c                 ó   — || j                   v S )z´
        Check if a policy exists.

        Args:
            policy_name: Name of the policy to check

        Returns:
            True if policy exists, False otherwise
        )r‚   r©   s     r*   Ú
has_policyzPolicyRegistry.has_policy'  s   € ð ˜dŸn™nÐ,Ð,r)   c                 ó   — | j                   S )zœ
        Check if the registry has been initialized with policies.

        Returns:
            True if policies have been loaded, False otherwise
        )r†   rN   s    r*   Úis_initializedzPolicyRegistry.is_initialized3  s   € ð × Ñ Ð r)   c                 ó<   — i | _         i | _        i | _        d| _        y)z7
        Clear all policies from the registry.
        FN)r‚   rƒ   r„   r†   rN   s    r*   ÚclearzPolicyRegistry.clear<  s"   € ð ˆŒØ "ˆÔØˆŒØ!ˆÕr)   )ÚdbrŠ   c                 ó8   — | j                   j                  |«      S )zS
        Return the provenance of an in-memory policy, or None if unknown.
        )r„   rž   r©   s     r*   Ú
get_sourcezPolicyRegistry.get_sourceE  s   € ð �}‰}× Ñ  Ó-Ð-r)   c                 ó,   — t        | j                  «      S )zT
        Return the policies loaded from config.yaml, keyed by policy name.
        )rG   rƒ   rN   s    r*   Úlist_config_policiesz#PolicyRegistry.list_config_policiesK  s   € ô �D×)Ñ)Ó*Ð*r)   r”   Úsourcec                 óÂ   — || j                   |<   i | j                  ¥||i¥| _        |dk(  ri | j                  ¥||i¥| _        d| _        t	        j
                  d|«       y)zÔ
        Add or update a single policy.

        Args:
            policy_name: Name of the policy
            policy: Policy object to add
            source: Provenance of the policy ("db" or "config")
        rŠ   TzAdded/updated policy: %sN)r‚   r„   rƒ   r†   r   r�   )rO   r3   r”   r¼   s       r*   Ú
add_policyzPolicyRegistry.add_policyQ  sd   € ð '-ˆ�‰�{Ñ#Ø>˜4Ÿ=™=Ð>¨+°vÑ>ˆŒØ�XÒØ$R t×'<Ñ'<Ð$R¸kÈ6Ñ$RˆDÔ!Ø ˆÔÜ×"Ñ"Ð#=¸{ÕKr)   c                 óš  — || j                   vry| j                  j                  |«      }|�=|| j                   |<   i | j                  ¥|di¥| _        t	        j
                  d|«       y| j                   |= | j                  j                  «       D ��ci c]  \  }}||k7  sŒ||“Œ c}}| _        t	        j
                  d|«       yc c}}w )a:  
        Remove a policy by name. If a config-defined policy shares the name,
        it is restored immediately instead of waiting for the next DB sync.

        Args:
            policy_name: Name of the policy to remove

        Returns:
            True if policy was removed, False if it didn't exist
        FrŠ   z3Removed policy: %s; restored config-defined versionTzRemoved policy: %s)r‚   rƒ   rž   r„   r   r�   r‹   )rO   r3   Úconfig_fallbackÚnamer¼   s        r*   Úremove_policyzPolicyRegistry.remove_policya  s¿   € ð ˜dŸn™nÑ,ØØ!%×!6Ñ!6×!:Ñ!:¸;Ó!GˆØÐ&Ø*9ˆD�N‰N˜;Ñ'ØD˜tŸ}™}ÐD¨k¸8ÑDˆDŒMÜ ×&Ñ&Ð'\Ð^iÔjØØ�N‰N˜;Ð'Ø:>¿-¹-×:MÑ:MÓ:O×g©,¨$°ÐSWÐ[fÓSf˜˜v™ÓgˆŒÜ×"Ñ"Ð#7¸ÔEØùó hs   ÂCÂ"CÚpolicy_requestrr   r   rB   c           
   ƒ   ó<  K  — 	 t        j                  t        j                  «      }|j                  ddd||j
                  xs g |j                  xs g ||dœ	}|j                  �|j                  |d<   |j                  �|j                  |d<   |�
||d<   ||d	<   |j                  �0t        j                  |j                  j                  «       «      |d
<   |j                  �;t        di |j                  ¤Ž}t        j                  |j                  «       «      |d<   t        |«      j!                  |¬«      ƒ d{  –—† }| j#                  |j                  |j                  |j                  |j
                  |j                  dœ|j                  r|j                  j                  «       nd|j                  dœ«      }| j%                  |j                  |«       t'        |«      S 7 Œ¨# t(        $ r)}	t+        j,                  d|	«       t)        d|	› �«      ‚d}	~	ww xY w­w)a'  
        Add a policy to the database.

        Args:
            policy_request: The policy creation request
            prisma_client: The Prisma client instance
            created_by: User who created the policy

        Returns:
            PolicyDBResponse with the created policy
        r{   r|   T)	r3   r4   r5   r7   r9   r<   r=   r@   rA   Nr:   r;   rB   rC   r>   r?   ©r\   r›   r�   zError adding policy to DB: %szError adding policy to DB: r(   )r   Únowr   Úutcr3   r<   r=   r:   r;   r>   ÚjsonÚdumpsÚ
model_dumpr?   r   rv   r^   rŒ   r¾   r~   rŽ   r   Ú	exception)
rO   rÃ   rr   rB   rÆ   r\   Úvalidated_pipelineÚcreated_policyr”   r•   s
             r*   Úadd_policy_to_dbzPolicyRegistry.add_policy_to_db}  s  è ø€ ð"2	?Ü!Ÿ™¤h§l¡lÓ3ˆCð  .×9Ñ9Ø"#Ø".Ø!Ø!$Ø"0×"?Ñ"?Ò"EÀ2Ø%3×%EÑ%EÒ%KÈØ!Ø!ñ
.ˆDð ×%Ñ%Ð1Ø"0×"8Ñ"8��Y‘Ø×)Ñ)Ð5Ø&4×&@Ñ&@��]Ñ#ØÐ%Ø%/��\Ñ"Ø%/��\Ñ"Ø×'Ñ'Ð3Ü$(§J¡J¨~×/GÑ/G×/RÑ/RÓ/TÓ$U��[Ñ!Ø×&Ñ&Ð2Ü,=Ñ,XÀ×@WÑ@WÑ,XÐ"Ü#'§:¡:Ð.@×.KÑ.KÓ.MÓ#N��ZÑ ä*7¸Ó*F×*MÑ*MÐSWÐ*MÓ*X×$XˆNð !×.Ñ.Ø×*Ñ*à-×5Ñ5Ø#1×#=Ñ#=à-×<Ñ<Ø"0×"BÑ"Bñ#ð LZ×KcÒKc .×":Ñ":×"EÑ"EÔ"GÐimØ .× 7Ñ 7ñ	óˆFð �O‰O˜N×6Ñ6¸Ô?ä-¨nÓ=Ð=ð% %Yùô& ò 	?Ü ×*Ñ*Ð+JÈAÔNÜÐ9¸!¸Ð=Ó>Ð>ûð	?üs<   ‚H„D8G' Ä<G%Ä=B'G' Ç$HÇ%G' Ç'	HÇ0$HÈHÈHr2   rC   c              ƒ   óð  K  — 	 t        |«      j                  d|i¬«      ƒ d{  –—† }|€t        d|› d�«      ‚t        |dd«      }|dk7  rt        d	|› d
�«      ‚t	        j
                  t        j                  «      |dœ}|j                  �|j                  |d<   |j                  �|j                  |d<   |j                  �|j                  |d<   |j                  �|j                  |d<   |j                  �|j                  |d<   |j                  �0t        j                  |j                  j!                  «       «      |d<   |j"                  �;t%        di |j"                  ¤Ž}t        j                  |j!                  «       «      |d<   t        |«      j'                  d|i|¬«      ƒ d{  –—† }	t)        |	«      S 7 �Œ˜7 Œ# t        $ r)}
t+        j,                  d|
«       t        d|
› �«      ‚d}
~
ww xY w­w)aç  
        Update a policy in the database. Only draft versions can be updated.

        Args:
            policy_id: The ID of the policy to update
            policy_request: The policy update request
            prisma_client: The Prisma client instance
            updated_by: User who updated the policy

        Returns:
            PolicyDBResponse with the updated policy

        Raises:
            Exception: If policy is not in draft status (only drafts are editable).
        r2   ©ra   NúPolicy with ID ú
 not foundr5   r|   Údraftz<Only draft versions can be updated. This policy has status 'ú'.)rA   rC   r3   r:   r;   r<   r=   r>   r?   ©ra   r\   zError updating policy in DB: %szError updating policy in DB: r(   )rv   rd   rŽ   r}   r   rÆ   r   rÇ   r3   r:   r;   r<   r=   r>   rÈ   rÉ   rÊ   r?   r   rj   r~   r   rË   )rO   r2   rÃ   rr   rC   Úexistingr5   Úupdate_datarÌ   Úupdated_policyr•   s              r*   Úupdate_policy_in_dbz"PolicyRegistry.update_policy_in_dbÂ  s
  è ø€ ð,(	AÜ$1°-Ó$@×$LÑ$LÐT_ÐajÐSkÐ$LÓ$l×lˆHØÐÜ /°)°¸JÐ GÓHÐHÜ$+¨HÐ6FÈÓ$UˆNØ Ò(ÜÐ"^Ð_mÐ^nÐnpÐ qÓrÐrô 'Ÿl™l¬8¯<©<Ó8Ø(ñ5ˆKð
 ×)Ñ)Ð5Ø-;×-GÑ-G�˜MÑ*Ø×%Ñ%Ð1Ø)7×)?Ñ)?�˜IÑ&Ø×)Ñ)Ð5Ø-;×-GÑ-G�˜MÑ*Ø×,Ñ,Ð8Ø0>×0MÑ0M�Ð,Ñ-Ø×/Ñ/Ð;Ø3A×3SÑ3S�Ð/Ñ0Ø×'Ñ'Ð3Ü+/¯:©:°n×6NÑ6N×6YÑ6YÓ6[Ó+\�˜KÑ(Ø×&Ñ&Ð2Ü,=Ñ,XÀ×@WÑ@WÑ,XÐ"Ü*.¯*©*Ð5G×5RÑ5RÓ5TÓ*U�˜JÑ'ä*7¸Ó*F×*MÑ*MØ" IÐ.Ø ð +Nó +÷ %ˆNô .¨nÓ=Ð=ðI mùð:%ùô ò 	AÜ ×*Ñ*Ð+LÈaÔPÜÐ;¸A¸3Ð?Ó@Ð@ûð	AüsK   ‚G6„ G ¤F<¥FG Æ,F?Æ-G Æ;G6Æ<G Æ?G Ç	G3Ç
$G.Ç.G3Ç3G6c              ƒ   óæ  K  — 	 t        |«      j                  d|i¬«      ƒ d{  –—† }|€t        d|› d�«      ‚t        |dd«      }|j                  }t        |«      j                  d|i¬«      ƒ d{  –—†  dd	|› d
�i}|dk(  r1| j                  |«       | j                  |«      dk(  rd|d<   |S d|d<   |S 7 Œ“7 ŒF# t        $ r)}t        j                  d|«       t        d|› �«      ‚d}~ww xY w­w)aÈ  
        Delete a policy version from the database.

        If the deleted version was production, it is removed from the in-memory
        registry. No other version is auto-promoted; admin must explicitly promote.

        Args:
            policy_id: The ID of the policy version to delete
            prisma_client: The Prisma client instance

        Returns:
            Dict with "message" and optional "warning" if production was deleted.
        r2   rÐ   NrÑ   rÒ   r5   r|   ÚmessageúPolicy z deleted successfullyrŠ   z]Production version was deleted. The config-defined policy with the same name is active again.Úwarningz‰Production version was deleted. No other version was promoted. Promote another version to production if this policy should remain active.z!Error deleting policy from DB: %szError deleting policy from DB: )
rv   rd   rŽ   r}   r3   rn   rÂ   r¹   r   rË   )rO   r2   rr   r”   r5   r3   Úresultr•   s           r*   Údelete_policy_from_dbz$PolicyRegistry.delete_policy_from_db  s1  è ø€ ð$	CÜ"/°Ó">×"JÑ"JÐR]Ð_hÐQiÐ"JÓ"j×jˆFàˆ~Ü /°)°¸JÐ GÓHÐHä$+¨FÐ4DÀlÓ$SˆNØ!'×!3Ñ!3ˆKô   Ó.×5Ñ5¸[È)Ð<TÐ5ÓU×UÐUà-6¸'À)ÀÐLaÐ8bÐ,cˆFð  Ò-Ø×"Ñ" ;Ô/Ø—?‘? ;Ó/°8Ò;àwð ˜9Ñ%ð ˆMð	eð ˜9Ñ%ð
 ˆMð5 køð Vùô$ ò 	CÜ ×*Ñ*Ð+NÐPQÔRÜÐ=¸a¸SÐAÓBÐBûð	CüsW   ‚C1„ B< ¤B8¥AB< Á3B:Á4<B< Â0C1Â1B< Â7C1Â8B< Â:B< Â<	C.Ã$C)Ã)C.Ã.C1c              ƒ   óà   K  — 	 t        |«      j                  d|i¬«      ƒ d{  –—† }|€yt        |«      S 7 Œ# t        $ r)}t	        j
                  d|«       t        d|› �«      ‚d}~ww xY w­w)zü
        Get a policy by ID from the database.

        Args:
            policy_id: The ID of the policy to retrieve
            prisma_client: The Prisma client instance

        Returns:
            PolicyDBResponse if found, None otherwise
        r2   rÐ   Nz Error getting policy from DB: %szError getting policy from DB: )rv   rd   r~   rŽ   r   rË   )rO   r2   rr   r”   r•   s        r*   Úget_policy_by_id_from_dbz'PolicyRegistry.get_policy_by_id_from_db4  s~   è ø€ ð		BÜ"/°Ó">×"JÑ"JÐR]Ð_hÐQiÐ"JÓ"j×jˆFàˆ~Øä-¨fÓ5Ð5ð kùô ò 	BÜ ×*Ñ*Ð+MÈqÔQÜÐ<¸Q¸CÐ@ÓAÐAûð	Büs:   ‚A.„ 9 ¤7¥9 «A.¬
9 ¶A.·9 ¹	A+Á$A&Á&A+Á+A.c                 ó8   — | j                   j                  |«      S )aæ  
        Return a policy version by ID from in-memory cache (no DB access).

        Used when the request body specifies policy_<uuid> to execute a specific version
        (e.g. published or draft). The cache is populated by sync_policies_from_db,
        which loads draft and published versions keyed by policy_id.

        Args:
            policy_id: The policy version ID (raw UUID, no prefix)

        Returns:
            (policy_name, Policy) if found, None otherwise
        )r…   rž   )rO   r2   s     r*   Úget_policy_by_id_for_requestz+PolicyRegistry.get_policy_by_id_for_requestN  s   € ð ×#Ñ#×'Ñ'¨	Ó2Ð2r)   r5   c              ƒ   ó  K  — 	 i }|�||d<   t        |«      j                  |r|ndddi¬«      ƒ d{  –—† }|D �cg c]  }t        |«      ‘Œ c}S 7 Œc c}w # t        $ r)}t	        j
                  d|«       t        d|› �«      ‚d}~ww xY w­w)ak  
        Get all policies from the database, optionally filtered by version_status.

        Args:
            prisma_client: The Prisma client instance
            version_status: If set, only return policies with this status
                           ("draft", "published", "production").

        Returns:
            List of PolicyDBResponse objects
        Nr5   r@   Údesc©ra   re   z"Error getting policies from DB: %sz Error getting policies from DB: )rv   rg   r~   rŽ   r   rË   )rO   rr   r5   ra   ÚpoliciesÚpr•   s          r*   Úget_all_policies_from_dbz'PolicyRegistry.get_all_policies_from_db^  s¬   è ø€ ð 	DØ+-ˆEØÐ)Ø*8�Ð&Ñ'ä$1°-Ó$@×$JÑ$JÙ$‘e¨$Ø# VÐ,ð %Kó %÷ ˆHð
 <DÖD°aÔ.¨qÕ1ÒDÐDðúò
 EøÜò 	DÜ ×*Ñ*Ð+OÐQRÔSÜÐ>¸q¸cÐBÓCÐCûð	DüsI   ‚B„.A ²A³A »AÁA ÁBÁA ÁA Á	B	Á $BÂB	Â	Bc              ƒ   óì  K  — 	 | j                  |d¬«      ƒ d{  –—† }|D �ci c]n  }|j                  | j                  |j                  |j                  |j                  |j
                  |j                  dœ|j                  |j                  dœ«      “Œp }}t        |«      t        | j                  «      z  D ]  }t        j                  d|«       Œ | j                  D �ci c]  }|d“Œ }}|D �ci c]  }|d“Œ }}i | j                  ¥|¥| _        i |¥|¥| _        i | _        t!        |«      j#                  d	d
ddgiiddi¬«      ƒ d{  –—† }	|	D ]�  }
| j                  |
j                  |
j                  |
j                  |
j
                  xs g |
j                  xs g dœ|
j                  |
j                  dœ«      }|
j                  |f| j                  |
j$                  <   Œ’ d| _        t        j(                  dt+        |«      t+        |	«      t+        | j                  «      «       y7 �Œc c}w c c}w c c}w 7 Œð# t,        $ r)}t        j.                  d|«       t-        d|› �«      ‚d}~ww xY w­w)a¥  
        Sync policies from the database to in-memory registry.
        - Production versions are loaded into _policies (by policy name) for resolution.
        - Config-loaded policies are preserved; on a name conflict the DB version wins.
        - Draft and published versions are loaded into _policies_by_id so request-body
          policy_<uuid> overrides can be resolved without DB access in the hot path.
        r|   ©r5   Nr›   r�   zVPolicy '%s' is defined in both config.yaml and the DB; the DB version takes precedencerŠ   r·   r5   ÚinrÓ   Ú	publishedr@   rå   ræ   Tz�Synced %s production policies and %s draft/published (by ID) from DB to in-memory registry (%s config-defined policies preserved)z"Error syncing policies from DB: %sz Error syncing policies from DB: )ré   r3   rŒ   r:   r;   r<   r=   r>   r?   Úsetrƒ   r   rÝ   r‚   r„   r…   rv   rg   r2   r†   r‘   r’   rŽ   rË   )rO   rr   r|   Úpolicy_responseÚdb_policiesr3   rÁ   Úconfig_sourcesÚ
db_sourcesÚnon_productionry   r”   r•   s                r*   Úsync_policies_from_dbz$PolicyRegistry.sync_policies_from_db}  s¢  è ø€ ð:	DØ&*×&CÑ&CÀMÐbnÐ&CÓ&o× oˆJð (2ö"ð $ð  ×+Ñ+¨T×-?Ñ-?Ø#×/Ñ/à#2×#:Ñ#:Ø'6×'BÑ'Bà#2×#AÑ#AØ&5×&GÑ&Gñ'ð &5×%>Ñ%>Ø$3×$<Ñ$<ñ	ó.ñ ð"ˆKð "ô   # ;Ó/´#°d×6KÑ6KÓ2LÑLò �Ü$×,Ñ,ØlØõðð
 ae×`uÑ`uÖDvÐX\ÀTÈ8Á^ÐDvˆNÐDvØ_jÖGkÐW[ÈÈdÉ
ÐGkˆJÐGkØE × 5Ñ 5ÐE¸ÐEˆDŒNØ<˜~Ð<°Ð<ˆDŒMà#%ˆDÔ Ü*7¸Ó*F×*PÑ*PØ'¨$°¸+Ð0FÐ)GÐHØ# VÐ,ð +Qó +÷ %ˆNð &ò P�Ø×+Ñ+Ø—O‘Oà#&§;¡;Ø'*§¡à#&×#5Ñ#5Ò#;¸Ø&)×&;Ñ&;Ò&A¸rñ'ð &)§]¡]Ø$'§L¡Lñ	ó�ð 8;·±ÈÐ6O�×$Ñ$ S§]¡]Ò3ðPð  !%ˆDÔÜ ×%Ñ%ð TÜ�J“Ü�NÓ#Ü�D×)Ñ)Ó*õ	ðc !pûò"ùò* EwùÚGkð
%ùô6 ò 	DÜ ×*Ñ*Ð+OÐQRÔSÜÐ>¸q¸cÐBÓCÐCûð	Düsq   ‚I4„H? šH+›H? £A3H.ÂAH? Ã"
H3Ã,H? Ã2
H8Ã<AH? ÅH=ÅCH? È*I4È+H? È.H? È?	I1É$I,É,I1É1I4c           
   ƒ   ó   K  — ddl m} 	 | j                  |d¬«      ƒ d{  –—† }i }|D ]r  }| j                  |j                  |j
                  |j                  |j                  |j                  dœ|j                  |j                  dœ«      }|||j                  <   Œt |j                  ||d¬«      }t        |j                  «      S 7 Œ¦# t        $ r)}	t        j                   d	|	«       t        d
|	› �«      ‚d}	~	ww xY w­w)aU  
        Resolve all guardrails for a policy from the database.

        Uses the existing PolicyResolver to handle inheritance chain resolution.

        Args:
            policy_name: Name of the policy to resolve
            prisma_client: The Prisma client instance

        Returns:
            List of resolved guardrail names
        r   )ÚPolicyResolverr|   rë   Nr›   r�   )r3   rç   Úcontextz&Error resolving guardrails from DB: %sz$Error resolving guardrails from DB: )Ú+litellm.proxy.policy_engine.policy_resolverrö   ré   rŒ   r3   r:   r;   r<   r=   r>   r?   Úresolve_policy_guardrailsÚsortedr˜   rŽ   r   rË   )
rO   r3   rr   rö   rç   Útemp_policiesrï   r”   Úresolved_policyr•   s
             r*   Úresolve_guardrails_from_dbz)PolicyRegistry.resolve_guardrails_from_dbÄ  s#  è ø€ õ" 	Oð 	Hà$(×$AÑ$AÀ-Ð`lÐ$AÓ$m×mˆHð $&ˆMØ#+ò D�Ø×+Ñ+Ø#×/Ñ/à#2×#:Ñ#:Ø'6×'BÑ'Bà#2×#AÑ#AØ&5×&GÑ&Gñ'ð &5×%>Ñ%>Ø$3×$<Ñ$<ñ	ó�ð >D�˜o×9Ñ9Ò:ðDð" &4×%MÑ%MØ'Ø&Øð &Nó &ˆOô ˜/×4Ñ4Ó5Ð5ð7 nùô8 ò 	HÜ ×*Ñ*Ð+SÐUVÔWÜÐBÀ1À#ÐFÓGÐGûð	Hüs9   ‚C>ŠC	  C¡B%C	 ÃC>ÃC	 Ã		C;Ã$C6Ã6C;Ã;C>c              ƒ   ó2  K  — 	 t        |«      j                  d|iddi¬«      ƒ d{  –—† }|D �cg c]  }t        |«      ‘Œ }}t        ||t	        |«      ¬«      S 7 Œ3c c}w # t
        $ r)}t        j                  d|«       t        d|› �«      ‚d}~ww xY w­w)	a,  
        Get all versions of a policy by name, ordered by version_number descending.

        Args:
            policy_name: Name of the policy
            prisma_client: The Prisma client instance

        Returns:
            PolicyVersionListResponse with policy_name and list of versions
        r3   r4   rå   ræ   N)r3   ÚversionsÚtotal_countzError getting versions: %szError getting versions: )rv   rg   r~   r   r’   rŽ   r   rË   )rO   r3   rr   ÚrowsÚrrÿ   r•   s          r*   Úget_versions_by_policy_namez*PolicyRegistry.get_versions_by_policy_nameù  s²   è ø€ ð	<Ü -¨mÓ <× FÑ FØ$ kÐ2Ø'¨Ð0ð !Gó !÷ ˆDð GKÖKÀÔ9¸!Õ<ÐKˆHÐKÜ,Ø'Ø!Ü ›Môð ðúò Løô ò 	<Ü ×*Ñ*Ð+GÈÔKÜÐ6°q°cÐ:Ó;Ð;ûð	<üsI   ‚B„#A" §A¨A" °AÁA" ÁBÁA" ÁA" Á"	BÁ+$BÂBÂBÚsource_policy_idc              ƒ   ó  K  — 	 |�at        |«      j                  d|i¬«      ƒ d{  –—† }|€t        d|› d�«      ‚|j                  |k7  rUt        d|j                  › d|› d�«      ‚t        |«      j	                  |d	d
œ¬«      ƒ d{  –—† }|€t        d|› d�«      ‚|}t        |«      j	                  d|iddi¬«      ƒ d{  –—† }|r|j
                  dz   nd}t        j                  t        j                  «      }	t        |«      j                  d|iddi¬«      ƒ d{  –—†  ||d|j                  ddd|j                  |j                  |j                  xs g |j                   xs g |	|	||dœ}
|j"                  �Ht%        |j"                  t&        «      rt)        j*                  |j"                  «      n|j"                  |
d<   |j,                  �Ht%        |j,                  t&        «      rt)        j*                  |j,                  «      n|j,                  |
d<   t        |«      j/                  |
¬«      ƒ d{  –—† }t1        |«      S 7 �Œ"7 �ŒÃ7 �Œ‹7 �Œ07 Œ# t        $ r)}t3        j4                  d|«       t        d|› �«      ‚d}~ww xY w­w)aä  
        Create a new draft version of a policy. Copies all fields from the source.
        Source is current production if source_policy_id is None.

        Args:
            policy_name: Name of the policy
            prisma_client: The Prisma client instance
            source_policy_id: Policy ID to clone from; if None, use current production
            created_by: User who created the version

        Returns:
            PolicyDBResponse for the new draft version
        Nr2   rÐ   zSource policy rÒ   zSource policy name 'z' does not match 'ú'r|   ©r3   r5   z(No production version found for policy 'r3   r4   rå   ræ   r{   r7   FrÕ   rÓ   T)r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r@   rA   rB   rC   r>   r?   rÅ   zError creating new version: %szError creating new version: )rx   rd   rŽ   r3   Ú
find_firstr4   r   rÆ   r   rÇ   rv   rl   r2   r:   r;   r<   r=   r>   rŸ   rG   rÈ   rÉ   r?   r^   r~   r   rË   )rO   r3   rr   r  rB   r¼   ÚprodÚlatestÚnext_numrÆ   r\   Úcreatedr•   s                r*   Úcreate_new_versionz!PolicyRegistry.create_new_version  s½  è ø€ ð(@	@ØÐ+Ü;¸MÓJ×VÑVØ&Ð(8Ð9ð  Wó  ÷ �ð �>Ü# nÐ5EÐ4FÀjÐ$QÓRÐRØ×%Ñ%¨Ò4Ü#Ð&:¸6×;MÑ;MÐ:NÐN`ÐalÐ`mÐmnÐ$oÓpÐpô %AÀÓ$O×$ZÑ$Zà'2Ø*6ñð %[ó %÷ �ð �<Ü#Ð&NÈ{ÈmÐ[\Ð$]Ó^Ð^Ø�ô #?¸}Ó"M×"XÑ"XØ$ kÐ2Ø'¨Ð0ð #Yó #÷ ˆFñ >D˜v×4Ñ4°qÒ8ÈˆHä!Ÿ™¤h§l¡lÓ3ˆCä Ó.×:Ñ:Ø$ kÐ2Ø! 5Ð)ð ;ó ÷ ð ð  +Ø"*Ø")Ø%+×%5Ñ%5Ø!Ø $Ø!%Ø!Ÿ>™>Ø%×1Ñ1Ø"(×"7Ñ"7Ò"=¸2Ø%+×%=Ñ%=Ò%CÀØ!Ø!Ø(Ø(ñ.ˆDð$ ×ÑÐ+ä4>¸v×?OÑ?OÔQUÔ4V”D—J‘J˜v×/Ñ/Ô0Ð\b×\lÑ\lð �[Ñ!ð �‰Ð*ÜBLÈVÏ_É_Ô^bÔBc¤4§:¡:¨f¯o©oÔ#>Ðio×ixÑix��ZÑ ä#0°Ó#?×#FÑ#FÈDÐ#FÓ#Q×QˆGÜ-¨gÓ6Ð6ðwùðùðùðùð< Rùäò 	@Ü ×*Ñ*Ð+KÈQÔOÜÐ:¸1¸#Ð>Ó?Ð?ûð	@üsƒ   ‚J„"I ¦I§A!I ÂIÂ	:I ÃIÃAI Ä!IÄ"DI È8IÈ9I ÉJÉI ÉI ÉI ÉI ÉI É	JÉ$JÊJÊJÚ
new_statusc           	   ƒ   ó>  K  — 	 |dvrt        d|› d�«      ‚t        |«      j                  d|i¬«      ƒ d{  –—† }|€t        d|› d�«      ‚t        |d	d
«      }|j                  }t        j                  t        j                  «      }|dk(  rJ|dk7  rt        d|› d�«      ‚t        |«      j                  d|id|||dœ¬«      ƒ d{  –—† }	t        |	«      S |dvrt        d|› d�«      ‚|dk(  rt        d«      ‚t        |«      j                  |d
dœd||dœ¬«      ƒ d{  –—†  t        |«      j                  d|id
|||dœ¬«      ƒ d{  –—† }	| j                  |«       | j                  ||	j                  |	j                  |	j                   xs g |	j"                  xs g dœ|	j$                  |	j&                  dœ«      }
| j)                  ||
«       t        |	«      S 7 �Œ§7 �Œ7 ŒÂ7 Œ™# t         $ r)}t+        j,                  d|«       t        d|› �«      ‚d}~ww xY w­w)a®  
        Update a policy version's status. Valid transitions:
        - draft -> published (sets published_at)
        - published -> production (sets production_at, demotes current production to published, updates in-memory)
        - production -> published (demotes, removes from in-memory)
        - draft -> production: NOT allowed (must publish first)
        - published -> draft: NOT allowed

        Args:
            policy_id: The policy version ID
            new_status: "published" or "production"
            prisma_client: The Prisma client instance
            updated_by: User who updated

        Returns:
            PolicyDBResponse for the updated version
        )rí   r|   zInvalid status 'z#'. Use 'published' or 'production'.r2   rÐ   NrÑ   rÒ   r5   r|   rí   rÓ   z7Only draft versions can be published. Current status: 'rÔ   )r5   r8   rA   rC   rÕ   )rÓ   rí   zJOnly draft or published versions can be promoted to production. Current: 'zGCannot promote draft directly to production. Publish the version first.r  )r5   rA   rC   )r5   r9   rA   rC   r›   r�   z!Error updating version status: %szError updating version status: )rŽ   rv   rd   r}   r3   r   rÆ   r   rÇ   rj   r~   rl   rÂ   rŒ   r:   r;   r<   r=   r>   r?   r¾   r   rË   )rO   r2   r  rr   rC   ry   Úcurrentr3   rÆ   Úupdatedr”   r•   s               r*   Úupdate_version_statusz$PolicyRegistry.update_version_statusm  sŽ  è ø€ ð0O	CØÐ!<Ñ<ÜÐ"2°:°,Ð>aÐ bÓcÐcä,¨]Ó;×GÑGÈ{Ð\eÐNfÐGÓg×gˆCØˆ{Ü /°)°¸JÐ GÓHÐHä$ SÐ*:¸LÓIˆGØ!$§¡ˆKÜ!Ÿ™¤h§l¡lÓ3ˆCà˜[Ò(Ø˜gÒ%Ü#Ð&]Ð^eÐ]fÐfhÐ$iÓjÐjÜ -¨mÓ <× CÑ CØ&¨	Ð2à*5Ø(+Ø&)Ø&0ñ	ð !Dó !÷ �ô 2°'Ó:Ð:ð Ð4Ñ4ÜØ`ÐahÐ`iÐikÐlóð ð ˜'Ò!ÜÐ iÓjÐjô   Ó.×:Ñ:à#.Ø&2ñð
 '2Ø"%Ø",ñð ;ó 
÷ 
ð 
ô *¨-Ó8×?Ñ?Ø" IÐ.à&2Ø%(Ø"%Ø",ñ	ð @ó ÷ ˆGð ×Ñ˜{Ô+Ø ×.Ñ.Øà&Ÿ™Ø#*×#6Ñ#6à&×5Ñ5Ò;¸Ø")×";Ñ";Ò"A¸rñ#ð ")×!2Ñ!2Ø '× 0Ñ 0ñ	óˆFð �O‰O˜K¨Ô0ä-¨gÓ6Ð6ðQ hùðùð*
øðùô8 ò 	CÜ ×*Ñ*Ð+NÐPQÔRÜÐ=¸a¸SÐAÓBÐBûð	Cüs}   ‚H„3G( ·G¸BG( ÃG!Ã	G( ÃHÃA	G( Ä!G$Ä"*G( ÅG&ÅBG( ÇHÇG( Ç!G( Ç$G( Ç&G( Ç(	HÇ1$HÈHÈHÚpolicy_id_aÚpolicy_id_bc              ƒ   ó   K  — 	 t        |«      j                  d|i¬«      ƒ d{  –—† }t        |«      j                  d|i¬«      ƒ d{  –—† }|€t        d|› d�«      ‚|€t        d|› d�«      ‚t        |«      }t        |«      }d}i }	|D ](  }
t	        ||
«      }t	        ||
«      }||k7  sŒ!||dœ|	|
<   Œ* t        |||	¬«      S 7 Œ 7 Œ}# t        $ r)}t        j                  d	|«       t        d
|› �«      ‚d}~ww xY w­w)aT  
        Compare two policy versions and return field-by-field diffs.

        Args:
            policy_id_a: First policy version ID
            policy_id_b: Second policy version ID
            prisma_client: The Prisma client instance

        Returns:
            PolicyVersionCompareResponse with both versions and field_diffs
        r2   rÐ   NrÜ   rÒ   )r:   r;   r<   r=   r>   r?   )Ú	version_aÚ	version_b)r  r  Úfield_diffszError comparing versions: %szError comparing versions: )rv   rd   rŽ   r~   r}   r   r   rË   )rO   r  r  rr   ÚaÚbÚresp_aÚresp_bÚcompare_fieldsr  ÚfieldÚval_aÚval_br•   s                 r*   Úcompare_versionszPolicyRegistry.compare_versionsÖ  s9  è ø€ ð""	>Ü*¨=Ó9×EÑEÈ[ÐZeÐLfÐEÓg×gˆAÜ*¨=Ó9×EÑEÈ[ÐZeÐLfÐEÓg×gˆAØˆyÜ '¨+¨°jÐ AÓBÐBØˆyÜ '¨+¨°jÐ AÓBÐBä6°qÓ9ˆFÜ6°qÓ9ˆFð%ˆNð @BˆKØ'ò R�Ü ¨Ó.�Ü ¨Ó.�Ø˜E“>Ø7<È5Ñ)Q�K Ò&ð	Rô 0Ø Ø Ø'ôð ð5 høØgùô< ò 	>Ü ×*Ñ*Ð+IÈ1ÔMÜÐ8¸¸Ð<Ó=Ð=ûð	>üsQ   ‚C>„ C	 ¤C¥$C	 Á	CÁ
A"C	 Â-C	 ÃC>ÃC	 ÃC	 Ã		C;Ã$C6Ã6C;Ã;C>c              ƒ   ó,  K  — 	 t        |«      j                  d|i¬«      ƒ d{  –—†  | j                  |«       d|› d�}| j                  |«      dk(  r|ddœS d	|iS 7 Œ8# t        $ r)}t        j                  d
|«       t	        d|› �«      ‚d}~ww xY w­w)a8  
        Delete all versions of a policy. Also removes from in-memory registry.

        Args:
            policy_name: Name of the policy
            prisma_client: The Prisma client instance

        Returns:
            Dict with "message" and optional "warning" if a config-defined policy took over.
        r3   rÐ   NzAll versions of policy 'z' deleted successfullyrŠ   z[All DB versions were deleted. The config-defined policy with the same name is active again.)rÛ   rÝ   rÛ   zError deleting all versions: %szError deleting all versions: )rv   rp   rÂ   r¹   rŽ   r   rË   )rO   r3   rr   rÛ   r•   s        r*   Údelete_all_versionsz"PolicyRegistry.delete_all_versions  s¶   è ø€ ð	AÜ Ó.×:Ñ:À-ÐQ\ÐA]Ð:Ó^×^Ð^Ø×Ñ˜{Ô+Ø7¸°}ÐDZÐ[ˆGØ�‰˜{Ó+¨xÒ7à&àuñð ð ˜wÐ'Ð'ð _ùô ò 	AÜ ×*Ñ*Ð+LÈaÔPÜÐ;¸A¸3Ð?Ó@Ð@ûð	AüsD   ‚B„ A ¤A¥3A ÁBÁA ÁBÁA Á	BÁ($BÂBÂB)rK   N)r·   rM   )rr   r   rK   Nrq   )1r#   r$   r%   Ú__doc__r‡   r   r&   rG   rH   r–   r   r   rŒ   Ústaticmethodr   r   r    rª   r­   rF   r°   rE   r²   r´   r¶   r
   r¹   r»   r¾   rÂ   r   r   rÎ   r   rÙ   rß   rá   Útuplerã   ré   rô   rý   r   r  r  r  r   r!  r#  r(   r)   r*   r€   r€   £   sé  „ ñ
ò(ðM¨W°S¸$¸sÀF¸{Ñ:KÐ5KÑ-Lð MÐQUó Mð6%
¨ð %
¸4ÀÀSÀ¹>ð %
Èfó %
ðN ð
ØÐ 4Ñ5ð
à	˜TÑ	!ò
ó ð
ð
/ cð 
/¨f°t©mó 
/ð% $ s¨F {Ñ"3ó %ð+ $ s¡)ó +ð
- cð 
-¨dó 
-ð! ó !ó"ð. cð .¨g°nÑ.EÈÑ.Ló .ð+ g¨c°6¨kÑ&:ó +ñL cð L°6ð LÀ7È>ÑCZð LÐfjó Lð ¨ð °ó ð@ "&ñ	C?à+ðC?ð &ðC?ð ˜$‘Jð	C?ð
 
óC?ðT "&ñ>Aàð>Að ,ð>Að &ð	>Að
 ˜$‘Jð>Að 
ó>Að@0Càð0Cð &ð0Cð 
��c�Ñ	ó	0CðdBàðBð &ðBð 
˜DÑ	 ó	Bð43°cð 3¸eÀCÈÀKÑ>PÐSWÑ>Wó 3ð& &*ñDà%ðDð ˜d™
ðDð 
ÐÑ	ó	Dð>EDà%ðEDð 
óEDðN3Hàð3Hð &ð3Hð 
ˆc‰ó	3Hðj<àð<ð &ð<ð 
#ó	<ðD (,Ø!%ñT@àðT@ð &ðT@ð  ™*ð	T@ð
 ˜$‘JðT@ð 
óT@ðv "&ñgCàðgCð ðgCð &ð	gCð
 ˜$‘JðgCð 
ógCðR3>àð3>ð ð3>ð &ð	3>ð
 
&ó3>ðjAàðAð &ðAð 
��c�Ñ	ô	Ar)   r€   Ú_policy_registryc                  ó.   — t         €
t        «       a t         S )zk
    Get the global PolicyRegistry singleton.

    Returns:
        The global PolicyRegistry instance
    )r'  r€   r(   r)   r*   Úget_policy_registryr)  /  s   € ô ÐÜ)Ó+ÐÜÐr)   )rr   r   rK   z%TableActions[_PolicyVersionSourceRow])1r$  rÈ   Úcollections.abcr   r   r   r   Útypingr   r   r	   r
   r   r   r   r   r   Úlitellm._loggingr   Ú%litellm.repositories.prisma_protocolsr   Ú'litellm.repositories.table_repositoriesr   Ú!litellm.types.proxy.policy_enginer   r   r   r   r   r   r   r   r   r   Úlitellm.proxy.utilsr   r   r'   r!   r,   r1   rJ   r[   rv   rx   r~   r€   r'  r)  r(   r)   r*   ú<module>r1     sï   ðòó ß -ß '÷
÷ 
õ 
õ 2Ý >Ý D÷÷ ÷ ñ Ý0ð #,Ð ˜%Ó +ô�yô ô=˜¨%õ =ô
�ô ô*A˜hô Aô:I˜ô Ið( ð Ð4Fó óð
 Jð Ð3Có ÷0EAñ EAðR +/Ð �. 4Ñ'Ó .ð
˜^ô 
r)   