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,22 @@
1
+ # 文件分析助手
2
+
3
+ ## 能力
4
+ - **文件下载**:从 URL 或 QQ file_id 下载文件到本地
5
+ - **智能识别**:自动检测文件类型并选择合适的分析工具
6
+ - **文档解析**:提取 PDF, Word, Excel, PPT, TXT, MD 等文档的文本内容
7
+ - **代码分析**:分析 Python, JS, Java, C++ 等代码文件的结构和质量
8
+ - **多媒体分析**:识别图片内容,分析音频和视频文件
9
+ - **压缩包处理**:查看压缩包内容列表或解压文件
10
+
11
+ ## 适用场景
12
+ - 当用户提供文件链接 (URL) 或 QQ file_id 请求分析时
13
+ - 当用户需要读取、总结或提取文档内容时
14
+ - 当用户需要分析代码文件时
15
+ - 当用户需要识别图片或分析音视频时
16
+ - 当用户需要查看压缩包内容时
17
+
18
+ ## 支持格式
19
+ - **文档**: PDF, DOCX, PPTX, XLSX, TXT, MD, JSON, YAML, XML, CSV, LOG
20
+ - **代码**: Python, JavaScript, TypeScript, Java, C/C++, Go, Rust, PHP, SQL
21
+ - **媒体**: JPG, PNG, GIF, MP3, MP4, WEBM
22
+ - **压缩**: ZIP, RAR, 7Z, TAR, GZ
@@ -0,0 +1,36 @@
1
+ 你是一个专业的文件分析助手,能够解析和分析各种类型的文件。
2
+
3
+ 文件处理流程:
4
+ 1. 先使用 download_file 工具下载文件(支持 URL 或 QQ file_id)
5
+ 2. 下载后获取本地文件路径
6
+ 3. 使用 detect_file_type 检测文件类型
7
+ 4. 根据文件类型选择合适的分析工具
8
+
9
+ 根据文件类型选择工具:
10
+
11
+ 1. **检测文件类型** → detect_file_type(不确定文件类型时先用此工具)
12
+ 2. **读取文本文件** → read_text_file(txt, md, log, rst, json, yaml, xml 等纯文本)
13
+ 3. **代码分析** → analyze_code(py, js, ts, c, java, go, rs, php, rb, sql, r 等代码文件)
14
+ 4. **PDF 解析** → extract_pdf
15
+ 5. **Word 文档** → extract_docx
16
+ 6. **PowerPoint** → extract_pptx
17
+ 7. **Excel 表格** → extract_xlsx
18
+ 8. **压缩包** → extract_archive(支持 zip, tar, gz, 7z, rar 等)
19
+ 9. **图像分析** → analyze_multimodal
20
+ 10. **音频/视频** → analyze_multimodal
21
+
22
+ 【未知格式处理策略】
23
+ - 如果文件类型未知或无法识别,**先尝试使用 read_text_file 处理**
24
+ - read_text_file 会自动检测编码,如果能成功解码则返回文本内容
25
+ - 如果 read_text_file 返回编码错误或乱码,说明文件是二进制文件
26
+ - 对于明显的二进制文件,可以告知用户:"文件格式无法识别,可能是二进制文件"
27
+ - 不要立即拒绝,给纯文本处理一个机会
28
+
29
+ 注意事项:
30
+ - 压缩包支持列出文件列表或解压,根据用户需求选择
31
+ - 大文件(>10MB)会部分读取或拒绝,根据文件类型自动处理
32
+ - 文档类文件提取纯文本内容,图片会单独处理
33
+ - 分析完成后务必调用 cleanup_temp 清理临时文件
34
+ - 保持回答简洁,聚焦于用户需要的信息
35
+
36
+ 如果问题涉及时间,立刻调用时间工具获取。
@@ -0,0 +1 @@
1
+ # Tools for File Analysis Agent
@@ -0,0 +1,17 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "analyze_code",
5
+ "description": "分析代码文件,提取代码结构、统计信息、注释等。支持 py, js, ts, c, java, go, rs, php, rb 等编程语言。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "file_path": {
10
+ "type": "string",
11
+ "description": "本地文件路径"
12
+ }
13
+ },
14
+ "required": ["file_path"]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,427 @@
1
+ import chardet
2
+ from pathlib import Path
3
+ from typing import Any, Dict
4
+ import re
5
+ import logging
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ LANGUAGE_MAP: dict[str, str] = {
10
+ ".py": "Python",
11
+ ".js": "JavaScript",
12
+ ".ts": "TypeScript",
13
+ ".jsx": "React JavaScript",
14
+ ".tsx": "React TypeScript",
15
+ ".c": "C",
16
+ ".cpp": "C++",
17
+ ".cc": "C++",
18
+ ".h": "C/C++ Header",
19
+ ".hpp": "C++ Header",
20
+ ".cs": "C#",
21
+ ".java": "Java",
22
+ ".kt": "Kotlin",
23
+ ".scala": "Scala",
24
+ ".go": "Go",
25
+ ".rs": "Rust",
26
+ ".rb": "Ruby",
27
+ ".php": "PHP",
28
+ ".swift": "Swift",
29
+ ".m": "Objective-C / MATLAB/Octave",
30
+ ".mm": "Objective-C++",
31
+ ".pyw": "Python (GUI)",
32
+ ".lua": "Lua",
33
+ ".r": "R",
34
+ ".sql": "SQL",
35
+ ".sh": "Shell",
36
+ ".bash": "Bash",
37
+ ".zsh": "Zsh",
38
+ ".ps1": "PowerShell",
39
+ ".yaml": "YAML",
40
+ ".yml": "YAML",
41
+ ".json": "JSON",
42
+ ".xml": "XML",
43
+ ".html": "HTML",
44
+ ".htm": "HTML",
45
+ ".css": "CSS",
46
+ ".scss": "SCSS",
47
+ ".less": "LESS",
48
+ ".vue": "Vue",
49
+ ".svelte": "Svelte",
50
+ ".dart": "Dart",
51
+ ".ex": "Elixir",
52
+ ".exs": "Elixir",
53
+ ".erl": "Erlang",
54
+ ".hrl": "Erlang Header",
55
+ ".ml": "OCaml",
56
+ ".mli": "OCaml Interface",
57
+ ".hs": "Haskell",
58
+ ".lhs": "Literate Haskell",
59
+ ".jl": "Julia",
60
+ ".mat": "MATLAB",
61
+ ".pl": "Perl",
62
+ ".pm": "Perl Module",
63
+ ".t": "Perl Test",
64
+ ".awk": "AWK",
65
+ ".groovy": "Groovy",
66
+ ".gradle": "Gradle",
67
+ ".proto": "Protocol Buffer",
68
+ ".thrift": "Thrift",
69
+ }
70
+
71
+ COMMENT_PATTERNS: dict[str, tuple[str | None, str | None]] = {
72
+ "Python": ('"""', '"""'),
73
+ "JavaScript": ("/*", "*/"),
74
+ "TypeScript": ("/*", "*/"),
75
+ "Java": ("/*", "*/"),
76
+ "Kotlin": ("/*", "*/"),
77
+ "Go": ("/*", "*/"),
78
+ "Rust": ("/*", "*/"),
79
+ "Ruby": ("=begin", "=end"),
80
+ "PHP": ("/*", "*/"),
81
+ "C": ("/*", "*/"),
82
+ "C++": ("/*", "*/"),
83
+ "C#": ("/*", "*/"),
84
+ "Swift": ("/*", "*/"),
85
+ "SQL": ("/*", "*/"),
86
+ "Shell": ("#", None),
87
+ "Bash": ("#", None),
88
+ "CSS": ("/*", "*/"),
89
+ "HTML": ("<!--", "-->"),
90
+ "XML": ("<!--", "-->"),
91
+ "YAML": ("#", None),
92
+ "JSON": (None, None),
93
+ "Lua": ("--[[", "]]"),
94
+ "Dart": ("/*", "*/"),
95
+ "Scala": ("/*", "*/"),
96
+ "Elixir": ("#", None),
97
+ "Erlang": ("%", None),
98
+ "Haskell": ("{-", "-}"),
99
+ "Julia": ("#=", "=#"),
100
+ "Perl": ("#", None),
101
+ "Groovy": ("/*", "*/"),
102
+ }
103
+
104
+
105
+ async def execute(args: Dict[str, Any], context: Dict[str, Any]) -> str:
106
+ file_path: str = args.get("file_path", "")
107
+ path = Path(file_path)
108
+
109
+ if not path.exists():
110
+ return f"错误:文件不存在 {file_path}"
111
+
112
+ if not path.is_file():
113
+ return f"错误:{file_path} 不是文件"
114
+
115
+ try:
116
+ with open(path, "rb") as binary_file:
117
+ raw_data: bytes = binary_file.read()
118
+
119
+ detected = chardet.detect(raw_data)
120
+ encoding: str | None = detected.get("encoding") if detected else "utf-8"
121
+ confidence: float = detected.get("confidence", 0) if detected else 0
122
+
123
+ if encoding is None or confidence < 0.5:
124
+ encoding = "utf-8"
125
+
126
+ try:
127
+ content = raw_data.decode(encoding)
128
+ except UnicodeDecodeError:
129
+ content = raw_data.decode("utf-8")
130
+
131
+ file_size = path.stat().st_size
132
+ language = _detect_language(path, content)
133
+
134
+ lines = content.split("\n")
135
+ total_lines = len(lines)
136
+ code_lines = sum(
137
+ 1 for line in lines if line.strip() and not _is_comment(line, language)
138
+ )
139
+ comment_lines = sum(1 for line in lines if _is_comment(line, language))
140
+ blank_lines = sum(1 for line in lines if not line.strip())
141
+
142
+ info: list[str] = []
143
+ info.append(f"文件大小:{file_size} 字节")
144
+ info.append(f"检测编码:{encoding} (置信度: {confidence:.2f})")
145
+ info.append(f"编程语言:{language}")
146
+ info.append(f"总行数:{total_lines}")
147
+ info.append(f"代码行数:{code_lines}")
148
+ info.append(f"注释行数:{comment_lines}")
149
+ info.append(f"空行数:{blank_lines}")
150
+
151
+ if language != "Plain Text":
152
+ imports = _extract_imports(content, language)
153
+ functions = _extract_functions(content, language)
154
+ classes = _extract_classes(content, language)
155
+ comment_blocks = _extract_comment_blocks(content, language)
156
+
157
+ if imports:
158
+ info.append(f"\n导入模块 ({len(imports)}):")
159
+ for imp in imports[:20]:
160
+ info.append(f" - {imp}")
161
+ if len(imports) > 20:
162
+ info.append(f" ... (还有 {len(imports) - 20} 个)")
163
+
164
+ if classes:
165
+ info.append(f"\n类定义 ({len(classes)}):")
166
+ for cls in classes[:10]:
167
+ info.append(f" - {cls}")
168
+ if len(classes) > 10:
169
+ info.append(f" ... (还有 {len(classes) - 10} 个)")
170
+
171
+ if functions:
172
+ info.append(f"\n函数定义 ({len(functions)}):")
173
+ for func in functions[:15]:
174
+ info.append(f" - {func}")
175
+ if len(functions) > 15:
176
+ info.append(f" ... (还有 {len(functions) - 15} 个)")
177
+
178
+ if comment_blocks:
179
+ info.append(f"\n文档注释 ({len(comment_blocks)}):")
180
+ for i, comment in enumerate(comment_blocks[:5], 1):
181
+ lines_preview = "\n".join(comment.split("\n")[:3])
182
+ if len(comment.split("\n")) > 3:
183
+ lines_preview += "..."
184
+ info.append(f" {i}. {lines_preview}")
185
+ if len(comment_blocks) > 5:
186
+ info.append(f" ... (还有 {len(comment_blocks) - 5} 个)")
187
+
188
+ content_preview = "\n".join(lines[:50])
189
+ if total_lines > 50:
190
+ content_preview += f"\n... (共 {total_lines} 行,已显示前 50 行)"
191
+
192
+ info.append(f"\n--- 文件内容预览 ---\n{content_preview}")
193
+
194
+ return "\n".join(info)
195
+
196
+ except Exception as e:
197
+ logger.exception(f"分析代码失败: {e}")
198
+ return f"分析代码失败: {e}"
199
+
200
+
201
+ def _detect_language(path: Path, content: str) -> str:
202
+ ext = path.suffix.lower()
203
+ language = LANGUAGE_MAP.get(ext, "Plain Text")
204
+
205
+ if language == "Plain Text":
206
+ if content.startswith("#!/usr/bin/python") or content.startswith(
207
+ "#!/usr/bin/env python"
208
+ ):
209
+ language = "Python"
210
+ elif content.startswith("#!/usr/bin/node") or content.startswith(
211
+ "#!/usr/bin/env node"
212
+ ):
213
+ language = "JavaScript"
214
+ elif content.startswith("#!/bin/bash") or content.startswith("#!/usr/bin/bash"):
215
+ language = "Bash"
216
+
217
+ return language
218
+
219
+
220
+ def _is_comment(line: str, language: str) -> bool:
221
+ line = line.strip()
222
+ if not line:
223
+ return False
224
+
225
+ comment_starts = ["#", "//", "--", "%", ";", '"']
226
+ for cs in comment_starts:
227
+ if line.startswith(cs):
228
+ return True
229
+
230
+ if language in ("HTML", "XML", "CSS"):
231
+ if "<!--" in line:
232
+ return True
233
+
234
+ return False
235
+
236
+
237
+ def _extract_imports(content: str, language: str) -> list[str]:
238
+ """从代码中提取导入的模块
239
+
240
+ 参数:
241
+ content: 代码内容
242
+ language: 编程语言
243
+
244
+ 返回:
245
+ 导入的模块列表
246
+ """
247
+ imports: list[str] = []
248
+ patterns: list[tuple[str, str]] = [
249
+ (r"^import\s+([\w.]+)", "Python"),
250
+ (r"^from\s+([\w.]+)\s+import", "Python"),
251
+ (r"^import\s+\{([^}]+)\}", "JavaScript"),
252
+ (r"^import\s+([\w{}/.]+)", "JavaScript"),
253
+ (r"^use\s+crate::([\w:]+)", "Rust"),
254
+ (r"^use\s+([\w:]+)", "Rust"),
255
+ (r'^#include\s+[<"]([^\s>""]+)', "C/C++"),
256
+ (r"^package\s+([\w.]+)", "Java"),
257
+ (r"^import\s+([\w.]+);", "Java"),
258
+ (r"^use\s+([\w:]+)", "Go"),
259
+ (r'^require\s+[\'"]([^\'"]+)[\'"]', "Ruby"),
260
+ (r"^use\s+([\w\\]+)", "PHP"),
261
+ ]
262
+
263
+ for line in content.split("\n"):
264
+ line = line.strip()
265
+ for pattern, lang in patterns:
266
+ if lang != language:
267
+ continue
268
+ match = re.match(pattern, line)
269
+ if match:
270
+ imports.append(match.group(1))
271
+
272
+ return list(dict.fromkeys(imports))
273
+
274
+
275
+ def _extract_functions(content: str, language: str) -> list[str]:
276
+ """从代码中提取函数定义
277
+
278
+ 参数:
279
+ content: 代码内容
280
+ language: 编程语言
281
+
282
+ 返回:
283
+ 函数名列表
284
+ """
285
+ functions: list[str] = []
286
+ patterns: dict[str, str] = {
287
+ "Python": r"def\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
288
+ "JavaScript": r"(?:function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)|const\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=\s*(?:async\s+)?\(",
289
+ "TypeScript": r"(?:function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)|const\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=\s*(?:async\s+)?\(",
290
+ "Java": r"(?:public|private|protected|static|\s)*\s*(?:void|[\w<>]+)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
291
+ "Kotlin": r"fun\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
292
+ "Go": r"func\s+(?:[(\w]+\s+)?([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
293
+ "Rust": r"fn\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
294
+ "C": r"(?:static\s+)?(?:void|[\w*]+)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
295
+ "C++": r"(?:static\s+)?(?:void|[\w*]+)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
296
+ "Ruby": r"def\s+([a-zA-Z_][a-zA-Z0-9_?!]*)",
297
+ "PHP": r"function\s+([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*\(",
298
+ "Swift": r"func\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(",
299
+ "Shell": r"^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(\)",
300
+ }
301
+
302
+ pattern = patterns.get(language)
303
+ if not pattern:
304
+ return functions
305
+
306
+ for line in content.split("\n"):
307
+ line = line.strip()
308
+ match = re.match(pattern, line)
309
+ if match:
310
+ func_name = match.group(1) if not match.group(2) else match.group(2)
311
+ functions.append(func_name)
312
+
313
+ return functions
314
+
315
+
316
+ def _extract_classes(content: str, language: str) -> list[str]:
317
+ """从代码中提取类定义
318
+
319
+ 参数:
320
+ content: 代码内容
321
+ language: 编程语言
322
+
323
+ 返回:
324
+ 类名列表
325
+ """
326
+ classes: list[str] = []
327
+ patterns: dict[str, str] = {
328
+ "Python": r"^class\s+([a-zA-Z_][a-zA-Z0-9_]*)",
329
+ "JavaScript": r"class\s+([a-zA-Z_$][a-zA-Z0-9_$]*)",
330
+ "TypeScript": r"class\s+([a-zA-Z_$][a-zA-Z0-9_$]*)",
331
+ "Java": r"(?:public|private|protected|\s)*\s*class\s+([a-zA-Z_][a-zA-Z0-9_]*)",
332
+ "Kotlin": r"class\s+([a-zA-Z_][a-zA-Z0-9_]*)",
333
+ "Go": r"type\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+struct",
334
+ "Rust": r"struct\s+([a-zA-Z_][a-zA-Z0-9_]*)",
335
+ "C++": r"class\s+([a-zA-Z_][a-zA-Z0-9_]*)",
336
+ "C#": r"class\s+([a-zA-Z_][a-zA-Z0-9_]*)",
337
+ "Ruby": r"^class\s+([A-Z][a-zA-Z0-9_]*)",
338
+ "PHP": r"class\s+([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)",
339
+ "Swift": r"class\s+([a-zA-Z_][a-zA-Z0-9_]*)",
340
+ }
341
+
342
+ pattern = patterns.get(language)
343
+ if not pattern:
344
+ return classes
345
+
346
+ for line in content.split("\n"):
347
+ line = line.strip()
348
+ match = re.match(pattern, line)
349
+ if match:
350
+ classes.append(match.group(1))
351
+
352
+ return classes
353
+
354
+
355
+ def _extract_comment_blocks(content: str, language: str) -> list[str]:
356
+ """提取代码中的块注释
357
+
358
+ 参数:
359
+ content: 代码内容
360
+ language: 编程语言
361
+
362
+ 返回:
363
+ 注释块列表
364
+ """
365
+ blocks: list[str] = []
366
+
367
+ if language not in COMMENT_PATTERNS:
368
+ return blocks
369
+
370
+ start_delim, end_delim = COMMENT_PATTERNS[language]
371
+ if start_delim is None:
372
+ return blocks
373
+
374
+ lines = content.split("\n")
375
+ in_block = False
376
+ current_block: list[str] = []
377
+
378
+ for i, line in enumerate(lines):
379
+ line_lower = line.strip()
380
+
381
+ if not in_block:
382
+ if line_lower.startswith(start_delim):
383
+ in_block = True
384
+ current_block = [line]
385
+ else:
386
+ current_block.append(line)
387
+ # 处理块注释结束
388
+ if end_delim:
389
+ if line_lower.endswith(end_delim) or end_delim in line_lower:
390
+ in_block = False
391
+ _add_block_if_valid(blocks, current_block)
392
+ current_block = []
393
+ # 处理单行注释连续出现的情况(伪块注释)
394
+ else:
395
+ if line.strip().startswith("#") or line.strip().startswith("//"):
396
+ # 继续收集连续的单行注释
397
+ pass
398
+ else:
399
+ # 单行注释中断,保存之前的块
400
+ # 注意:当前行不是注释,所以不应该加入 current_block,而是应该处理掉之前的 block
401
+ # 但上面的逻辑已经 append 了,这实际上是把非注释行也加进去了,这是个小 bug
402
+ # 为了保持原有逻辑大致不变但简化复杂度,我们这里做个修正:
403
+ # 如果是单行注释模式,current_block 实际上在上一行结束时就应该判断是否继续
404
+ # 这里的原始逻辑其实是把当前非注释行也加进去了然后结束。
405
+ # 我们简化一下:遇到非注释行,结束块。
406
+ current_block.pop() # 移除刚才加进去的非注释行
407
+ in_block = False
408
+ _add_block_if_valid(blocks, current_block)
409
+ current_block = []
410
+
411
+ # 处理文件末尾遗留的块
412
+ if current_block:
413
+ _add_block_if_valid(blocks, current_block)
414
+
415
+ return blocks
416
+
417
+
418
+ def _add_block_if_valid(blocks: list[str], current_block: list[str]) -> None:
419
+ """如果块内容有效且长度足够,则添加到列表
420
+
421
+ 参数:
422
+ blocks: 目标列表
423
+ current_block: 当前块内容
424
+ """
425
+ block_content = "\n".join(current_block)
426
+ if len(block_content) > 20:
427
+ blocks.append(block_content)
@@ -0,0 +1,25 @@
1
+ {
2
+ "type": "function",
3
+ "function": {
4
+ "name": "analyze_multimodal",
5
+ "description": "使用多模态 AI 模型分析图像、音频或视频内容。自动检测媒体类型并使用相应的分析提示词。",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "file_path": {
10
+ "type": "string",
11
+ "description": "本地媒体文件路径"
12
+ },
13
+ "media_type": {
14
+ "type": "string",
15
+ "description": "媒体类型:'image'、'audio'、'video' 或 'auto'(自动检测),默认为 'auto'"
16
+ },
17
+ "prompt": {
18
+ "type": "string",
19
+ "description": "额外的分析指令,例如'提取图中所有手机号'、'转写音频内容'"
20
+ }
21
+ },
22
+ "required": ["file_path"]
23
+ }
24
+ }
25
+ }