Coverage for agentos/tools/file_tools.py: 41%
64 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-02 09:59 +0800
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-02 09:59 +0800
1"""
2文件操作工具集。
3"""
5from __future__ import annotations
7import os
8import aiofiles
10from agentos.tools.base import BaseTool, PermissionLevel, ToolResult
13class ReadFileTool(BaseTool):
15 """文件读取工具。"""
17 name = "read_file"
18 description = "读取文件内容,返回全部文本。"
19 permission_level = PermissionLevel.SAFE
21 @property
22 def parameters(self) -> dict:
23 return {
24 "type": "object",
25 "properties": {
26 "file_path": {
27 "type": "string",
28 "description": "要读取的文件绝对路径",
29 },
30 },
31 "required": ["file_path"],
32 }
34 async def execute(self, arguments: dict, sandbox=None) -> ToolResult:
35 file_path = arguments["file_path"]
36 try:
37 async with aiofiles.open(file_path, "r", encoding="utf-8") as f:
38 content = await f.read()
39 return ToolResult.ok("", output=content)
40 except FileNotFoundError:
41 return ToolResult.fail("", error=f"File not found: {file_path}")
42 except PermissionError:
43 return ToolResult.fail("", error=f"Permission denied: {file_path}")
44 except Exception as e:
45 return ToolResult.fail("", error=str(e))
48class WriteFileTool(BaseTool):
50 """文件写入工具。"""
52 name = "write_file"
53 description = "写入文本内容到文件。如果文件已存在则覆盖。"
54 permission_level = PermissionLevel.MODERATE
56 @property
57 def parameters(self) -> dict:
58 return {
59 "type": "object",
60 "properties": {
61 "file_path": {"type": "string", "description": "要写入的文件路径"},
62 "content": {"type": "string", "description": "要写入的文本内容"},
63 },
64 "required": ["file_path", "content"],
65 }
67 async def execute(self, arguments: dict, sandbox=None) -> ToolResult:
68 file_path = arguments["file_path"]
69 content = arguments["content"]
70 try:
71 os.makedirs(os.path.dirname(file_path), exist_ok=True)
72 async with aiofiles.open(file_path, "w", encoding="utf-8") as f:
73 await f.write(content)
74 return ToolResult.ok("", output=f"Written {len(content)} bytes to {file_path}")
75 except Exception as e:
76 return ToolResult.fail("", error=str(e))
78 def is_write_operation(self, arguments: dict) -> bool:
79 return True
82class ListDirectoryTool(BaseTool):
84 """目录列表工具。"""
86 name = "list_directory"
87 description = "列出目录下的所有文件和子目录。"
88 permission_level = PermissionLevel.SAFE
90 @property
91 def parameters(self) -> dict:
92 return {
93 "type": "object",
94 "properties": {
95 "path": {"type": "string", "description": "要列出的目录路径"},
96 },
97 "required": ["path"],
98 }
100 async def execute(self, arguments: dict, sandbox=None) -> ToolResult:
101 path = arguments["path"]
102 try:
103 entries = os.listdir(path)
104 lines = []
105 for entry in sorted(entries):
106 full_path = os.path.join(path, entry)
107 tag = "[DIR]" if os.path.isdir(full_path) else "[FILE]"
108 size = os.path.getsize(full_path) if os.path.isfile(full_path) else 0
109 lines.append(f"{tag} {entry} ({size} bytes)")
110 return ToolResult.ok("", output="\n".join(lines))
111 except FileNotFoundError:
112 return ToolResult.fail("", error=f"Directory not found: {path}")
113 except Exception as e:
114 return ToolResult.fail("", error=str(e))