
    OKi62                        S r SSKJr  SSKrSSKrSSKrSSKrSSKJ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JrJrJr  SS
 jrSS jrSS jr " S S\\\   \\4   5      rS/rg)zFile search middleware for Anthropic text editor and memory tools.

This module provides Glob and Grep search tools that operate on files stored
in state or filesystem.
    )annotationsN)suppress)datetimetimezone)Path)Literal)tool)AgentMiddleware
AgentStateContextT	ResponseTc                l   ^^ SU ;   a  SU ;  a  g/ mSUU4S jjm T" U 5        T$ ! [          a     gf = f)z=Expand brace patterns like `*.{py,pyi}` into a list of globs.}{Nc                  > U R                  S5      nUS:X  a  TR                  U 5        g U R                  SU5      nUS:X  a  [        eU S U nXS-   S  nXS-   U nU(       d  [        eUR                  S5       H  nT" X6-   U-   5        M     g )Nr   r      ,)findappend
ValueErrorsplit)	currentstartendprefixsuffixinneroption_expandexpandeds	          i/var/www/html/dynamic-report/venv/lib/python3.13/site-packages/langchain/agents/middleware/file_search.pyr    )_expand_include_patterns.<locals>._expand   s    S!B;OOG$ll3&"9%q#	C(kk#&FFOf,- '    )r   strreturnNone)r   )patternr    r!   s    @@r"   _expand_include_patternsr)      sK    
g~#W,H. .& O  s   & 
33c                  ^  T (       d  g[        U 4S jS 5       5      (       a  g[        T 5      nUc  g U H-  n[        R                  " [        R
                  " U5      5        M/     g! [        R                   a     gf = f)z/Validate glob pattern used for include filters.Fc              3  ,   >#    U  H	  oT;   v   M     g 7fN ).0charr(   s     r"   	<genexpr>,_is_valid_include_pattern.<locals>.<genexpr>>   s     
<';t7?';s   ) 
T)anyr)   recompilefnmatch	translateerror)r(   r!   	candidates   `  r"   _is_valid_include_patternr<   9   st    

<';
<<<'0H!IJJw((34 "
  88 s   3A) )B ?B c                T   ^  [        U5      nU(       d  g[        U 4S jU 5       5      $ )z8Return True if the basename matches the include pattern.Fc              3  R   >#    U  H  n[         R                   " TU5      v   M     g 7fr,   )r8   )r.   r;   basenames     r"   r0   )_match_include_pattern.<locals>.<genexpr>T   s     NX	wx33Xs   $')r)   r5   )r?   r(   r!   s   `  r"   _match_include_patternrA   N   s$    '0HNXNNNr$   c                      \ rS rSrSrSSS.       SS jjrSS jr        SS jr        SS	 jr\	      SS
 j5       r
Srg)FilesystemFileSearchMiddlewareW   aV  Provides Glob and Grep search over filesystem files.

This middleware adds two tools that search through local filesystem:

- Glob: Fast file pattern matching by file path
- Grep: Fast content search using ripgrep or Python fallback

Example:
    ```python
    from langchain.agents import create_agent
    from langchain.agents.middleware import (
        FilesystemFileSearchMiddleware,
    )

    agent = create_agent(
        model=model,
        tools=[],  # Add tools as needed
        middleware=[
            FilesystemFileSearchMiddleware(root_path="/workspace"),
        ],
    )
    ```
T
   )use_ripgrepmax_file_size_mbc                  ^  [        U5      R                  5       T l        UT l        US-  S-  T l        [
        SSU 4S jjj5       n[
           S         SU 4S jjj5       nUT l        UT l        XE/T l        g)	zInitialize the search middleware.

Args:
    root_path: Root directory to search.
    use_ripgrep: Whether to use `ripgrep` for search.

        Falls back to Python if `ripgrep` unavailable.
    max_file_size_mb: Maximum file size to search in MB.
i   c                r  >  TR                  U5      nUR                  5       (       a  UR                  5       (       d  g/ nUR	                  U 5       H  nUR                  5       (       d  M  S[        UR                  TR                  5      5      -   nUR                  5       n[        R                  " UR                  [        R                  S9R                  5       nUR!                  XW45        M     U(       d  gU VV	s/ s H  u  pUPM	     n
nn	SR#                  U
5      $ ! [         a     gf = fs  sn	nf )a'  Fast file pattern matching tool that works with any codebase size.

Supports glob patterns like `**/*.js` or `src/**/*.ts`.

Returns matching file paths sorted by modification time.

Use this tool when you need to find files by name patterns.

Args:
    pattern: The glob pattern to match files against.
    path: The directory to search in. If not specified, searches from root.

Returns:
    Newline-separated list of matching file paths, sorted by modification
    time (most recently modified first). Returns `'No files found'` if no
    matches.
zNo files found/)tzr3   )_validate_and_resolve_pathr   existsis_dirglobis_filer%   relative_to	root_pathstatr   fromtimestampst_mtimer   utc	isoformatr   join)r(   path	base_fullmatchingmatchvirtual_pathrS   modified_atp_
file_pathsselfs              r"   glob_search<FilesystemFileSearchMiddleware.__init__.<locals>.glob_search   s    &( ;;DA	 ##%%Y-=-=-?-?' /1H"0==??#&U->->t~~-N)O#OL ::<D"*"8"88<<"X"b"b"dKOO\$?@ 1 '(01!J199Z(()  ('(& 2s   D# D3#
D0/D0Nc                  >  [         R                  " U 5        U(       a  [        U5      (       d  gSnTR                  (       aH  [        [        [        R                  [        R                  5         TR                  XU5      nSSS5        Uc  TR                  XU5      nU(       d  gTR                  XS5      $ ! [         R                   a  nSU 3s SnA$ SnAff = f! , (       d  f       Nb= f)a  Fast content search tool that works with any codebase size.

Searches file contents using regular expressions. Supports full regex
syntax and filters files by pattern with the include parameter.

Args:
    pattern: The regular expression pattern to search for in file contents.
    path: The directory to search in. If not specified, searches from root.
    include: File pattern to filter (e.g., `'*.js'`, `'*.{ts,tsx}'`).
    output_mode: Output format:

        - `'files_with_matches'`: Only file paths containing matches
        - `'content'`: Matching lines with `file:line:content` format
        - `'count'`: Count of matches per file

Returns:
    Search results formatted according to `output_mode`.
        Returns `'No matches found'` if no results.
zInvalid regex pattern: NzInvalid include patternzNo matches found)r6   r7   r:   r<   rF   r   FileNotFoundError
subprocessCalledProcessErrorTimeoutExpired_ripgrep_search_python_search_format_grep_results)r(   rY   includeoutput_modeeresultsrb   s         r"   grep_search<FilesystemFileSearchMiddleware.__init__.<locals>.grep_search   s    65

7# 8AA0 G%11--
 #227'JG --gWE) ,,WBB1 88 50445 s)   B: 1C :CCCC 
C.)rJ   )r(   r%   rY   r%   r&   r%   )rJ   Nfiles_with_matches)
r(   r%   rY   r%   rm   
str | Nonern   z1Literal['files_with_matches', 'content', 'count']r&   r%   )	r   resolverR   rF   max_file_size_bytesr	   rc   rq   tools)rb   rR   rF   rG   rc   rq   s   `     r"   __init__'FilesystemFileSearchMiddleware.__init__p   s      i002&#3d#:T#A  
(	) (	) 
(	)T 
 "&Ma	4	C4	C4	C  4	C K	4	C
 4	C 
4	Cl '&!/
r$   c                @   UR                  S5      (       d  SU-   nSU;   d  SU;   a  Sn[        U5      eUR                  S5      nU R                  U-  R	                  5       n UR                  U R                  5        U$ ! [         a    SU 3n[        U5      Sef = f)z7Validate and resolve a virtual path to filesystem path.rJ   z..~zPath traversal not allowedzPath outside root directory: N)
startswithr   lstriprR   ru   rQ   )rb   rY   msgrelative	full_paths        r"   rL   9FilesystemFileSearchMiddleware._validate_and_resolve_path   s     s##:D 4<3$;.CS/! ;;s#^^h.779		,!!$..1
 	  	,1$8CS/t+	,s   $B Bc                J    U R                  U5      nUR                  5       (       d  0 $ SS/nU(       a  UR                  SU/5        UR                  SU[	        U5      /5         [
        R                  " USSSSS9n0 nUR                  R                  5        H  n [        R                  " U5      n	U	S	   S
:X  a|  U	S   S   S   n
S[	        [        U
5      R                  U R                   5      5      -   nU	S   S   nU	S   S   S   R#                  S5      nX;  a  / X{'   X{   R%                  X45        M  M     U$ ! [         a    0 s $ f = f! [
        R                  [        4 a    U R                  XU5      s $ f = f! [        R&                  [(        4 a     GM  f = f)z Search using ripgrep subprocess.rgz--jsonz--globz--T   F)capture_outputtexttimeoutchecktyper\   datarY   r   rJ   line_numberlinesr3   )rL   r   rM   extendr%   rg   runri   rf   rk   stdout
splitlinesjsonloadsr   rQ   rR   rstripr   JSONDecodeErrorKeyError)rb   r(   	base_pathrm   rZ   cmdresultrp   liner   rY   r]   line_num	line_texts                 r"   rj   .FilesystemFileSearchMiddleware._ripgrep_search  s   	77	BI !!I XJJ'*+

D'3y>23
	D^^#F 57MM,,.Dzz$'<7*</7D#&T$Z-C-CDNN-S)T#TL#F|M:H $VW 5f = D DT JI#202-)00(1FG + /  [  	I	. ))+<= 	D&&w7CC	D& (((3 s6   D? &E BF?EE,F ?F F"!F"c                    U R                  U5      nUR                  5       (       d  0 $ [        R                  " U5      n0 nUR                  S5       H  nUR                  5       (       d  M  U(       a  [        UR                  U5      (       d  M>  UR                  5       R                  U R                  :  a  Mh   UR                  5       n[        UR!                  5       S5       Ha  u  pUR#                  U
5      (       d  M  S[%        UR'                  U R(                  5      5      -   nX;  a  / Xk'   Xk   R+                  X45        Mc     M     U$ ! [         a    0 s $ f = f! [        [        4 a     GM$  f = f)z%Search using Python regex (fallback).*r   rJ   )rL   r   rM   r6   r7   rglobrP   rA   namerS   st_sizerv   	read_textUnicodeDecodeErrorPermissionError	enumerater   searchr%   rQ   rR   r   )rb   r(   r   rm   rZ   regexrp   	file_pathcontentr   r   r]   s               r"   rk   -FilesystemFileSearchMiddleware._python_search8  sW   	77	BI !!I

7#46 #-I$$&& 5inngNN ~~''$*B*BB#--/
 #,G,>,>,@!"D<<%%#&Y-B-B4>>-R)S#SL#202-)00(1AB #E% .2 G  	I	0 '8 s#   E <E#E E #E87E8c           	     $   US:X  a(  SR                  [        U R                  5       5      5      $ US:X  aY  / n[        U R                  5       5       H)  nX    H  u  pEUR                  U SU SU 35        M      M+     SR                  U5      $ US:X  aV  / n[        U R                  5       5       H&  n[	        X   5      nUR                  U SU 35        M(     SR                  U5      $ SR                  [        U R                  5       5      5      $ )z)Format grep results based on output mode.rs   r3   r   :count)rX   sortedkeysr   len)rp   rn   r   r   r   r   r   s          r"   rl   3FilesystemFileSearchMiddleware._format_grep_resultsc  s     ..99VGLLN344)#E#GLLN3	&-&8NHLLI;az4&!AB '9 4 99U##'!E#GLLN3	G./	{!E734 4 99U## yy/00r$   )rc   rq   rv   rR   rw   rF   N)rR   r%   rF   boolrG   intr&   r'   )rY   r%   r&   r   )r(   r%   r   r%   rm   rt   r&    dict[str, list[tuple[int, str]]])rp   r   rn   r%   r&   r%   )__name__
__module____qualname____firstlineno____doc__rx   rL   rj   rk   staticmethodrl   __static_attributes__r-   r$   r"   rC   rC   W   s    8 ! "y0 y0 	y0
 y0 
y0v033'*35?3	)3j))'*)5?)	))V 1111 
1 1r$   rC   )r(   r%   r&   zlist[str] | None)r(   r%   r&   r   )r?   r%   r(   r%   r&   r   )r   
__future__r   r8   r   r6   rg   
contextlibr   r   r   pathlibr   typingr   langchain_core.toolsr	   !langchain.agents.middleware.typesr
   r   r   r   r)   r<   rA   rC   __all__r-   r$   r"   <module>r      sn    #   	   '   % ^ ^D*Og1_Z	5JHV_5_%` g1V	 %r$   