Undefined-bot 2.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. Undefined/__init__.py +3 -0
  2. Undefined/__main__.py +6 -0
  3. Undefined/ai.py +1215 -0
  4. Undefined/config.py +371 -0
  5. Undefined/end_summary_storage.py +48 -0
  6. Undefined/faq.py +244 -0
  7. Undefined/handlers.py +1247 -0
  8. Undefined/injection_response_agent.py +131 -0
  9. Undefined/main.py +126 -0
  10. Undefined/memory.py +120 -0
  11. Undefined/onebot.py +512 -0
  12. Undefined/rate_limit.py +130 -0
  13. Undefined/render.py +123 -0
  14. Undefined/scheduled_task_storage.py +88 -0
  15. Undefined/services/__init__.py +1 -0
  16. Undefined/services/queue_manager.py +206 -0
  17. Undefined/skills/README.md +53 -0
  18. Undefined/skills/__init__.py +10 -0
  19. Undefined/skills/agents/README.md +144 -0
  20. Undefined/skills/agents/__init__.py +116 -0
  21. Undefined/skills/agents/entertainment_agent/config.json +17 -0
  22. Undefined/skills/agents/entertainment_agent/handler.py +220 -0
  23. Undefined/skills/agents/entertainment_agent/intro.md +25 -0
  24. Undefined/skills/agents/entertainment_agent/prompt.md +20 -0
  25. Undefined/skills/agents/entertainment_agent/tools/__init__.py +1 -0
  26. Undefined/skills/agents/entertainment_agent/tools/ai_draw_one/config.json +34 -0
  27. Undefined/skills/agents/entertainment_agent/tools/ai_draw_one/handler.py +62 -0
  28. Undefined/skills/agents/entertainment_agent/tools/ai_study_helper/config.json +22 -0
  29. Undefined/skills/agents/entertainment_agent/tools/ai_study_helper/handler.py +35 -0
  30. Undefined/skills/agents/entertainment_agent/tools/get_current_time/config.json +12 -0
  31. Undefined/skills/agents/entertainment_agent/tools/get_current_time/handler.py +5 -0
  32. Undefined/skills/agents/entertainment_agent/tools/horoscope/config.json +24 -0
  33. Undefined/skills/agents/entertainment_agent/tools/horoscope/handler.py +141 -0
  34. Undefined/skills/agents/entertainment_agent/tools/minecraft_skin/config.json +43 -0
  35. Undefined/skills/agents/entertainment_agent/tools/minecraft_skin/handler.py +55 -0
  36. Undefined/skills/agents/entertainment_agent/tools/novel_search/config.json +25 -0
  37. Undefined/skills/agents/entertainment_agent/tools/novel_search/handler.py +31 -0
  38. Undefined/skills/agents/entertainment_agent/tools/renjian/config.json +12 -0
  39. Undefined/skills/agents/entertainment_agent/tools/renjian/handler.py +30 -0
  40. Undefined/skills/agents/entertainment_agent/tools/wenchang_dijun/config.json +12 -0
  41. Undefined/skills/agents/entertainment_agent/tools/wenchang_dijun/handler.py +44 -0
  42. Undefined/skills/agents/file_analysis_agent/__init__.py +1 -0
  43. Undefined/skills/agents/file_analysis_agent/config.json +21 -0
  44. Undefined/skills/agents/file_analysis_agent/handler.py +248 -0
  45. Undefined/skills/agents/file_analysis_agent/intro.md +22 -0
  46. Undefined/skills/agents/file_analysis_agent/prompt.md +36 -0
  47. Undefined/skills/agents/file_analysis_agent/tools/__init__.py +1 -0
  48. Undefined/skills/agents/file_analysis_agent/tools/analyze_code/config.json +17 -0
  49. Undefined/skills/agents/file_analysis_agent/tools/analyze_code/handler.py +427 -0
  50. Undefined/skills/agents/file_analysis_agent/tools/analyze_multimodal/config.json +25 -0
  51. Undefined/skills/agents/file_analysis_agent/tools/analyze_multimodal/handler.py +178 -0
  52. Undefined/skills/agents/file_analysis_agent/tools/cleanup_temp/config.json +16 -0
  53. Undefined/skills/agents/file_analysis_agent/tools/cleanup_temp/handler.py +35 -0
  54. Undefined/skills/agents/file_analysis_agent/tools/detect_file_type/config.json +17 -0
  55. Undefined/skills/agents/file_analysis_agent/tools/detect_file_type/handler.py +221 -0
  56. Undefined/skills/agents/file_analysis_agent/tools/download_file/config.json +21 -0
  57. Undefined/skills/agents/file_analysis_agent/tools/download_file/handler.py +124 -0
  58. Undefined/skills/agents/file_analysis_agent/tools/extract_archive/config.json +25 -0
  59. Undefined/skills/agents/file_analysis_agent/tools/extract_archive/handler.py +190 -0
  60. Undefined/skills/agents/file_analysis_agent/tools/extract_docx/config.json +17 -0
  61. Undefined/skills/agents/file_analysis_agent/tools/extract_docx/handler.py +78 -0
  62. Undefined/skills/agents/file_analysis_agent/tools/extract_pdf/config.json +21 -0
  63. Undefined/skills/agents/file_analysis_agent/tools/extract_pdf/handler.py +67 -0
  64. Undefined/skills/agents/file_analysis_agent/tools/extract_pptx/config.json +17 -0
  65. Undefined/skills/agents/file_analysis_agent/tools/extract_pptx/handler.py +73 -0
  66. Undefined/skills/agents/file_analysis_agent/tools/extract_xlsx/config.json +17 -0
  67. Undefined/skills/agents/file_analysis_agent/tools/extract_xlsx/handler.py +101 -0
  68. Undefined/skills/agents/file_analysis_agent/tools/get_current_time/config.json +12 -0
  69. Undefined/skills/agents/file_analysis_agent/tools/get_current_time/handler.py +5 -0
  70. Undefined/skills/agents/file_analysis_agent/tools/read_text_file/config.json +21 -0
  71. Undefined/skills/agents/file_analysis_agent/tools/read_text_file/handler.py +90 -0
  72. Undefined/skills/agents/info_agent/config.json +17 -0
  73. Undefined/skills/agents/info_agent/handler.py +220 -0
  74. Undefined/skills/agents/info_agent/intro.md +22 -0
  75. Undefined/skills/agents/info_agent/prompt.md +27 -0
  76. Undefined/skills/agents/info_agent/tools/__init__.py +1 -0
  77. Undefined/skills/agents/info_agent/tools/baiduhot/config.json +18 -0
  78. Undefined/skills/agents/info_agent/tools/baiduhot/handler.py +49 -0
  79. Undefined/skills/agents/info_agent/tools/base64/config.json +22 -0
  80. Undefined/skills/agents/info_agent/tools/base64/handler.py +44 -0
  81. Undefined/skills/agents/info_agent/tools/douyinhot/config.json +18 -0
  82. Undefined/skills/agents/info_agent/tools/douyinhot/handler.py +53 -0
  83. Undefined/skills/agents/info_agent/tools/get_current_time/config.json +12 -0
  84. Undefined/skills/agents/info_agent/tools/get_current_time/handler.py +5 -0
  85. Undefined/skills/agents/info_agent/tools/gold_price/config.json +12 -0
  86. Undefined/skills/agents/info_agent/tools/gold_price/handler.py +58 -0
  87. Undefined/skills/agents/info_agent/tools/hash/config.json +22 -0
  88. Undefined/skills/agents/info_agent/tools/hash/handler.py +43 -0
  89. Undefined/skills/agents/info_agent/tools/history/config.json +12 -0
  90. Undefined/skills/agents/info_agent/tools/history/handler.py +37 -0
  91. Undefined/skills/agents/info_agent/tools/net_check/config.json +17 -0
  92. Undefined/skills/agents/info_agent/tools/net_check/handler.py +117 -0
  93. Undefined/skills/agents/info_agent/tools/news_tencent/config.json +17 -0
  94. Undefined/skills/agents/info_agent/tools/news_tencent/handler.py +38 -0
  95. Undefined/skills/agents/info_agent/tools/qq_level_query/config.json +29 -0
  96. Undefined/skills/agents/info_agent/tools/qq_level_query/handler.py +48 -0
  97. Undefined/skills/agents/info_agent/tools/speed/config.json +17 -0
  98. Undefined/skills/agents/info_agent/tools/speed/handler.py +37 -0
  99. Undefined/skills/agents/info_agent/tools/tcping/config.json +21 -0
  100. Undefined/skills/agents/info_agent/tools/tcping/handler.py +53 -0
  101. Undefined/skills/agents/info_agent/tools/weather_query/config.json +22 -0
  102. Undefined/skills/agents/info_agent/tools/weather_query/handler.py +207 -0
  103. Undefined/skills/agents/info_agent/tools/weibohot/config.json +18 -0
  104. Undefined/skills/agents/info_agent/tools/weibohot/handler.py +49 -0
  105. Undefined/skills/agents/info_agent/tools/whois/config.json +17 -0
  106. Undefined/skills/agents/info_agent/tools/whois/handler.py +63 -0
  107. Undefined/skills/agents/naga_code_analysis_agent/config.json +17 -0
  108. Undefined/skills/agents/naga_code_analysis_agent/handler.py +222 -0
  109. Undefined/skills/agents/naga_code_analysis_agent/intro.md +17 -0
  110. Undefined/skills/agents/naga_code_analysis_agent/prompt.md +19 -0
  111. Undefined/skills/agents/naga_code_analysis_agent/tools/__init__.py +1 -0
  112. Undefined/skills/agents/naga_code_analysis_agent/tools/get_current_time/config.json +12 -0
  113. Undefined/skills/agents/naga_code_analysis_agent/tools/get_current_time/handler.py +5 -0
  114. Undefined/skills/agents/naga_code_analysis_agent/tools/glob/config.json +17 -0
  115. Undefined/skills/agents/naga_code_analysis_agent/tools/glob/handler.py +37 -0
  116. Undefined/skills/agents/naga_code_analysis_agent/tools/list_directory/config.json +17 -0
  117. Undefined/skills/agents/naga_code_analysis_agent/tools/list_directory/handler.py +31 -0
  118. Undefined/skills/agents/naga_code_analysis_agent/tools/read_file/config.json +17 -0
  119. Undefined/skills/agents/naga_code_analysis_agent/tools/read_file/handler.py +66 -0
  120. Undefined/skills/agents/naga_code_analysis_agent/tools/read_naga_intro/config.json +12 -0
  121. Undefined/skills/agents/naga_code_analysis_agent/tools/read_naga_intro/handler.py +327 -0
  122. Undefined/skills/agents/naga_code_analysis_agent/tools/search_file_content/config.json +25 -0
  123. Undefined/skills/agents/naga_code_analysis_agent/tools/search_file_content/handler.py +46 -0
  124. Undefined/skills/agents/scheduler_agent/__init__.py +1 -0
  125. Undefined/skills/agents/scheduler_agent/config.json +17 -0
  126. Undefined/skills/agents/scheduler_agent/handler.py +218 -0
  127. Undefined/skills/agents/scheduler_agent/intro.md +17 -0
  128. Undefined/skills/agents/scheduler_agent/prompt.md +67 -0
  129. Undefined/skills/agents/scheduler_agent/tools/__init__.py +1 -0
  130. Undefined/skills/agents/scheduler_agent/tools/create_schedule_task/config.json +37 -0
  131. Undefined/skills/agents/scheduler_agent/tools/create_schedule_task/handler.py +68 -0
  132. Undefined/skills/agents/scheduler_agent/tools/delete_schedule_task/config.json +19 -0
  133. Undefined/skills/agents/scheduler_agent/tools/delete_schedule_task/handler.py +26 -0
  134. Undefined/skills/agents/scheduler_agent/tools/get_current_time/config.json +12 -0
  135. Undefined/skills/agents/scheduler_agent/tools/get_current_time/handler.py +5 -0
  136. Undefined/skills/agents/scheduler_agent/tools/list_schedule_tasks/config.json +11 -0
  137. Undefined/skills/agents/scheduler_agent/tools/list_schedule_tasks/handler.py +47 -0
  138. Undefined/skills/agents/scheduler_agent/tools/update_schedule_task/config.json +39 -0
  139. Undefined/skills/agents/scheduler_agent/tools/update_schedule_task/handler.py +46 -0
  140. Undefined/skills/agents/social_agent/config.json +17 -0
  141. Undefined/skills/agents/social_agent/handler.py +220 -0
  142. Undefined/skills/agents/social_agent/intro.md +17 -0
  143. Undefined/skills/agents/social_agent/prompt.md +19 -0
  144. Undefined/skills/agents/social_agent/tools/__init__.py +1 -0
  145. Undefined/skills/agents/social_agent/tools/bilibili_search/config.json +21 -0
  146. Undefined/skills/agents/social_agent/tools/bilibili_search/handler.py +68 -0
  147. Undefined/skills/agents/social_agent/tools/bilibili_user_info/config.json +17 -0
  148. Undefined/skills/agents/social_agent/tools/bilibili_user_info/handler.py +68 -0
  149. Undefined/skills/agents/social_agent/tools/get_current_time/config.json +12 -0
  150. Undefined/skills/agents/social_agent/tools/get_current_time/handler.py +5 -0
  151. Undefined/skills/agents/social_agent/tools/music_global_search/config.json +21 -0
  152. Undefined/skills/agents/social_agent/tools/music_global_search/handler.py +47 -0
  153. Undefined/skills/agents/social_agent/tools/music_info_get/config.json +22 -0
  154. Undefined/skills/agents/social_agent/tools/music_info_get/handler.py +35 -0
  155. Undefined/skills/agents/social_agent/tools/music_lyrics/config.json +22 -0
  156. Undefined/skills/agents/social_agent/tools/music_lyrics/handler.py +26 -0
  157. Undefined/skills/agents/social_agent/tools/video_random_recommend/config.json +21 -0
  158. Undefined/skills/agents/social_agent/tools/video_random_recommend/handler.py +21 -0
  159. Undefined/skills/agents/web_agent/config.json +17 -0
  160. Undefined/skills/agents/web_agent/handler.py +221 -0
  161. Undefined/skills/agents/web_agent/intro.md +14 -0
  162. Undefined/skills/agents/web_agent/prompt.md +16 -0
  163. Undefined/skills/agents/web_agent/tools/__init__.py +1 -0
  164. Undefined/skills/agents/web_agent/tools/crawl_webpage/config.json +21 -0
  165. Undefined/skills/agents/web_agent/tools/crawl_webpage/handler.py +102 -0
  166. Undefined/skills/agents/web_agent/tools/get_current_time/config.json +12 -0
  167. Undefined/skills/agents/web_agent/tools/get_current_time/handler.py +5 -0
  168. Undefined/skills/agents/web_agent/tools/web_search/config.json +21 -0
  169. Undefined/skills/agents/web_agent/tools/web_search/handler.py +29 -0
  170. Undefined/skills/tools/README.md +85 -0
  171. Undefined/skills/tools/__init__.py +120 -0
  172. Undefined/skills/tools/debug/config.json +17 -0
  173. Undefined/skills/tools/debug/handler.py +35 -0
  174. Undefined/skills/tools/end/config.json +17 -0
  175. Undefined/skills/tools/end/handler.py +24 -0
  176. Undefined/skills/tools/get_current_time/config.json +12 -0
  177. Undefined/skills/tools/get_current_time/handler.py +5 -0
  178. Undefined/skills/tools/get_forward_msg/config.json +17 -0
  179. Undefined/skills/tools/get_forward_msg/handler.py +131 -0
  180. Undefined/skills/tools/get_group_member_info/config.json +38 -0
  181. Undefined/skills/tools/get_group_member_info/handler.py +142 -0
  182. Undefined/skills/tools/get_messages_by_time/config.json +30 -0
  183. Undefined/skills/tools/get_messages_by_time/handler.py +128 -0
  184. Undefined/skills/tools/get_picture/config.json +45 -0
  185. Undefined/skills/tools/get_picture/handler.py +191 -0
  186. Undefined/skills/tools/get_recent_messages/config.json +30 -0
  187. Undefined/skills/tools/get_recent_messages/handler.py +88 -0
  188. Undefined/skills/tools/qq_like/config.json +22 -0
  189. Undefined/skills/tools/qq_like/handler.py +58 -0
  190. Undefined/skills/tools/render_html/config.json +26 -0
  191. Undefined/skills/tools/render_html/handler.py +39 -0
  192. Undefined/skills/tools/render_latex/config.json +26 -0
  193. Undefined/skills/tools/render_latex/handler.py +78 -0
  194. Undefined/skills/tools/render_markdown/config.json +26 -0
  195. Undefined/skills/tools/render_markdown/handler.py +63 -0
  196. Undefined/skills/tools/save_memory/config.json +17 -0
  197. Undefined/skills/tools/save_memory/handler.py +17 -0
  198. Undefined/skills/tools/send_message/config.json +21 -0
  199. Undefined/skills/tools/send_message/handler.py +60 -0
  200. Undefined/skills/tools/send_private_message/config.json +21 -0
  201. Undefined/skills/tools/send_private_message/handler.py +35 -0
  202. Undefined/utils/__init__.py +0 -0
  203. Undefined/utils/common.py +186 -0
  204. Undefined/utils/history.py +284 -0
  205. Undefined/utils/scheduler.py +286 -0
  206. Undefined/utils/sender.py +140 -0
  207. undefined_bot-2.1.0.dist-info/METADATA +259 -0
  208. undefined_bot-2.1.0.dist-info/RECORD +211 -0
  209. undefined_bot-2.1.0.dist-info/WHEEL +4 -0
  210. undefined_bot-2.1.0.dist-info/entry_points.txt +2 -0
  211. undefined_bot-2.1.0.dist-info/licenses/LICENSE +7 -0
@@ -0,0 +1,190 @@
1
+ from pathlib import Path
2
+ from typing import Any, Dict
3
+ import logging
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+
8
+ async def execute(args: Dict[str, Any], context: Dict[str, Any]) -> str:
9
+ file_path: str = args.get("file_path", "")
10
+ action: str = args.get("action", "list")
11
+ extract_path: str | None = args.get("extract_path")
12
+
13
+ path = Path(file_path)
14
+
15
+ if not path.exists():
16
+ return f"错误:文件不存在 {file_path}"
17
+
18
+ if not path.is_file():
19
+ return f"错误:{file_path} 不是文件"
20
+
21
+ suffix = path.suffix.lower()
22
+
23
+ try:
24
+ if suffix == ".zip":
25
+ return await _extract_zip(path, action, extract_path)
26
+ elif suffix in [".tar", ".gz", ".bz2", ".xz"]:
27
+ return await _extract_tar(path, action, extract_path)
28
+ elif suffix == ".7z":
29
+ return await _extract_7z(path, action, extract_path)
30
+ elif suffix == ".rar":
31
+ return await _extract_rar(path, action, extract_path)
32
+ else:
33
+ return f"不支持的压缩格式: {suffix}"
34
+
35
+ except Exception as e:
36
+ logger.exception(f"解析压缩包失败: {e}")
37
+ return f"解析压缩包失败: {e}"
38
+
39
+
40
+ async def _extract_zip(path: Path, action: str, extract_path: str | None) -> str:
41
+ import zipfile
42
+
43
+ with zipfile.ZipFile(path, "r") as zip_ref:
44
+ file_list = zip_ref.namelist()
45
+ total_size = sum(info.file_size for info in zip_ref.infolist())
46
+
47
+ info: list[str] = []
48
+ info.append(f"文件大小:{path.stat().st_size} 字节")
49
+ info.append(f"压缩包内文件数:{len(file_list)}")
50
+ info.append(f"解压后总大小:{total_size} 字节")
51
+
52
+ if action == "list":
53
+ info.append("\n文件列表(前 100 个):")
54
+ for i, name in enumerate(file_list[:100], 1):
55
+ info.append(f" {i}. {name}")
56
+ if len(file_list) > 100:
57
+ info.append(f" ... (共 {len(file_list)} 个文件)")
58
+ return "\n".join(info)
59
+
60
+ else:
61
+ if extract_path:
62
+ target_dir = Path(extract_path)
63
+ else:
64
+ target_dir = path.parent / f"extracted_{path.stem}"
65
+ target_dir.mkdir(exist_ok=True)
66
+
67
+ with zipfile.ZipFile(path, "r") as zip_ref:
68
+ zip_ref.extractall(target_dir)
69
+
70
+ info.append(f"\n已解压到:{target_dir}")
71
+ info.append(f"解压文件数:{len(file_list)}")
72
+ info.append("\n文件列表(前 50 个):")
73
+ for i, name in enumerate(file_list[:50], 1):
74
+ info.append(f" {i}. {name}")
75
+ if len(file_list) > 50:
76
+ info.append(f" ... (共 {len(file_list)} 个文件)")
77
+
78
+ return "\n".join(info)
79
+
80
+
81
+ async def _extract_tar(path: Path, action: str, extract_path: str | None) -> str:
82
+ import tarfile
83
+
84
+ with tarfile.open(path, "r:*") as tar_ref:
85
+ members = tar_ref.getmembers()
86
+ file_list = [m.name for m in members]
87
+ total_size = sum(m.size for m in members)
88
+
89
+ info: list[str] = []
90
+ info.append(f"文件大小:{path.stat().st_size} 字节")
91
+ info.append(f"压缩包内文件数:{len(file_list)}")
92
+ info.append(f"解压后总大小:{total_size} 字节")
93
+
94
+ if action == "list":
95
+ info.append("\n文件列表(前 100 个):")
96
+ for i, name in enumerate(file_list[:100], 1):
97
+ info.append(f" {i}. {name}")
98
+ if len(file_list) > 100:
99
+ info.append(f" ... (共 {len(file_list)} 个文件)")
100
+ return "\n".join(info)
101
+
102
+ else:
103
+ if extract_path:
104
+ target_dir = Path(extract_path)
105
+ else:
106
+ target_dir = path.parent / f"extracted_{path.stem}"
107
+ target_dir.mkdir(exist_ok=True)
108
+
109
+ with tarfile.open(path, "r:*") as tar_ref:
110
+ tar_ref.extractall(target_dir)
111
+
112
+ info.append(f"\n已解压到:{target_dir}")
113
+ info.append(f"解压文件数:{len(file_list)}")
114
+
115
+ return "\n".join(info)
116
+
117
+
118
+ async def _extract_7z(path: Path, action: str, extract_path: str | None) -> str:
119
+ import py7zr
120
+
121
+ with py7zr.SevenZipFile(path, "r") as archive:
122
+ file_list: list[str] = []
123
+ total_size = 0
124
+ for file_info in archive.files:
125
+ file_list.append(file_info.filename)
126
+ total_size += file_info.uncompressed
127
+
128
+ info: list[str] = []
129
+ info.append(f"文件大小:{path.stat().st_size} 字节")
130
+ info.append(f"压缩包内文件数:{len(file_list)}")
131
+ info.append(f"解压后总大小:{total_size} 字节")
132
+
133
+ if action == "list":
134
+ info.append("\n文件列表(前 100 个):")
135
+ for i, name in enumerate(file_list[:100], 1):
136
+ info.append(f" {i}. {name}")
137
+ if len(file_list) > 100:
138
+ info.append(f" ... (共 {len(file_list)} 个文件)")
139
+ return "\n".join(info)
140
+
141
+ else:
142
+ if extract_path:
143
+ target_dir = Path(extract_path)
144
+ else:
145
+ target_dir = path.parent / f"extracted_{path.stem}"
146
+ target_dir.mkdir(exist_ok=True)
147
+
148
+ with py7zr.SevenZipFile(path, "r") as archive:
149
+ archive.extractall(target_dir)
150
+
151
+ info.append(f"\n已解压到:{target_dir}")
152
+ info.append(f"解压文件数:{len(file_list)}")
153
+
154
+ return "\n".join(info)
155
+
156
+
157
+ async def _extract_rar(path: Path, action: str, extract_path: str | None) -> str:
158
+ import rarfile
159
+
160
+ with rarfile.RarFile(path, "r") as rar_ref:
161
+ file_list = rar_ref.namelist()
162
+ total_size = sum(info.file_size for info in rar_ref.infolist())
163
+
164
+ info: list[str] = []
165
+ info.append(f"文件大小:{path.stat().st_size} 字节")
166
+ info.append(f"压缩包内文件数:{len(file_list)}")
167
+ info.append(f"解压后总大小:{total_size} 字节")
168
+
169
+ if action == "list":
170
+ info.append("\n文件列表(前 100 个):")
171
+ for i, name in enumerate(file_list[:100], 1):
172
+ info.append(f" {i}. {name}")
173
+ if len(file_list) > 100:
174
+ info.append(f" ... (共 {len(file_list)} 个文件)")
175
+ return "\n".join(info)
176
+
177
+ else:
178
+ if extract_path:
179
+ target_dir = Path(extract_path)
180
+ else:
181
+ target_dir = path.parent / f"extracted_{path.stem}"
182
+ target_dir.mkdir(exist_ok=True)
183
+
184
+ with rarfile.RarFile(path, "r") as rar_ref:
185
+ rar_ref.extractall(target_dir)
186
+
187
+ info.append(f"\n已解压到:{target_dir}")
188
+ info.append(f"解压文件数:{len(file_list)}")
189
+
190
+ return "\n".join(info)
@@ -0,0 +1,17 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "extract_docx",
5
+ "description": "提取 Microsoft Word 文档 (.docx) 的文本内容和基本元数据。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "file_path": {
10
+ "type": "string",
11
+ "description": "本地 Word 文档路径"
12
+ }
13
+ },
14
+ "required": ["file_path"]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,78 @@
1
+ from docx import Document
2
+ from pathlib import Path
3
+ from typing import Any, Dict
4
+ import logging
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ async def execute(args: Dict[str, Any], context: Dict[str, Any]) -> str:
10
+ file_path: str = args.get("file_path", "")
11
+
12
+ path = Path(file_path)
13
+
14
+ if not path.exists():
15
+ return f"错误:文件不存在 {file_path}"
16
+
17
+ if not path.is_file():
18
+ return f"错误:{file_path} 不是文件"
19
+
20
+ try:
21
+ doc = Document(str(path))
22
+
23
+ info: list[str] = []
24
+ info.append(f"文件大小:{path.stat().st_size} 字节")
25
+
26
+ core_props = doc.core_properties
27
+ if core_props:
28
+ info.append("\n文档属性:")
29
+ if core_props.title:
30
+ info.append(f" 标题: {core_props.title}")
31
+ if core_props.author:
32
+ info.append(f" 作者: {core_props.author}")
33
+ if core_props.last_modified_by:
34
+ info.append(f" 最后修改者: {core_props.last_modified_by}")
35
+ if core_props.created:
36
+ info.append(f" 创建时间: {core_props.created}")
37
+ if core_props.modified:
38
+ info.append(f" 修改时间: {core_props.modified}")
39
+ if core_props.comments:
40
+ info.append(f" 备注: {core_props.comments}")
41
+
42
+ paragraphs = list(doc.paragraphs)
43
+ tables = doc.tables
44
+
45
+ info.append(f"\n段落数:{len(paragraphs)}")
46
+ info.append(f"表格数:{len(tables)}")
47
+
48
+ text_content = ""
49
+ for para in paragraphs:
50
+ text = para.text.strip()
51
+ if text:
52
+ text_content += text + "\n"
53
+
54
+ if not text_content.strip():
55
+ text_content = "(文档未检测到文本内容)"
56
+
57
+ info.append(f"\n文本内容预览(前 5000 字符):\n{text_content[:5000]}")
58
+ if len(text_content) > 5000:
59
+ info.append(f"\n... (共 {len(text_content)} 字符)")
60
+
61
+ if tables:
62
+ info.append("\n表格内容:")
63
+ for i, table in enumerate(tables[:3], 1):
64
+ info.append(f"\n表格 {i}:")
65
+ for row in table.rows[:5]:
66
+ cells = [cell.text.strip() for cell in row.cells]
67
+ row_text = " | ".join(cells)
68
+ info.append(f" {row_text}")
69
+ if len(table.rows) > 5:
70
+ info.append(f" ... (共 {len(table.rows)} 行)")
71
+ if len(tables) > 3:
72
+ info.append(f"\n... (还有 {len(tables) - 3} 个表格)")
73
+
74
+ return "\n".join(info)
75
+
76
+ except Exception as e:
77
+ logger.exception(f"解析 Word 文档失败: {e}")
78
+ return f"解析 Word 文档失败: {e}"
@@ -0,0 +1,21 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "extract_pdf",
5
+ "description": "提取 PDF 文档的文本内容和元数据。使用 PyMuPDF (fitz) 解析,支持获取页数、作者、标题等信息。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "file_path": {
10
+ "type": "string",
11
+ "description": "本地 PDF 文件路径"
12
+ },
13
+ "extract_images": {
14
+ "type": "boolean",
15
+ "description": "是否提取图片(会返回图片数量和位置信息),默认为 false"
16
+ }
17
+ },
18
+ "required": ["file_path"]
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,67 @@
1
+ import fitz
2
+ from pathlib import Path
3
+ from typing import Any, Dict
4
+ import logging
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ async def execute(args: Dict[str, Any], context: Dict[str, Any]) -> str:
10
+ file_path: str = args.get("file_path", "")
11
+ extract_images: bool = args.get("extract_images", False)
12
+
13
+ path = Path(file_path)
14
+
15
+ if not path.exists():
16
+ return f"错误:文件不存在 {file_path}"
17
+
18
+ if not path.is_file():
19
+ return f"错误:{file_path} 不是文件"
20
+
21
+ try:
22
+ doc = fitz.open(str(path))
23
+ page_count = len(doc)
24
+
25
+ info: list[str] = []
26
+ info.append(f"文件大小:{path.stat().st_size} 字节")
27
+ info.append(f"页数:{page_count}")
28
+
29
+ metadata = doc.metadata
30
+ if metadata:
31
+ info.append("\n文档元数据:")
32
+ for key, value in metadata.items():
33
+ if value:
34
+ info.append(f" {key}: {value}")
35
+
36
+ text_content = ""
37
+ image_count = 0
38
+
39
+ for page_num in range(page_count):
40
+ page = doc.load_page(page_num)
41
+ text_raw = page.get_text()
42
+ text = str(text_raw) if text_raw else ""
43
+ text_content += f"\n--- 第 {page_num + 1} 页 ---\n"
44
+ text_content += text
45
+
46
+ if extract_images:
47
+ images = page.get_images()
48
+ for _ in images:
49
+ image_count += 1
50
+
51
+ if extract_images:
52
+ info.append(f"\n图片数量:{image_count}")
53
+
54
+ if not text_content.strip():
55
+ text_content = "(文档未检测到文本内容,可能是扫描版 PDF 或图片)"
56
+
57
+ info.append(f"\n文本内容预览(前 5000 字符):\n{text_content[:5000]}")
58
+ if len(text_content) > 5000:
59
+ info.append(f"\n... (共 {len(text_content)} 字符)")
60
+
61
+ doc.close()
62
+
63
+ return "\n".join(info)
64
+
65
+ except Exception as e:
66
+ logger.exception(f"解析 PDF 失败: {e}")
67
+ return f"解析 PDF 失败: {e}"
@@ -0,0 +1,17 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "extract_pptx",
5
+ "description": "提取 Microsoft PowerPoint 演示文稿 (.pptx) 的文本内容,包括幻灯片文本和基本结构。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "file_path": {
10
+ "type": "string",
11
+ "description": "本地 PowerPoint 文件路径"
12
+ }
13
+ },
14
+ "required": ["file_path"]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,73 @@
1
+ from pptx import Presentation
2
+ from pathlib import Path
3
+ from typing import Any, Dict
4
+ import logging
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ async def execute(args: Dict[str, Any], context: Dict[str, Any]) -> str:
10
+ file_path: str = args.get("file_path", "")
11
+
12
+ path = Path(file_path)
13
+
14
+ if not path.exists():
15
+ return f"错误:文件不存在 {file_path}"
16
+
17
+ if not path.is_file():
18
+ return f"错误:{file_path} 不是文件"
19
+
20
+ try:
21
+ prs = Presentation(str(path))
22
+
23
+ info: list[str] = []
24
+ info.append(f"文件大小:{path.stat().st_size} 字节")
25
+
26
+ slide_count = len(prs.slides)
27
+ info.append(f"幻灯片数量:{slide_count}")
28
+
29
+ if prs.core_properties.title:
30
+ info.append(f"标题: {prs.core_properties.title}")
31
+ if prs.core_properties.author:
32
+ info.append(f"作者: {prs.core_properties.author}")
33
+ if prs.core_properties.last_modified_by:
34
+ info.append(f"最后修改者: {prs.core_properties.last_modified_by}")
35
+
36
+ text_content = ""
37
+
38
+ for slide_num, slide in enumerate(prs.slides, 1):
39
+ slide_text = f"\n--- 幻灯片 {slide_num} ---\n"
40
+
41
+ title = ""
42
+ if slide.shapes.title:
43
+ title = slide.shapes.title.text.strip()
44
+ if title:
45
+ slide_text += f"标题: {title}\n"
46
+
47
+ content_count = 0
48
+ for shape in slide.shapes:
49
+ if shape != slide.shapes.title:
50
+ shape_text = getattr(shape, "text", None)
51
+ if shape_text:
52
+ text = shape_text.strip()
53
+ if text and len(text) > 0:
54
+ content_count += 1
55
+ slide_text += f"{text}\n"
56
+
57
+ if not title and content_count == 0:
58
+ slide_text += "(空白幻灯片)"
59
+
60
+ text_content += slide_text
61
+
62
+ if not text_content.strip():
63
+ text_content = "(演示文稿未检测到文本内容)"
64
+
65
+ info.append(f"\n内容预览(前 5000 字符):\n{text_content[:5000]}")
66
+ if len(text_content) > 5000:
67
+ info.append(f"\n... (共 {len(text_content)} 字符)")
68
+
69
+ return "\n".join(info)
70
+
71
+ except Exception as e:
72
+ logger.exception(f"解析 PowerPoint 失败: {e}")
73
+ return f"解析 PowerPoint 失败: {e}"
@@ -0,0 +1,17 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "extract_xlsx",
5
+ "description": "提取 Microsoft Excel 工作簿 (.xlsx, .xls, .csv) 的表格数据,包括工作表列表和内容预览。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "file_path": {
10
+ "type": "string",
11
+ "description": "本地 Excel 或 CSV 文件路径"
12
+ }
13
+ },
14
+ "required": ["file_path"]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,101 @@
1
+ from pathlib import Path
2
+ from typing import Any, Dict
3
+ import logging
4
+ import csv
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ async def execute(args: Dict[str, Any], context: Dict[str, Any]) -> str:
10
+ file_path: str = args.get("file_path", "")
11
+
12
+ path = Path(file_path)
13
+
14
+ if not path.exists():
15
+ return f"错误:文件不存在 {file_path}"
16
+
17
+ if not path.is_file():
18
+ return f"错误:{file_path} 不是文件"
19
+
20
+ try:
21
+ info: list[str] = []
22
+ info.append(f"文件大小:{path.stat().st_size} 字节")
23
+
24
+ if path.suffix.lower() == ".csv":
25
+ return await _extract_csv(path, info)
26
+ else:
27
+ return await _extract_excel(path, info)
28
+
29
+ except Exception as e:
30
+ logger.exception(f"解析 Excel/CSV 失败: {e}")
31
+ return f"解析 Excel/CSV 失败: {e}"
32
+
33
+
34
+ async def _extract_csv(path: Path, info: list[str]) -> str:
35
+ try:
36
+ with open(path, "r", encoding="utf-8-sig") as f:
37
+ reader = csv.reader(f)
38
+ rows = list(reader)
39
+
40
+ if not rows:
41
+ return "CSV 文件为空"
42
+
43
+ info.append("工作表:CSV (单个)")
44
+ info.append(f"总行数:{len(rows)}")
45
+ if rows:
46
+ info.append(f"列数:{len(rows[0])}")
47
+
48
+ preview = []
49
+ preview.append("\n--- 前 20 行预览 ---\n")
50
+ for i, row in enumerate(rows[:20], 1):
51
+ preview.append(f"行 {i}: {' | '.join(row)}")
52
+ if len(rows) > 20:
53
+ preview.append(f"\n... (共 {len(rows)} 行)")
54
+
55
+ return "\n".join(info) + "\n" + "\n".join(preview)
56
+
57
+ except Exception as e:
58
+ return f"解析 CSV 失败: {e}"
59
+
60
+
61
+ async def _extract_excel(path: Path, info: list[str]) -> str:
62
+ try:
63
+ from openpyxl import load_workbook
64
+
65
+ wb = load_workbook(str(path), read_only=True, data_only=True)
66
+
67
+ sheet_names = wb.sheetnames
68
+ info.append(f"工作表数量:{len(sheet_names)}")
69
+ info.append(f"工作表列表:{', '.join(sheet_names)}")
70
+
71
+ all_content = []
72
+
73
+ for sheet_name in sheet_names[:5]:
74
+ ws = wb[sheet_name]
75
+ rows = list(ws.iter_rows(max_row=100, values_only=True))
76
+
77
+ if not rows:
78
+ continue
79
+
80
+ max_cols = max(len(row) for row in rows if row)
81
+ info.append(f"\n工作表 '{sheet_name}':")
82
+ info.append(f" 行数(前 100 行): {len(rows)}")
83
+ info.append(f" 列数: {max_cols}")
84
+
85
+ preview = []
86
+ preview.append(f" --- {sheet_name} 前 15 行预览 ---\n")
87
+ for i, row in enumerate(rows[:15], 1):
88
+ row_values = [str(cell) if cell is not None else "" for cell in row]
89
+ preview.append(f" 行 {i}: {' | '.join(row_values)}")
90
+ if len(rows) > 15:
91
+ preview.append(f" ... (共 {len(rows)} 行)")
92
+ all_content.append("\n".join(preview))
93
+
94
+ if len(sheet_names) > 5:
95
+ info.append(f"\n... (还有 {len(sheet_names) - 5} 个工作表)")
96
+
97
+ return "\n".join(info) + "\n" + "\n".join(all_content)
98
+
99
+ except Exception as e:
100
+ logger.exception(f"解析 Excel 失败: {e}")
101
+ return f"解析 Excel 失败: {e}"
@@ -0,0 +1,12 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "get_current_time",
5
+ "description": "获取当前系统时间。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {},
9
+ "required": []
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ from typing import Any, Dict
2
+ from datetime import datetime
3
+
4
+ async def execute(args: Dict[str, Any], context: Dict[str, Any]) -> str:
5
+ return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@@ -0,0 +1,21 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "read_text_file",
5
+ "description": "读取文本文件内容,自动检测文件编码。支持 txt, md, log, rst, json, yaml, xml, html, css, js, py 等纯文本格式。大文件可限制读取行数。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "file_path": {
10
+ "type": "string",
11
+ "description": "本地文件路径"
12
+ },
13
+ "max_lines": {
14
+ "type": "number",
15
+ "description": "最大读取行数,默认读取全部"
16
+ }
17
+ },
18
+ "required": ["file_path"]
19
+ }
20
+ }
21
+ }