§
    ÚŽ’jÓC  ã                   óº   — d Z ddlZddlmZmZmZ ddlmZmZ ddl	m
Z
mZmZmZ ddlmZ dd	lmZmZ d
dlmZ g d¢ZdZ G d„ de¦  «        Z G d„ de¦  «        ZdS )zThe grep tool in agentscope.é    N)ÚAnyÚListÚLiteralé   )ÚToolBaseÚToolMiddlewareBaseé   )ÚPermissionContextÚPermissionDecisionÚPermissionBehaviorÚPermissionRule)Ú	ToolChunk)Ú	TextBlockÚToolResultStateé   )ÚBackendBase)z.gitz.svnz.hgz.bzrz.jjz.sléú   c                   ó8   ‡ — e Zd ZdZdedee         fˆ fd„Zˆ xZS )ÚRipgrepTimeoutErrorz(Custom error class for ripgrep timeouts.ÚmessageÚpartial_resultsc                 óX   •— t          ¦   «                              |¦  «         || _        d S ©N)ÚsuperÚ__init__r   )Úselfr   r   Ú	__class__s      €úLC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\tool\_builtin\_grep.pyr   zRipgrepTimeoutError.__init__"   s)   ø€ Ý‰Œ×Ò˜Ñ!Ô!Ð!Ø.ˆÔÐÐó    )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstrÚlistr   Ú__classcell__©r   s   @r   r   r      sU   ø€ € € € € Ø2Ð2ð/ ð /°d¸3´ið /ð /ð /ð /ð /ð /ð /ð /ð /ð /r   r   c                   óî  ‡ — e Zd ZU dZd Zeed<   	 dZeed<   	 ddddœdd	dœdg d
¢dddœdddœdddœdddœdddœdddœdddœddddœddddœddddœddddœddddœdd ddd!œd"œd#gd$œZe	ee
f         ed%<   dZeed&<   dZeed'<   dZeed(<   dZeed)<   dZeed*<   	 	 dJd,ee         d+z  d-ed+z  d.d+fˆ fd/„Zd0e	ee
f         d1ed.efd2„Zd3ed+z  d0e	ee
f         d.efd4„Zd0e	ee
f         d.ee         fd5„Z	 dKd6ee         d7ed+z  d8ed.eee         ed+z  f         fd9„Z	 dLd;ee         d<ed=ed.ee         fd>„Z	 	 	 	 	 	 	 	 	 	 	 dMd#ed?ed+z  d@e d
         dAed+z  dBed+z  dCedDed1ed+z  dEedFed+z  d8edGedHe
d.e!fdI„Z"ˆ xZ#S )NÚGrepz8The grep tool for searching file contents using ripgrep.Únamea  A powerful search tool built on ripgrep

  Usage:
- ALWAYS use Grep for search tasks. NEVER invoke `grep` or `rg` as a Bash command. The Grep tool has been optimized for correct permissions and access.
- Supports full regex syntax (e.g., "log.*Error", "function\s+\w+")
- Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust")
- Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts per file
- Context lines: use context parameter or -A/-B/-C for lines after/before/around matches
- Case-insensitive search: set i to true
- Multiline regex: set multiline to true for patterns spanning multiple lines
- Limit results: use head_limit to cap the number of results returnedÚdescriptionÚobjectÚstringz>The regular expression pattern to search for in file contents.)Útyper+   zFFile or directory to search in. Defaults to current working directory.)ÚcontentÚfiles_with_matchesÚcountzöOutput mode: 'content' shows matching lines (supports -A/-B/-C context, -n line numbers, head_limit), 'files_with_matches' shows file paths (supports head_limit), 'count' shows match counts (supports head_limit). Defaults to 'files_with_matches'.r0   )r.   Úenumr+   Údefaultz:Glob pattern to filter files (e.g., '*.js', '*.{ts,tsx}').zKFile type to search (rg --type). Common types: js, py, rust, go, java, etc.ÚintegerzJNumber of lines to show after each match. Requires output_mode: 'content'.zKNumber of lines to show before each match. Requires output_mode: 'content'.zAlias for context.zZNumber of context lines to show before and after matches. Requires output_mode: 'content'.ÚbooleanzOShow line numbers in output. Requires output_mode: 'content'. Defaults to true.T)r.   r+   r3   zCase insensitive search.Fz&Case insensitive search (alias for i).z[Enable multiline mode where . matches newlines and patterns can span lines. Default: false.z^Limit output to first N lines/entries. Defaults to 250 when unspecified. Pass 0 for unlimited.r   )r.   r+   ÚminimumzESkip first N lines/entries before applying head_limit. Defaults to 0.)r.   r+   r3   r6   )ÚpatternÚpathÚoutput_modeÚglobr.   ú-Aú-Bú-CÚcontextÚnÚiÚcase_insensitiveÚ	multilineÚ
head_limitÚoffsetr7   )r.   Ú
propertiesÚrequiredÚinput_schemaÚis_mcpÚis_read_onlyÚis_concurrency_safeÚis_external_toolÚis_state_injectedNÚmiddlewaresÚbackendÚreturnc                 óz   •— ddl m} t          ¦   «                              |¬¦  «         |p	 |¦   «         | _         dS )a  Initialize the grep tool.

        Args:
            middlewares (`List[ToolMiddlewareBase] | None`, optional):
                Tool middlewares wrapping the tool execution.
            backend (`BackendBase | None`, optional):
                The sandbox backend to use for shell execution. When
                ``None``, a :class:`LocalBackend` is created.
                Ripgrep is always invoked via ``exec_shell`` so that
                the same code path works for local, Docker, and E2B
                backends.
        r   )ÚLocalBackend)rM   N)Ú_backendrQ   r   r   )r   rM   rN   rQ   r   s       €r   r   zGrep.__init__Ÿ   sH   ø€ ð" 	+Ð*Ð*Ð*Ð*Ð*å‰Œ×Ò [ÐÑ1Ô1Ð1ØÐ1 < <¡>¤>ˆŒˆˆr   Ú
tool_inputr>   c              ƒ   ó<   K  — t          t          j        d¬¦  «        S )z"Check permissions for grep search.zGrep search is read-only.)Úbehaviorr   )r   r   ÚPASSTHROUGH)r   rS   r>   s      r   Úcheck_permissionszGrep.check_permissionsµ   s(   è è € õ "Ý'Ô3Ø/ð
ñ 
ô 
ð 	
r   Úrule_contentc              ƒ   ó¦   K  — |€dS |                      dd¦  «        }|s| j                             ¦   «         ƒ d{V —†}t          j        ||¦  «        S )aá  Check if a permission rule matches the grep search path.

        Matches rule_content as a glob pattern against the "path" parameter.
        If no path is given, falls back to the current working directory.
        If rule_content is None, matches all invocations (tool-name-level
        rule).

        Args:
            rule_content (`str | None`):
                Glob pattern to match against the search path (e.g., "src/**"),
                or None to match all invocations
            tool_input (`dict[str, Any]`):
                The tool input data containing optional "path" key

        Returns:
            `bool`:
                True if the glob pattern matches the search path, False
                otherwise
        NTr8   Ú )ÚgetrR   ÚgetcwdÚfnmatch)r   rX   rS   r8   s       r   Ú
match_rulezGrep.match_ruleÀ   se   è è € ð2 ÐØ�4à�~Š~˜f bÑ)Ô)ˆØð 	0Øœ×-Ò-Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ð/ˆDÝŒ˜t \Ñ2Ô2Ð2r   c              ƒ   ó   K  — | j                              ¦   «         ƒ d{V —†}|                     d¦  «        p|}| j                              ||¬¦  «        }|                     d¦  «        dz   }t          | j        |t          j        d¬¦  «        gS )a½  Generate suggested permission rules for the grep search path.

        Suggests a rule based on the search path. If no path is provided,
        suggests a rule for the current directory.

        Args:
            tool_input (`dict[str, Any]`):
                The tool input data containing optional "path" key

        Returns:
            `List[PermissionRule]`:
                A single suggested rule covering the search directory
        Nr8   )Úcwdz/\z/**Ú	suggested)Ú	tool_namerX   rU   Úsource)	rR   r\   r[   ÚabspathÚrstripr   r*   r   ÚALLOW)r   rS   Úbackend_cwdr8   Úabs_pathr7   s         r   Úgenerate_suggestionszGrep.generate_suggestionsá   s¤   è è € ð" !œM×0Ò0Ñ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2ˆØ�~Š~˜fÑ%Ô%Ð4¨ˆà”=×(Ò(¨°;Ð(Ñ?Ô?ˆð —/’/ %Ñ(Ô(¨5Ñ0ˆõ Øœ)Ø$Ý+Ô1Ø"ð	ñ ô ð
ð 	
r   ÚitemsÚlimitrD   c                 ó’   — |dk    r||d…         dfS |�|nt           }||||z   …         }t          |¦  «        |z
  |k    }||r|ndfS )zuApply head_limit and offset to a list of items.

        Returns (sliced_items, applied_limit_if_truncated).
        r   N)ÚDEFAULT_HEAD_LIMITÚlen)r   rj   rk   rD   Úeffective_limitÚslicedÚwas_truncateds          r   Ú_apply_head_limitzGrep._apply_head_limit  sl   € ð �AŠ:ˆ:Ø˜˜˜”> 4Ð'Ð'Ø#(Ð#4˜%˜%Õ:LˆØ�v ¨Ñ 8Ð8Ô9ˆÝ˜E™
œ
 VÑ+¨oÒ=ˆØ¨=ÐB˜˜¸dÐCÐCr   é   ÚargsÚsearch_pathÚtimeoutc              ƒ   óâ  K  — dg|¢|‘}| j                              |t          |¦  «        ¬¦  «        ƒ d{V —†}|j        dk    r|j        dk    rt          d|› d�g ¦  «        ‚|j        dvrH|j                             d	d
¬¦  «                             ¦   «         }t          d|j        › d|› �¦  «        ‚|j	                             d	d
¬¦  «        }d„ | 
                    d¦  «        D ¦   «         }|S )a>  Run ripgrep and return output lines.

        Builds an argument vector and dispatches it through
        ``backend.exec_shell`` (which runs the program directly, without
        a shell), so the same code path works for local, Docker, and E2B
        backends and needs no platform-specific argument quoting.
        Úrg)rv   Néÿÿÿÿs	   timed outzRipgrep search timed out after z8 seconds. Try searching a more specific path or pattern.)r   r   zutf-8Úignore)Úerrorszripgrep error (code z): c                 ób   — g | ],}|                      d ¦  «        ¯|                      d ¦  «        ‘Œ-S )ú)re   )Ú.0Úlines     r   ú
<listcomp>z%Grep._run_ripgrep.<locals>.<listcomp>;  sE   € ð 
ð 
ð 
Ø"&¸T¿[º[ÈÑ=NÔ=Nð
Ø�KŠK˜ÑÔð
ð 
ð 
r   ú
)rR   Ú
exec_shellÚfloatÚ	exit_codeÚstderrr   ÚdecodeÚstripÚRuntimeErrorÚstdoutÚsplit)	r   rt   ru   rv   ÚcommandÚresultÚ	error_msgÚrawÚliness	            r   Ú_run_ripgrepzGrep._run_ripgrep  s`  è è € ð Ð,˜$Ð, Ð,ˆà”}×/Ò/ØÝ˜'‘N”Nð 0ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆð
 Ô˜rÒ!Ð! f¤m°|Ò&CÐ&CÝ%ðA°'ð Að Að Aàñô ð ð Ô 6Ð)Ð)Øœ×,Ò,ØØð -ñ ô ÷ Še‰gŒgð õ ØG vÔ'7ÐGÐG¸IÐGÐGñô ð ð Œm×"Ò" 7°8Ð"Ñ<Ô<ˆð
ð 
Ø*-¯)ª)°D©/¬/ð
ñ 
ô 
ˆð ˆr   r8   r9   r:   r.   r@   rA   rB   rC   r?   Úkwargsc              ‹   óÒ  K  — |p| j                              ¦   «         ƒ d{V —†}|
�1|
dk     r+t          t          d¬¦  «        gt          j        d¬¦  «        S |dk     r+t          t          d¬¦  «        gt          j        d¬¦  «        S dg}t          D ]}|                     d	d
|› �g¦  «         Œ|                     ddg¦  «         |	r|                     ddg¦  «         |s|r|                     d¦  «         |dk    r|                     d¦  «         n|dk    r|                     d¦  «         |r|dk    r|                     d¦  «         |dk    rÙ| 	                    d¦  «        }| 	                    d¦  «        }| 	                    d¦  «        }|�%|                     dt          |¦  «        g¦  «         ns|�%|                     dt          |¦  «        g¦  «         nL|�$|                     dt          |¦  «        g¦  «         |�$|                     dt          |¦  «        g¦  «         |                     d¦  «        r|                     d|g¦  «         n|                     |¦  «         |�|                     d|g¦  «         |�‡|                     ¦   «         }g }|D ]R}d|v rd|v r|                     |¦  «         Œ |                     d„ |                     d¦  «        D ¦   «         ¦  «         ŒS|D ]}|                     d	|g¦  «         Œ	 |                      ||¦  «        ƒ d{V —†}n™# t          $ rB}t          t          t          |¦  «        ¬¦  «        gt          j        d¬¦  «        cY d}~S d}~wt          $ rB}t          t          t          |¦  «        ¬¦  «        gt          j        d¬¦  «        cY d}~S d}~ww xY w|s.t          t          d |› �¬¦  «        gt          j        d¬¦  «        S |                      ||
|¦  «        \  }}d!}|�d"|› �}|r|d#|› �z  }|d$z  }t          t          d%                     |¦  «        |z   ¬¦  «        gt          j        d¬¦  «        S )&aN  Execute the grep search using ripgrep.

        Args:
            pattern: The regex pattern to search for
            path: The directory or file path to search in
            output_mode: Output mode ('content', 'files_with_matches', 'count')
            glob: Glob pattern to filter files
            type: File type to filter by (rg --type)
            i: Case-insensitive search (rg -i)
            case_insensitive: Alias for i (backward compatibility)
            context: Number of context lines around matches
            multiline: Enable multiline regex matching
            head_limit: Maximum number of results to return
            (default 250, 0=unlimited)
            offset: Skip first N results
            n: Show line numbers (content mode only, default True)
            **kwargs: Additional parameters (-A, -B, -C)
        Nr   z'Error: head_limit must be non-negative.)ÚtextT)r/   ÚstateÚis_lastz#Error: offset must be non-negative.z--hiddenz--globú!z--max-columnsÚ500z-Uz--multiline-dotallz-ir0   z-lr1   z-cr/   z-nr;   r<   r=   ú-z-ez--typeÚ{Ú}c              3   ó   K  — | ]}|¯|V — Œ	d S r   © )r~   Úps     r   ú	<genexpr>zGrep.call.<locals>.<genexpr>¸  s'   è è € Ð(HÐ(H¨qÀaÐ(H¨Ð(HÐ(HÐ(HÐ(HÐ(HÐ(Hr   ú,zNo matches found for pattern: rZ   z,

[Showing results with pagination = limit: z
, offset: ú]r�   )rR   r\   r   r   r   ÚERRORÚVCS_DIRECTORIES_TO_EXCLUDEÚextendÚappendr[   r$   Ú
startswithrŠ   r�   r   rˆ   ÚSUCCESSrr   Újoin)r   r7   r8   r9   r:   r.   r@   rA   r>   rB   rC   rD   r?   r‘   ru   rt   Úvcs_dirÚAÚBÚCÚraw_patternsÚglob_patternsrŽ   ÚgpÚresultsÚeÚlimitedÚapplied_limitÚsuffixs                                r   Úcallz	Grep.call@  sŽ  è è € ðL Ð: D¤M×$8Ò$8Ñ$:Ô$:Ð:Ð:Ð:Ð:Ð:Ð:ˆàÐ! j°1¢n nÝåÐ#LÐMÑMÔMðõ &Ô+Øðñ ô ð ð �AŠ:ˆ:ÝåÐ#HÐIÑIÔIðõ &Ô+Øðñ ô ð ð &˜,ˆõ 2ð 	3ð 	3ˆGØ�KŠK˜ = w = =Ð1Ñ2Ô2Ð2Ð2ð 	�Š�_ eÐ,Ñ-Ô-Ð-ð ð 	6Ø�KŠK˜Ð3Ð4Ñ5Ô5Ð5ð ð 	Ð ð 	Ø�KŠK˜ÑÔÐð Ð.Ò.Ð.Ø�KŠK˜ÑÔÐÐØ˜GÒ#Ð#Ø�KŠK˜ÑÔÐð ð 	� 	Ò)Ð)Ø�KŠK˜ÑÔÐð ˜)Ò#Ð#Ø—
’
˜4Ñ Ô ˆAØ—
’
˜4Ñ Ô ˆAØ—
’
˜4Ñ Ô ˆAàÐ"Ø—’˜T¥3 w¡<¤<Ð0Ñ1Ô1Ð1Ð1Ø�Ø—’˜T¥3 q¡6¤6˜NÑ+Ô+Ð+Ð+à�=Ø—K’K ¥s¨1¡v¤v Ñ/Ô/Ð/Ø�=Ø—K’K ¥s¨1¡v¤v Ñ/Ô/Ð/ð ×Ò˜cÑ"Ô"ð 	!Ø�KŠK˜˜w˜Ñ(Ô(Ð(Ð(à�KŠK˜Ñ Ô Ð ð ÐØ�KŠK˜ 4Ð(Ñ)Ô)Ð)ð ÐØŸ:š:™<œ<ˆLØ')ˆMØ#ð Ið I�Ø˜#�:�: #¨ * *Ø!×(Ò(¨Ñ-Ô-Ð-Ð-à!×(Ò(Ð(HÐ(H°C·I²I¸c±N´NÐ(HÑ(HÔ(HÑHÔHÐHÐHØ#ð ,ð ,�Ø—’˜X r˜NÑ+Ô+Ð+Ð+ð	Ø ×-Ò-¨d°KÑ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@ˆGˆGøÝ"ð 	ð 	ð 	ÝÝ"­¨A©¬Ð/Ñ/Ô/Ð0Ý%Ô+Øðñ ô ð ð ð ð ð ð øøøøõ
 ð 	ð 	ð 	ÝÝ"­¨A©¬Ð/Ñ/Ô/Ð0Ý%Ô+Øðñ ô ð ð ð ð ð ð øøøøð	øøøð ð 	ÝåÐ#MÀGÐ#MÐ#MÐNÑNÔNðõ &Ô-Øðñ ô ð ð "&×!7Ò!7ØØØñ"
ô "
Ñˆ�ð ˆØÐ$ð*Ø'ð*ð *ð ð ð 0ØÐ/ vÐ/Ð/Ñ/�Ø�c‰MˆFåÝ D§I¢I¨gÑ$6Ô$6¸Ñ$?Ð@Ñ@Ô@ÐAÝ!Ô)Øð
ñ 
ô 
ð 	
s0   ÌL- Ì-
OÌ77M4Í.OÍ4OÎ7N>Î8OÎ>O)NN)r   )rs   )Nr0   NNFFNFNr   T)$r    r!   r"   r#   r*   r$   Ú__annotations__r+   rG   Údictr   rH   ÚboolrI   rJ   rK   rL   r   r   r   r   r
   r   rW   r^   r   ri   r%   ÚintÚtuplerr   r�   r   r   r´   r&   r'   s   @r   r)   r)   '   sô  ø€ € € € € € ØBÐBà€Dˆ#ÐÐÑØ/ð
I€K�ð 
Ið 
Iñ 
Ið 2ð ð !ð (ðð ð !ð 0ðð ð !ØBÐBÐBð 4ð 0ð
ð 
ð !ð !ðð ð !ð =ðð ð "ð 3ðð ð "ð 3ðð ð "Ø3ðð ð
 "ð ðð ð "ð <àð	ð ð "Ø9Ø ðð ð "ØGØ ð!ð !ð "ð "ð !ðð ð "ð (ð ðð ð "ð -àØðð ðeY
ð Y
ðt �Kðy]$ð ]$€L�$�s˜C�x”.ð ]ð ]ñ ]ð~ €FˆDÐÐÑØ€L�$ÐÐÑØ $Ð˜Ð$Ð$Ñ$Ø"Ð�dÐ"Ð"Ñ"Ø#Ð�tÐ#Ð#Ñ#ð 8<Ø&*ð2ð 2àÐ,Ô-°Ñ4ð2ð ˜tÑ#ð2ð 
ð	2ð 2ð 2ð 2ð 2ð 2ð,	
à˜˜c˜”Nð	
ð #ð	
ð 
ð		
ð 	
ð 	
ð 	
ð3à˜D‘jð3ð ˜˜c˜”Nð3ð 
ð	3ð 3ð 3ð 3ðB 
à˜˜c˜”Nð 
ð 
ˆnÔ	ð 
ð  
ð  
ð  
ðL ð	Dð Dà�CŒyðDð �T‰zðDð ð	Dð
 
ˆt�CŒy˜# ™*Ð$Ô	%ðDð Dð Dð Dð* ð	*ð *à�3Œið*ð ð*ð ð	*ð
 
ˆcŒð*ð *ð *ð *ð^  ð
 !ØØØØ!&Ø"ØØ!%ØØð#h
ð h
àðh
ð �D‰jðh
ð ðô
ð	h
ð �D‰jðh
ð �D‰jðh
ð ðh
ð ðh
ð �t‘ðh
ð ðh
ð ˜$‘Jðh
ð  ð!h
ð" ð#h
ð$ ð%h
ð& 
ð'h
ð h
ð h
ð h
ð h
ð h
ð h
ð h
r   r)   )r#   r]   Útypingr   r   r   Ú_baser   r   Ú
permissionr
   r   r   r   Ú	_responser   r   r   r   rR   r   r¢   rm   Ú	Exceptionr   r)   rœ   r   r   ú<module>r¿      sF  ðà "Ð "Ø €€€Ø %Ð %Ð %Ð %Ð %Ð %Ð %Ð %Ð %Ð %à 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0ðð ð ð ð ð ð ð ð ð ð ð ð "Ð !Ð !Ð !Ð !Ð !Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø !Ð !Ð !Ð !Ð !Ð !ðð ð Ð ð Ð ð/ð /ð /ð /ð /˜)ñ /ô /ð /ðA
ð A
ð A
ð A
ð A
ˆ8ñ A
ô A
ð A
ð A
ð A
r   