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,172 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Tool Caller Integration Test
4
+
5
+ 验证 ToolCaller 与 AgenticEdit 的集成是否正常工作。
6
+ """
7
+
8
+ import sys
9
+ import os
10
+
11
+ # 添加项目根目录到 Python 路径
12
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../../../../..'))
13
+
14
+ from unittest.mock import Mock
15
+ from autocoder.common import AutoCoderArgs
16
+ from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool, ToolResult
17
+ from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
18
+ from autocoder.common.v2.agent.tool_caller import ToolCaller
19
+ from autocoder.common.v2.agent.tool_caller.plugins.examples import LoggingPlugin, SecurityFilterPlugin
20
+
21
+
22
+ class TestToolResolver(BaseToolResolver):
23
+ """测试用的工具解析器"""
24
+
25
+ def resolve(self) -> ToolResult:
26
+ if isinstance(self.tool, ExecuteCommandTool):
27
+ return ToolResult(
28
+ success=True,
29
+ message=f"Test: Command '{self.tool.command}' executed",
30
+ content={"output": f"Mock output for: {self.tool.command}"}
31
+ )
32
+ else:
33
+ return ToolResult(
34
+ success=False,
35
+ message=f"Test: Unsupported tool type {type(self.tool).__name__}"
36
+ )
37
+
38
+
39
+ def test_tool_caller_basic():
40
+ """测试 ToolCaller 基本功能"""
41
+ print("Testing ToolCaller basic functionality...")
42
+
43
+ # 创建工具解析器映射
44
+ tool_resolver_map = {
45
+ ExecuteCommandTool: TestToolResolver
46
+ }
47
+
48
+ # 创建 ToolCaller
49
+ args = AutoCoderArgs(source_dir=".")
50
+ tool_caller = ToolCaller(
51
+ tool_resolver_map=tool_resolver_map,
52
+ args=args,
53
+ enable_plugins=True
54
+ )
55
+
56
+ # 测试工具调用
57
+ tool = ExecuteCommandTool(command="echo 'test'", requires_approval=False)
58
+ result = tool_caller.call_tool(tool)
59
+
60
+ assert result.success, f"Tool call failed: {result.message}"
61
+ print("✓ Basic tool calling works")
62
+
63
+ return tool_caller
64
+
65
+
66
+ def test_plugin_system(tool_caller):
67
+ """测试插件系统"""
68
+ print("Testing plugin system...")
69
+
70
+ # 注册插件
71
+ logging_plugin = LoggingPlugin(enabled=True)
72
+ security_plugin = SecurityFilterPlugin(enabled=True)
73
+
74
+ assert tool_caller.register_plugin(logging_plugin), "Failed to register logging plugin"
75
+ assert tool_caller.register_plugin(security_plugin), "Failed to register security plugin"
76
+ print("✓ Plugin registration works")
77
+
78
+ # 检查插件状态
79
+ status = tool_caller.get_plugin_status()
80
+ assert status["total_plugins"] == 2, f"Expected 2 plugins, got {status['total_plugins']}"
81
+ assert status["enabled_plugins"] == 2, f"Expected 2 enabled plugins, got {status['enabled_plugins']}"
82
+ print("✓ Plugin status reporting works")
83
+
84
+ # 测试插件功能
85
+ safe_tool = ExecuteCommandTool(command="echo 'safe'", requires_approval=False)
86
+ result = tool_caller.call_tool(safe_tool)
87
+ assert result.success, "Safe tool call failed"
88
+ print("✓ Safe tool call with plugins works")
89
+
90
+ # 测试安全过滤
91
+ dangerous_tool = ExecuteCommandTool(command="rm -rf /", requires_approval=False)
92
+ result = tool_caller.call_tool(dangerous_tool)
93
+ assert result.success, "Dangerous tool should be blocked but return success"
94
+ print("✓ Security filtering works")
95
+
96
+ # 检查统计
97
+ log_stats = logging_plugin.get_statistics()
98
+ assert log_stats["total_logged_calls"] > 0, "No calls logged"
99
+ print("✓ Logging plugin statistics work")
100
+
101
+ filter_stats = security_plugin.get_filter_statistics()
102
+ assert filter_stats["blocked_count"] > 0, "No dangerous commands blocked"
103
+ print("✓ Security filter statistics work")
104
+
105
+
106
+ def test_integration_with_mock_agent():
107
+ """测试与模拟代理的集成"""
108
+ print("Testing integration with mock agent...")
109
+
110
+ # 创建模拟代理
111
+ mock_agent = Mock()
112
+
113
+ # 创建工具解析器映射
114
+ tool_resolver_map = {
115
+ ExecuteCommandTool: TestToolResolver
116
+ }
117
+
118
+ # 创建 ToolCaller
119
+ args = AutoCoderArgs(source_dir=".")
120
+ tool_caller = ToolCaller(
121
+ tool_resolver_map=tool_resolver_map,
122
+ agent=mock_agent,
123
+ args=args,
124
+ enable_plugins=True
125
+ )
126
+
127
+ # 测试工具调用
128
+ tool = ExecuteCommandTool(command="echo 'integration test'", requires_approval=False)
129
+ result = tool_caller.call_tool(tool)
130
+
131
+ assert result.success, f"Integration test failed: {result.message}"
132
+ print("✓ Integration with mock agent works")
133
+
134
+ # 测试统计信息
135
+ stats = tool_caller.get_stats()
136
+ assert stats["total_calls"] > 0, "No calls recorded"
137
+ assert stats["success_rate"] == 1.0, f"Expected 100% success rate, got {stats['success_rate']}"
138
+ print("✓ Statistics collection works")
139
+
140
+
141
+ def main():
142
+ """主测试函数"""
143
+ print("=" * 60)
144
+ print("Tool Caller Integration Test")
145
+ print("=" * 60)
146
+
147
+ try:
148
+ # 基本功能测试
149
+ tool_caller = test_tool_caller_basic()
150
+
151
+ # 插件系统测试
152
+ test_plugin_system(tool_caller)
153
+
154
+ # 集成测试
155
+ test_integration_with_mock_agent()
156
+
157
+ print("\n" + "=" * 60)
158
+ print("✓ All integration tests passed!")
159
+ print("=" * 60)
160
+
161
+ return True
162
+
163
+ except Exception as e:
164
+ print(f"\n✗ Integration test failed: {e}")
165
+ import traceback
166
+ traceback.print_exc()
167
+ return False
168
+
169
+
170
+ if __name__ == "__main__":
171
+ success = main()
172
+ sys.exit(0 if success else 1)
@@ -0,0 +1,14 @@
1
+ """
2
+ Tool Call Plugins
3
+
4
+ 工具调用插件系统,提供插件接口和基础实现。
5
+ """
6
+
7
+ from .plugin_interface import ToolCallPlugin, PluginPriority
8
+ from .base_plugin import BaseToolCallPlugin
9
+
10
+ __all__ = [
11
+ "ToolCallPlugin",
12
+ "BaseToolCallPlugin",
13
+ "PluginPriority"
14
+ ]
@@ -0,0 +1,126 @@
1
+ """
2
+ Base Tool Call Plugin
3
+
4
+ 提供工具调用插件的基础实现。
5
+ """
6
+
7
+ from typing import Any, Dict, Optional, TYPE_CHECKING
8
+ from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult
9
+ from .plugin_interface import ToolCallPlugin, PluginPriority
10
+ from loguru import logger
11
+
12
+ if TYPE_CHECKING:
13
+ from autocoder.common.v2.agent.agentic_edit import AgenticEdit
14
+
15
+
16
+ class BaseToolCallPlugin(ToolCallPlugin):
17
+ """
18
+ 工具调用插件基础实现类
19
+
20
+ 提供常见功能的默认实现,插件开发者可以继承此类。
21
+ """
22
+
23
+ def __init__(self, enabled: bool = True):
24
+ """
25
+ 初始化插件
26
+
27
+ Args:
28
+ enabled: 插件是否启用
29
+ """
30
+ self._enabled = enabled
31
+ self._config = {}
32
+
33
+ @property
34
+ def enabled(self) -> bool:
35
+ """插件是否启用"""
36
+ return self._enabled
37
+
38
+ def set_enabled(self, enabled: bool) -> None:
39
+ """设置插件启用状态"""
40
+ self._enabled = enabled
41
+
42
+ def set_config(self, config: Dict[str, Any]) -> None:
43
+ """设置插件配置"""
44
+ self._config = config
45
+
46
+ def get_config(self, key: str, default: Any = None) -> Any:
47
+ """获取配置项"""
48
+ return self._config.get(key, default)
49
+
50
+ def log_info(self, message: str) -> None:
51
+ """记录信息日志"""
52
+ logger.info(f"[{self.name}] {message}")
53
+
54
+ def log_warning(self, message: str) -> None:
55
+ """记录警告日志"""
56
+ logger.warning(f"[{self.name}] {message}")
57
+
58
+ def log_error(self, message: str) -> None:
59
+ """记录错误日志"""
60
+ logger.error(f"[{self.name}] {message}")
61
+
62
+ def create_context(self, **kwargs) -> Dict[str, Any]:
63
+ """创建上下文信息"""
64
+ context = {
65
+ "plugin_name": self.name,
66
+ "plugin_priority": self.priority.value,
67
+ "timestamp": __import__("time").time()
68
+ }
69
+ context.update(kwargs)
70
+ return context
71
+
72
+ def should_process_tool(self, tool: BaseTool, agent: Optional['AgenticEdit']) -> bool:
73
+ """
74
+ 判断是否应该处理这个工具
75
+
76
+ 默认实现:只有当插件启用时才处理
77
+ """
78
+ return self.enabled
79
+
80
+ def before_tool_execution(
81
+ self,
82
+ tool: BaseTool,
83
+ agent: Optional['AgenticEdit'],
84
+ context: Optional[Dict[str, Any]] = None
85
+ ) -> BaseTool:
86
+ """
87
+ 工具执行前的处理
88
+
89
+ 默认实现:记录日志并返回原始工具
90
+ """
91
+ if self.enabled:
92
+ self.log_info(f"Before execution of {type(tool).__name__}")
93
+ return tool
94
+
95
+ def after_tool_execution(
96
+ self,
97
+ tool: BaseTool,
98
+ tool_result: ToolResult,
99
+ agent: Optional['AgenticEdit'],
100
+ context: Optional[Dict[str, Any]] = None
101
+ ) -> ToolResult:
102
+ """
103
+ 工具执行后的处理
104
+
105
+ 默认实现:记录日志并返回原始结果
106
+ """
107
+ if self.enabled:
108
+ success_str = "successfully" if tool_result.success else "with error"
109
+ self.log_info(f"After execution of {type(tool).__name__} {success_str}")
110
+ return tool_result
111
+
112
+ def on_tool_error(
113
+ self,
114
+ tool: BaseTool,
115
+ error: Exception,
116
+ agent: Optional['AgenticEdit'],
117
+ context: Optional[Dict[str, Any]] = None
118
+ ) -> Optional[ToolResult]:
119
+ """
120
+ 工具执行出错时的处理
121
+
122
+ 默认实现:记录错误日志,不提供替代结果
123
+ """
124
+ if self.enabled:
125
+ self.log_error(f"Error in {type(tool).__name__}: {str(error)}")
126
+ return None
@@ -0,0 +1,13 @@
1
+ """
2
+ Tool Call Plugin Examples
3
+
4
+ 示例插件集合,展示如何开发和使用工具调用插件。
5
+ """
6
+
7
+ from .logging_plugin import LoggingPlugin
8
+ from .security_filter_plugin import SecurityFilterPlugin
9
+
10
+ __all__ = [
11
+ "LoggingPlugin",
12
+ "SecurityFilterPlugin"
13
+ ]
@@ -0,0 +1,164 @@
1
+ """
2
+ Logging Plugin Example
3
+
4
+ 记录工具调用日志的示例插件。
5
+ """
6
+
7
+ import json
8
+ from typing import Optional, Dict, Any, TYPE_CHECKING
9
+ from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult
10
+ from ..base_plugin import BaseToolCallPlugin
11
+ from ..plugin_interface import PluginPriority
12
+
13
+ if TYPE_CHECKING:
14
+ from autocoder.common.v2.agent.agentic_edit import AgenticEdit
15
+
16
+
17
+ class LoggingPlugin(BaseToolCallPlugin):
18
+ """
19
+ 日志记录插件
20
+
21
+ 记录所有工具调用的详细信息,包括参数、执行时间和结果。
22
+ """
23
+
24
+ def __init__(self, enabled: bool = True, detailed_logging: bool = False):
25
+ """
26
+ 初始化日志插件
27
+
28
+ Args:
29
+ enabled: 插件是否启用
30
+ detailed_logging: 是否记录详细日志(包括工具参数和结果内容)
31
+ """
32
+ super().__init__(enabled)
33
+ self.detailed_logging = detailed_logging
34
+ self.call_history = []
35
+
36
+ @property
37
+ def name(self) -> str:
38
+ return "logging"
39
+
40
+ @property
41
+ def priority(self) -> PluginPriority:
42
+ return PluginPriority.LOW # 记录日志通常优先级较低
43
+
44
+ @property
45
+ def description(self) -> str:
46
+ return "Records detailed logs of all tool calls and executions"
47
+
48
+ def before_tool_execution(
49
+ self,
50
+ tool: BaseTool,
51
+ agent: Optional['AgenticEdit'],
52
+ context: Optional[Dict[str, Any]] = None
53
+ ) -> BaseTool:
54
+ """记录工具执行前的信息"""
55
+ if not self.enabled:
56
+ return tool
57
+
58
+ call_info = {
59
+ "tool_name": type(tool).__name__,
60
+ "timestamp": context.get("timestamp") if context else None,
61
+ "call_id": context.get("call_id") if context else None,
62
+ "phase": "before_execution"
63
+ }
64
+
65
+ if self.detailed_logging:
66
+ call_info["tool_params"] = tool.model_dump() if hasattr(tool, 'model_dump') else str(tool)
67
+
68
+ self.call_history.append(call_info)
69
+ self.log_info(f"Starting execution of {type(tool).__name__}")
70
+
71
+ if self.detailed_logging:
72
+ self.log_info(f"Tool parameters: {json.dumps(call_info.get('tool_params', {}), indent=2)}")
73
+
74
+ return tool
75
+
76
+ def after_tool_execution(
77
+ self,
78
+ tool: BaseTool,
79
+ tool_result: ToolResult,
80
+ agent: Optional['AgenticEdit'],
81
+ context: Optional[Dict[str, Any]] = None
82
+ ) -> ToolResult:
83
+ """记录工具执行后的信息"""
84
+ if not self.enabled:
85
+ return tool_result
86
+
87
+ call_info = {
88
+ "tool_name": type(tool).__name__,
89
+ "timestamp": context.get("timestamp") if context else None,
90
+ "call_id": context.get("call_id") if context else None,
91
+ "phase": "after_execution",
92
+ "success": tool_result.success,
93
+ "message": tool_result.message
94
+ }
95
+
96
+ if self.detailed_logging and tool_result.content:
97
+ # 只记录前500个字符,避免日志过长
98
+ content_str = str(tool_result.content)
99
+ if len(content_str) > 500:
100
+ content_str = content_str[:500] + "..."
101
+ call_info["result_content"] = content_str
102
+
103
+ self.call_history.append(call_info)
104
+
105
+ status = "successfully" if tool_result.success else "with error"
106
+ self.log_info(f"Completed execution of {type(tool).__name__} {status}")
107
+
108
+ if not tool_result.success:
109
+ self.log_warning(f"Tool execution failed: {tool_result.message}")
110
+
111
+ if self.detailed_logging:
112
+ self.log_info(f"Result: {json.dumps(call_info, indent=2, default=str)}")
113
+
114
+ return tool_result
115
+
116
+ def on_tool_error(
117
+ self,
118
+ tool: BaseTool,
119
+ error: Exception,
120
+ agent: Optional['AgenticEdit'],
121
+ context: Optional[Dict[str, Any]] = None
122
+ ) -> Optional[ToolResult]:
123
+ """记录工具执行错误"""
124
+ if not self.enabled:
125
+ return None
126
+
127
+ call_info = {
128
+ "tool_name": type(tool).__name__,
129
+ "timestamp": context.get("timestamp") if context else None,
130
+ "call_id": context.get("call_id") if context else None,
131
+ "phase": "error",
132
+ "error_type": type(error).__name__,
133
+ "error_message": str(error)
134
+ }
135
+
136
+ self.call_history.append(call_info)
137
+ self.log_error(f"Tool {type(tool).__name__} failed with {type(error).__name__}: {str(error)}")
138
+
139
+ # 不提供恢复结果,只记录错误
140
+ return None
141
+
142
+ def get_call_history(self) -> list:
143
+ """获取调用历史"""
144
+ return self.call_history.copy()
145
+
146
+ def clear_history(self) -> None:
147
+ """清空调用历史"""
148
+ self.call_history.clear()
149
+ self.log_info("Call history cleared")
150
+
151
+ def get_statistics(self) -> Dict[str, Any]:
152
+ """获取统计信息"""
153
+ total_calls = len([call for call in self.call_history if call["phase"] == "after_execution"])
154
+ successful_calls = len([call for call in self.call_history
155
+ if call["phase"] == "after_execution" and call.get("success", False)])
156
+ error_calls = len([call for call in self.call_history if call["phase"] == "error"])
157
+
158
+ return {
159
+ "total_logged_calls": total_calls,
160
+ "successful_calls": successful_calls,
161
+ "error_calls": error_calls,
162
+ "success_rate": successful_calls / total_calls if total_calls > 0 else 0.0,
163
+ "detailed_logging": self.detailed_logging
164
+ }
@@ -0,0 +1,198 @@
1
+ """
2
+ Security Filter Plugin Example
3
+
4
+ 安全过滤插件,用于拦截和过滤敏感信息。
5
+ """
6
+
7
+ import re
8
+ from copy import deepcopy
9
+ from typing import Optional, Dict, Any, List, TYPE_CHECKING
10
+ from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult, ExecuteCommandTool
11
+ from ..base_plugin import BaseToolCallPlugin
12
+ from ..plugin_interface import PluginPriority
13
+
14
+ if TYPE_CHECKING:
15
+ from autocoder.common.v2.agent.agentic_edit import AgenticEdit
16
+
17
+
18
+ class SecurityFilterPlugin(BaseToolCallPlugin):
19
+ """
20
+ 安全过滤插件
21
+
22
+ 过滤敏感信息,如密码、API密钥等,防止在工具执行过程中泄露。
23
+ """
24
+
25
+ def __init__(self, enabled: bool = True):
26
+ """
27
+ 初始化安全过滤插件
28
+
29
+ Args:
30
+ enabled: 插件是否启用
31
+ """
32
+ super().__init__(enabled)
33
+
34
+ # 敏感信息正则模式
35
+ self.sensitive_patterns = [
36
+ (r'password\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'password=***'),
37
+ (r'passwd\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'passwd=***'),
38
+ (r'api_key\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'api_key=***'),
39
+ (r'secret\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'secret=***'),
40
+ (r'token\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'token=***'),
41
+ (r'--password\s+([^\s]+)', '--password ***'),
42
+ (r'-p\s+([^\s]+)', '-p ***'),
43
+ ]
44
+
45
+ # 危险命令模式
46
+ self.dangerous_commands = [
47
+ r'rm\s+-rf\s+/',
48
+ r'sudo\s+rm\s+-rf',
49
+ r'format\s+c:',
50
+ r'del\s+/q\s+/s\s+c:\\',
51
+ r'shutdown\s+(-s|-r|-h)',
52
+ r'halt',
53
+ r'reboot',
54
+ ]
55
+
56
+ self.filtered_count = 0
57
+ self.blocked_count = 0
58
+
59
+ @property
60
+ def name(self) -> str:
61
+ return "security_filter"
62
+
63
+ @property
64
+ def priority(self) -> PluginPriority:
65
+ return PluginPriority.HIGHEST # 安全过滤应该最先执行
66
+
67
+ @property
68
+ def description(self) -> str:
69
+ return "Filters sensitive information and blocks dangerous commands"
70
+
71
+ def should_process_tool(self, tool: BaseTool, agent: Optional['AgenticEdit']) -> bool:
72
+ """只处理执行命令工具和其他可能包含敏感信息的工具"""
73
+ return self.enabled and isinstance(tool, (ExecuteCommandTool,))
74
+
75
+ def before_tool_execution(
76
+ self,
77
+ tool: BaseTool,
78
+ agent: Optional['AgenticEdit'],
79
+ context: Optional[Dict[str, Any]] = None
80
+ ) -> BaseTool:
81
+ """在工具执行前过滤敏感信息"""
82
+ if not self.should_process_tool(tool, agent):
83
+ return tool
84
+
85
+ # 创建工具的副本以避免修改原始工具
86
+ filtered_tool = deepcopy(tool)
87
+
88
+ if isinstance(filtered_tool, ExecuteCommandTool):
89
+ original_command = filtered_tool.command
90
+
91
+ # 检查危险命令
92
+ if self._is_dangerous_command(original_command):
93
+ self.blocked_count += 1
94
+ self.log_warning(f"Blocked dangerous command: {original_command}")
95
+ # 创建一个安全的替代命令
96
+ filtered_tool.command = "echo 'BLOCKED: Potentially dangerous command detected'"
97
+ return filtered_tool
98
+
99
+ # 过滤敏感信息
100
+ filtered_command = self._filter_sensitive_info(original_command)
101
+ if filtered_command != original_command:
102
+ self.filtered_count += 1
103
+ self.log_info(f"Filtered sensitive information from command")
104
+ filtered_tool.command = filtered_command
105
+
106
+ return filtered_tool
107
+
108
+ def after_tool_execution(
109
+ self,
110
+ tool: BaseTool,
111
+ tool_result: ToolResult,
112
+ agent: Optional['AgenticEdit'],
113
+ context: Optional[Dict[str, Any]] = None
114
+ ) -> ToolResult:
115
+ """在工具执行后过滤结果中的敏感信息"""
116
+ if not self.should_process_tool(tool, agent):
117
+ return tool_result
118
+
119
+ # 创建结果的副本
120
+ filtered_result = ToolResult(
121
+ success=tool_result.success,
122
+ message=self._filter_sensitive_info(tool_result.message),
123
+ content=self._filter_result_content(tool_result.content)
124
+ )
125
+
126
+ return filtered_result
127
+
128
+ def _is_dangerous_command(self, command: str) -> bool:
129
+ """检查是否为危险命令"""
130
+ command_lower = command.lower().strip()
131
+
132
+ for pattern in self.dangerous_commands:
133
+ if re.search(pattern, command_lower, re.IGNORECASE):
134
+ return True
135
+
136
+ return False
137
+
138
+ def _filter_sensitive_info(self, text: str) -> str:
139
+ """过滤文本中的敏感信息"""
140
+ if not text:
141
+ return text
142
+
143
+ filtered_text = text
144
+
145
+ for pattern, replacement in self.sensitive_patterns:
146
+ filtered_text = re.sub(pattern, replacement, filtered_text, flags=re.IGNORECASE)
147
+
148
+ return filtered_text
149
+
150
+ def _filter_result_content(self, content: Any) -> Any:
151
+ """过滤结果内容中的敏感信息"""
152
+ if content is None:
153
+ return content
154
+
155
+ if isinstance(content, str):
156
+ return self._filter_sensitive_info(content)
157
+
158
+ elif isinstance(content, dict):
159
+ filtered_content = {}
160
+ for key, value in content.items():
161
+ if isinstance(value, str):
162
+ filtered_content[key] = self._filter_sensitive_info(value)
163
+ else:
164
+ filtered_content[key] = value
165
+ return filtered_content
166
+
167
+ elif isinstance(content, list):
168
+ return [
169
+ self._filter_sensitive_info(item) if isinstance(item, str) else item
170
+ for item in content
171
+ ]
172
+
173
+ return content
174
+
175
+ def add_sensitive_pattern(self, pattern: str, replacement: str) -> None:
176
+ """添加新的敏感信息模式"""
177
+ self.sensitive_patterns.append((pattern, replacement))
178
+ self.log_info(f"Added new sensitive pattern: {pattern}")
179
+
180
+ def add_dangerous_command(self, pattern: str) -> None:
181
+ """添加新的危险命令模式"""
182
+ self.dangerous_commands.append(pattern)
183
+ self.log_info(f"Added new dangerous command pattern: {pattern}")
184
+
185
+ def get_filter_statistics(self) -> Dict[str, Any]:
186
+ """获取过滤统计信息"""
187
+ return {
188
+ "filtered_count": self.filtered_count,
189
+ "blocked_count": self.blocked_count,
190
+ "sensitive_patterns_count": len(self.sensitive_patterns),
191
+ "dangerous_patterns_count": len(self.dangerous_commands)
192
+ }
193
+
194
+ def reset_statistics(self) -> None:
195
+ """重置统计信息"""
196
+ self.filtered_count = 0
197
+ self.blocked_count = 0
198
+ self.log_info("Filter statistics reset")