§
    ÚŽ’j++  ã                  óº   — d Z ddlmZ ddlZddl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mZ dd
lmZ erddlmZ dd„Z G d„ de¦  «        ZdS )zThe glob tool in agentscope.é    )ÚannotationsN)ÚTYPE_CHECKINGÚAnyÚListé   )Ú	TextBlockÚToolResultState)ÚPermissionBehaviorÚPermissionContextÚPermissionDecisionÚPermissionRuleé   )ÚToolBaseÚToolMiddlewareBase)Ú	ToolChunké   )ÚBackendBaseÚreturnÚstrc                 ó|   — ddl m}  |                      d¦  «                             d¦  «        }t	          |¦  «        S )a,  Resolve the on-disk path of the bundled ``_glob_helper.py`` script.

    Used by :class:`Glob` when no explicit ``glob_helper_path`` is
    provided (i.e. the local-workspace case). The path is obtained via
    :mod:`importlib.resources` so it works for both editable and
    installed packages.
    r   Nz!agentscope.tool._builtin._scriptsz_glob_helper.py)Úimportlib.resourcesÚ	resourcesÚfilesÚjoinpathr   )Ú_resÚrefs     úLC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\tool\_builtin\_glob.pyÚ_default_glob_helper_pathr      sH   € ð 'Ð&Ð&Ð&Ð&Ð&à
�*Š*Ð8Ñ
9Ô
9×
BÒ
BØñô €Cõ ˆs‰8Œ8€Oó    c                  óâ   ‡ — e Zd ZU dZd Zded<   	 dZded<   	 dddd	œdd
d	œdœdgdœZded<   dZded<   dZ	ded<   dZ
ded<   dZded<   dZded<   	 	 	 d.d/ˆ fd!„Zd0d&„Zd1d(„Zd2d*„Z	 d3d4d-„Zˆ xZS )5ÚGlobz-The glob tool for fast file pattern matching.r   Únamea  Fast file pattern matching tool that works with
any codebase size.

Supports glob patterns like "**/*.js" or "src/**/*.ts" and returns
matching file paths sorted by modification time (newest first).

Use this tool when you need to find files by pattern across the
codebase.ÚdescriptionÚobjectÚstringzBThe glob pattern to match against (e.g., '**/*.py', 'src/**/*.ts'))Útyper#   zIThe base directory to search from (defaults to current working directory))ÚpatternÚpathr'   )r&   Ú
propertiesÚrequiredúdict[str, Any]Úinput_schemaFÚboolÚis_mcpTÚis_read_onlyÚis_concurrency_safeÚis_external_toolÚis_state_injectedNÚbackendúBackendBase | NoneÚglob_helper_pathú
str | NoneÚmiddlewaresúList[ToolMiddlewareBase] | Noner   ÚNonec                óÜ   •— ddl m} t          ¦   «                              |¬¦  «         |p	 |¦   «         | _         t	          | j         |¦  «        | _        |�|nt          ¦   «         | _        dS )a7  Initialize the glob tool.

        Args:
            middlewares (`List[ToolMiddlewareBase] | None`, optional):
                Tool middlewares wrapping the tool execution.
            backend (`BackendBase | None`, optional):
                The sandbox backend to use. When ``None``, a
                :class:`LocalBackend` is created automatically.
            glob_helper_path (`str | None`, optional):
                Filesystem path (inside the backend's environment) to
                the ``_glob_helper.py`` script. When ``None``, the
                path is resolved from the installed package resources
                (suitable for :class:`LocalBackend`). Remote backends
                (Docker, E2B) should pass the path where the script
                was deployed during workspace initialization.
        r   )ÚLocalBackend)r7   N)Ú_backendr;   ÚsuperÚ__init__Ú
isinstanceÚ	_is_localr   Ú_glob_helper_path)Úselfr3   r5   r7   r;   Ú	__class__s        €r   r>   zGlob.__init__Q   s€   ø€ ð, 	+Ð*Ð*Ð*Ð*Ð*å‰Œ×Ò [ÐÑ1Ô1Ð1ØÐ1 < <¡>¤>ˆŒõ $ D¤M°<Ñ@Ô@ˆŒð  Ð+ð Ðå*Ñ,Ô,ð 	ÔÐÐr   Ú
tool_inputÚcontextr   r   c              ƒ  ó<   K  — t          t          j        d¬¦  «        S )z¬Check permissions for glob pattern matching.

        Glob is a read-only tool. Return PASSTHROUGH to let the engine
        handle EXPLORE mode and rule matching.
        z#Glob pattern matching is read-only.)ÚbehaviorÚmessage)r   r
   ÚPASSTHROUGH)rB   rD   rE   s      r   Úcheck_permissionszGlob.check_permissionsu   s(   è è € õ "Ý'Ô3Ø9ð
ñ 
ô 
ð 	
r   Úrule_contentc              ƒ  óÎ   K  — |€dS |                      dd¦  «        }|rt          j        ||¦  «        rdS |                      dd¦  «        }|rt          j        ||¦  «        rdS dS )a  Check if a permission rule matches the glob pattern or path.

        Matches rule_content as a glob pattern against the "pattern" or "path"
        parameters. This allows rules to match either the search pattern itself
        or the directory being searched. If rule_content is None, matches all
        invocations (tool-name-level rule).

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

        Returns:
            `bool`:
                True if the rule matches the pattern or path, False otherwise
        NTr(   Ú r'   F)ÚgetÚfnmatch)rB   rK   rD   r(   r'   s        r   Ú
match_rulezGlob.match_rule„   s‚   è è € ð0 ÐØ�4ð �~Š~˜f bÑ)Ô)ˆØð 	•G”O D¨,Ñ7Ô7ð 	Ø�4ð —.’. ¨BÑ/Ô/ˆØð 	•w” w°Ñ=Ô=ð 	Ø�4àˆur   úList[PermissionRule]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 glob search.

        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
        Nr(   )Úcwdz/\z/**Ú	suggested)Ú	tool_namerK   rG   Úsource)	r<   ÚgetcwdrN   ÚabspathÚrstripr   r"   r
   ÚALLOW)rB   rD   Úbackend_cwdr(   Úabs_pathr'   s         r   Úgenerate_suggestionszGlob.generate_suggestions«   s¤   è è € ð" !œM×0Ò0Ñ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2ˆØ�~Š~˜fÑ%Ô%Ð4¨ˆð
 ”=×(Ò(¨°;Ð(Ñ?Ô?ˆØ—/’/ %Ñ(Ô(¨5Ñ0ˆõ Øœ)Ø$Ý+Ô1Ø"ð	ñ ô ð
ð 	
r   r(   r   c              ƒ  óò  K  — |r|n| j                              ¦   «         ƒ d{V —†}| j                              |¦  «        ƒ d{V —†s.t          t	          d|› �¬¦  «        gt
          j        d¬¦  «        S | j        rt          j	        nd}|| j
        d|d|g}| j                              |d	¬
¦  «        ƒ d{V —†}|                     ¦   «         s`|j                             dd¬¦  «                             ¦   «         }t          t	          |rd|› �nd¬¦  «        gt
          j        d¬¦  «        S 	 t!          j        |j                             dd¬¦  «        ¦  «        }n# t           j        t(          f$ r g }Y nw xY wt+          |¦  «        dk    r.t          t	          d|› �¬¦  «        gt
          j        d¬¦  «        S t          t	          d                     |¦  «        ¬¦  «        gt
          j        d¬¦  «        S )aÕ  Execute the glob pattern matching and return the results.

        Invokes the standalone ``_glob_helper.py`` script via
        ``exec_shell``. The script performs high-performance
        ``os.walk`` + ``os.scandir`` matching and returns results
        sorted by modification time (newest first) as JSON.

        This unified path works identically across Local, Docker,
        and E2B backends.

        Args:
            pattern (`str`):
                The glob pattern to match against (e.g. ``**/*.py``).
            path (`str | None`, optional):
                Base directory to search from. Defaults to the current
                working directory when ``None``.

        Returns:
            `ToolChunk`:
                On success, the matched file paths joined by newlines
                (or a "no files found" message). If the base directory
                is missing or the helper fails, an error chunk with
                ``ToolResultState.ERROR``.
        NzDirectory not found: )ÚtextT)ÚcontentÚstateÚis_lastÚpython3z	--patternz
--base-dirg      >@)Útimeoutzutf-8Úreplace)ÚerrorszGlob helper failed: z(Glob helper failed with no error output.r   z!No files found matching pattern: ú
)r<   rW   Úis_dirr   r   r	   ÚERRORr@   ÚsysÚ
executablerA   Ú
exec_shellÚokÚstderrÚdecodeÚstripÚjsonÚloadsÚstdoutÚJSONDecodeErrorÚ
ValueErrorÚlenÚRUNNINGÚjoin)	rB   r'   r(   Úbase_dirÚpythonÚcommandÚresultrn   Úmatchess	            r   Úcallz	Glob.callÎ   s}  è è € ð:  ÐA�4�4¨4¬=×+?Ò+?Ñ+AÔ+AÐ%AÐ%AÐ%AÐ%AÐ%AÐ%Aˆð
 ”]×)Ò)¨(Ñ3Ô3Ð3Ð3Ð3Ð3Ð3Ð3ð 	ÝåÐ#E¸8Ð#EÐ#EÐFÑFÔFðõ &Ô+Øðñ ô ð ð $(¤>Ð@•”�°yˆàØÔ"ØØØØð
ˆð ”}×/Ò/°ÀÐ/ÑFÔFÐFÐFÐFÐFÐFÐFˆð
 �yŠy‰{Œ{ð 	Ø”]×)Ò)¨'¸)Ð)ÑDÔD×JÒJÑLÔLˆFÝåà!ðHÐ<°FÐ<Ð<Ð<àGðñ ô ðõ &Ô+Øð
ñ 
ô 
ð 
ð	Ý”jØ”×$Ò$ W°YÐ$Ñ?Ô?ñô ˆGˆGøõ Ô$¥jÐ1ð 	ð 	ð 	ØˆGˆGˆGð	øøøõ ˆw‰<Œ<˜1ÒÐÝåØJÀÐJÐJðñ ô ðõ
 &Ô-Øðñ ô ð õ Ý D§I¢I¨gÑ$6Ô$6Ð7Ñ7Ô7Ð8Ý!Ô)Øð
ñ 
ô 
ð 	
s   Ä-.E ÅE7Å6E7)NNN)r3   r4   r5   r6   r7   r8   r   r9   )rD   r+   rE   r   r   r   )rK   r6   rD   r+   r   r-   )rD   r+   r   rQ   )N)r'   r   r(   r6   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   Ú__annotations__r#   r,   r.   r/   r0   r1   r2   r>   rJ   rP   r]   r~   Ú__classcell__)rC   s   @r   r!   r!   *   s§  ø€ € € € € € Ø7Ð7à€DÐÐÐÑØ/ð€Kð ð ð ñ ð 2ð ð !ð 3ðð ð !ð :ðð ð
ð 
ð �Kð$ð $€Lð ð ð ñ ð" €FÐÐÐÑØ€LÐÐÐÑØ $ÐÐ$Ð$Ð$Ñ$Ø"ÐÐ"Ð"Ð"Ñ"Ø#ÐÐ#Ð#Ð#Ñ#ð '+Ø'+Ø7;ð	"
ð "
ð "
ð "
ð "
ð "
ð "
ðH
ð 
ð 
ð 
ð%ð %ð %ð %ðN!
ð !
ð !
ð !
ðL  ðc
ð c
ð c
ð c
ð c
ð c
ð c
ð c
ð c
r   r!   )r   r   )r‚   Ú
__future__r   rO   rq   rj   Útypingr   r   r   rH   r   r	   Ú
permissionr
   r   r   r   Ú_baser   r   Ú	_responser   r<   r   r   r!   © r   r   ú<module>r‹      sB  ðà "Ð "à "Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø 
€
€
€
Ø +Ð +Ð +Ð +Ð +Ð +Ð +Ð +Ð +Ð +à 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1ðð ð ð ð ð ð ð ð ð ð ð ð 1Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø !Ð !Ð !Ð !Ð !Ð !àð &Ø%Ð%Ð%Ð%Ð%Ð%ðð ð ð ð"G
ð G
ð G
ð G
ð G
ˆ8ñ G
ô G
ð G
ð G
ð G
r   