beswarm 0.2.49__tar.gz → 0.2.51__tar.gz

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.

Potentially problematic release.


This version of beswarm might be problematic. Click here for more details.

Files changed (163) hide show
  1. {beswarm-0.2.49 → beswarm-0.2.51}/PKG-INFO +1 -1
  2. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/agents/chatgroup.py +2 -2
  3. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/agents/planact.py +2 -2
  4. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/response.py +2 -0
  5. beswarm-0.2.51/beswarm/aient/aient/models/__init__.py +2 -0
  6. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/excute_command.py +1 -1
  7. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/read_file.py +1 -1
  8. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/websearch.py +1 -1
  9. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/write_file.py +1 -1
  10. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/utils/scripts.py +1 -1
  11. beswarm-0.2.51/beswarm/aient/main.py +15 -0
  12. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/knowledge_graph.py +59 -1
  13. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/taskmanager.py +1 -1
  14. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/__init__.py +1 -1
  15. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/click.py +3 -3
  16. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/completion.py +1 -1
  17. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/edit_file.py +2 -2
  18. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/graph.py +1 -1
  19. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/planner.py +3 -3
  20. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/repomap.py +1 -1
  21. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/request_input.py +1 -1
  22. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/screenshot.py +1 -1
  23. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/search_arxiv.py +1 -1
  24. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/search_web.py +1 -1
  25. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/subtasks.py +1 -1
  26. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/worker.py +1 -1
  27. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/tools/write_csv.py +1 -1
  28. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/utils.py +1 -1
  29. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm.egg-info/PKG-INFO +1 -1
  30. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm.egg-info/SOURCES.txt +32 -60
  31. {beswarm-0.2.49 → beswarm-0.2.51}/pyproject.toml +1 -1
  32. {beswarm-0.2.49 → beswarm-0.2.51}/test/test_graph.py +103 -0
  33. beswarm-0.2.49/beswarm/aient/main.py +0 -50
  34. beswarm-0.2.49/beswarm/aient/setup.py +0 -15
  35. beswarm-0.2.49/beswarm/aient/src/aient/models/__init__.py +0 -9
  36. beswarm-0.2.49/beswarm/aient/src/aient/models/claude.py +0 -573
  37. beswarm-0.2.49/beswarm/aient/src/aient/models/duckduckgo.py +0 -241
  38. beswarm-0.2.49/beswarm/aient/src/aient/models/gemini.py +0 -357
  39. beswarm-0.2.49/beswarm/aient/src/aient/models/groq.py +0 -234
  40. beswarm-0.2.49/beswarm/aient/src/aient/models/vertex.py +0 -420
  41. beswarm-0.2.49/beswarm/aient/test/chatgpt.py +0 -161
  42. beswarm-0.2.49/beswarm/aient/test/claude.py +0 -32
  43. beswarm-0.2.49/beswarm/aient/test/test.py +0 -2
  44. beswarm-0.2.49/beswarm/aient/test/test_API.py +0 -6
  45. beswarm-0.2.49/beswarm/aient/test/test_Deepbricks.py +0 -20
  46. beswarm-0.2.49/beswarm/aient/test/test_aiwaves.py +0 -25
  47. beswarm-0.2.49/beswarm/aient/test/test_aiwaves_arxiv.py +0 -19
  48. beswarm-0.2.49/beswarm/aient/test/test_ask_gemini.py +0 -8
  49. beswarm-0.2.49/beswarm/aient/test/test_class.py +0 -17
  50. beswarm-0.2.49/beswarm/aient/test/test_claude.py +0 -23
  51. beswarm-0.2.49/beswarm/aient/test/test_claude_zh_char.py +0 -26
  52. beswarm-0.2.49/beswarm/aient/test/test_download_pdf.py +0 -56
  53. beswarm-0.2.49/beswarm/aient/test/test_gemini.py +0 -97
  54. beswarm-0.2.49/beswarm/aient/test/test_get_token_dict.py +0 -21
  55. beswarm-0.2.49/beswarm/aient/test/test_jieba.py +0 -32
  56. beswarm-0.2.49/beswarm/aient/test/test_json.py +0 -65
  57. beswarm-0.2.49/beswarm/aient/test/test_logging.py +0 -32
  58. beswarm-0.2.49/beswarm/aient/test/test_py_run.py +0 -26
  59. beswarm-0.2.49/beswarm/aient/test/test_requests.py +0 -162
  60. beswarm-0.2.49/beswarm/aient/test/test_tikitoken.py +0 -19
  61. beswarm-0.2.49/beswarm/aient/test/test_token.py +0 -94
  62. beswarm-0.2.49/beswarm/aient/test/test_wildcard.py +0 -20
  63. {beswarm-0.2.49 → beswarm-0.2.51}/MANIFEST.in +0 -0
  64. {beswarm-0.2.49 → beswarm-0.2.51}/README.md +0 -0
  65. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/__init__.py +0 -0
  66. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/__init__.py +0 -0
  67. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/__init__.py +0 -0
  68. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/log_config.py +0 -0
  69. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/models.py +0 -0
  70. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/request.py +0 -0
  71. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/test/test_base_api.py +0 -0
  72. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/test/test_geminimask.py +0 -0
  73. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/test/test_image.py +0 -0
  74. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/test/test_payload.py +0 -0
  75. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/core/utils.py +0 -0
  76. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/models/audio.py +0 -0
  77. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/models/base.py +0 -0
  78. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/models/chatgpt.py +0 -0
  79. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/__init__.py +0 -0
  80. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/arXiv.py +0 -0
  81. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/config.py +0 -0
  82. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/get_time.py +0 -0
  83. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/image.py +0 -0
  84. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/list_directory.py +0 -0
  85. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/read_image.py +0 -0
  86. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/readonly.py +0 -0
  87. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/registry.py +0 -0
  88. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/plugins/run_python.py +0 -0
  89. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/utils/__init__.py +0 -0
  90. {beswarm-0.2.49/beswarm/aient/src → beswarm-0.2.51/beswarm/aient}/aient/utils/prompt.py +0 -0
  91. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_Web_crawler.py +0 -0
  92. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_ddg_search.py +0 -0
  93. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_google_search.py +0 -0
  94. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_ollama.py +0 -0
  95. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_plugin.py +0 -0
  96. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_search.py +0 -0
  97. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_url.py +0 -0
  98. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_whisper.py +0 -0
  99. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/aient/test/test_yjh.py +0 -0
  100. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/bemcp/bemcp/__init__.py +0 -0
  101. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/bemcp/bemcp/decorator.py +0 -0
  102. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/bemcp/bemcp/main.py +0 -0
  103. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/bemcp/bemcp/utils.py +0 -0
  104. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/bemcp/test/client.py +0 -0
  105. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/bemcp/test/server.py +0 -0
  106. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/broker.py +0 -0
  107. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/core.py +0 -0
  108. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/prompt.py +0 -0
  109. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/README.md +0 -0
  110. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/arduino-tags.scm +0 -0
  111. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/c-tags.scm +0 -0
  112. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/chatito-tags.scm +0 -0
  113. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/commonlisp-tags.scm +0 -0
  114. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/cpp-tags.scm +0 -0
  115. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/csharp-tags.scm +0 -0
  116. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/d-tags.scm +0 -0
  117. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/dart-tags.scm +0 -0
  118. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/elisp-tags.scm +0 -0
  119. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/elixir-tags.scm +0 -0
  120. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/elm-tags.scm +0 -0
  121. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/gleam-tags.scm +0 -0
  122. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/go-tags.scm +0 -0
  123. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/java-tags.scm +0 -0
  124. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/javascript-tags.scm +0 -0
  125. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/lua-tags.scm +0 -0
  126. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/pony-tags.scm +0 -0
  127. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/properties-tags.scm +0 -0
  128. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/python-tags.scm +0 -0
  129. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/r-tags.scm +0 -0
  130. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/racket-tags.scm +0 -0
  131. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/ruby-tags.scm +0 -0
  132. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/rust-tags.scm +0 -0
  133. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/solidity-tags.scm +0 -0
  134. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/swift-tags.scm +0 -0
  135. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-language-pack/udev-tags.scm +0 -0
  136. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/README.md +0 -0
  137. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/c-tags.scm +0 -0
  138. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/c_sharp-tags.scm +0 -0
  139. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/cpp-tags.scm +0 -0
  140. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/dart-tags.scm +0 -0
  141. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/elisp-tags.scm +0 -0
  142. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/elixir-tags.scm +0 -0
  143. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/elm-tags.scm +0 -0
  144. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/go-tags.scm +0 -0
  145. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/hcl-tags.scm +0 -0
  146. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/java-tags.scm +0 -0
  147. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/javascript-tags.scm +0 -0
  148. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/kotlin-tags.scm +0 -0
  149. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/ocaml-tags.scm +0 -0
  150. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/php-tags.scm +0 -0
  151. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/python-tags.scm +0 -0
  152. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/ql-tags.scm +0 -0
  153. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/ruby-tags.scm +0 -0
  154. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/rust-tags.scm +0 -0
  155. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/scala-tags.scm +0 -0
  156. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm/queries/tree-sitter-languages/typescript-tags.scm +0 -0
  157. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm.egg-info/dependency_links.txt +0 -0
  158. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm.egg-info/requires.txt +0 -0
  159. {beswarm-0.2.49 → beswarm-0.2.51}/beswarm.egg-info/top_level.txt +0 -0
  160. {beswarm-0.2.49 → beswarm-0.2.51}/setup.cfg +0 -0
  161. {beswarm-0.2.49 → beswarm-0.2.51}/test/test_TaskManager.py +0 -0
  162. {beswarm-0.2.49 → beswarm-0.2.51}/test/test_broker.py +0 -0
  163. {beswarm-0.2.49 → beswarm-0.2.51}/test/test_new_TaskManager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beswarm
3
- Version: 0.2.49
3
+ Version: 0.2.51
4
4
  Summary: MAS
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -15,8 +15,8 @@ from typing import List, Dict, Union
15
15
  from ..broker import MessageBroker
16
16
  from ..bemcp.bemcp import MCPManager
17
17
  from ..utils import register_mcp_tools
18
- from ..aient.src.aient.models import chatgpt
19
- from ..aient.src.aient.plugins import get_function_call_list, registry
18
+ from ..aient.aient.models import chatgpt
19
+ from ..aient.aient.plugins import get_function_call_list, registry
20
20
 
21
21
  worker_system_prompt = """
22
22
  你是{name}。帮助用户头脑风暴。请分析不同用户的观点,并给出你的观点。
@@ -10,8 +10,8 @@ from datetime import datetime
10
10
  from typing import List, Dict, Union
11
11
 
12
12
  from ..broker import MessageBroker
13
- from ..aient.src.aient.models import chatgpt
14
- from ..aient.src.aient.plugins import get_function_call_list, registry
13
+ from ..aient.aient.models import chatgpt
14
+ from ..aient.aient.plugins import get_function_call_list, registry
15
15
  from ..prompt import worker_system_prompt, instruction_system_prompt
16
16
  from ..utils import extract_xml_content, get_current_screen_image_message, replace_xml_content, register_mcp_tools, setup_logger
17
17
 
@@ -33,6 +33,8 @@ def gemini_json_poccess(response_str):
33
33
  promptTokenCount = safe_get(response_json, "usageMetadata", "promptTokenCount", default=0)
34
34
  candidatesTokenCount = safe_get(response_json, "usageMetadata", "candidatesTokenCount", default=0)
35
35
  totalTokenCount = safe_get(response_json, "usageMetadata", "totalTokenCount", default=0)
36
+ if finishReason != "STOP":
37
+ logger.error(f"finishReason: {finishReason}")
36
38
 
37
39
  content = reasoning_content = safe_get(json_data, "parts", 0, "text", default="")
38
40
  b64_json = safe_get(json_data, "parts", 0, "inlineData", "data", default="")
@@ -0,0 +1,2 @@
1
+ from .chatgpt import *
2
+ from .audio import *
@@ -276,4 +276,4 @@ for i in content.split("\\n"):
276
276
  # print(excute_command(python_long_task_command))
277
277
 
278
278
  # print(get_python_executable("python -c 'print(123)'"))
279
- # python -m beswarm.aient.src.aient.plugins.excute_command
279
+ # python -m beswarm.aient.aient.plugins.excute_command
@@ -181,7 +181,7 @@ Examples:
181
181
  return f"<tool_error>读取文件时发生错误: {e}</tool_error>"
182
182
 
183
183
  if __name__ == "__main__":
184
- # python -m beswarm.aient.src.aient.plugins.read_file
184
+ # python -m beswarm.aient.aient.plugins.read_file
185
185
  result = read_file("./work/cax/Lenia Notebook.ipynb")
186
186
  print(result)
187
187
  print(len(result))
@@ -344,7 +344,7 @@ async def get_search_results(query):
344
344
 
345
345
  if __name__ == "__main__":
346
346
  os.system("clear")
347
- # python -m beswarm.aient.src.aient.plugins.websearch
347
+ # python -m beswarm.aient.aient.plugins.websearch
348
348
  print(get_url_content(""))
349
349
  # from aient.models import chatgpt
350
350
  # print(get_search_results("今天的微博热搜有哪些?", chatgpt.chatgpt_api_url.v1_url))
@@ -87,4 +87,4 @@ if __name__ == "__main__":
87
87
  with open("test.txt", "r", encoding="utf-8") as file:
88
88
  content = file.read()
89
89
  print(write_to_file("test.txt", content))
90
- # python -m beswarm.aient.src.aient.plugins.write_file
90
+ # python -m beswarm.aient.aient.plugins.write_file
@@ -1050,4 +1050,4 @@ if __name__ == "__main__":
1050
1050
  # print(parse_function_xml(test_xml))
1051
1051
  print(remove_xml_tags_and_content(test_xml))
1052
1052
 
1053
- # 运行本文件:python -m beswarm.aient.src.aient.utils.scripts
1053
+ # 运行本文件:python -m beswarm.aient.aient.utils.scripts
@@ -0,0 +1,15 @@
1
+ import os
2
+
3
+ from aient.utils import prompt
4
+ from aient.models import chatgpt
5
+ GPT_ENGINE = os.environ.get('MODEL')
6
+
7
+ API = os.environ.get('API_KEY')
8
+ API_URL = os.environ.get('BASE_URL', None)
9
+
10
+ message = "hi"
11
+ systemprompt = os.environ.get('SYSTEMPROMPT', prompt.chatgpt_system_prompt)
12
+
13
+ bot = chatgpt(api_key=API, api_url=API_URL , engine=GPT_ENGINE, system_prompt=systemprompt)
14
+ for text in bot.ask_stream(message):
15
+ print(text, end="")
@@ -1,6 +1,7 @@
1
1
  import uuid
2
2
  import networkx as nx
3
3
  from pathlib import Path
4
+ from .aient.aient.utils.scripts import unescape_html
4
5
 
5
6
  class KnowledgeGraphManager:
6
7
  """
@@ -68,6 +69,7 @@ class KnowledgeGraphManager:
68
69
  if path is None or not path.strip() or path.strip() in ['.', '/']:
69
70
  return "root"
70
71
 
72
+ path = unescape_html(path)
71
73
  segments = [s for s in path.strip('/').split('/') if s and s != '.']
72
74
  current_node_id = "root"
73
75
 
@@ -104,6 +106,9 @@ class KnowledgeGraphManager:
104
106
 
105
107
  def add_node(self, parent_path: str, node_name: str, description: str = "", tags: list[str] = None) -> str:
106
108
  """在指定父节点下添加一个新节点。"""
109
+ parent_path = unescape_html(parent_path)
110
+ node_name = unescape_html(node_name)
111
+ description = unescape_html(description)
107
112
  if not node_name.strip():
108
113
  return "❌ 错误:节点名称不能为空。"
109
114
  if '/' in node_name:
@@ -125,6 +130,32 @@ class KnowledgeGraphManager:
125
130
  self._save_graph()
126
131
  return f"✅ 成功在 '{parent_path}' 下添加节点 '{node_name}'。"
127
132
 
133
+ def _get_path_by_node_id(self, node_id: str) -> str:
134
+ """通过节点ID获取其在图中的完整路径。"""
135
+ if node_id == "root":
136
+ return "."
137
+
138
+ path_segments = []
139
+ current_id = node_id
140
+ while current_id != "root":
141
+ if current_id not in self.graph:
142
+ return None
143
+
144
+ # 假设每个节点只有一个父节点(树状结构)
145
+ predecessors = list(self.graph.predecessors(current_id))
146
+ if not predecessors:
147
+ return None
148
+
149
+ parent_id = predecessors[0]
150
+ node_name = self.graph.nodes[current_id].get('name')
151
+ if node_name is None:
152
+ return None
153
+
154
+ path_segments.append(node_name)
155
+ current_id = parent_id
156
+
157
+ return "/".join(reversed(path_segments))
158
+
128
159
  def _get_tags(self, node_id: str) -> list[str]:
129
160
  """获取节点的标签列表。"""
130
161
  tags_str = self.graph.nodes[node_id].get('tags', '')
@@ -138,6 +169,7 @@ class KnowledgeGraphManager:
138
169
 
139
170
  def add_tags_to_node(self, node_path: str, tags_to_add: list[str]) -> str:
140
171
  """向指定节点添加一个或多个标签。"""
172
+ node_path = unescape_html(node_path)
141
173
  node_id = self._get_node_id_by_path(node_path)
142
174
  if node_id is None:
143
175
  return f"❌ 错误:路径 '{node_path}' 不存在。"
@@ -150,6 +182,7 @@ class KnowledgeGraphManager:
150
182
 
151
183
  def remove_tags_from_node(self, node_path: str, tags_to_remove: list[str]) -> str:
152
184
  """从指定节点移除一个或多个标签。"""
185
+ node_path = unescape_html(node_path)
153
186
  node_id = self._get_node_id_by_path(node_path)
154
187
  if node_id is None:
155
188
  return f"❌ 错误:路径 '{node_path}' 不存在。"
@@ -169,6 +202,7 @@ class KnowledgeGraphManager:
169
202
 
170
203
  def delete_node(self, node_path: str) -> str:
171
204
  """删除一个节点及其所有子孙节点。"""
205
+ node_path = unescape_html(node_path)
172
206
  if node_path is None or node_path.strip() in ['.', '/']:
173
207
  return "❌ 错误:不能删除根节点。"
174
208
 
@@ -185,6 +219,8 @@ class KnowledgeGraphManager:
185
219
 
186
220
  def rename_node(self, node_path: str, new_name: str) -> str:
187
221
  """重命名一个节点。"""
222
+ node_path = unescape_html(node_path)
223
+ new_name = unescape_html(new_name)
188
224
  if not new_name.strip():
189
225
  return "❌ 错误:新名称不能为空。"
190
226
  if '/' in new_name:
@@ -207,6 +243,8 @@ class KnowledgeGraphManager:
207
243
 
208
244
  def move_node(self, source_path: str, target_parent_path: str) -> str:
209
245
  """将一个节点移动到另一个父节点下。"""
246
+ source_path = unescape_html(source_path)
247
+ target_parent_path = unescape_html(target_parent_path)
210
248
  source_id = self._get_node_id_by_path(source_path)
211
249
  if source_id is None:
212
250
  return f"❌ 错误:源路径 '{source_path}' 不存在。"
@@ -233,9 +271,29 @@ class KnowledgeGraphManager:
233
271
 
234
272
  def get_node_details(self, node_path: str) -> str:
235
273
  """获取指定路径节点的所有详细信息。"""
274
+ node_path = unescape_html(node_path)
236
275
  node_id = self._get_node_id_by_path(node_path)
237
276
  if node_id is None:
238
- return f"❌ 错误:路径 '{node_path}' 不存在。"
277
+ path_segments = [s for s in node_path.strip('/').split('/') if s and s != '.']
278
+ if not path_segments:
279
+ return f"❌ 错误:路径 '{node_path}' 不存在。"
280
+
281
+ target_name = path_segments[-1]
282
+ suggestions = []
283
+ for n_id, data in self.graph.nodes(data=True):
284
+ if n_id != 'root' and target_name in data.get('name', ''):
285
+ full_path = self._get_path_by_node_id(n_id)
286
+ if full_path:
287
+ suggestions.append(full_path)
288
+
289
+ if suggestions:
290
+ # 去重并排序
291
+ suggestions = sorted(list(set(suggestions)))
292
+ message = f"❌ 错误:路径 '{node_path}' 不存在。\n\n您是不是要找:\n"
293
+ message += "\n".join([f"- {s}" for s in suggestions])
294
+ return message
295
+ else:
296
+ return f"❌ 错误:路径 '{node_path}' 不存在。"
239
297
 
240
298
  node_data = self.graph.nodes[node_id]
241
299
  description = node_data.get('description', '无描述。')
@@ -5,7 +5,7 @@ import asyncio
5
5
  from enum import Enum
6
6
  from pathlib import Path
7
7
 
8
- from .aient.src.aient.plugins import registry
8
+ from .aient.aient.plugins import registry
9
9
 
10
10
  class TaskStatus(Enum):
11
11
  """任务状态枚举"""
@@ -21,7 +21,7 @@ from .click import find_and_click_element, scroll_screen
21
21
  from .subtasks import create_task, resume_task, get_all_tasks_status, get_task_result, create_tasks_from_csv
22
22
 
23
23
  #显式导入 aient.plugins 中的所需内容
24
- from ..aient.src.aient.plugins import (
24
+ from ..aient.aient.plugins import (
25
25
  get_time,
26
26
  read_file,
27
27
  read_image,
@@ -7,10 +7,10 @@ import base64
7
7
  import pyperclip # 新增:用于操作剪贴板
8
8
  import platform # 新增:用于检测操作系统
9
9
  from PIL import Image, ImageDraw
10
- from ..aient.src.aient.plugins import register_tool
10
+ from ..aient.aient.plugins import register_tool
11
11
 
12
- from ..aient.src.aient.models import chatgpt
13
- from ..aient.src.aient.core.utils import get_image_message, get_text_message
12
+ from ..aient.aient.models import chatgpt
13
+ from ..aient.aient.core.utils import get_image_message, get_text_message
14
14
 
15
15
  def display_image_with_bounding_boxes_and_masks_py(
16
16
  original_image,
@@ -1,4 +1,4 @@
1
- from ..aient.src.aient.plugins import register_tool
1
+ from ..aient.aient.plugins import register_tool
2
2
 
3
3
  @register_tool()
4
4
  def task_complete(message: str) -> str:
@@ -1,8 +1,8 @@
1
1
  import os
2
2
  import re
3
3
  import difflib
4
- from ..aient.src.aient.plugins import register_tool
5
- from ..aient.src.aient.utils.scripts import unescape_html
4
+ from ..aient.aient.plugins import register_tool
5
+ from ..aient.aient.utils.scripts import unescape_html
6
6
 
7
7
  @register_tool()
8
8
  def edit_file(file_path, diff_content, match_precision=0.9):
@@ -2,7 +2,7 @@ import ast
2
2
  from typing import List
3
3
 
4
4
  from ..core import kgm
5
- from ..aient.src.aient.plugins import register_tool
5
+ from ..aient.aient.plugins import register_tool
6
6
 
7
7
  @register_tool()
8
8
  def add_knowledge_node(parent_path: str, node_name: str, description: str = "", tags: List[str] = None) -> str:
@@ -1,8 +1,8 @@
1
1
  import os
2
- from ..aient.src.aient.plugins import register_tool, get_function_call_list
2
+ from ..aient.aient.plugins import register_tool, get_function_call_list
3
3
 
4
- from ..aient.src.aient.models import chatgpt
5
- from ..aient.src.aient.prompt import planner_system_prompt
4
+ from ..aient.aient.models import chatgpt
5
+ from ..aient.aient.prompt import planner_system_prompt
6
6
 
7
7
  @register_tool()
8
8
  async def planner(goal, tools, work_dir):
@@ -10,7 +10,7 @@ import warnings
10
10
  from pathlib import Path
11
11
  from collections import Counter, defaultdict, namedtuple
12
12
 
13
- from ..aient.src.aient.plugins import register_tool
13
+ from ..aient.aient.plugins import register_tool
14
14
 
15
15
  from tqdm import tqdm
16
16
  from diskcache import Cache
@@ -1,4 +1,4 @@
1
- from ..aient.src.aient.plugins import register_tool
1
+ from ..aient.aient.plugins import register_tool
2
2
 
3
3
  @register_tool()
4
4
  def request_admin_input(prompt: str) -> str:
@@ -1,4 +1,4 @@
1
- from ..aient.src.aient.plugins import register_tool
1
+ from ..aient.aient.plugins import register_tool
2
2
 
3
3
  @register_tool()
4
4
  def save_screenshot_to_file(save_path):
@@ -1,7 +1,7 @@
1
1
  import requests
2
2
  import csv
3
3
  from datetime import datetime
4
- from ..aient.src.aient.plugins import register_tool
4
+ from ..aient.aient.plugins import register_tool
5
5
 
6
6
  @register_tool()
7
7
  def search_arxiv(query, max_results=5, sort_by='relevance', sort_order='descending',
@@ -4,7 +4,7 @@ import json
4
4
  import httpx
5
5
  import threading
6
6
 
7
- from ..aient.src.aient.plugins import register_tool, get_url_content # Assuming a similar plugin structure
7
+ from ..aient.aient.plugins import register_tool, get_url_content # Assuming a similar plugin structure
8
8
 
9
9
  class ThreadWithReturnValue(threading.Thread):
10
10
  def run(self):
@@ -1,7 +1,7 @@
1
1
  import ast
2
2
  from pathlib import Path
3
3
  from ..core import task_manager
4
- from ..aient.src.aient.plugins import register_tool, registry
4
+ from ..aient.aient.plugins import register_tool, registry
5
5
 
6
6
  worker_fun = registry.tools["worker"]
7
7
 
@@ -4,7 +4,7 @@ from typing import List, Dict, Union
4
4
  from ..core import mcp_manager, broker, task_manager, kgm
5
5
  from ..agents.planact import BrokerWorker
6
6
  from ..agents.chatgroup import ChatGroupWorker
7
- from ..aient.src.aient.plugins import register_tool
7
+ from ..aient.aient.plugins import register_tool
8
8
 
9
9
 
10
10
  @register_tool()
@@ -1,7 +1,7 @@
1
1
  import csv
2
2
  import ast
3
3
  import os
4
- from ..aient.src.aient.plugins import register_tool
4
+ from ..aient.aient.plugins import register_tool
5
5
 
6
6
  @register_tool()
7
7
  def append_row_to_csv(file_path: str, data: list):
@@ -37,7 +37,7 @@ def replace_xml_content(original_string: str, tag_name: str, replacement_content
37
37
 
38
38
  import io
39
39
  import base64
40
- from .aient.src.aient.core.utils import get_image_message, get_text_message
40
+ from .aient.aient.core.utils import get_image_message, get_text_message
41
41
 
42
42
  async def get_current_screen_image_message(prompt):
43
43
  print("instruction agent 正在截取当前屏幕...")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beswarm
3
- Version: 0.2.49
3
+ Version: 0.2.51
4
4
  Summary: MAS
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -16,74 +16,46 @@ beswarm.egg-info/top_level.txt
16
16
  beswarm/agents/chatgroup.py
17
17
  beswarm/agents/planact.py
18
18
  beswarm/aient/main.py
19
- beswarm/aient/setup.py
20
- beswarm/aient/src/aient/__init__.py
21
- beswarm/aient/src/aient/core/__init__.py
22
- beswarm/aient/src/aient/core/log_config.py
23
- beswarm/aient/src/aient/core/models.py
24
- beswarm/aient/src/aient/core/request.py
25
- beswarm/aient/src/aient/core/response.py
26
- beswarm/aient/src/aient/core/utils.py
27
- beswarm/aient/src/aient/core/test/test_base_api.py
28
- beswarm/aient/src/aient/core/test/test_geminimask.py
29
- beswarm/aient/src/aient/core/test/test_image.py
30
- beswarm/aient/src/aient/core/test/test_payload.py
31
- beswarm/aient/src/aient/models/__init__.py
32
- beswarm/aient/src/aient/models/audio.py
33
- beswarm/aient/src/aient/models/base.py
34
- beswarm/aient/src/aient/models/chatgpt.py
35
- beswarm/aient/src/aient/models/claude.py
36
- beswarm/aient/src/aient/models/duckduckgo.py
37
- beswarm/aient/src/aient/models/gemini.py
38
- beswarm/aient/src/aient/models/groq.py
39
- beswarm/aient/src/aient/models/vertex.py
40
- beswarm/aient/src/aient/plugins/__init__.py
41
- beswarm/aient/src/aient/plugins/arXiv.py
42
- beswarm/aient/src/aient/plugins/config.py
43
- beswarm/aient/src/aient/plugins/excute_command.py
44
- beswarm/aient/src/aient/plugins/get_time.py
45
- beswarm/aient/src/aient/plugins/image.py
46
- beswarm/aient/src/aient/plugins/list_directory.py
47
- beswarm/aient/src/aient/plugins/read_file.py
48
- beswarm/aient/src/aient/plugins/read_image.py
49
- beswarm/aient/src/aient/plugins/readonly.py
50
- beswarm/aient/src/aient/plugins/registry.py
51
- beswarm/aient/src/aient/plugins/run_python.py
52
- beswarm/aient/src/aient/plugins/websearch.py
53
- beswarm/aient/src/aient/plugins/write_file.py
54
- beswarm/aient/src/aient/utils/__init__.py
55
- beswarm/aient/src/aient/utils/prompt.py
56
- beswarm/aient/src/aient/utils/scripts.py
57
- beswarm/aient/test/chatgpt.py
58
- beswarm/aient/test/claude.py
59
- beswarm/aient/test/test.py
60
- beswarm/aient/test/test_API.py
61
- beswarm/aient/test/test_Deepbricks.py
19
+ beswarm/aient/aient/__init__.py
20
+ beswarm/aient/aient/core/__init__.py
21
+ beswarm/aient/aient/core/log_config.py
22
+ beswarm/aient/aient/core/models.py
23
+ beswarm/aient/aient/core/request.py
24
+ beswarm/aient/aient/core/response.py
25
+ beswarm/aient/aient/core/utils.py
26
+ beswarm/aient/aient/core/test/test_base_api.py
27
+ beswarm/aient/aient/core/test/test_geminimask.py
28
+ beswarm/aient/aient/core/test/test_image.py
29
+ beswarm/aient/aient/core/test/test_payload.py
30
+ beswarm/aient/aient/models/__init__.py
31
+ beswarm/aient/aient/models/audio.py
32
+ beswarm/aient/aient/models/base.py
33
+ beswarm/aient/aient/models/chatgpt.py
34
+ beswarm/aient/aient/plugins/__init__.py
35
+ beswarm/aient/aient/plugins/arXiv.py
36
+ beswarm/aient/aient/plugins/config.py
37
+ beswarm/aient/aient/plugins/excute_command.py
38
+ beswarm/aient/aient/plugins/get_time.py
39
+ beswarm/aient/aient/plugins/image.py
40
+ beswarm/aient/aient/plugins/list_directory.py
41
+ beswarm/aient/aient/plugins/read_file.py
42
+ beswarm/aient/aient/plugins/read_image.py
43
+ beswarm/aient/aient/plugins/readonly.py
44
+ beswarm/aient/aient/plugins/registry.py
45
+ beswarm/aient/aient/plugins/run_python.py
46
+ beswarm/aient/aient/plugins/websearch.py
47
+ beswarm/aient/aient/plugins/write_file.py
48
+ beswarm/aient/aient/utils/__init__.py
49
+ beswarm/aient/aient/utils/prompt.py
50
+ beswarm/aient/aient/utils/scripts.py
62
51
  beswarm/aient/test/test_Web_crawler.py
63
- beswarm/aient/test/test_aiwaves.py
64
- beswarm/aient/test/test_aiwaves_arxiv.py
65
- beswarm/aient/test/test_ask_gemini.py
66
- beswarm/aient/test/test_class.py
67
- beswarm/aient/test/test_claude.py
68
- beswarm/aient/test/test_claude_zh_char.py
69
52
  beswarm/aient/test/test_ddg_search.py
70
- beswarm/aient/test/test_download_pdf.py
71
- beswarm/aient/test/test_gemini.py
72
- beswarm/aient/test/test_get_token_dict.py
73
53
  beswarm/aient/test/test_google_search.py
74
- beswarm/aient/test/test_jieba.py
75
- beswarm/aient/test/test_json.py
76
- beswarm/aient/test/test_logging.py
77
54
  beswarm/aient/test/test_ollama.py
78
55
  beswarm/aient/test/test_plugin.py
79
- beswarm/aient/test/test_py_run.py
80
- beswarm/aient/test/test_requests.py
81
56
  beswarm/aient/test/test_search.py
82
- beswarm/aient/test/test_tikitoken.py
83
- beswarm/aient/test/test_token.py
84
57
  beswarm/aient/test/test_url.py
85
58
  beswarm/aient/test/test_whisper.py
86
- beswarm/aient/test/test_wildcard.py
87
59
  beswarm/aient/test/test_yjh.py
88
60
  beswarm/bemcp/bemcp/__init__.py
89
61
  beswarm/bemcp/bemcp/decorator.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "beswarm"
3
- version = "0.2.49"
3
+ version = "0.2.51"
4
4
  description = "MAS"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -203,6 +203,67 @@ class KnowledgeGraphManager:
203
203
  self._save_graph()
204
204
  return f"✅ 成功将节点 '{source_path}' 移动到 '{target_parent_path}' 下。"
205
205
 
206
+ def _get_path_by_node_id(self, node_id: str) -> str:
207
+ """通过节点ID获取其在图中的完整路径。"""
208
+ if node_id == "root":
209
+ return "."
210
+
211
+ path_segments = []
212
+ current_id = node_id
213
+ while current_id != "root":
214
+ if current_id not in self.graph:
215
+ return None
216
+
217
+ predecessors = list(self.graph.predecessors(current_id))
218
+ if not predecessors:
219
+ return None
220
+
221
+ parent_id = predecessors[0]
222
+ node_name = self.graph.nodes[current_id].get('name')
223
+ if node_name is None:
224
+ return None
225
+
226
+ path_segments.append(node_name)
227
+ current_id = parent_id
228
+
229
+ return "/".join(reversed(path_segments))
230
+
231
+ def get_node_details(self, node_path: str) -> str:
232
+ """获取指定路径节点的所有详细信息。"""
233
+ node_id = self._get_node_id_by_path(node_path)
234
+ if node_id is None:
235
+ path_segments = [s for s in node_path.strip('/').split('/') if s and s != '.']
236
+ if not path_segments:
237
+ return f"❌ 错误:路径 '{node_path}' 不存在。"
238
+
239
+ target_name = path_segments[-1]
240
+ suggestions = []
241
+ for n_id, data in self.graph.nodes(data=True):
242
+ if n_id != 'root' and target_name in data.get('name', ''):
243
+ full_path = self._get_path_by_node_id(n_id)
244
+ if full_path:
245
+ suggestions.append(full_path)
246
+
247
+ if suggestions:
248
+ suggestions = sorted(list(set(suggestions)))
249
+ message = f"❌ 错误:路径 '{node_path}' 不存在。\n\n您是不是要找:\n"
250
+ message += "\n".join([f"- {s}" for s in suggestions])
251
+ return message
252
+ else:
253
+ return f"❌ 错误:路径 '{node_path}' 不存在。"
254
+
255
+ node_data = self.graph.nodes[node_id]
256
+ description = node_data.get('description', '无描述。')
257
+ tags = self._get_tags(node_id)
258
+
259
+ details = [f"节点: {node_path}", f"描述: {description}"]
260
+ if tags:
261
+ details.append(f"标签: {' '.join([f'#{t}' for t in tags])}")
262
+ else:
263
+ details.append("标签: 无")
264
+
265
+ return "\n".join(details)
266
+
206
267
  def render_tree(self, show_source_tags=False) -> str:
207
268
  """渲染整个知识图谱为树状结构的文本。"""
208
269
  if not self.graph or "root" not in self.graph:
@@ -326,5 +387,47 @@ def main_test_loop():
326
387
 
327
388
  input("\n按回车键继续...")
328
389
 
390
+ def run_automated_tests():
391
+ """运行自动化测试,验证核心功能。"""
392
+ print("\n" + "="*50)
393
+ print("🚀 开始运行自动化测试...")
394
+ print("="*50)
395
+
396
+ test_file = "test_graph.graphml"
397
+ if os.path.exists(test_file):
398
+ os.remove(test_file)
399
+
400
+ kgm = KnowledgeGraphManager(storage_path=test_file)
401
+
402
+ # 1. 测试节点建议功能
403
+ print("\n" + colors.HEADER + "1. 测试 'get_node_details' 的建议功能..." + colors.ENDC)
404
+ kgm.add_node(".", "技术")
405
+ kgm.add_node("技术", "深度学习")
406
+ kgm.add_node("技术/深度学习", "挑战")
407
+ kgm.add_node(".", "应用")
408
+ kgm.add_node("应用", "挑战")
409
+
410
+ # 查找一个不存在但有明确建议的节点
411
+ result = kgm.get_node_details("挑战")
412
+ expected_suggestions = ["技术/深度学习/挑战", "应用/挑战"]
413
+
414
+ print(f"查询 '挑战' 的结果:\n{result}")
415
+
416
+ all_found = all(suggestion in result for suggestion in expected_suggestions)
417
+ if "您是不是要找" in result and all_found:
418
+ print(colors.OKGREEN + "✅ 测试通过: 成功提供了正确的建议。" + colors.ENDC)
419
+ else:
420
+ print(colors.FAIL + "❌ 测试失败: 未能提供正确的建议。" + colors.ENDC)
421
+
422
+ # 2. 清理测试文件
423
+ if os.path.exists(test_file):
424
+ os.remove(test_file)
425
+ print("\n" + "🧹 清理测试文件完成。")
426
+ print("\n" + "="*50)
427
+ print("✅ 自动化测试结束。")
428
+ print("="*50)
429
+
430
+
329
431
  if __name__ == "__main__":
432
+ run_automated_tests()
330
433
  main_test_loop()