§
    ÚŽ’jÄ=  ã                   óº   — d Z ddl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 ddlmZ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 ddlmZmZ  G d„ de¦  «        ZdS )zThe edit tool in agentscope.é    N)ÚAnyÚListé   )ÚToolBaseÚToolMiddlewareBase)ÚDEFAULT_DANGEROUS_FILESÚDEFAULT_DANGEROUS_DIRECTORIESé   )ÚPermissionContextÚPermissionDecisionÚPermissionBehaviorÚPermissionModeÚPermissionRule)Ú	ToolChunk)Ú	TextBlockÚToolResultState)Ú
AgentStateé   )ÚBackendBaseÚ_normalize_newlinesc                   óÎ  ‡ — 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d
dœddddœdœg d¢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<   eeddfdee         dee         dee         dz  dedz  ddf
ˆ fd„Zd e	ee
f         d!edefd"„Zd#edz  d e	ee
f         defd$„Zd e	ee
f         dee         fd%„Z	 	 d,d&ed'ed(ed)ed*edz  defd+„Z ˆ xZ!S )-ÚEditz@The edit tool for performing exact string replacements in files.Únamea:  Performs exact string replacements in files.

Usage:
- You must use your `Read` tool at least once in the conversation
  before editing. This tool will error if you attempt an edit without
  reading the file.
- When editing text from Read tool output, ensure you preserve the
  exact indentation (tabs/spaces) as it appears AFTER the line number
  prefix. The line number prefix format is: line number + tab.
  Everything after that is the actual file content to match. Never
  include any part of the line number prefix in the old_string or
  new_string.
- ALWAYS prefer editing existing files in the codebase. NEVER write
  new files unless explicitly required.
- Only use emojis if the user explicitly requests it. Avoid adding
  emojis to files unless asked.
- The edit will FAIL if `old_string` is not unique in the file.ÚdescriptionÚobjectÚstringz&The absolute path to the file to edit.)Útyper   zUThe exact string to replace. Must match exactly including whitespace and indentation.z&The string to replace old_string with.ÚbooleanzfIf true, replace all occurrences. If false (default), only replace if there is exactly one occurrence.F)r   r   Údefault)Ú	file_pathÚ
old_stringÚ
new_stringÚreplace_all)r    r!   r"   )r   Ú
propertiesÚrequiredÚinput_schemaÚis_mcpÚis_read_onlyÚis_concurrency_safeÚis_external_toolTÚis_state_injectedNÚdangerous_filesÚdangerous_directoriesÚmiddlewaresÚbackendÚreturnc                 óÊ   •— ddl m} t          ¦   «                              |¬¦  «         t	          |¦  «        | _        t	          |¦  «        | _        |p	 |¦   «         | _         dS )a†  Initialize the edit tool.

        Args:
            dangerous_files (`list[str]`, optional):
                Sensitive files that require explicit user confirmation,
                even in BYPASS mode. Matched by basename
                (case-insensitive). Defaults to `DEFAULT_DANGEROUS_FILES`.
                Pass a custom list to fully replace the defaults, or `[]`
                to disable the filename check.
            dangerous_directories (`list[str]`, optional):
                Sensitive directories that require explicit user
                confirmation. Matched when any path segment equals an
                entry (case-insensitive). Defaults to
                `DEFAULT_DANGEROUS_DIRECTORIES`. Pass a custom list to
                fully replace the defaults, or `[]` to disable the
                directory check.
            middlewares (`List[ToolMiddlewareBase] | None`, optional):
                Tool middlewares wrapping the tool execution.
            backend (`BackendBase | None`, optional):
                The sandbox backend to use for file I/O. When ``None``,
                a :class:`LocalBackend` is created.
        r   )ÚLocalBackend)r.   N)Ú_backendr2   ÚsuperÚ__init__Úlistr,   r-   )Úselfr,   r-   r.   r/   r2   Ú	__class__s         €úLC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\tool\_builtin\_edit.pyr5   zEdit.__init__W   si   ø€ ð: 	+Ð*Ð*Ð*Ð*Ð*å‰Œ×Ò [ÐÑ1Ô1Ð1Ý# OÑ4Ô4ˆÔÝ%)Ð*?Ñ%@Ô%@ˆÔ"ØÐ1 < <¡>¤>ˆŒˆˆó    Ú
tool_inputÚcontextc              ƒ   ó´  K  — |                      d¦  «        }|st          t          j        d¬¦  «        S |                      |¦  «        r t          t          j        d|› �dd¬¦  «        S |j        t          j        t          j	        fv r6|  
                    ||¦  «        r t          t          j        d|› d	�d
¬¦  «        S t          t          j        d¬¦  «        S )a|  Check permissions for file editing.

        This method implements Edit-specific permission checks:
        1. Dangerous path check (safety check, bypass-immune)
        2. ACCEPT_EDITS mode check for files in working directories

        Args:
            tool_input (`dict[str, Any]`):
                The tool input containing "file_path" key
            context (`PermissionContext`):
                The permission context with mode and rules

        Returns:
            `PermissionDecision`:
                ASK for dangerous paths, ALLOW for safe operations in
                ACCEPT_EDITS mode, PASSTHROUGH otherwise
        r    zNo file path provided)ÚbehaviorÚmessagez6Permission required: Edit operation on sensitive file z)Safety check: dangerous file or directoryT)r>   r?   Údecision_reasonÚbypass_immunezPermission granted for editing z (in working directory)z5File is in working directory and not a dangerous path)r>   r?   r@   Ú )Úgetr   r   ÚPASSTHROUGHÚ_is_dangerous_pathÚASKÚmoder   ÚACCEPT_EDITSÚDONT_ASKÚ_path_in_allowed_working_pathÚALLOW)r7   r;   r<   r    s       r9   Úcheck_permissionszEdit.check_permissions{   s$  è è € ð. —N’N ;Ñ/Ô/ˆ	Øð 	Ý%Ý+Ô7Ø/ðñ ô ð ð ×"Ò" 9Ñ-Ô-ð 	Ý%Ý+Ô/ð.Ø"+ð.ð .à KØ"ðñ ô ð ð Œ<ÝÔ'ÝÔ#ð
ð 
ð 
ð ×1Ò1°)¸WÑEÔEð Ý)Ý/Ô5ð.¸ið .ð .ð .ð%'ð	ñ ô ð õ "Ý'Ô3Øð
ñ 
ô 
ð 	
r:   Úrule_contentc              ƒ   ól   K  — |€dS |                      dd¦  «        }|sdS t          j        ||¦  «        S )a‹  Check if a permission rule matches the file path.

        Matches rule_content as a glob pattern against the "file_path"
        parameter using fnmatch. If rule_content is None, matches all
        invocations (tool-name-level rule).

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

        Returns:
            `bool`:
                True if the glob pattern matches the file path, False otherwise
        NTr    rB   F)rC   Úfnmatch)r7   rM   r;   r    s       r9   Ú
match_rulezEdit.match_rule»   sE   è è € ð, ÐØ�4à—N’N ;°Ñ3Ô3ˆ	Øð 	Ø�5ÝŒ˜y¨,Ñ7Ô7Ð7r:   c              ƒ   óì   K  — |                      dd¦  «        }|sg S | j                             |¦  «        }|r|                     d¦  «        dz   nd}t	          | j        |t          j        d¬¦  «        gS )a  Generate suggested permission rules for the file path.

        Suggests a glob pattern covering the parent directory of the file,
        allowing the user to grant permission for the entire directory at once.

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

        Returns:
            `List[PermissionRule]`:
                A single suggested rule covering the parent directory
                (e.g., file "/src/main.py" -> rule "src/**")
        r    rB   z/\z/**z**Ú	suggested)Ú	tool_namerM   r>   Úsource)rC   r3   ÚdirnameÚrstripr   r   r   rK   )r7   r;   r    ÚparentÚpatterns        r9   Úgenerate_suggestionszEdit.generate_suggestionsÙ   sŽ   è è € ð$ —N’N ;°Ñ3Ô3ˆ	Øð 	ØˆIà”×&Ò& yÑ1Ô1ˆð 5;ÐD�6—=’= Ñ'Ô'¨%Ñ/Ð/Àˆõ Øœ)Ø$Ý+Ô1Ø"ð	ñ ô ð
ð 	
r:   r    r!   r"   r#   Ú_agent_statec           	   ƒ   óN  K  — | j                              |¦  «        s.t          t          d|› �¬¦  «        gt          j        d¬¦  «        S | j                              |¦  «        ƒ d{V —†s.t          t          d|› �¬¦  «        gt          j        d¬¦  «        S ||k    r+t          t          d¬¦  «        gt          j        d¬¦  «        S d}|�h|j                             |¦  «        ƒ d{V —†}|€+t          t          d¬¦  «        gt          j        d¬¦  «        S d	 	                    |j
        ¦  «        }n˜	 | j                              |¦  «        ƒ d{V —†}t          |                     d
d¬¦  «        ¦  «        }nR# t          $ rE}	t          t          dt          |	¦  «        › �¬¦  «        gt          j        d¬¦  «        cY d}	~	S d}	~	ww xY w|                     |¦  «        }
|
dk    r.t          t          d|› �¬¦  «        gt          j        d¬¦  «        S |
dk    r4|s2t          t          d|
› d|› d�¬¦  «        gt          j        d¬¦  «        S |r|                     ||¦  «        }n|                     ||d¦  «        }	 | j                              ||                     d
¦  «        ¦  «        ƒ d{V —† nR# t          $ rE}	t          t          dt          |	¦  «        › �¬¦  «        gt          j        d¬¦  «        cY d}	~	S d}	~	ww xY w|rd|
› d�nd}d	 	                    t)          j        |                     d¬¦  «        |                     d¬¦  «        d|› �d|› �d¬¦  «        ¦  «        }t          t          d|› d|› �¬¦  «        gt          j        d|||r|
nddœ¬ ¦  «        S )!z'Execute the edit and return the result.z0Error: file_path must be an absolute path, got: )ÚtextT)ÚcontentÚstateÚis_lastNzError: File not found: zCError: old_string and new_string are identical. No changes to make.zBError: To edit a file, you must first read it using the Read tool.rB   zutf-8Úreplace)ÚerrorszError reading file: r   zError: old_string not found in r   zError: old_string appears z
 times in zT. Set replace_all=true to replace all occurrences, or make old_string more specific.zError writing file: zall z occurrencesz1 occurrence)Úkeependsza/zb/r
   )ÚfromfileÚtofileÚnzSuccessfully replaced z in )Údiffr    Úoccurrences)r]   r^   r_   Úmetadata)r3   Úisabsr   r   r   ÚERRORÚfile_existsÚtool_contextÚ	get_cacheÚjoinÚlinesÚ	read_filer   ÚdecodeÚ	ExceptionÚstrÚcountr`   Ú
write_fileÚencodeÚdifflibÚunified_diffÚ
splitlinesÚRUNNING)r7   r    r!   r"   r#   rZ   r]   ÚcacheÚrawÚerg   Úupdated_contentÚreplacement_msgÚ	diff_texts                 r9   Úcallz	Edit.callý   sU  è è € ð Œ}×"Ò" 9Ñ-Ô-ð 	Ýåð6Ø*3ð6ð 6ðñ ô ðõ &Ô+Øðñ ô ð ð ”]×.Ò.¨yÑ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9ð 	ÝåÐ#H¸YÐ#HÐ#HÐIÑIÔIðõ &Ô+Øðñ ô ð ð ˜Ò#Ð#Ýåð=ðñ ô ðõ &Ô+Øðñ ô ð ð ˆØÐ#Ø&Ô3×=Ò=¸iÑHÔHÐHÐHÐHÐHÐHÐHˆEØˆ}å å!ð"6ðñ ô ðõ *Ô/Ø ð	ñ 	ô 	ð 	ð —g’g˜eœkÑ*Ô*ˆGˆGðØ œM×3Ò3°IÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>�õ .Ø—J’J˜w¨y�JÑ9Ô9ñô ��øõ ð ð ð Ý Ý&Ð,KÅ3ÀqÁ6Ä6Ð,KÐ,KÐLÑLÔLÐMÝ)Ô/Ø ðñ ô ð ð ð ð ð ð øøøøðøøøð —m’m JÑ/Ô/ˆð ˜!ÒÐÝåØJ¸yÐJÐJðñ ô ðõ
 &Ô+Øðñ ô ð ð ˜Š?ˆ? ;ˆ?Ýåð9¸ð 9ð 9Ø(1ð9ð 9ð 9ðñ ô ð	õ &Ô+Øðñ ô ð ð  ð 	Ø%Ÿošo¨j¸*ÑEÔEˆOˆOà%ŸošoØØØñô ˆOð
	Ø”-×*Ò*ØØ×&Ò& wÑ/Ô/ñô ð ð ð ð ð ð ð ð øõ ð 	ð 	ð 	ÝÝ"Ð(G½sÀ1¹v¼vÐ(GÐ(GÐHÑHÔHÐIÝ%Ô+Øðñ ô ð ð ð ð ð ð øøøøð	øøøð 1<ÐOÐ,�;Ð,Ð,Ð,Ð,Àð 	ð —G’GÝÔ Ø×"Ò"¨DÐ"Ñ1Ô1Ø×*Ò*°DÐ*Ñ9Ô9Ø)˜iÐ)Ð)Ø'˜IÐ'Ð'Øðñ ô ñ
ô 
ˆ	õ åð&°/ð &ð &Ø#ð&ð &ðñ ô ðõ "Ô)Øà!Ø&Ø.9Ð@˜{˜{¸qðð ð
ñ 
ô 
ð 	
s=   Ä7AE< Å<
GÆ:GÇ GÇGÊ4J7 Ê7
LË:LË;LÌL)FN)"Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   rs   Ú__annotations__r   r&   Údictr   r'   Úboolr(   r)   r*   r+   r   r	   r6   r   r   r   r5   r   r   rL   rP   r   rY   r   r   r�   Ú__classcell__)r8   s   @r9   r   r      sÒ  ø€ € € € € € ØJÐJà€Dˆ#ÐÐÑØ/ðC€K�ð Cð Cñ Cð" 2ð ð !ØGðð ð
 !ð<ðð ð !ØGðð ð
 "ð"ð !ðð ð!
ð 
ð4 >Ð=Ð=ð9$ð $€L�$�s˜C�x”.ð ð ñ ð> €FˆDÐÐÑØ€L�$ÐÐÑØ %Ð˜Ð%Ð%Ñ%Ø"Ð�dÐ"Ð"Ñ"Ø"Ð�tÐ"Ð"Ñ"ð &=Ø+HØ7;Ø&*ð"2ð "2à˜cœð"2ð  $ Cœyð"2ð Ð,Ô-°Ñ4ð	"2ð
 ˜tÑ#ð"2ð 
ð"2ð "2ð "2ð "2ð "2ð "2ðH>
à˜˜c˜”Nð>
ð #ð>
ð 
ð	>
ð >
ð >
ð >
ð@8à˜D‘jð8ð ˜˜c˜”Nð8ð 
ð	8ð 8ð 8ð 8ð<"
à˜˜c˜”Nð"
ð 
ˆnÔ	ð"
ð "
ð "
ð "
ðR "Ø*.ði
ð i
àði
ð ði
ð ð	i
ð
 ði
ð ! 4Ñ'ði
ð 
ði
ð i
ð i
ð i
ð i
ð i
ð i
ð i
r:   r   )r…   rw   rO   Útypingr   r   Ú_baser   r   Ú
_constantsr   r	   Ú
permissionr   r   r   r   r   Ú	_responser   r?   r   r   r^   r   r3   r   r   r   © r:   r9   ú<module>r�      sO  ðà "Ð "Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ð Ð à 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0ðð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð "Ð !Ð !Ð !Ð !Ð !Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø Ð Ð Ð Ð Ð Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6ðM
ð M
ð M
ð M
ð M
ˆ8ñ M
ô M
ð M
ð M
ð M
r:   