§
    ÚŽ’j�*  ã                   óž   — d 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
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 read tool in agentscope.é    N)ÚAnyÚListé   )ÚToolBaseÚToolMiddlewareBaseé   )ÚPermissionContextÚPermissionDecisionÚPermissionBehaviorÚ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œ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<   	 	 	 d+d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z  def
d*„Zˆ xZS )-ÚReadzThe read tool.ÚnameaÒ  Reads a file from the local filesystem. You can access any file directly by using this tool.
Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.

Usage:
- The file_path parameter must be an absolute path, not a relative path
- By default, it reads up to 2000 lines starting from the beginning of the file
- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters
- Results are returned using cat -n format, with line numbers starting at 1
- This tool allows you to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as you're a multimodal LLM.
- This tool can read PDF files (.pdf). For large PDFs (more than 10 pages), you MUST provide the pages parameter to read specific pages.ÚdescriptionÚobjectÚstringz&The absolute path to the file to read.)Útyper   Úintegerz?Optional 1-based line number to start reading from (default: 1)r   )r   r   ÚdefaultÚminimumzCOptional maximum number of lines to read (default: 2000, max: 2000)éÐ  )r   r   r   Úmaximumr   )Ú	file_pathÚoffsetÚlimitr    )r   Ú
propertiesÚrequiredÚinput_schemaFÚis_mcpTÚis_read_onlyÚis_concurrency_safeÚis_external_toolÚis_state_injectedNÚmax_line_charactersÚmiddlewaresÚbackendÚreturnc                 óˆ   •— ddl m} t          ¦   «                              |¬¦  «         || _        |p	 |¦   «         | _         dS )aî  Initialize the read tool.

        Args:
            max_line_characters (`int`, defaults to 2000):
                The maximum number of characters to include for each line when
                reading files. Lines longer than this will be truncated with
                a "[truncated]" suffix. This prevents overwhelming the agent
                with excessively long lines while still providing useful
                content.
            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)Ú_backendr0   ÚsuperÚ__init__Ú_max_line_characters)Úselfr+   r,   r-   r0   Ú	__class__s        €úLC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\tool\_builtin\_read.pyr3   zRead.__init__F   sP   ø€ ð* 	+Ð*Ð*Ð*Ð*Ð*å‰Œ×Ò [ÐÑ1Ô1Ð1Ø$7ˆÔ!ØÐ1 < <¡>¤>ˆŒˆˆó    Ú
tool_inputÚcontextc              ƒ   ó<   K  — t          t          j        d¬¦  «        S )zÿCheck permissions for file reading.

        Read is a read-only tool. In EXPLORE mode the engine already handles
        the ALLOW via _check_explore_mode, so here we just return PASSTHROUGH
        to let the engine continue with rule matching.
        zFile reading is read-only.)ÚbehaviorÚmessage)r
   r   ÚPASSTHROUGH)r5   r9   r:   s      r7   Úcheck_permissionszRead.check_permissionsa   s(   è è € õ "Ý'Ô3Ø0ð
ñ 
ô 
ð 	
r8   Ú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    Ú F)ÚgetÚfnmatch)r5   r@   r9   r    s       r7   Ú
match_rulezRead.match_ruleq   sE   è è € ð. ÐØ�4à—N’N ;°Ñ3Ô3ˆ	Øð 	Ø�5ÝŒ˜y¨,Ñ7Ô7Ð7r8   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_namer@   r<   Úsource)rC   r1   ÚdirnameÚrstripr   r   r   ÚALLOW)r5   r9   r    ÚparentÚpatterns        r7   Úgenerate_suggestionszRead.generate_suggestions�   sŽ   è è € ð$ —N’N ;°Ñ3Ô3ˆ	Øð 	ØˆIà”×&Ò& yÑ1Ô1ˆð 5;ÐD�6—=’= Ñ'Ô'¨%Ñ/Ð/Àˆõ Øœ)Ø$Ý+Ô1Ø"ð	ñ ô ð
ð 	
r8   r!   r"   Ú_agent_statec           	   ƒ   ód  K  — | j                              |¦  «        s.t          t          d|› �¬¦  «        gt          j        d¬¦  «        S | j                              |¦  «        ƒ d{V —†s.t          t          d|› �¬¦  «        gt          j        d¬¦  «        S | j                              |¦  «        ƒ d{V —†r.t          t          d|› �¬¦  «        gt          j        d¬¦  «        S 	 d}|�)|j         	                    |¦  «        ƒ d{V —†}|�|j
        }|€€| j                              |¦  «        ƒ d{V —†}|                     dd	¬
¦  «        }t          |¦  «        }|                     d¬¦  «        }|�"|j                             ||¬¦  «        ƒ d{V —† |dz
  }	|	|z   }
||	|
…         }g }t!          ||¬¦  «        D ]a\  }}|                     d¦  «        }t%          |¦  «        | j        k    r|d| j        …         dz   }|d›d|› �}|                     |¦  «         Œbd                     |¦  «        }t          t          |¬¦  «        gt          j        d¬¦  «        S # t.          $ rE}t          t          dt1          |¦  «        › �¬¦  «        gt          j        d¬¦  «        cY d}~S d}~ww xY w)z7Read the file and return the content with line numbers.z0Error: file_path must be an absolute path, got: )ÚtextT)ÚcontentÚstateÚis_lastNzError: File does not exist: z(Error: Path is a directory, not a file: zutf-8Úreplace)Úerrors)Úkeepends)r    Úlinesr   )Ústartz
z[truncated]Ú6dú	ú
zError reading file: )r1   Úisabsr   r   r   ÚERRORÚfile_existsÚis_dirÚtool_contextÚ	get_cacherY   Ú	read_fileÚdecoder   Ú
splitlinesÚ
cache_fileÚ	enumeraterK   Úlenr4   ÚappendÚjoinÚRUNNINGÚ	ExceptionÚstr)r5   r    r!   r"   rP   rY   ÚcacheÚrawÚcontent_strÚ	start_idxÚend_idxÚselected_linesÚformatted_linesÚiÚlineÚline_contentÚformatted_lineÚresultÚes                      r7   Úcallz	Read.call´   sÂ  è è € ð Œ}×"Ò" 9Ñ-Ô-ð 
	Ýåð,Ø )ð,ð ,ðñ ô ðõ &Ô+Øð	ñ 	ô 	ð 	ð ”]×.Ò.¨yÑ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9ð 	ÝåÐ#MÀ)Ð#MÐ#MÐNÑNÔNðõ &Ô+Øðñ ô ð ð ”×%Ò% iÑ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0ð 
	Ýåð'Ø$ð'ð 'ðñ ô ðõ &Ô+Øð	ñ 	ô 	ð 	ð<	àˆEØÐ'Ø*Ô7×AÒAÀ)ÑLÔLÐLÐLÐLÐLÐLÐL�ØÐ$Ø!œK�Eàˆ}Ø œM×3Ò3°IÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>�Ø!Ÿjšj¨¸˜jÑCÔC�õ 2°+Ñ>Ô>�Ø#×.Ò.¸Ð.Ñ=Ô=�ð  Ð+Ø&Ô3×>Ò>Ø"+Ø#ð ?ñ ô ð ð ð ð ð ð ð ð  ™
ˆIØ %Ñ'ˆGØ" 9¨WÐ#4Ô5ˆNð !ˆOÝ$ ^¸6ÐBÑBÔBð 7ð 7‘��4à#Ÿ{š{¨6Ñ2Ô2�õ �|Ñ$Ô$ tÔ'@Ò@Ð@à$Ð%@ tÔ'@Ð%@ÔAØ'ñ(ð !ð %&Ð!:Ð!:Ð!:¨LÐ!:Ð!:�Ø×&Ò& ~Ñ6Ô6Ð6Ð6ð —Y’Y˜Ñ/Ô/ˆFåÝ"¨Ð/Ñ/Ô/Ð0Ý%Ô-Øðñ ô ð øõ ð 	ð 	ð 	ÝÝ"Ð(G½sÀ1¹v¼vÐ(GÐ(GÐHÑHÔHÐIÝ%Ô+Øðñ ô ð ð ð ð ð ð øøøøð	øøøs   Ã(E7I  É 
J/É*:J*Ê$J/Ê*J/)r   NN)r   r   N) Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   rn   Ú__annotations__r   r%   Údictr   r&   Úboolr'   r(   r)   r*   Úintr   r   r   r3   r	   r
   r?   rE   r   rO   r   r   r|   Ú__classcell__)r6   s   @r7   r   r      s§  ø€ € € € € € ØÐà€Dˆ#ÐÐÑØ/ð	L€K�ð 	Lð 	Lñ 	Lð 2ð ð !ØGðð ð
 "ð $àØðð ð "ð -àØØðð ð
ð 
ð* !�Mð/$ð $€L�$�s˜C�x”.ð ð ñ ð4 €FˆDÐÐÑØ€L�$ÐÐÑØ $Ð˜Ð$Ð$Ñ$Ø"Ð�dÐ"Ð"Ñ"Ø"Ð�tÐ"Ð"Ñ"ð $(Ø7;Ø&*ð	2ð 2à ð2ð Ð,Ô-°Ñ4ð2ð ˜tÑ#ð	2ð
 
ð2ð 2ð 2ð 2ð 2ð 2ð6
à˜˜c˜”Nð
ð #ð
ð 
ð	
ð 
ð 
ð 
ð 8à˜D‘jð8ð ˜˜c˜”Nð8ð 
ð	8ð 8ð 8ð 8ð>"
à˜˜c˜”Nð"
ð 
ˆnÔ	ð"
ð "
ð "
ð "
ðN ØØ*.ðið iàðið ðið ð	ið
 ! 4Ñ'ðið 
ðið ið ið ið ið ið ið ir8   r   )r€   rD   Útypingr   r   Ú_baser   r   Ú
permissionr	   r
   r   r   Ú	_responser   r=   r   r   rT   r   r1   r   r   r   © r8   r7   ú<module>r‹      s  ðà "Ð "Ø €€€Ø Ð Ð Ð Ð Ð Ð Ð à 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0ðð ð ð ð ð ð ð ð ð ð ð ð "Ð !Ð !Ð !Ð !Ð !Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø Ð Ð Ð Ð Ð Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6ðJð Jð Jð Jð Jˆ8ñ Jô Jð Jð Jð Jr8   