
    i+                       % S r SSKJr  SSKrSSKrSSKrSSKJrJr  SSK	J
r
  SSKJr  SSKJr  SSKJr  \S	   r  " S
 S\5      r " S S\5      r\\/\\   4   r S#S jrS#S jrS#S jrS#S jrS#S jr\\\\\S.rS\S'    S$S jrS%S jr S%S jr!S%S jr"        S&S jr#S'S jr$\
" SS9 " S S5      5       r%\
" SS9 " S  S!5      5       r&/ S"Qr'g)(z5Shared redaction utilities for middleware components.    )annotationsN)CallableSequence)	dataclass)Literal)urlparse)	TypedDict)blockredactmaskhashc                  B    \ rS rSr% SrS\S'   S\S'   S\S'   S\S'   S	rg
)PIIMatch   z1Represents an individual match of sensitive data.strtypevalueintstartend N)__name__
__module____qualname____firstlineno____doc____annotations____static_attributes__r       `/home/james-whalen/.local/lib/python3.13/site-packages/langchain/agents/middleware/_redaction.pyr   r      s    ;
IJJ	Hr   r   c                  0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )PIIDetectionError   z=Raised when configured to block on detected sensitive values.c                x   > Xl         [        U5      U l        [        U5      nSU SU S3n[        TU ]  U5        g)zInitialize the exception with match context.

Args:
    pii_type: Name of the detected sensitive type.
    matches: All matches that were detected for that type.
z	Detected z instance(s) of z in text contentN)pii_typelistmatcheslensuper__init__)selfr%   r'   countmsg	__class__s        r    r*   PIIDetectionError.__init__   sA     !G}G% 0
:JKr   )r'   r%   )r%   r   r'   zSequence[PIIMatch]returnNone)r   r   r   r   r   r*   r   __classcell__)r.   s   @r    r"   r"      s    G r   r"   c           
         Sn[         R                  " X5       Vs/ s H9  n[        SUR                  5       UR	                  5       UR                  5       S9PM;     sn$ s  snf )z"Detect email addresses in content.z3\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\bemailr   r   r   r   refinditerr   groupr   r   contentpatternmatchs      r    detect_emailr>   1   s^    DG [[2 3E 	++-++-				
 3     A Ac           
         Sn/ n[         R                  " X5       H\  nUR                  5       n[        U5      (       d  M%  UR	                  [        SUUR                  5       UR                  5       S95        M^     U$ )z<Detect credit card numbers in content using Luhn validation.z*\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\bcredit_cardr5   )r7   r8   r9   _passes_luhnappendr   r   r   )r;   r<   r'   r=   card_numbers        r    detect_credit_cardrE   ?   sh    ;GGW.kkm$$NN&%++-			 / Nr   c           
     &   / nSn[         R                  " X 5       Ha  nUR                  5       n [        R                  " U5        UR                  [        SUUR                  5       UR                  5       S95        Mc     U$ ! [
         a     Mt  f = f)z)Detect IPv4 or IPv6 addresses in content.z!\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\bipr5   )
r7   r8   r9   	ipaddress
ip_address
ValueErrorrC   r   r   r   )r;   r'   ipv4_patternr=   ip_candidates        r    	detect_iprM   S   s     G7L\3{{}	  . 	"kkmIIK		
 4 N  		s   B
BBc           
         Sn[         R                  " X5       Vs/ s H9  n[        SUR                  5       UR	                  5       UR                  5       S9PM;     sn$ s  snf )z Detect MAC addresses in content.z)\b([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\bmac_addressr5   r6   r:   s      r    detect_mac_addressrP   j   s^    :G [[2 3E 	++-++-				
 3  r?   c           
       ^^	 / nSn[         R                  " X 5       Hz  nUR                  5       n[        U5      nUR                  S;   d  M0  UR
                  (       d  MC  UR                  [        SUUR                  5       UR                  5       S95        M|     Sn[         R                  " X`5       H  nUR                  5       UR                  5       sm	m[        UU	4S jU 5       5      (       a  MA  UR                  5       nSU;   d  UR                  S5      (       d  Mo  S	U 3n[        U5      nUR
                  (       d  M  S
UR
                  ;   d  M  UR                  [        SUT	TS95        M     U$ )z9Detect URLs in content using regex and stdlib validation.zhttps?://[^\s<>\"{}|\\^`\[\]]+)httphttpsurlr5   zy\b(?:www\.)?[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?:/[^\s]*)?c              3     >#    U  HA  oS    Ts=:*  =(       a    US   :  Os  =(       d    US    Ts=:  =(       a    US   :*  Os  v   MC     g7f)r   r   Nr   ).0mr   r   s     r    	<genexpr>detect_url.<locals>.<genexpr>   sD     _W^RSzU--QuX-M7c1M1MQuX1MMW^s   A	A/zwww.zhttp://.)r7   r8   r9   r   schemenetlocrC   r   r   r   any
startswith)
r;   r'   scheme_patternr=   rT   resultbare_patterntest_urlr   r   s
           @@r    
detect_urlrd   x   s5    G 7N^5kkm#==--&---NN++-				 6 	L 
 \3[[]EIIK
s_W^___kkm #:// Hh'F}}}!5"!#	 4. Nr   )r4   rA   rG   rO   rT   zdict[str, Detector]BUILTIN_DETECTORSc                .   U  Vs/ s H$  oR                  5       (       d  M  [        U5      PM&     nnS[        U5      s=::  a  S::  d   g  gSn[        [	        U5      5       H$  u  pEUnUS-  S:X  a  US-  nUS:  a  US-  nX6-  nM&     US-  S:H  $ s  snf )	z4Validate credit card number using the Luhn checksum.   r   Fr         	   
   )isdigitr   r(   	enumeratereversed)rD   ddigitschecksumindexdigitr   s          r    rB   rB      s    )9kYY[fc!fkF9V"" #H!(6"2319>QJEqy
 4 b=A :s
   BBc                    U n[        US SS9 H-  nSUS   R                  5        S3nUS US    U-   X#S   S  -   nM/     U$ )	Nc                    U S   $ Nr   r   items    r    <lambda>(_apply_redact_strategy.<locals>.<lambda>       $w-r   Tkeyreversez
[REDACTED_r   ]r   r   )sortedupper)r;   r'   ra   r=   replacements        r    _apply_redact_strategyr      sc    F%?N"5=#6#6#8"9;(%.)K7&u:PP O Mr   c                   U n[        US SS9 GHN  nUS   nUS   nUS:X  a\  UR                  S5      n[        U5      S:X  a9  US	   R                  S
5      n[        U5      S:  a  US    SUS    3OUS    S3nOSnOUS:X  aK  SR                  S U 5       5      n	SU;   a  SO	SU;   a  SOSn
U
(       a  SU
 SU
 SU
 U	SS   3nOSU	SS   3nOzUS:X  a+  UR                  S
5      n[        U5      S:X  a  SUS    3OSnOIUS:X  a!  SU;   a  SOSn
SU
 SU
 SU
 SU
 SU
 USS   3nO"US:X  a  SnO[        U5      S:  a  SUSS   3OSnUS US     U-   X#S!   S  -   nGMQ     U$ )"Nc                    U S   $ rv   r   rw   s    r    ry   &_apply_mask_strategy.<locals>.<lambda>   r{   r   Tr|   r   r   r4   @rh   ri   r[   r   z@****.z@****z****rA    c              3  R   #    U  H  oR                  5       (       d  M  Uv   M     g 7f)N)rl   )rV   cs     r    rX   '_apply_mask_strategy.<locals>.<genexpr>   s     !BUiik!!Us   '	'- z************rG      z*.*.*.rO   :z**rT   z[MASKED_URL]r   r   )r   splitr(   join)r;   r'   ra   r=   r   r%   partsdomain_partsmaskeddigits_only	separatoroctetss               r    _apply_mask_strategyr      s   F%?Ng=wKK$E5zQ$Qx~~c2 <(A- Qxj|B'7&89!!H:U+   &''!BU!BBK"e|u"I	{$yki[UWUXIYHZ['BC(8'9:[[%F.1&kQ.>vfRj\*FF&"e|IYKr)BykI;bTYZ\Z]T^S_`  #F,/JNtE"#J<(F(%.)F2V%LN5KKC OD Mr   c                    U n[        US SS9 HZ  n[        R                  " US   R                  5       5      R	                  5       S S nSUS    SU S	3nUS US
    U-   X#S   S  -   nM\     U$ )Nc                    U S   $ rv   r   rw   s    r    ry   &_apply_hash_strategy.<locals>.<lambda>   r{   r   Tr|   r      <r   z_hash:>r   r   )r   hashlibsha256encode	hexdigest)r;   r'   ra   r=   digestr   s         r    _apply_hash_strategyr      s    F%?Ng 5 5 78BBDRaH%-vha8(%.)K7&u:PP O Mr   c                    U(       d  U $ US:X  a  [        X5      $ US:X  a  [        X5      $ US:X  a  [        X5      $ US:X  a  [        US   S   U5      eSU 3n[	        U5      e)z8Apply the configured strategy to matches within content.r   r   r   r
   r   r   zUnknown redaction strategy: )r   r   r   r"   rJ   )r;   r'   strategyr-   s       r    apply_strategyr      sy     8%g776#G556#G557
6 2G<<(

3C
S/r   c                   ^ ^ UcB  T [         ;  a/  ST  S[        [         R                  5       5       S3n[        U5      e[         T    $ [	        U[
        5      (       a!  [        R                  " U5      mSUU 4S jjnU$ U$ )z7Return a callable detector for the given configuration.zUnknown PII type: z. Must be one of z or provide a custom detector.c           
        > TR                  U 5       Vs/ s H9  n[        TUR                  5       UR                  5       UR	                  5       S9PM;     sn$ s  snf )Nr5   )r8   r   r9   r   r   )r;   r=   r<   r%   s     r    regex_detector(resolve_detector.<locals>.regex_detector!  s\     %--g6 7E !++-++-			 7  s   A Ar;   r   r0   list[PIIMatch])re   r&   keysrJ   
isinstancer   r7   compile)r%   detectorr-   r   r<   s   `   @r    resolve_detectorr     s    ,,$XJ /""&'8'='='?"@!AA_a  S/! **(C  **X&		 		 Or   T)frozenc                  J    \ rS rSr% SrS\S'   SrS\S'   SrS	\S
'   SS jrSr	g)RedactionRulei0  z-Configuration for handling a single PII type.r   r%   r   RedactionStrategyr   NDetector | str | Noner   c                    [        U R                  U R                  5      n[        U R                  U R                  US9$ )z6Resolve runtime detector and return an immutable rule.)r%   r   r   )r   r%   r   ResolvedRedactionRuler   )r+   resolved_detectors     r    resolveRedactionRule.resolve8  s5    ,T]]DMMJ$]]]]&
 	
r   r   )r0   r   )
r   r   r   r   r   r   r   r   r   r   r   r   r    r   r   0  s%    7M"*H*&*H#*
r   r   c                  B    \ rS rSr% SrS\S'   S\S'   S\S'   SS	 jrS
rg)r   iB  z,Resolved redaction rule ready for execution.r   r%   r   r   Detectorr   c                l    U R                  U5      nU(       d  U/ 4$ [        XU R                  5      nX24$ )z>Apply this rule to content, returning new content and matches.)r   r   r   )r+   r;   r'   updateds       r    applyResolvedRedactionRule.applyJ  s6    --(B; 4==Ar   r   N)r;   r   r0   ztuple[str, list[PIIMatch]])r   r   r   r   r   r   r   r   r   r   r    r   r   B  s    6M r   r   )
r"   r   r   r   r   rE   r>   rM   rP   rd   r   )rD   r   r0   bool)r;   r   r'   r   r0   r   )r;   r   r'   r   r   r   r0   r   )r%   r   r   r   r0   r   )(r   
__future__r   r   rH   r7   collections.abcr   r   dataclassesr   typingr   urllib.parser   typing_extensionsr	   r   r   	Exceptionr"   r   r&   r   r>   rE   rM   rP   rd   re   r   rB   r   r   r   r   r   r   r   __all__r   r   r    <module>r      s*   ; "   	 . !  ! '=>  By 	 " SE4>)* D(.2l %
%* &  9"$N   		(8 $
 
 
" $      r   