auto-coder 0.1.400__py3-none-any.whl → 2.0.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.

Potentially problematic release.


This version of auto-coder might be problematic. Click here for more details.

Files changed (579) hide show
  1. auto_coder-2.0.0.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.0.dist-info/METADATA +558 -0
  3. auto_coder-2.0.0.dist-info/RECORD +795 -0
  4. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
  5. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
  6. autocoder/__init__.py +31 -0
  7. autocoder/agent/auto_filegroup.py +32 -13
  8. autocoder/agent/auto_learn_from_commit.py +9 -1
  9. autocoder/agent/base_agentic/__init__.py +3 -0
  10. autocoder/agent/base_agentic/agent_hub.py +1 -1
  11. autocoder/agent/base_agentic/base_agent.py +235 -136
  12. autocoder/agent/base_agentic/default_tools.py +119 -118
  13. autocoder/agent/base_agentic/test_base_agent.py +1 -1
  14. autocoder/agent/base_agentic/tool_registry.py +32 -20
  15. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +25 -4
  16. autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
  17. autocoder/agent/base_agentic/types.py +42 -0
  18. autocoder/agent/entry_command_agent/chat.py +73 -59
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +1029 -2310
  22. autocoder/auto_coder_terminal.py +26 -0
  23. autocoder/auto_coder_terminal_v3.py +190 -0
  24. autocoder/chat/conf_command.py +224 -124
  25. autocoder/chat/models_command.py +361 -299
  26. autocoder/chat/rules_command.py +79 -31
  27. autocoder/chat_auto_coder.py +1021 -372
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +26 -9
  30. autocoder/commands/auto_web.py +1 -1
  31. autocoder/commands/tools.py +44 -44
  32. autocoder/common/__init__.py +150 -128
  33. autocoder/common/ac_style_command_parser/__init__.py +39 -2
  34. autocoder/common/ac_style_command_parser/config.py +422 -0
  35. autocoder/common/ac_style_command_parser/parser.py +292 -78
  36. autocoder/common/ac_style_command_parser/test_parser.py +241 -16
  37. autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
  38. autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
  39. autocoder/common/action_yml_file_manager.py +25 -13
  40. autocoder/common/agent_events/__init__.py +52 -0
  41. autocoder/common/agent_events/agent_event_emitter.py +193 -0
  42. autocoder/common/agent_events/event_factory.py +177 -0
  43. autocoder/common/agent_events/examples.py +307 -0
  44. autocoder/common/agent_events/types.py +113 -0
  45. autocoder/common/agent_events/utils.py +68 -0
  46. autocoder/common/agent_hooks/__init__.py +44 -0
  47. autocoder/common/agent_hooks/examples.py +582 -0
  48. autocoder/common/agent_hooks/hook_executor.py +217 -0
  49. autocoder/common/agent_hooks/hook_manager.py +288 -0
  50. autocoder/common/agent_hooks/types.py +133 -0
  51. autocoder/common/agent_hooks/utils.py +99 -0
  52. autocoder/common/agent_query_queue/queue_executor.py +324 -0
  53. autocoder/common/agent_query_queue/queue_manager.py +325 -0
  54. autocoder/common/agents/__init__.py +11 -0
  55. autocoder/common/agents/agent_manager.py +323 -0
  56. autocoder/common/agents/agent_parser.py +189 -0
  57. autocoder/common/agents/example_usage.py +344 -0
  58. autocoder/common/agents/integration_example.py +330 -0
  59. autocoder/common/agents/test_agent_parser.py +545 -0
  60. autocoder/common/async_utils.py +101 -0
  61. autocoder/common/auto_coder_lang.py +23 -972
  62. autocoder/common/autocoderargs_parser/__init__.py +14 -0
  63. autocoder/common/autocoderargs_parser/parser.py +184 -0
  64. autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
  65. autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
  66. autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
  67. autocoder/common/autocoderargs_parser/token_parser.py +290 -0
  68. autocoder/common/buildin_tokenizer.py +2 -4
  69. autocoder/common/code_auto_generate.py +149 -74
  70. autocoder/common/code_auto_generate_diff.py +163 -70
  71. autocoder/common/code_auto_generate_editblock.py +179 -89
  72. autocoder/common/code_auto_generate_strict_diff.py +167 -72
  73. autocoder/common/code_auto_merge_editblock.py +13 -6
  74. autocoder/common/code_modification_ranker.py +1 -1
  75. autocoder/common/command_completer.py +3 -3
  76. autocoder/common/command_file_manager/manager.py +183 -47
  77. autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
  78. autocoder/common/command_templates.py +1 -1
  79. autocoder/common/conf_utils.py +2 -4
  80. autocoder/common/conversations/config.py +11 -3
  81. autocoder/common/conversations/get_conversation_manager.py +100 -2
  82. autocoder/common/conversations/llm_stats_models.py +264 -0
  83. autocoder/common/conversations/manager.py +112 -28
  84. autocoder/common/conversations/models.py +16 -2
  85. autocoder/common/conversations/storage/index_manager.py +134 -10
  86. autocoder/common/core_config/__init__.py +63 -0
  87. autocoder/common/core_config/agentic_mode_manager.py +109 -0
  88. autocoder/common/core_config/base_manager.py +123 -0
  89. autocoder/common/core_config/compatibility.py +151 -0
  90. autocoder/common/core_config/config_manager.py +156 -0
  91. autocoder/common/core_config/conversation_manager.py +31 -0
  92. autocoder/common/core_config/exclude_manager.py +72 -0
  93. autocoder/common/core_config/file_manager.py +177 -0
  94. autocoder/common/core_config/human_as_model_manager.py +129 -0
  95. autocoder/common/core_config/lib_manager.py +54 -0
  96. autocoder/common/core_config/main_manager.py +81 -0
  97. autocoder/common/core_config/mode_manager.py +126 -0
  98. autocoder/common/core_config/models.py +70 -0
  99. autocoder/common/core_config/test_memory_manager.py +1056 -0
  100. autocoder/common/env_manager.py +282 -0
  101. autocoder/common/env_manager_usage_example.py +211 -0
  102. autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
  103. autocoder/common/file_checkpoint/manager.py +264 -48
  104. autocoder/common/file_checkpoint/test_backup.py +1 -18
  105. autocoder/common/file_checkpoint/test_manager.py +270 -1
  106. autocoder/common/file_checkpoint/test_store.py +1 -17
  107. autocoder/common/file_handler/__init__.py +23 -0
  108. autocoder/common/file_handler/active_context_handler.py +159 -0
  109. autocoder/common/file_handler/add_files_handler.py +409 -0
  110. autocoder/common/file_handler/chat_handler.py +180 -0
  111. autocoder/common/file_handler/coding_handler.py +401 -0
  112. autocoder/common/file_handler/commit_handler.py +200 -0
  113. autocoder/common/file_handler/lib_handler.py +156 -0
  114. autocoder/common/file_handler/list_files_handler.py +111 -0
  115. autocoder/common/file_handler/mcp_handler.py +268 -0
  116. autocoder/common/file_handler/models_handler.py +493 -0
  117. autocoder/common/file_handler/remove_files_handler.py +172 -0
  118. autocoder/common/file_monitor/test_file_monitor.py +307 -0
  119. autocoder/common/git_utils.py +51 -10
  120. autocoder/common/global_cancel.py +15 -6
  121. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  122. autocoder/common/international/__init__.py +31 -0
  123. autocoder/common/international/demo_international.py +92 -0
  124. autocoder/common/international/message_manager.py +157 -0
  125. autocoder/common/international/messages/__init__.py +56 -0
  126. autocoder/common/international/messages/async_command_messages.py +507 -0
  127. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  128. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  129. autocoder/common/international/messages/command_help_messages.py +986 -0
  130. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  131. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  132. autocoder/common/international/messages/queue_command_messages.py +751 -0
  133. autocoder/common/international/messages/rules_command_messages.py +77 -0
  134. autocoder/common/international/messages/sdk_messages.py +1707 -0
  135. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  136. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  137. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  138. autocoder/common/international/test_international.py +612 -0
  139. autocoder/common/linter_core/__init__.py +28 -0
  140. autocoder/common/linter_core/base_linter.py +61 -0
  141. autocoder/common/linter_core/config_loader.py +271 -0
  142. autocoder/common/linter_core/formatters/__init__.py +0 -0
  143. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  144. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  145. autocoder/common/linter_core/linter.py +166 -0
  146. autocoder/common/linter_core/linter_factory.py +216 -0
  147. autocoder/common/linter_core/linter_manager.py +333 -0
  148. autocoder/common/linter_core/linters/__init__.py +9 -0
  149. autocoder/common/linter_core/linters/java_linter.py +342 -0
  150. autocoder/common/linter_core/linters/python_linter.py +115 -0
  151. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  152. autocoder/common/linter_core/models/__init__.py +7 -0
  153. autocoder/common/linter_core/models/lint_result.py +91 -0
  154. autocoder/common/linter_core/models.py +33 -0
  155. autocoder/common/linter_core/tests/__init__.py +3 -0
  156. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  157. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  158. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  159. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  160. autocoder/common/linter_core/tests/test_integration.py +317 -0
  161. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  162. autocoder/common/linter_core/tests/test_linters.py +265 -0
  163. autocoder/common/linter_core/tests/test_models.py +81 -0
  164. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  165. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  166. autocoder/common/llm_friendly_package/__init__.py +31 -0
  167. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  168. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  169. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  170. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  171. autocoder/common/llm_friendly_package/models.py +40 -0
  172. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  173. autocoder/common/llms/__init__.py +15 -0
  174. autocoder/common/llms/demo_error_handling.py +85 -0
  175. autocoder/common/llms/factory.py +142 -0
  176. autocoder/common/llms/manager.py +264 -0
  177. autocoder/common/llms/pricing.py +121 -0
  178. autocoder/common/llms/registry.py +288 -0
  179. autocoder/common/llms/schema.py +77 -0
  180. autocoder/common/llms/simple_demo.py +45 -0
  181. autocoder/common/llms/test_quick_model.py +116 -0
  182. autocoder/common/llms/test_remove_functionality.py +182 -0
  183. autocoder/common/llms/tests/__init__.py +1 -0
  184. autocoder/common/llms/tests/test_manager.py +330 -0
  185. autocoder/common/llms/tests/test_registry.py +364 -0
  186. autocoder/common/mcp_tools/__init__.py +62 -0
  187. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  188. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  189. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  190. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  191. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  192. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  193. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  194. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  195. autocoder/common/model_speed_tester.py +32 -26
  196. autocoder/common/priority_directory_finder/__init__.py +142 -0
  197. autocoder/common/priority_directory_finder/examples.py +230 -0
  198. autocoder/common/priority_directory_finder/finder.py +283 -0
  199. autocoder/common/priority_directory_finder/models.py +236 -0
  200. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  201. autocoder/common/project_scanner/__init__.py +18 -0
  202. autocoder/common/project_scanner/compat.py +77 -0
  203. autocoder/common/project_scanner/scanner.py +436 -0
  204. autocoder/common/project_tracker/__init__.py +27 -0
  205. autocoder/common/project_tracker/api.py +228 -0
  206. autocoder/common/project_tracker/demo.py +272 -0
  207. autocoder/common/project_tracker/tracker.py +487 -0
  208. autocoder/common/project_tracker/types.py +53 -0
  209. autocoder/common/pruner/__init__.py +67 -0
  210. autocoder/common/pruner/agentic_conversation_pruner.py +746 -0
  211. autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
  212. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  213. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  214. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  215. autocoder/common/pruner/conversation_normalizer.py +347 -0
  216. autocoder/common/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
  217. autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
  218. autocoder/common/pruner/test_context_pruner.py +546 -0
  219. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  220. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  221. autocoder/common/pruner/tool_content_detector.py +227 -0
  222. autocoder/common/pruner/tools/__init__.py +18 -0
  223. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  224. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  225. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  226. autocoder/common/pull_requests/__init__.py +9 -1
  227. autocoder/common/pull_requests/utils.py +122 -1
  228. autocoder/common/rag_manager/rag_manager.py +36 -40
  229. autocoder/common/rulefiles/__init__.py +53 -1
  230. autocoder/common/rulefiles/api.py +250 -0
  231. autocoder/common/rulefiles/core/__init__.py +14 -0
  232. autocoder/common/rulefiles/core/manager.py +241 -0
  233. autocoder/common/rulefiles/core/selector.py +805 -0
  234. autocoder/common/rulefiles/models/__init__.py +20 -0
  235. autocoder/common/rulefiles/models/index.py +16 -0
  236. autocoder/common/rulefiles/models/init_rule.py +18 -0
  237. autocoder/common/rulefiles/models/rule_file.py +18 -0
  238. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  239. autocoder/common/rulefiles/models/summary.py +16 -0
  240. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  241. autocoder/common/rulefiles/utils/__init__.py +34 -0
  242. autocoder/common/rulefiles/utils/monitor.py +86 -0
  243. autocoder/common/rulefiles/utils/parser.py +230 -0
  244. autocoder/common/save_formatted_log.py +67 -10
  245. autocoder/common/search_replace.py +8 -1
  246. autocoder/common/search_replace_patch/__init__.py +24 -0
  247. autocoder/common/search_replace_patch/base.py +115 -0
  248. autocoder/common/search_replace_patch/manager.py +248 -0
  249. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  250. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  251. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  252. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  253. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  254. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  255. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  256. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  257. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  258. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  259. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  260. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  261. autocoder/common/shell_commands/__init__.py +197 -0
  262. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  263. autocoder/common/shell_commands/command_executor.py +1127 -0
  264. autocoder/common/shell_commands/error_recovery.py +541 -0
  265. autocoder/common/shell_commands/exceptions.py +120 -0
  266. autocoder/common/shell_commands/interactive_executor.py +476 -0
  267. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  268. autocoder/common/shell_commands/interactive_process.py +744 -0
  269. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  270. autocoder/common/shell_commands/monitoring.py +529 -0
  271. autocoder/common/shell_commands/process_cleanup.py +386 -0
  272. autocoder/common/shell_commands/process_manager.py +606 -0
  273. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  274. autocoder/common/shell_commands/tests/__init__.py +6 -0
  275. autocoder/common/shell_commands/tests/conftest.py +118 -0
  276. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  277. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  278. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  279. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  280. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  281. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  282. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  283. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  284. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  285. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  286. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  287. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  288. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  289. autocoder/common/shell_commands/timeout_config.py +315 -0
  290. autocoder/common/shell_commands/timeout_manager.py +352 -0
  291. autocoder/common/terminal_paste/__init__.py +14 -0
  292. autocoder/common/terminal_paste/demo.py +145 -0
  293. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  294. autocoder/common/terminal_paste/paste_handler.py +200 -0
  295. autocoder/common/terminal_paste/paste_manager.py +118 -0
  296. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  297. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  298. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  299. autocoder/common/terminal_paste/utils.py +163 -0
  300. autocoder/common/test_autocoder_args.py +232 -0
  301. autocoder/common/test_env_manager.py +173 -0
  302. autocoder/common/test_env_manager_integration.py +159 -0
  303. autocoder/common/text_similarity/__init__.py +9 -0
  304. autocoder/common/text_similarity/demo.py +216 -0
  305. autocoder/common/text_similarity/examples.py +266 -0
  306. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  307. autocoder/common/text_similarity/text_similarity.py +194 -0
  308. autocoder/common/text_similarity/utils.py +125 -0
  309. autocoder/common/todos/__init__.py +61 -0
  310. autocoder/common/todos/cache/__init__.py +16 -0
  311. autocoder/common/todos/cache/base_cache.py +89 -0
  312. autocoder/common/todos/cache/cache_manager.py +228 -0
  313. autocoder/common/todos/cache/memory_cache.py +225 -0
  314. autocoder/common/todos/config.py +155 -0
  315. autocoder/common/todos/exceptions.py +35 -0
  316. autocoder/common/todos/get_todo_manager.py +161 -0
  317. autocoder/common/todos/manager.py +537 -0
  318. autocoder/common/todos/models.py +239 -0
  319. autocoder/common/todos/storage/__init__.py +14 -0
  320. autocoder/common/todos/storage/base_storage.py +76 -0
  321. autocoder/common/todos/storage/file_storage.py +278 -0
  322. autocoder/common/tokens/__init__.py +15 -0
  323. autocoder/common/tokens/counter.py +44 -2
  324. autocoder/common/tools_manager/__init__.py +17 -0
  325. autocoder/common/tools_manager/examples.py +162 -0
  326. autocoder/common/tools_manager/manager.py +385 -0
  327. autocoder/common/tools_manager/models.py +39 -0
  328. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  329. autocoder/common/tools_manager/utils.py +191 -0
  330. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  331. autocoder/common/v2/agent/agentic_edit.py +2729 -2052
  332. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
  338. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  340. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +565 -30
  344. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  346. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  347. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  349. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  350. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +244 -51
  352. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  353. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  354. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +409 -140
  355. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  356. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +209 -194
  359. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
  360. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
  361. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  362. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  363. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  364. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  365. autocoder/common/v2/agent/agentic_edit_types.py +386 -10
  366. autocoder/common/v2/agent/runner/__init__.py +31 -0
  367. autocoder/common/v2/agent/runner/base_runner.py +92 -0
  368. autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
  369. autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
  370. autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
  371. autocoder/common/v2/agent/runner/tool_display.py +589 -0
  372. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  373. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  374. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  375. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  376. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  377. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  378. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  379. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  380. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  381. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  382. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  383. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  384. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  385. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  386. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  387. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  388. autocoder/common/v2/code_auto_generate.py +136 -78
  389. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  390. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  391. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  392. autocoder/common/v2/code_auto_merge.py +1 -1
  393. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  394. autocoder/common/v2/code_diff_manager.py +3 -3
  395. autocoder/common/v2/code_editblock_manager.py +4 -14
  396. autocoder/common/v2/code_manager.py +1 -1
  397. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  398. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  399. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  400. autocoder/common/wrap_llm_hint/utils.py +432 -0
  401. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  402. autocoder/completer/__init__.py +8 -0
  403. autocoder/completer/command_completer_v2.py +1051 -0
  404. autocoder/default_project/__init__.py +501 -0
  405. autocoder/dispacher/__init__.py +4 -12
  406. autocoder/dispacher/actions/action.py +165 -7
  407. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  408. autocoder/index/entry.py +117 -125
  409. autocoder/{agent → index/filter}/agentic_filter.py +323 -334
  410. autocoder/index/filter/normal_filter.py +5 -11
  411. autocoder/index/filter/quick_filter.py +1 -1
  412. autocoder/index/index.py +36 -9
  413. autocoder/index/tests/__init__.py +1 -0
  414. autocoder/index/tests/run_tests.py +195 -0
  415. autocoder/index/tests/test_entry.py +303 -0
  416. autocoder/index/tests/test_index_manager.py +314 -0
  417. autocoder/index/tests/test_module_integration.py +300 -0
  418. autocoder/index/tests/test_symbols_utils.py +183 -0
  419. autocoder/inner/__init__.py +4 -0
  420. autocoder/inner/agentic.py +932 -0
  421. autocoder/inner/async_command_handler.py +992 -0
  422. autocoder/inner/conversation_command_handlers.py +623 -0
  423. autocoder/inner/merge_command_handler.py +213 -0
  424. autocoder/inner/queue_command_handler.py +684 -0
  425. autocoder/models.py +95 -266
  426. autocoder/plugins/git_helper_plugin.py +31 -29
  427. autocoder/plugins/token_helper_plugin.py +156 -37
  428. autocoder/pyproject/__init__.py +32 -29
  429. autocoder/rag/agentic_rag.py +215 -75
  430. autocoder/rag/cache/simple_cache.py +1 -2
  431. autocoder/rag/loaders/image_loader.py +1 -1
  432. autocoder/rag/long_context_rag.py +42 -26
  433. autocoder/rag/qa_conversation_strategy.py +1 -1
  434. autocoder/rag/terminal/__init__.py +17 -0
  435. autocoder/rag/terminal/args.py +581 -0
  436. autocoder/rag/terminal/bootstrap.py +61 -0
  437. autocoder/rag/terminal/command_handlers.py +653 -0
  438. autocoder/rag/terminal/formatters/__init__.py +20 -0
  439. autocoder/rag/terminal/formatters/base.py +70 -0
  440. autocoder/rag/terminal/formatters/json_format.py +66 -0
  441. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  442. autocoder/rag/terminal/formatters/text.py +28 -0
  443. autocoder/rag/terminal/init.py +120 -0
  444. autocoder/rag/terminal/utils.py +106 -0
  445. autocoder/rag/test_agentic_rag.py +389 -0
  446. autocoder/rag/test_doc_filter.py +3 -3
  447. autocoder/rag/test_long_context_rag.py +1 -1
  448. autocoder/rag/test_token_limiter.py +517 -10
  449. autocoder/rag/token_counter.py +3 -0
  450. autocoder/rag/token_limiter.py +19 -15
  451. autocoder/rag/tools/__init__.py +26 -2
  452. autocoder/rag/tools/bochaai_example.py +343 -0
  453. autocoder/rag/tools/bochaai_sdk.py +541 -0
  454. autocoder/rag/tools/metaso_example.py +268 -0
  455. autocoder/rag/tools/metaso_sdk.py +417 -0
  456. autocoder/rag/tools/recall_tool.py +28 -7
  457. autocoder/rag/tools/run_integration_tests.py +204 -0
  458. autocoder/rag/tools/test_all_providers.py +318 -0
  459. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  460. autocoder/rag/tools/test_final_integration.py +215 -0
  461. autocoder/rag/tools/test_metaso_integration.py +424 -0
  462. autocoder/rag/tools/test_metaso_real.py +171 -0
  463. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  464. autocoder/rag/tools/test_web_search_tool.py +509 -0
  465. autocoder/rag/tools/todo_read_tool.py +202 -0
  466. autocoder/rag/tools/todo_write_tool.py +412 -0
  467. autocoder/rag/tools/web_crawl_tool.py +634 -0
  468. autocoder/rag/tools/web_search_tool.py +558 -0
  469. autocoder/rag/tools/web_tools_example.py +119 -0
  470. autocoder/rag/types.py +16 -0
  471. autocoder/rag/variable_holder.py +4 -2
  472. autocoder/rags.py +86 -79
  473. autocoder/regexproject/__init__.py +23 -21
  474. autocoder/run_context.py +9 -0
  475. autocoder/sdk/__init__.py +50 -161
  476. autocoder/sdk/api.py +370 -0
  477. autocoder/sdk/async_runner/__init__.py +26 -0
  478. autocoder/sdk/async_runner/async_executor.py +650 -0
  479. autocoder/sdk/async_runner/async_handler.py +356 -0
  480. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  481. autocoder/sdk/async_runner/task_metadata.py +284 -0
  482. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  483. autocoder/sdk/cli/__init__.py +2 -5
  484. autocoder/sdk/cli/formatters.py +28 -204
  485. autocoder/sdk/cli/handlers.py +77 -44
  486. autocoder/sdk/cli/main.py +158 -170
  487. autocoder/sdk/cli/options.py +95 -22
  488. autocoder/sdk/constants.py +139 -51
  489. autocoder/sdk/core/auto_coder_core.py +484 -267
  490. autocoder/sdk/core/bridge.py +298 -118
  491. autocoder/sdk/exceptions.py +18 -12
  492. autocoder/sdk/formatters/__init__.py +19 -0
  493. autocoder/sdk/formatters/input.py +64 -0
  494. autocoder/sdk/formatters/output.py +247 -0
  495. autocoder/sdk/formatters/stream.py +54 -0
  496. autocoder/sdk/models/__init__.py +6 -5
  497. autocoder/sdk/models/options.py +55 -18
  498. autocoder/sdk/utils/formatters.py +27 -195
  499. autocoder/suffixproject/__init__.py +28 -25
  500. autocoder/terminal/__init__.py +14 -0
  501. autocoder/terminal/app.py +454 -0
  502. autocoder/terminal/args.py +32 -0
  503. autocoder/terminal/bootstrap.py +178 -0
  504. autocoder/terminal/command_processor.py +521 -0
  505. autocoder/terminal/command_registry.py +57 -0
  506. autocoder/terminal/help.py +97 -0
  507. autocoder/terminal/tasks/__init__.py +5 -0
  508. autocoder/terminal/tasks/background.py +77 -0
  509. autocoder/terminal/tasks/task_event.py +70 -0
  510. autocoder/terminal/ui/__init__.py +13 -0
  511. autocoder/terminal/ui/completer.py +268 -0
  512. autocoder/terminal/ui/keybindings.py +75 -0
  513. autocoder/terminal/ui/session.py +41 -0
  514. autocoder/terminal/ui/toolbar.py +64 -0
  515. autocoder/terminal/utils/__init__.py +13 -0
  516. autocoder/terminal/utils/errors.py +18 -0
  517. autocoder/terminal/utils/paths.py +19 -0
  518. autocoder/terminal/utils/shell.py +43 -0
  519. autocoder/terminal_v3/__init__.py +10 -0
  520. autocoder/terminal_v3/app.py +201 -0
  521. autocoder/terminal_v3/handlers/__init__.py +5 -0
  522. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  523. autocoder/terminal_v3/models/__init__.py +6 -0
  524. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  525. autocoder/terminal_v3/models/message.py +50 -0
  526. autocoder/terminal_v3/models/tool_display.py +247 -0
  527. autocoder/terminal_v3/ui/__init__.py +7 -0
  528. autocoder/terminal_v3/ui/keybindings.py +56 -0
  529. autocoder/terminal_v3/ui/layout.py +141 -0
  530. autocoder/terminal_v3/ui/styles.py +43 -0
  531. autocoder/tsproject/__init__.py +23 -23
  532. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  533. autocoder/utils/llms.py +88 -80
  534. autocoder/utils/math_utils.py +101 -0
  535. autocoder/utils/model_provider_selector.py +16 -4
  536. autocoder/utils/operate_config_api.py +33 -5
  537. autocoder/utils/thread_utils.py +2 -2
  538. autocoder/version.py +4 -2
  539. autocoder/workflow_agents/__init__.py +84 -0
  540. autocoder/workflow_agents/agent.py +143 -0
  541. autocoder/workflow_agents/exceptions.py +573 -0
  542. autocoder/workflow_agents/executor.py +489 -0
  543. autocoder/workflow_agents/loader.py +737 -0
  544. autocoder/workflow_agents/runner.py +267 -0
  545. autocoder/workflow_agents/types.py +172 -0
  546. autocoder/workflow_agents/utils.py +434 -0
  547. autocoder/workflow_agents/workflow_manager.py +211 -0
  548. auto_coder-0.1.400.dist-info/METADATA +0 -396
  549. auto_coder-0.1.400.dist-info/RECORD +0 -425
  550. auto_coder-0.1.400.dist-info/licenses/LICENSE +0 -201
  551. autocoder/auto_coder_server.py +0 -672
  552. autocoder/benchmark.py +0 -138
  553. autocoder/common/ac_style_command_parser/example.py +0 -7
  554. autocoder/common/cleaner.py +0 -31
  555. autocoder/common/command_completer_v2.py +0 -615
  556. autocoder/common/directory_cache/__init__.py +0 -1
  557. autocoder/common/directory_cache/cache.py +0 -192
  558. autocoder/common/directory_cache/test_cache.py +0 -190
  559. autocoder/common/file_checkpoint/examples.py +0 -217
  560. autocoder/common/llm_friendly_package_example.py +0 -138
  561. autocoder/common/llm_friendly_package_test.py +0 -63
  562. autocoder/common/pull_requests/test_module.py +0 -1
  563. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  564. autocoder/common/text.py +0 -30
  565. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  566. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  567. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  568. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  569. autocoder/plugins/dynamic_completion_example.py +0 -148
  570. autocoder/plugins/sample_plugin.py +0 -160
  571. autocoder/sdk/cli/__main__.py +0 -26
  572. autocoder/sdk/cli/completion_wrapper.py +0 -38
  573. autocoder/sdk/cli/install_completion.py +0 -301
  574. autocoder/sdk/models/messages.py +0 -209
  575. autocoder/sdk/session/__init__.py +0 -32
  576. autocoder/sdk/session/session.py +0 -106
  577. autocoder/sdk/session/session_manager.py +0 -56
  578. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
  579. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,331 @@
1
+ """
2
+ Tool Call Plugin Manager
3
+
4
+ 工具调用插件管理器,负责管理和协调插件的执行。
5
+ """
6
+
7
+ import os
8
+ import importlib
9
+ import importlib.util
10
+ import inspect
11
+ from typing import List, Dict, Optional, Any, TYPE_CHECKING
12
+ from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult
13
+ from .plugins.plugin_interface import ToolCallPlugin, PluginPriority
14
+ from loguru import logger
15
+
16
+ if TYPE_CHECKING:
17
+ from autocoder.common.v2.agent.agentic_edit import AgenticEdit
18
+
19
+
20
+ class ToolCallPluginManager:
21
+ """
22
+ 工具调用插件管理器
23
+
24
+ 负责插件的注册、管理和执行流程控制。
25
+ """
26
+
27
+ def __init__(self):
28
+ """初始化插件管理器"""
29
+ self._plugins: List[ToolCallPlugin] = []
30
+ self._plugin_registry: Dict[str, ToolCallPlugin] = {}
31
+ self._global_enabled = True
32
+
33
+ @property
34
+ def plugins(self) -> List[ToolCallPlugin]:
35
+ """获取所有插件(按优先级排序)"""
36
+ return sorted(self._plugins, key=lambda p: p.priority.value)
37
+
38
+ @property
39
+ def enabled_plugins(self) -> List[ToolCallPlugin]:
40
+ """获取所有启用的插件(按优先级排序)"""
41
+ if not self._global_enabled:
42
+ return []
43
+ return [p for p in self.plugins if p.enabled]
44
+
45
+ @property
46
+ def global_enabled(self) -> bool:
47
+ """插件系统是否全局启用"""
48
+ return self._global_enabled
49
+
50
+ def set_global_enabled(self, enabled: bool) -> None:
51
+ """设置插件系统全局启用状态"""
52
+ self._global_enabled = enabled
53
+ logger.info(f"Plugin system globally {'enabled' if enabled else 'disabled'}")
54
+
55
+ def register_plugin(self, plugin: ToolCallPlugin) -> bool:
56
+ """
57
+ 注册插件
58
+
59
+ Args:
60
+ plugin: 插件实例
61
+
62
+ Returns:
63
+ bool: 注册是否成功
64
+ """
65
+ try:
66
+ if plugin.name in self._plugin_registry:
67
+ logger.warning(f"Plugin '{plugin.name}' already registered, replacing")
68
+ self.unregister_plugin(plugin.name)
69
+
70
+ self._plugins.append(plugin)
71
+ self._plugin_registry[plugin.name] = plugin
72
+
73
+ logger.info(f"Registered plugin: {plugin.name} (priority: {plugin.priority.value})")
74
+ return True
75
+
76
+ except Exception as e:
77
+ logger.error(f"Failed to register plugin {plugin.name}: {str(e)}")
78
+ return False
79
+
80
+ def unregister_plugin(self, plugin_name: str) -> bool:
81
+ """
82
+ 注销插件
83
+
84
+ Args:
85
+ plugin_name: 插件名称
86
+
87
+ Returns:
88
+ bool: 注销是否成功
89
+ """
90
+ try:
91
+ if plugin_name not in self._plugin_registry:
92
+ logger.warning(f"Plugin '{plugin_name}' not found")
93
+ return False
94
+
95
+ plugin = self._plugin_registry[plugin_name]
96
+ self._plugins.remove(plugin)
97
+ del self._plugin_registry[plugin_name]
98
+
99
+ logger.info(f"Unregistered plugin: {plugin_name}")
100
+ return True
101
+
102
+ except Exception as e:
103
+ logger.error(f"Failed to unregister plugin {plugin_name}: {str(e)}")
104
+ return False
105
+
106
+ def get_plugin(self, plugin_name: str) -> Optional[ToolCallPlugin]:
107
+ """
108
+ 获取插件实例
109
+
110
+ Args:
111
+ plugin_name: 插件名称
112
+
113
+ Returns:
114
+ Optional[ToolCallPlugin]: 插件实例,如果不存在则返回None
115
+ """
116
+ return self._plugin_registry.get(plugin_name)
117
+
118
+ def enable_plugin(self, plugin_name: str) -> bool:
119
+ """
120
+ 启用插件
121
+
122
+ Args:
123
+ plugin_name: 插件名称
124
+
125
+ Returns:
126
+ bool: 是否成功
127
+ """
128
+ plugin = self.get_plugin(plugin_name)
129
+ if plugin and hasattr(plugin, 'set_enabled'):
130
+ plugin.set_enabled(True)
131
+ logger.info(f"Enabled plugin: {plugin_name}")
132
+ return True
133
+ return False
134
+
135
+ def disable_plugin(self, plugin_name: str) -> bool:
136
+ """
137
+ 禁用插件
138
+
139
+ Args:
140
+ plugin_name: 插件名称
141
+
142
+ Returns:
143
+ bool: 是否成功
144
+ """
145
+ plugin = self.get_plugin(plugin_name)
146
+ if plugin and hasattr(plugin, 'set_enabled'):
147
+ plugin.set_enabled(False)
148
+ logger.info(f"Disabled plugin: {plugin_name}")
149
+ return True
150
+ return False
151
+
152
+ def load_plugins_from_directory(self, directory: str) -> int:
153
+ """
154
+ 从指定目录加载插件
155
+
156
+ Args:
157
+ directory: 插件目录路径
158
+
159
+ Returns:
160
+ int: 成功加载的插件数量
161
+ """
162
+ if not os.path.exists(directory):
163
+ logger.warning(f"Plugin directory not found: {directory}")
164
+ return 0
165
+
166
+ loaded_count = 0
167
+
168
+ for filename in os.listdir(directory):
169
+ if filename.endswith('.py') and not filename.startswith('__'):
170
+ module_name = filename[:-3]
171
+ try:
172
+ # 动态导入模块
173
+ spec = importlib.util.spec_from_file_location(
174
+ module_name,
175
+ os.path.join(directory, filename)
176
+ )
177
+ module = importlib.util.module_from_spec(spec)
178
+ spec.loader.exec_module(module)
179
+
180
+ # 查找插件类
181
+ for name, obj in inspect.getmembers(module):
182
+ if (inspect.isclass(obj) and
183
+ issubclass(obj, ToolCallPlugin) and
184
+ obj != ToolCallPlugin):
185
+
186
+ # 实例化并注册插件
187
+ plugin_instance = obj()
188
+ if self.register_plugin(plugin_instance):
189
+ loaded_count += 1
190
+
191
+ except Exception as e:
192
+ logger.error(f"Failed to load plugin from {filename}: {str(e)}")
193
+
194
+ logger.info(f"Loaded {loaded_count} plugins from {directory}")
195
+ return loaded_count
196
+
197
+ def execute_before_hooks(
198
+ self,
199
+ tool: BaseTool,
200
+ agent: Optional['AgenticEdit'],
201
+ context: Optional[Dict[str, Any]] = None
202
+ ) -> BaseTool:
203
+ """
204
+ 执行工具执行前的钩子
205
+
206
+ Args:
207
+ tool: 工具实例
208
+ agent: 代理实例
209
+ context: 上下文信息
210
+
211
+ Returns:
212
+ BaseTool: 处理后的工具实例
213
+ """
214
+ if not self._global_enabled:
215
+ return tool
216
+
217
+ current_tool = tool
218
+ processed_plugins = []
219
+
220
+ for plugin in self.enabled_plugins:
221
+ try:
222
+ if plugin.should_process_tool(current_tool, agent):
223
+ current_tool = plugin.before_tool_execution(current_tool, agent, context)
224
+ processed_plugins.append(plugin.name)
225
+ except Exception as e:
226
+ logger.error(f"Error in plugin {plugin.name} before_tool_execution: {str(e)}")
227
+
228
+ if processed_plugins:
229
+ logger.debug(f"Before hooks executed by plugins: {', '.join(processed_plugins)}")
230
+
231
+ return current_tool
232
+
233
+ def execute_after_hooks(
234
+ self,
235
+ tool: BaseTool,
236
+ tool_result: ToolResult,
237
+ agent: Optional['AgenticEdit'],
238
+ context: Optional[Dict[str, Any]] = None
239
+ ) -> ToolResult:
240
+ """
241
+ 执行工具执行后的钩子
242
+
243
+ Args:
244
+ tool: 工具实例
245
+ tool_result: 工具执行结果
246
+ agent: 代理实例
247
+ context: 上下文信息
248
+
249
+ Returns:
250
+ ToolResult: 处理后的工具执行结果
251
+ """
252
+ if not self._global_enabled:
253
+ return tool_result
254
+
255
+ current_result = tool_result
256
+ processed_plugins = []
257
+
258
+ for plugin in self.enabled_plugins:
259
+ try:
260
+ if plugin.should_process_tool(tool, agent):
261
+ current_result = plugin.after_tool_execution(tool, current_result, agent, context)
262
+ processed_plugins.append(plugin.name)
263
+ except Exception as e:
264
+ logger.error(f"Error in plugin {plugin.name} after_tool_execution: {str(e)}")
265
+
266
+ if processed_plugins:
267
+ logger.debug(f"After hooks executed by plugins: {', '.join(processed_plugins)}")
268
+
269
+ return current_result
270
+
271
+ def execute_error_hooks(
272
+ self,
273
+ tool: BaseTool,
274
+ error: Exception,
275
+ agent: Optional['AgenticEdit'],
276
+ context: Optional[Dict[str, Any]] = None
277
+ ) -> Optional[ToolResult]:
278
+ """
279
+ 执行工具执行错误的钩子
280
+
281
+ Args:
282
+ tool: 工具实例
283
+ error: 异常信息
284
+ agent: 代理实例
285
+ context: 上下文信息
286
+
287
+ Returns:
288
+ Optional[ToolResult]: 如果某个插件提供了替代结果,则返回该结果
289
+ """
290
+ if not self._global_enabled:
291
+ return None
292
+
293
+ for plugin in self.enabled_plugins:
294
+ try:
295
+ if plugin.should_process_tool(tool, agent):
296
+ result = plugin.on_tool_error(tool, error, agent, context)
297
+ if result is not None:
298
+ logger.info(f"Plugin {plugin.name} provided error recovery result")
299
+ return result
300
+ except Exception as e:
301
+ logger.error(f"Error in plugin {plugin.name} on_tool_error: {str(e)}")
302
+
303
+ return None
304
+
305
+ def get_plugin_status(self) -> Dict[str, Any]:
306
+ """
307
+ 获取插件系统状态
308
+
309
+ Returns:
310
+ Dict[str, Any]: 插件系统状态信息
311
+ """
312
+ return {
313
+ "global_enabled": self._global_enabled,
314
+ "total_plugins": len(self._plugins),
315
+ "enabled_plugins": len(self.enabled_plugins),
316
+ "plugins": [
317
+ {
318
+ "name": plugin.name,
319
+ "priority": plugin.priority.value,
320
+ "enabled": plugin.enabled,
321
+ "description": plugin.description
322
+ }
323
+ for plugin in self.plugins
324
+ ]
325
+ }
326
+
327
+ def clear_plugins(self) -> None:
328
+ """清空所有插件"""
329
+ self._plugins.clear()
330
+ self._plugin_registry.clear()
331
+ logger.info("All plugins cleared")
@@ -0,0 +1,337 @@
1
+ """
2
+ Tool Caller
3
+
4
+ 工具调用器核心模块,负责工具执行和插件系统集成。
5
+ """
6
+
7
+ import time
8
+ from typing import Dict, Type, Optional, Any, TYPE_CHECKING
9
+ from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult
10
+ from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
11
+ from .tool_call_plugin_manager import ToolCallPluginManager
12
+ from .default_tool_resolver_map import get_default_tool_resolver_map
13
+ from loguru import logger
14
+
15
+ if TYPE_CHECKING:
16
+ from autocoder.common.v2.agent.agentic_edit import AgenticEdit
17
+ from autocoder.common import AutoCoderArgs
18
+
19
+
20
+ class ToolCaller:
21
+ """
22
+ 工具调用器
23
+
24
+ 负责工具的调用执行,集成插件系统,提供工具执行的拦截和修改能力。
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ tool_resolver_map: Optional[Dict[Type[BaseTool], Type[BaseToolResolver]]] = None,
30
+ agent: Optional['AgenticEdit'] = None,
31
+ args: Optional['AutoCoderArgs'] = None,
32
+ enable_plugins: bool = True
33
+ ):
34
+ """
35
+ 初始化工具调用器
36
+
37
+ Args:
38
+ tool_resolver_map: 工具类型到解析器类的映射,如果为None则使用默认映射
39
+ agent: 代理实例
40
+ args: 自动编码器参数
41
+ enable_plugins: 是否启用插件系统
42
+ """
43
+ self.tool_resolver_map = tool_resolver_map or get_default_tool_resolver_map()
44
+ self.agent = agent
45
+ self.args = args
46
+ self.plugin_manager = ToolCallPluginManager()
47
+ self.plugin_manager.set_global_enabled(enable_plugins)
48
+
49
+ # 统计信息
50
+ self._stats = {
51
+ "total_calls": 0,
52
+ "successful_calls": 0,
53
+ "failed_calls": 0,
54
+ "plugin_intercepted_calls": 0,
55
+ "total_execution_time": 0.0
56
+ }
57
+
58
+ # 自动加载插件
59
+ self._auto_load_plugins()
60
+
61
+ def _auto_load_plugins(self) -> None:
62
+ """自动加载插件"""
63
+ try:
64
+ # 从默认插件目录加载插件
65
+ if self.args and hasattr(self.args, 'source_dir'):
66
+ plugin_dirs = [
67
+ f"{self.args.source_dir}/.auto-coder/plugins/tool_caller",
68
+ f"{self.args.source_dir}/plugins/tool_caller"
69
+ ]
70
+ for plugin_dir in plugin_dirs:
71
+ if plugin_dir:
72
+ loaded = self.plugin_manager.load_plugins_from_directory(plugin_dir)
73
+ if loaded > 0:
74
+ logger.info(f"Auto-loaded {loaded} plugins from {plugin_dir}")
75
+ except Exception as e:
76
+ logger.warning(f"Failed to auto-load plugins: {str(e)}")
77
+
78
+ def call_tool(
79
+ self,
80
+ tool: BaseTool,
81
+ context: Optional[Dict[str, Any]] = None
82
+ ) -> ToolResult:
83
+ """
84
+ 调用工具执行
85
+
86
+ Args:
87
+ tool: 工具实例
88
+ context: 上下文信息
89
+
90
+ Returns:
91
+ ToolResult: 工具执行结果
92
+ """
93
+ start_time = time.time()
94
+ self._stats["total_calls"] += 1
95
+
96
+ # 创建执行上下文
97
+ exec_context = self._create_execution_context(tool, context)
98
+
99
+ try:
100
+ # 执行前置插件钩子
101
+ processed_tool = self.plugin_manager.execute_before_hooks(
102
+ tool, self.agent, exec_context
103
+ )
104
+
105
+ # 检查工具是否被插件修改
106
+ if processed_tool != tool:
107
+ self._stats["plugin_intercepted_calls"] += 1
108
+ logger.debug(f"Tool {type(tool).__name__} was modified by plugins")
109
+
110
+ # 执行工具
111
+ tool_result = self._execute_tool(processed_tool)
112
+
113
+ # 执行后置插件钩子
114
+ final_result = self.plugin_manager.execute_after_hooks(
115
+ processed_tool, tool_result, self.agent, exec_context
116
+ )
117
+
118
+ # 更新统计信息
119
+ if final_result.success:
120
+ self._stats["successful_calls"] += 1
121
+ else:
122
+ self._stats["failed_calls"] += 1
123
+
124
+ execution_time = time.time() - start_time
125
+ self._stats["total_execution_time"] += execution_time
126
+
127
+ # 添加执行统计到结果中
128
+ if hasattr(final_result, 'content') and isinstance(final_result.content, dict):
129
+ final_result.content["execution_stats"] = {
130
+ "execution_time": execution_time,
131
+ "plugins_processed": len(self.plugin_manager.enabled_plugins)
132
+ }
133
+
134
+ return final_result
135
+
136
+ except Exception as e:
137
+ # 执行错误插件钩子
138
+ recovery_result = self.plugin_manager.execute_error_hooks(
139
+ tool, e, self.agent, exec_context
140
+ )
141
+
142
+ if recovery_result is not None:
143
+ logger.info(f"Plugin provided recovery result for {type(tool).__name__}")
144
+ self._stats["successful_calls"] += 1
145
+ return recovery_result
146
+
147
+ # 没有插件提供恢复结果,返回错误
148
+ self._stats["failed_calls"] += 1
149
+ logger.error(f"Tool execution failed: {str(e)}")
150
+
151
+ return ToolResult(
152
+ success=False,
153
+ message=f"Tool execution failed: {str(e)}",
154
+ content={
155
+ "error_type": type(e).__name__,
156
+ "error_message": str(e),
157
+ "tool_type": type(tool).__name__
158
+ }
159
+ )
160
+
161
+ def _create_execution_context(
162
+ self,
163
+ tool: BaseTool,
164
+ context: Optional[Dict[str, Any]]
165
+ ) -> Dict[str, Any]:
166
+ """
167
+ 创建执行上下文
168
+
169
+ Args:
170
+ tool: 工具实例
171
+ context: 额外的上下文信息
172
+
173
+ Returns:
174
+ Dict[str, Any]: 执行上下文
175
+ """
176
+ exec_context = {
177
+ "tool_type": type(tool).__name__,
178
+ "tool_params": tool.model_dump() if hasattr(tool, 'model_dump') else {},
179
+ "timestamp": time.time(),
180
+ "call_id": f"{type(tool).__name__}_{int(time.time() * 1000)}",
181
+ "agent_present": self.agent is not None,
182
+ "stats": self._stats.copy()
183
+ }
184
+
185
+ if context:
186
+ exec_context.update(context)
187
+
188
+ return exec_context
189
+
190
+ def _execute_tool(self, tool: BaseTool) -> ToolResult:
191
+ """
192
+ 执行工具的核心逻辑
193
+
194
+ Args:
195
+ tool: 工具实例
196
+
197
+ Returns:
198
+ ToolResult: 工具执行结果
199
+ """
200
+ # 获取工具解析器类
201
+ resolver_cls = self.tool_resolver_map.get(type(tool))
202
+ if not resolver_cls:
203
+ error_msg = f"No resolver implemented for tool {type(tool).__name__}"
204
+ logger.error(error_msg)
205
+ return ToolResult(
206
+ success=False,
207
+ message=error_msg,
208
+ content=None
209
+ )
210
+
211
+ # 创建并执行解析器
212
+ try:
213
+ logger.info(f"Creating resolver for tool: {type(tool).__name__}")
214
+ resolver = resolver_cls(
215
+ agent=self.agent,
216
+ tool=tool,
217
+ args=self.args
218
+ )
219
+
220
+ logger.info(f"Executing tool: {type(tool).__name__}")
221
+ tool_result = resolver.resolve()
222
+
223
+ logger.info(f"Tool Result: Success={tool_result.success}")
224
+ return tool_result
225
+
226
+ except Exception as e:
227
+ logger.exception(f"Error resolving tool {type(tool).__name__}: {e}")
228
+ raise
229
+
230
+ def register_plugin(self, plugin: 'ToolCallPlugin') -> bool:
231
+ """
232
+ 注册插件
233
+
234
+ Args:
235
+ plugin: 插件实例
236
+
237
+ Returns:
238
+ bool: 注册是否成功
239
+ """
240
+ return self.plugin_manager.register_plugin(plugin)
241
+
242
+ def unregister_plugin(self, plugin_name: str) -> bool:
243
+ """
244
+ 注销插件
245
+
246
+ Args:
247
+ plugin_name: 插件名称
248
+
249
+ Returns:
250
+ bool: 注销是否成功
251
+ """
252
+ return self.plugin_manager.unregister_plugin(plugin_name)
253
+
254
+ def enable_plugin(self, plugin_name: str) -> bool:
255
+ """
256
+ 启用插件
257
+
258
+ Args:
259
+ plugin_name: 插件名称
260
+
261
+ Returns:
262
+ bool: 是否成功
263
+ """
264
+ return self.plugin_manager.enable_plugin(plugin_name)
265
+
266
+ def disable_plugin(self, plugin_name: str) -> bool:
267
+ """
268
+ 禁用插件
269
+
270
+ Args:
271
+ plugin_name: 插件名称
272
+
273
+ Returns:
274
+ bool: 是否成功
275
+ """
276
+ return self.plugin_manager.disable_plugin(plugin_name)
277
+
278
+ def set_plugins_enabled(self, enabled: bool) -> None:
279
+ """
280
+ 设置插件系统启用状态
281
+
282
+ Args:
283
+ enabled: 是否启用
284
+ """
285
+ self.plugin_manager.set_global_enabled(enabled)
286
+
287
+ def get_stats(self) -> Dict[str, Any]:
288
+ """
289
+ 获取统计信息
290
+
291
+ Returns:
292
+ Dict[str, Any]: 统计信息
293
+ """
294
+ stats = self._stats.copy()
295
+ stats["plugin_status"] = self.plugin_manager.get_plugin_status()
296
+
297
+ # 计算成功率
298
+ if stats["total_calls"] > 0:
299
+ stats["success_rate"] = stats["successful_calls"] / stats["total_calls"]
300
+ stats["average_execution_time"] = stats["total_execution_time"] / stats["total_calls"]
301
+ else:
302
+ stats["success_rate"] = 0.0
303
+ stats["average_execution_time"] = 0.0
304
+
305
+ return stats
306
+
307
+ def reset_stats(self) -> None:
308
+ """重置统计信息"""
309
+ self._stats = {
310
+ "total_calls": 0,
311
+ "successful_calls": 0,
312
+ "failed_calls": 0,
313
+ "plugin_intercepted_calls": 0,
314
+ "total_execution_time": 0.0
315
+ }
316
+ logger.info("Tool caller statistics reset")
317
+
318
+ def load_plugins_from_directory(self, directory: str) -> int:
319
+ """
320
+ 从目录加载插件
321
+
322
+ Args:
323
+ directory: 插件目录路径
324
+
325
+ Returns:
326
+ int: 成功加载的插件数量
327
+ """
328
+ return self.plugin_manager.load_plugins_from_directory(directory)
329
+
330
+ def get_plugin_status(self) -> Dict[str, Any]:
331
+ """
332
+ 获取插件状态
333
+
334
+ Returns:
335
+ Dict[str, Any]: 插件状态信息
336
+ """
337
+ return self.plugin_manager.get_plugin_status()