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
autocoder/common/text.py DELETED
@@ -1,30 +0,0 @@
1
- from difflib import SequenceMatcher
2
-
3
- class TextSimilarity:
4
- def __init__(self, text_a, text_b):
5
- self.text_a = text_a
6
- self.text_b = text_b
7
- self.lines_a = self._split_into_lines(text_a)
8
- self.lines_b = self._split_into_lines(text_b)
9
- self.m = len(self.lines_a)
10
- self.n = len(self.lines_b)
11
-
12
- def _split_into_lines(self, text):
13
- return text.splitlines()
14
-
15
- def _levenshtein_ratio(self, s1, s2):
16
- return SequenceMatcher(None, s1, s2).ratio()
17
-
18
- def get_best_matching_window(self):
19
- best_similarity = 0
20
- best_window = []
21
-
22
- for i in range(self.n - self.m + 1): # 滑动窗口
23
- window_b = self.lines_b[i:i + self.m]
24
- similarity = self._levenshtein_ratio("\n".join(self.lines_a), "\n".join(window_b))
25
-
26
- if similarity > best_similarity:
27
- best_similarity = similarity
28
- best_window = window_b
29
-
30
- return best_similarity, "\n".join(best_window)
@@ -1,42 +0,0 @@
1
-
2
- import os
3
- from typing import Optional
4
- from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
5
- from autocoder.common.v2.agent.agentic_edit_types import ListPackageInfoTool, ToolResult
6
- from loguru import logger
7
- import typing
8
-
9
- if typing.TYPE_CHECKING:
10
- from autocoder.common.v2.agent.agentic_edit import AgenticEdit
11
-
12
- class ListPackageInfoToolResolver(BaseToolResolver):
13
- def __init__(self, agent: Optional['AgenticEdit'], tool: ListPackageInfoTool, args):
14
- super().__init__(agent, tool, args)
15
- self.tool: ListPackageInfoTool = tool
16
-
17
- def resolve(self) -> ToolResult:
18
- source_dir = self.args.source_dir or "."
19
- abs_source_dir = os.path.abspath(source_dir)
20
-
21
- input_path = self.tool.path.strip()
22
- abs_input_path = os.path.abspath(os.path.join(source_dir, input_path)) if not os.path.isabs(input_path) else input_path
23
-
24
- # 校验输入目录是否在项目目录内
25
- if not abs_input_path.startswith(abs_source_dir):
26
- return ToolResult(success=False, message=f"Error: Access denied. Path outside project: {self.tool.path}")
27
-
28
- rel_package_path = os.path.relpath(abs_input_path, abs_source_dir)
29
- active_md_path = os.path.join(abs_source_dir, ".auto-coder", "active-context", rel_package_path, "active.md")
30
-
31
- logger.info(f"Looking for package info at: {active_md_path}")
32
-
33
- if not os.path.exists(active_md_path):
34
- return ToolResult(success=True, message="No package info found for this path.", content="没有相关包信息。")
35
-
36
- try:
37
- with open(active_md_path, 'r', encoding='utf-8', errors='replace') as f:
38
- content = f.read()
39
- return ToolResult(success=True, message="Successfully retrieved package info.", content=content)
40
- except Exception as e:
41
- logger.error(f"Error reading package info file: {e}")
42
- return ToolResult(success=False, message=f"Error reading package info file: {e}")
@@ -1,70 +0,0 @@
1
- import pytest
2
- from unittest.mock import MagicMock, patch
3
- from autocoder.common.v2.agent.agentic_edit_tools \
4
- .execute_command_tool_resolver import ExecuteCommandToolResolver
5
- from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool
6
- from autocoder.common import AutoCoderArgs
7
-
8
-
9
- class TestExecuteCommandToolResolver:
10
- @pytest.fixture
11
- def mock_agent(self):
12
- agent = MagicMock()
13
- agent.args = AutoCoderArgs()
14
- agent.args.context_prune_safe_zone_tokens = 1000
15
- agent.context_prune_llm = None
16
- agent.current_conversations = []
17
- return agent
18
-
19
- @pytest.fixture
20
- def mock_tool(self):
21
- return ExecuteCommandTool(
22
- command="echo 'test output'",
23
- requires_approval=False
24
- )
25
-
26
-
27
- def test_command_execution_with_token_count(self, mock_agent, mock_tool):
28
- """测试命令执行并验证token统计功能"""
29
- resolver = ExecuteCommandToolResolver(mock_agent, mock_tool, mock_agent.args)
30
-
31
- # 模拟命令执行返回大量输出
32
- with patch("autocoder.common.run_cmd.run_cmd_subprocess") as mock_run_cmd:
33
- mock_run_cmd.return_value = (0, "test output " * 500) # 生成大量输出
34
-
35
- result = resolver.resolve()
36
-
37
- assert result.success
38
- assert "test output" in result.content
39
-
40
- # 验证token统计功能
41
- # 这里需要修改ExecuteCommandToolResolver来添加token统计功能
42
- # 测试将失败,符合TDD的红色阶段
43
-
44
- def test_output_pruning_when_exceeds_token_limit(self, mock_agent, mock_tool):
45
- """测试当输出超过token限制时的裁剪功能"""
46
- resolver = ExecuteCommandToolResolver(mock_agent, mock_tool, mock_agent.args)
47
-
48
- # 模拟命令执行返回大量输出
49
- with patch("autocoder.common.run_cmd.run_cmd_subprocess") as mock_run_cmd:
50
- mock_run_cmd.return_value = (0, "test output " * 500) # 生成大量输出
51
-
52
- result = resolver.resolve()
53
-
54
- assert result.success
55
- # 验证输出是否被裁剪
56
- # 这里需要修改ExecuteCommandToolResolver来添加裁剪功能
57
- # 测试将失败,符合TDD的红色阶段
58
-
59
- def test_command_execution_failure(self, mock_agent, mock_tool):
60
- """测试命令执行失败的情况"""
61
- resolver = ExecuteCommandToolResolver(mock_agent, mock_tool, mock_agent.args)
62
-
63
- # 模拟命令执行失败
64
- with patch("autocoder.common.run_cmd.run_cmd_subprocess") as mock_run_cmd:
65
- mock_run_cmd.return_value = (1, "command failed")
66
-
67
- result = resolver.resolve()
68
-
69
- assert not result.success
70
- assert "command failed" in result.message
@@ -1,163 +0,0 @@
1
- import pytest
2
- import os
3
- import tempfile
4
- import shutil
5
- from unittest.mock import patch, MagicMock
6
-
7
- from autocoder.common.v2.agent.agentic_edit_tools.search_files_tool_resolver import SearchFilesToolResolver
8
- from autocoder.common.v2.agent.agentic_edit_types import SearchFilesTool, ToolResult
9
- from autocoder.common import AutoCoderArgs
10
-
11
- # Helper function to create a directory structure with files for testing
12
- def create_test_files(base_dir, structure):
13
- """
14
- Creates a directory structure with files based on the provided dictionary.
15
- Keys are filenames (relative to base_dir), values are file contents.
16
- Directories are created automatically.
17
- """
18
- for path, content in structure.items():
19
- full_path = os.path.join(base_dir, path)
20
- os.makedirs(os.path.dirname(full_path), exist_ok=True)
21
- with open(full_path, 'w') as f:
22
- f.write(content)
23
-
24
- @pytest.fixture
25
- def search_tool_resolver(temp_search_dir):
26
- """Fixture to provide an instance of SearchFilesToolResolver."""
27
- # Create AutoCoderArgs with the temp directory as source_dir to allow the security check to pass
28
- args = AutoCoderArgs()
29
- args.source_dir = temp_search_dir # Set the source_dir to our temp directory
30
- return SearchFilesToolResolver(None, SearchFilesTool(path="", regex=""), args)
31
-
32
- @pytest.fixture(scope="function")
33
- def temp_search_dir():
34
- """Fixture to create a temporary directory with test files for searching."""
35
- temp_dir = tempfile.mkdtemp()
36
- test_structure = {
37
- "file1.txt": "Hello world\nThis is a test file.",
38
- "subdir/file2.py": "import sys\n\ndef main():\n print('Python script')\n",
39
- "subdir/another.txt": "Another text file with world.",
40
- ".hiddenfile": "This should be ignored by default",
41
- "no_match.md": "Markdown file."
42
- }
43
- create_test_files(temp_dir, test_structure)
44
- yield temp_dir # Provide the path to the test function
45
- shutil.rmtree(temp_dir) # Cleanup after test
46
-
47
- # --- Test Cases ---
48
-
49
- def test_resolve_finds_matches(search_tool_resolver, temp_search_dir):
50
- """Test that resolve finds matches correctly."""
51
- # Set up the tool with the pattern we want to search for
52
- tool = SearchFilesTool(
53
- path="", # Use empty path to search in the source_dir itself
54
- regex="world",
55
- file_pattern="*.txt"
56
- )
57
- search_tool_resolver.tool = tool
58
-
59
- # Call the resolve method directly
60
- response = search_tool_resolver.resolve()
61
-
62
- # Check the response
63
- assert isinstance(response, ToolResult)
64
- assert response.success
65
- assert "Search completed. Found 2 matches" in response.message
66
-
67
- # Check that the correct files were found
68
- assert len(response.content) == 2
69
- paths = [result["path"] for result in response.content]
70
- assert any("file1.txt" in path for path in paths)
71
- assert any("another.txt" in path for path in paths)
72
-
73
- # Check that the match lines contain our search pattern
74
- for result in response.content:
75
- assert "world" in result["match_line"]
76
-
77
- def test_resolve_no_matches(search_tool_resolver, temp_search_dir):
78
- """Test that resolve handles no matches correctly."""
79
- tool = SearchFilesTool(
80
- path="", # Use empty path to search in the source_dir itself
81
- regex="nonexistent_pattern",
82
- file_pattern="*"
83
- )
84
- search_tool_resolver.tool = tool
85
-
86
- response = search_tool_resolver.resolve()
87
-
88
- assert isinstance(response, ToolResult)
89
- assert response.success # Still success, just no results
90
- assert "Search completed. Found 0 matches" in response.message
91
- assert len(response.content) == 0
92
-
93
- def test_resolve_file_pattern(search_tool_resolver, temp_search_dir):
94
- """Test that the file_pattern is correctly applied."""
95
- # Test .txt pattern
96
- tool_txt = SearchFilesTool(
97
- path="", # Use empty path to search in the source_dir itself
98
- regex="world",
99
- file_pattern="*.txt" # Only search .txt files
100
- )
101
- search_tool_resolver.tool = tool_txt
102
-
103
- response_txt = search_tool_resolver.resolve()
104
-
105
- assert isinstance(response_txt, ToolResult)
106
- assert response_txt.success
107
- assert "Search completed. Found 2 matches" in response_txt.message
108
- # Ensure only .txt files were matched
109
- for result in response_txt.content:
110
- assert result["path"].endswith(".txt")
111
-
112
- # Test .py pattern
113
- tool_py = SearchFilesTool(
114
- path="", # Use empty path to search in the source_dir itself
115
- regex="print",
116
- file_pattern="*.py" # Only search .py files
117
- )
118
- search_tool_resolver.tool = tool_py
119
-
120
- response_py = search_tool_resolver.resolve()
121
-
122
- assert isinstance(response_py, ToolResult)
123
- assert response_py.success
124
- assert "Search completed. Found 1 matches" in response_py.message
125
- # Ensure only .py files were matched
126
- for result in response_py.content:
127
- assert result["path"].endswith(".py")
128
-
129
- def test_invalid_regex(search_tool_resolver, temp_search_dir):
130
- """Test that an invalid regex pattern is properly handled."""
131
- tool = SearchFilesTool(
132
- path="", # Use empty path to search in the source_dir itself
133
- regex="[invalid regex", # Invalid regex pattern
134
- file_pattern="*"
135
- )
136
- search_tool_resolver.tool = tool
137
-
138
- response = search_tool_resolver.resolve()
139
-
140
- assert isinstance(response, ToolResult)
141
- assert not response.success
142
- assert "Invalid regex pattern" in response.message
143
-
144
- def test_nonexistent_path(search_tool_resolver, temp_search_dir):
145
- """Test that a nonexistent path is properly handled."""
146
- # Create a path that we know doesn't exist under temp_search_dir
147
- nonexistent_path = "nonexistent_subdirectory"
148
-
149
- tool = SearchFilesTool(
150
- path=nonexistent_path, # This path doesn't exist in our temp directory
151
- regex="pattern",
152
- file_pattern="*"
153
- )
154
- search_tool_resolver.tool = tool
155
-
156
- response = search_tool_resolver.resolve()
157
-
158
- assert isinstance(response, ToolResult)
159
- assert not response.success
160
- assert "Error: Search path not found" in response.message
161
-
162
- # Add more tests as needed
163
-
@@ -1,183 +0,0 @@
1
- import json
2
- from typing import Dict, Callable, Type
3
- from autocoder.common.auto_coder_lang import get_system_language, format_str_jinja2
4
- from autocoder.common.v2.agent.agentic_edit_types import (
5
- BaseTool,
6
- ReadFileTool, WriteToFileTool, ReplaceInFileTool, ExecuteCommandTool,
7
- ListFilesTool, SearchFilesTool, ListCodeDefinitionNamesTool,
8
- AskFollowupQuestionTool, UseMcpTool, AttemptCompletionTool
9
- )
10
-
11
- # Define message templates for each tool in English and Chinese
12
- TOOL_DISPLAY_MESSAGES: Dict[Type[BaseTool], Dict[str, str]] = {
13
- ReadFileTool: {
14
- "en": "AutoCoder wants to read this file:\n[bold cyan]{{ path }}[/]",
15
- "zh": "AutoCoder 想要读取此文件:\n[bold cyan]{{ path }}[/]"
16
- },
17
- WriteToFileTool: {
18
- "en": (
19
- "AutoCoder wants to write to this file:\n[bold cyan]{{ path }}[/]\n\n"
20
- "[dim]Content Snippet:[/dim]\n{{ content_snippet }}{{ ellipsis }}"
21
- ),
22
- "zh": (
23
- "AutoCoder 想要写入此文件:\n[bold cyan]{{ path }}[/]\n\n"
24
- "[dim]内容片段:[/dim]\n{{ content_snippet }}{{ ellipsis }}"
25
- )
26
- },
27
- ReplaceInFileTool: {
28
- "en": (
29
- "AutoCoder wants to replace content in this file:\n[bold cyan]{{ path }}[/]\n\n"
30
- "[dim]Diff Snippet:[/dim]\n{{ diff_snippet }}{{ ellipsis }}"
31
- ),
32
- "zh": (
33
- "AutoCoder 想要替换此文件中的内容:\n[bold cyan]{{ path }}[/]\n\n"
34
- "[dim]差异片段:[/dim]\n{{ diff_snippet }}{{ ellipsis }}"
35
- )
36
- },
37
- ExecuteCommandTool: {
38
- "en": (
39
- "AutoCoder wants to execute this command:\n[bold yellow]{{ command }}[/]\n"
40
- "[dim](Requires Approval: {{ requires_approval }})[/]"
41
- ),
42
- "zh": (
43
- "AutoCoder 想要执行此命令:\n[bold yellow]{{ command }}[/]\n"
44
- "[dim](需要批准:{{ requires_approval }})[/]"
45
- )
46
- },
47
- ListFilesTool: {
48
- "en": (
49
- "AutoCoder wants to list files in:\n[bold green]{{ path }}[/] "
50
- "{{ recursive_text }}"
51
- ),
52
- "zh": (
53
- "AutoCoder 想要列出此目录中的文件:\n[bold green]{{ path }}[/] "
54
- "{{ recursive_text }}"
55
- )
56
- },
57
- SearchFilesTool: {
58
- "en": (
59
- "AutoCoder wants to search files in:\n[bold green]{{ path }}[/]\n"
60
- "[dim]File Pattern:[/dim] [yellow]{{ file_pattern }}[/]\n"
61
- "[dim]Regex:[/dim] [yellow]{{ regex }}[/]"
62
- ),
63
- "zh": (
64
- "AutoCoder 想要在此目录中搜索文件:\n[bold green]{{ path }}[/]\n"
65
- "[dim]文件模式:[/dim] [yellow]{{ file_pattern }}[/]\n"
66
- "[dim]正则表达式:[/dim] [yellow]{{ regex }}[/]"
67
- )
68
- },
69
- ListCodeDefinitionNamesTool: {
70
- "en": "AutoCoder wants to list definitions in:\n[bold green]{{ path }}[/]",
71
- "zh": "AutoCoder 想要列出此路径中的定义:\n[bold green]{{ path }}[/]"
72
- },
73
- AskFollowupQuestionTool: {
74
- "en": (
75
- "AutoCoder is asking a question:\n[bold magenta]{{ question }}[/]\n"
76
- "{{ options_text }}"
77
- ),
78
- "zh": (
79
- "AutoCoder 正在提问:\n[bold magenta]{{ question }}[/]\n"
80
- "{{ options_text }}"
81
- )
82
- },
83
- UseMcpTool: {
84
- "en": (
85
- "AutoCoder wants to use an MCP tool:\n"
86
- "[dim]Server:[/dim] [blue]{{ server_name }}[/]\n"
87
- "[dim]Tool:[/dim] [blue]{{ tool_name }}[/]\n"
88
- "[dim]Args:[/dim] {{ arguments_snippet }}{{ ellipsis }}"
89
- ),
90
- "zh": (
91
- "AutoCoder 想要使用 MCP 工具:\n"
92
- "[dim]服务器:[/dim] [blue]{{ server_name }}[/]\n"
93
- "[dim]工具:[/dim] [blue]{{ tool_name }}[/]\n"
94
- "[dim]参数:[/dim] {{ arguments_snippet }}{{ ellipsis }}"
95
- )
96
- }
97
- }
98
-
99
- def get_tool_display_message(tool: BaseTool) -> str:
100
- """
101
- Generates a user-friendly, internationalized string representation for a tool call.
102
-
103
- Args:
104
- tool: The tool instance (Pydantic model).
105
-
106
- Returns:
107
- A formatted string for display in the terminal.
108
- """
109
- lang = get_system_language()
110
- tool_type = type(tool)
111
-
112
- if tool_type not in TOOL_DISPLAY_MESSAGES:
113
- # Fallback for unknown tools
114
- return f"Unknown tool type: {tool_type.__name__}\nData: {tool.model_dump_json(indent=2)}"
115
-
116
- templates = TOOL_DISPLAY_MESSAGES[tool_type]
117
- template = templates.get(lang, templates.get("en", "Tool display template not found")) # Fallback to English
118
-
119
- # Prepare context specific to each tool type
120
- context = {}
121
- if isinstance(tool, ReadFileTool):
122
- context = {"path": tool.path}
123
- elif isinstance(tool, WriteToFileTool):
124
- snippet = tool.content[:150]
125
- context = {
126
- "path": tool.path,
127
- "content_snippet": snippet,
128
- "ellipsis": '...' if len(tool.content) > 150 else ''
129
- }
130
- elif isinstance(tool, ReplaceInFileTool):
131
- snippet = tool.diff
132
- context = {
133
- "path": tool.path,
134
- "diff_snippet": snippet,
135
- "ellipsis": ''
136
- }
137
- elif isinstance(tool, ExecuteCommandTool):
138
- context = {"command": tool.command, "requires_approval": tool.requires_approval}
139
- elif isinstance(tool, ListFilesTool):
140
- rec_text_en = '(Recursively)' if tool.recursive else '(Top Level)'
141
- rec_text_zh = '(递归)' if tool.recursive else '(顶层)'
142
- context = {
143
- "path": tool.path,
144
- "recursive_text": rec_text_zh if lang == 'zh' else rec_text_en
145
- }
146
- elif isinstance(tool, SearchFilesTool):
147
- context = {
148
- "path": tool.path,
149
- "file_pattern": tool.file_pattern or '*',
150
- "regex": tool.regex
151
- }
152
- elif isinstance(tool, ListCodeDefinitionNamesTool):
153
- context = {"path": tool.path}
154
- elif isinstance(tool, AskFollowupQuestionTool):
155
- options_text_en = ""
156
- options_text_zh = ""
157
- if tool.options:
158
- options_list_en = "\n".join([f"- {opt}" for opt in tool.options])
159
- options_list_zh = "\n".join([f"- {opt}" for opt in tool.options]) # Assuming options are simple enough not to need translation
160
- options_text_en = f"[dim]Options:[/dim]\n{options_list_en}"
161
- options_text_zh = f"[dim]选项:[/dim]\n{options_list_zh}"
162
- context = {
163
- "question": tool.question,
164
- "options_text": options_text_zh if lang == 'zh' else options_text_en
165
- }
166
- elif isinstance(tool, UseMcpTool):
167
- args_str = tool.query
168
- snippet = args_str[:100]
169
- context = {
170
- "server_name": tool.server_name,
171
- "tool_name": tool.tool_name,
172
- "arguments_snippet": snippet,
173
- "ellipsis": '...' if len(args_str) > 100 else ''
174
- }
175
- else:
176
- # Generic context for tools not specifically handled above
177
- context = tool.model_dump()
178
-
179
- try:
180
- return format_str_jinja2(template, **context)
181
- except Exception as e:
182
- # Fallback in case of formatting errors
183
- return f"Error formatting display for {tool_type.__name__}: {e}\nTemplate: {template}\nContext: {context}"
@@ -1,148 +0,0 @@
1
- """
2
- Dynamic Completion Example Plugin for Chat Auto Coder.
3
- """
4
-
5
- from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
6
- from autocoder.plugins import Plugin, PluginManager
7
-
8
-
9
- class DynamicCompletionExamplePlugin(Plugin):
10
- """A sample plugin demonstrating dynamic completion functionality."""
11
-
12
- name = "dynamic_completion_example"
13
- description = "Demonstrates the dynamic completion feature"
14
- version = "0.1.0"
15
-
16
- def __init__(self, manager: PluginManager, config: Optional[Dict[str, Any]] = None, config_path: Optional[str] = None):
17
- """Initialize the plugin.
18
-
19
- Args:
20
- manager: The plugin manager instance
21
- config: Optional configuration dictionary for the plugin
22
- config_path: Optional path to the configuration file
23
- """
24
- super().__init__(manager, config, config_path)
25
- self.items = ["item1", "item2", "item3", "custom_item"]
26
-
27
- def initialize(self) -> bool:
28
- """Initialize the plugin.
29
-
30
- Returns:
31
- True if initialization was successful, False otherwise
32
- """
33
- # Register for function interception if needed
34
- # self.manager.register_function_interception(self.name, "ask")
35
-
36
- # Register as a dynamic completion provider
37
- self.manager.register_dynamic_completion_provider(self.name, ["/example"])
38
-
39
- return True
40
-
41
- def get_commands(self) -> Dict[str, Tuple[Callable, str]]:
42
- """Get commands provided by this plugin.
43
-
44
- Returns:
45
- A dictionary of command name to handler and description
46
- """
47
- return {
48
- "example": (
49
- self.example_command,
50
- "Example command with dynamic completion",
51
- ),
52
- "example/add": (self.add_item, "Add a new item to the example list"),
53
- "example/list": (self.list_items, "List all available items"),
54
- }
55
-
56
- def get_completions(self) -> Dict[str, List[str]]:
57
- """Get completions provided by this plugin.
58
-
59
- Returns:
60
- A dictionary mapping command prefixes to completion options
61
- """
62
- # 基本的静态补全选项
63
- return {
64
- "/example": ["add", "list", "select"],
65
- }
66
-
67
- def get_dynamic_completions(
68
- self, command: str, current_input: str
69
- ) -> List[Tuple[str, str]]:
70
- """Get dynamic completions based on the current command context.
71
-
72
- Args:
73
- command: The base command (e.g., "/example select")
74
- current_input: The full current input including the command
75
-
76
- Returns:
77
- A list of tuples containing (completion_text, display_text)
78
- """
79
- # 如果是 /example select 命令,提供动态项目列表
80
- if current_input.startswith("/example select"):
81
- # 提取已输入的部分项目名
82
- parts = current_input.split(maxsplit=2)
83
- item_prefix = ""
84
- if len(parts) > 2:
85
- item_prefix = parts[2]
86
-
87
- # 返回匹配的项目
88
- return [
89
- (item, f"{item} (example item)")
90
- for item in self.items
91
- if item.startswith(item_prefix)
92
- ]
93
-
94
- return []
95
-
96
- def example_command(self, args: str) -> None:
97
- """Handle the example command.
98
-
99
- Args:
100
- args: Command arguments
101
- """
102
- if not args:
103
- print("Usage: /example [add|list|select]")
104
- return
105
-
106
- parts = args.split(maxsplit=1)
107
- subcommand = parts[0]
108
-
109
- if subcommand == "select" and len(parts) > 1:
110
- item = parts[1]
111
- if item in self.items:
112
- print(f"Selected item: {item}")
113
- else:
114
- print(
115
- f"Item '{item}' not found. Use /example list to see available items."
116
- )
117
- else:
118
- print(f"Unknown subcommand: {subcommand}. Use add, list, or select.")
119
-
120
- def add_item(self, args: str) -> None:
121
- """Add a new item to the list.
122
-
123
- Args:
124
- args: The item name to add
125
- """
126
- if not args:
127
- print("Please specify an item name to add.")
128
- return
129
-
130
- if args in self.items:
131
- print(f"Item '{args}' already exists.")
132
- else:
133
- self.items.append(args)
134
- print(f"Added item: {args}")
135
-
136
- def list_items(self, args: str) -> None:
137
- """List all available items.
138
-
139
- Args:
140
- args: Ignored
141
- """
142
- print("Available items:")
143
- for item in self.items:
144
- print(f" - {item}")
145
-
146
- def shutdown(self) -> None:
147
- """Shutdown the plugin."""
148
- pass