Coverage for agentos/tools/file_tools.py: 41%
64 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-08 10:59 +0800
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-08 10:59 +0800
1"""
2文件操作工具集。
3"""
5from __future__ import annotations
7import os
9import aiofiles
11from agentos.tools.base import BaseTool, PermissionLevel, ToolResult
14class 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, 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):
49 """文件写入工具。"""
51 name = "write_file"
52 description = "写入文本内容到文件。如果文件已存在则覆盖。"
53 permission_level = PermissionLevel.MODERATE
55 @property
56 def parameters(self) -> dict:
57 return {
58 "type": "object",
59 "properties": {
60 "file_path": {"type": "string", "description": "要写入的文件路径"},
61 "content": {"type": "string", "description": "要写入的文本内容"},
62 },
63 "required": ["file_path", "content"],
64 }
66 async def execute(self, arguments: dict, sandbox=None) -> ToolResult:
67 file_path = arguments["file_path"]
68 content = arguments["content"]
69 try:
70 os.makedirs(os.path.dirname(file_path), exist_ok=True)
71 async with aiofiles.open(file_path, "w", encoding="utf-8") as f:
72 await f.write(content)
73 return ToolResult.ok("", output=f"Written {len(content)} bytes to {file_path}")
74 except Exception as e:
75 return ToolResult.fail("", error=str(e))
77 def is_write_operation(self, arguments: dict) -> bool:
78 return True
81class ListDirectoryTool(BaseTool):
82 """目录列表工具。"""
84 name = "list_directory"
85 description = "列出目录下的所有文件和子目录。"
86 permission_level = PermissionLevel.SAFE
88 @property
89 def parameters(self) -> dict:
90 return {
91 "type": "object",
92 "properties": {
93 "path": {"type": "string", "description": "要列出的目录路径"},
94 },
95 "required": ["path"],
96 }
98 async def execute(self, arguments: dict, sandbox=None) -> ToolResult:
99 path = arguments["path"]
100 try:
101 entries = os.listdir(path)
102 lines = []
103 for entry in sorted(entries):
104 full_path = os.path.join(path, entry)
105 tag = "[DIR]" if os.path.isdir(full_path) else "[FILE]"
106 size = os.path.getsize(full_path) if os.path.isfile(full_path) else 0
107 lines.append(f"{tag} {entry} ({size} bytes)")
108 return ToolResult.ok("", output="\n".join(lines))
109 except FileNotFoundError:
110 return ToolResult.fail("", error=f"Directory not found: {path}")
111 except Exception as e:
112 return ToolResult.fail("", error=str(e))