auto-coder 1.0.0__py3-none-any.whl → 2.0.1__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 (574) hide show
  1. auto_coder-2.0.1.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.1.dist-info/METADATA +558 -0
  3. auto_coder-2.0.1.dist-info/RECORD +795 -0
  4. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
  5. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.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 +24 -3
  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 +77 -73
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +962 -2345
  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 +988 -398
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +25 -8
  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 +409 -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/git_utils.py +44 -8
  119. autocoder/common/global_cancel.py +15 -6
  120. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  121. autocoder/common/international/__init__.py +31 -0
  122. autocoder/common/international/demo_international.py +92 -0
  123. autocoder/common/international/message_manager.py +157 -0
  124. autocoder/common/international/messages/__init__.py +56 -0
  125. autocoder/common/international/messages/async_command_messages.py +507 -0
  126. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  127. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  128. autocoder/common/international/messages/command_help_messages.py +986 -0
  129. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  130. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  131. autocoder/common/international/messages/queue_command_messages.py +751 -0
  132. autocoder/common/international/messages/rules_command_messages.py +77 -0
  133. autocoder/common/international/messages/sdk_messages.py +1707 -0
  134. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  135. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  136. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  137. autocoder/common/international/test_international.py +612 -0
  138. autocoder/common/linter_core/__init__.py +28 -0
  139. autocoder/common/linter_core/base_linter.py +61 -0
  140. autocoder/common/linter_core/config_loader.py +271 -0
  141. autocoder/common/linter_core/formatters/__init__.py +0 -0
  142. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  143. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  144. autocoder/common/linter_core/linter.py +166 -0
  145. autocoder/common/linter_core/linter_factory.py +216 -0
  146. autocoder/common/linter_core/linter_manager.py +333 -0
  147. autocoder/common/linter_core/linters/__init__.py +9 -0
  148. autocoder/common/linter_core/linters/java_linter.py +342 -0
  149. autocoder/common/linter_core/linters/python_linter.py +115 -0
  150. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  151. autocoder/common/linter_core/models/__init__.py +7 -0
  152. autocoder/common/linter_core/models/lint_result.py +91 -0
  153. autocoder/common/linter_core/models.py +33 -0
  154. autocoder/common/linter_core/tests/__init__.py +3 -0
  155. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  156. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  157. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  158. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  159. autocoder/common/linter_core/tests/test_integration.py +317 -0
  160. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  161. autocoder/common/linter_core/tests/test_linters.py +265 -0
  162. autocoder/common/linter_core/tests/test_models.py +81 -0
  163. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  164. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  165. autocoder/common/llm_friendly_package/__init__.py +31 -0
  166. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  167. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  168. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  169. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  170. autocoder/common/llm_friendly_package/models.py +40 -0
  171. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  172. autocoder/common/llms/__init__.py +15 -0
  173. autocoder/common/llms/demo_error_handling.py +85 -0
  174. autocoder/common/llms/factory.py +142 -0
  175. autocoder/common/llms/manager.py +264 -0
  176. autocoder/common/llms/pricing.py +121 -0
  177. autocoder/common/llms/registry.py +316 -0
  178. autocoder/common/llms/schema.py +77 -0
  179. autocoder/common/llms/simple_demo.py +45 -0
  180. autocoder/common/llms/test_quick_model.py +116 -0
  181. autocoder/common/llms/test_remove_functionality.py +182 -0
  182. autocoder/common/llms/tests/__init__.py +1 -0
  183. autocoder/common/llms/tests/test_manager.py +330 -0
  184. autocoder/common/llms/tests/test_registry.py +364 -0
  185. autocoder/common/mcp_tools/__init__.py +62 -0
  186. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  187. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  188. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  189. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  190. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  191. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  192. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  193. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  194. autocoder/common/model_speed_tester.py +32 -26
  195. autocoder/common/priority_directory_finder/__init__.py +142 -0
  196. autocoder/common/priority_directory_finder/examples.py +230 -0
  197. autocoder/common/priority_directory_finder/finder.py +283 -0
  198. autocoder/common/priority_directory_finder/models.py +236 -0
  199. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  200. autocoder/common/project_scanner/__init__.py +18 -0
  201. autocoder/common/project_scanner/compat.py +77 -0
  202. autocoder/common/project_scanner/scanner.py +436 -0
  203. autocoder/common/project_tracker/__init__.py +27 -0
  204. autocoder/common/project_tracker/api.py +228 -0
  205. autocoder/common/project_tracker/demo.py +272 -0
  206. autocoder/common/project_tracker/tracker.py +487 -0
  207. autocoder/common/project_tracker/types.py +53 -0
  208. autocoder/common/pruner/__init__.py +67 -0
  209. autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
  210. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  211. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  212. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  213. autocoder/common/pruner/conversation_normalizer.py +347 -0
  214. autocoder/common/pruner/conversation_pruner.py +26 -6
  215. autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
  216. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  217. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  218. autocoder/common/pruner/tool_content_detector.py +227 -0
  219. autocoder/common/pruner/tools/__init__.py +18 -0
  220. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  221. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  222. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  223. autocoder/common/pull_requests/__init__.py +9 -1
  224. autocoder/common/pull_requests/utils.py +122 -1
  225. autocoder/common/rag_manager/rag_manager.py +36 -40
  226. autocoder/common/rulefiles/__init__.py +53 -1
  227. autocoder/common/rulefiles/api.py +250 -0
  228. autocoder/common/rulefiles/core/__init__.py +14 -0
  229. autocoder/common/rulefiles/core/manager.py +241 -0
  230. autocoder/common/rulefiles/core/selector.py +805 -0
  231. autocoder/common/rulefiles/models/__init__.py +20 -0
  232. autocoder/common/rulefiles/models/index.py +16 -0
  233. autocoder/common/rulefiles/models/init_rule.py +18 -0
  234. autocoder/common/rulefiles/models/rule_file.py +18 -0
  235. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  236. autocoder/common/rulefiles/models/summary.py +16 -0
  237. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  238. autocoder/common/rulefiles/utils/__init__.py +34 -0
  239. autocoder/common/rulefiles/utils/monitor.py +86 -0
  240. autocoder/common/rulefiles/utils/parser.py +230 -0
  241. autocoder/common/save_formatted_log.py +67 -10
  242. autocoder/common/search_replace.py +8 -1
  243. autocoder/common/search_replace_patch/__init__.py +24 -0
  244. autocoder/common/search_replace_patch/base.py +115 -0
  245. autocoder/common/search_replace_patch/manager.py +248 -0
  246. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  247. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  248. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  249. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  250. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  251. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  252. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  253. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  254. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  255. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  256. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  257. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  258. autocoder/common/shell_commands/__init__.py +197 -0
  259. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  260. autocoder/common/shell_commands/command_executor.py +1127 -0
  261. autocoder/common/shell_commands/error_recovery.py +541 -0
  262. autocoder/common/shell_commands/exceptions.py +120 -0
  263. autocoder/common/shell_commands/interactive_executor.py +476 -0
  264. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  265. autocoder/common/shell_commands/interactive_process.py +744 -0
  266. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  267. autocoder/common/shell_commands/monitoring.py +529 -0
  268. autocoder/common/shell_commands/process_cleanup.py +386 -0
  269. autocoder/common/shell_commands/process_manager.py +606 -0
  270. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  271. autocoder/common/shell_commands/tests/__init__.py +6 -0
  272. autocoder/common/shell_commands/tests/conftest.py +118 -0
  273. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  274. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  275. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  276. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  277. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  278. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  279. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  280. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  281. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  282. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  283. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  284. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  285. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  286. autocoder/common/shell_commands/timeout_config.py +315 -0
  287. autocoder/common/shell_commands/timeout_manager.py +352 -0
  288. autocoder/common/terminal_paste/__init__.py +14 -0
  289. autocoder/common/terminal_paste/demo.py +145 -0
  290. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  291. autocoder/common/terminal_paste/paste_handler.py +200 -0
  292. autocoder/common/terminal_paste/paste_manager.py +118 -0
  293. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  294. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  295. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  296. autocoder/common/terminal_paste/utils.py +163 -0
  297. autocoder/common/test_autocoder_args.py +232 -0
  298. autocoder/common/test_env_manager.py +173 -0
  299. autocoder/common/test_env_manager_integration.py +159 -0
  300. autocoder/common/text_similarity/__init__.py +9 -0
  301. autocoder/common/text_similarity/demo.py +216 -0
  302. autocoder/common/text_similarity/examples.py +266 -0
  303. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  304. autocoder/common/text_similarity/text_similarity.py +194 -0
  305. autocoder/common/text_similarity/utils.py +125 -0
  306. autocoder/common/todos/__init__.py +61 -0
  307. autocoder/common/todos/cache/__init__.py +16 -0
  308. autocoder/common/todos/cache/base_cache.py +89 -0
  309. autocoder/common/todos/cache/cache_manager.py +228 -0
  310. autocoder/common/todos/cache/memory_cache.py +225 -0
  311. autocoder/common/todos/config.py +155 -0
  312. autocoder/common/todos/exceptions.py +35 -0
  313. autocoder/common/todos/get_todo_manager.py +161 -0
  314. autocoder/common/todos/manager.py +537 -0
  315. autocoder/common/todos/models.py +239 -0
  316. autocoder/common/todos/storage/__init__.py +14 -0
  317. autocoder/common/todos/storage/base_storage.py +76 -0
  318. autocoder/common/todos/storage/file_storage.py +278 -0
  319. autocoder/common/tokens/counter.py +24 -2
  320. autocoder/common/tools_manager/__init__.py +17 -0
  321. autocoder/common/tools_manager/examples.py +162 -0
  322. autocoder/common/tools_manager/manager.py +385 -0
  323. autocoder/common/tools_manager/models.py +39 -0
  324. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  325. autocoder/common/tools_manager/utils.py +191 -0
  326. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  327. autocoder/common/v2/agent/agentic_edit.py +2699 -1856
  328. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  329. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
  330. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  331. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
  332. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
  338. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  340. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  344. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +356 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
  346. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  347. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
  349. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  350. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  352. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
  353. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
  354. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
  355. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  356. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  359. autocoder/common/v2/agent/agentic_edit_types.py +343 -9
  360. autocoder/common/v2/agent/runner/__init__.py +3 -3
  361. autocoder/common/v2/agent/runner/base_runner.py +12 -26
  362. autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
  363. autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
  364. autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
  365. autocoder/common/v2/agent/runner/tool_display.py +557 -159
  366. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  367. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  368. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  369. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  370. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  371. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  372. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  373. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  374. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  375. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  376. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  377. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  378. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  379. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  380. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  381. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  382. autocoder/common/v2/code_auto_generate.py +136 -78
  383. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  384. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  385. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  386. autocoder/common/v2/code_auto_merge.py +1 -1
  387. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  388. autocoder/common/v2/code_diff_manager.py +3 -3
  389. autocoder/common/v2/code_editblock_manager.py +4 -14
  390. autocoder/common/v2/code_manager.py +1 -1
  391. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  392. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  393. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  394. autocoder/common/wrap_llm_hint/utils.py +432 -0
  395. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  396. autocoder/completer/__init__.py +8 -0
  397. autocoder/completer/command_completer_v2.py +1094 -0
  398. autocoder/default_project/__init__.py +501 -0
  399. autocoder/dispacher/__init__.py +4 -12
  400. autocoder/dispacher/actions/action.py +400 -129
  401. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  402. autocoder/index/entry.py +117 -125
  403. autocoder/{agent → index/filter}/agentic_filter.py +322 -333
  404. autocoder/index/filter/normal_filter.py +5 -11
  405. autocoder/index/filter/quick_filter.py +1 -1
  406. autocoder/index/index.py +36 -9
  407. autocoder/index/tests/__init__.py +1 -0
  408. autocoder/index/tests/run_tests.py +195 -0
  409. autocoder/index/tests/test_entry.py +303 -0
  410. autocoder/index/tests/test_index_manager.py +314 -0
  411. autocoder/index/tests/test_module_integration.py +300 -0
  412. autocoder/index/tests/test_symbols_utils.py +183 -0
  413. autocoder/inner/__init__.py +4 -0
  414. autocoder/inner/agentic.py +923 -0
  415. autocoder/inner/async_command_handler.py +992 -0
  416. autocoder/inner/conversation_command_handlers.py +623 -0
  417. autocoder/inner/merge_command_handler.py +213 -0
  418. autocoder/inner/queue_command_handler.py +684 -0
  419. autocoder/models.py +95 -266
  420. autocoder/plugins/git_helper_plugin.py +31 -29
  421. autocoder/plugins/token_helper_plugin.py +65 -46
  422. autocoder/pyproject/__init__.py +32 -29
  423. autocoder/rag/agentic_rag.py +215 -75
  424. autocoder/rag/cache/simple_cache.py +1 -2
  425. autocoder/rag/loaders/image_loader.py +1 -1
  426. autocoder/rag/long_context_rag.py +42 -26
  427. autocoder/rag/qa_conversation_strategy.py +1 -1
  428. autocoder/rag/terminal/__init__.py +17 -0
  429. autocoder/rag/terminal/args.py +581 -0
  430. autocoder/rag/terminal/bootstrap.py +61 -0
  431. autocoder/rag/terminal/command_handlers.py +653 -0
  432. autocoder/rag/terminal/formatters/__init__.py +20 -0
  433. autocoder/rag/terminal/formatters/base.py +70 -0
  434. autocoder/rag/terminal/formatters/json_format.py +66 -0
  435. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  436. autocoder/rag/terminal/formatters/text.py +28 -0
  437. autocoder/rag/terminal/init.py +120 -0
  438. autocoder/rag/terminal/utils.py +106 -0
  439. autocoder/rag/test_agentic_rag.py +389 -0
  440. autocoder/rag/test_doc_filter.py +3 -3
  441. autocoder/rag/test_long_context_rag.py +1 -1
  442. autocoder/rag/test_token_limiter.py +517 -10
  443. autocoder/rag/token_counter.py +3 -0
  444. autocoder/rag/token_limiter.py +19 -15
  445. autocoder/rag/tools/__init__.py +26 -2
  446. autocoder/rag/tools/bochaai_example.py +343 -0
  447. autocoder/rag/tools/bochaai_sdk.py +541 -0
  448. autocoder/rag/tools/metaso_example.py +268 -0
  449. autocoder/rag/tools/metaso_sdk.py +417 -0
  450. autocoder/rag/tools/recall_tool.py +28 -7
  451. autocoder/rag/tools/run_integration_tests.py +204 -0
  452. autocoder/rag/tools/test_all_providers.py +318 -0
  453. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  454. autocoder/rag/tools/test_final_integration.py +215 -0
  455. autocoder/rag/tools/test_metaso_integration.py +424 -0
  456. autocoder/rag/tools/test_metaso_real.py +171 -0
  457. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  458. autocoder/rag/tools/test_web_search_tool.py +509 -0
  459. autocoder/rag/tools/todo_read_tool.py +202 -0
  460. autocoder/rag/tools/todo_write_tool.py +412 -0
  461. autocoder/rag/tools/web_crawl_tool.py +634 -0
  462. autocoder/rag/tools/web_search_tool.py +558 -0
  463. autocoder/rag/tools/web_tools_example.py +119 -0
  464. autocoder/rag/types.py +16 -0
  465. autocoder/rag/variable_holder.py +4 -2
  466. autocoder/rags.py +86 -79
  467. autocoder/regexproject/__init__.py +23 -21
  468. autocoder/sdk/__init__.py +46 -190
  469. autocoder/sdk/api.py +370 -0
  470. autocoder/sdk/async_runner/__init__.py +26 -0
  471. autocoder/sdk/async_runner/async_executor.py +650 -0
  472. autocoder/sdk/async_runner/async_handler.py +356 -0
  473. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  474. autocoder/sdk/async_runner/task_metadata.py +284 -0
  475. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  476. autocoder/sdk/cli/__init__.py +2 -5
  477. autocoder/sdk/cli/formatters.py +28 -204
  478. autocoder/sdk/cli/handlers.py +77 -44
  479. autocoder/sdk/cli/main.py +154 -171
  480. autocoder/sdk/cli/options.py +95 -22
  481. autocoder/sdk/constants.py +139 -51
  482. autocoder/sdk/core/auto_coder_core.py +484 -109
  483. autocoder/sdk/core/bridge.py +297 -115
  484. autocoder/sdk/exceptions.py +18 -12
  485. autocoder/sdk/formatters/__init__.py +19 -0
  486. autocoder/sdk/formatters/input.py +64 -0
  487. autocoder/sdk/formatters/output.py +247 -0
  488. autocoder/sdk/formatters/stream.py +54 -0
  489. autocoder/sdk/models/__init__.py +6 -5
  490. autocoder/sdk/models/options.py +55 -18
  491. autocoder/sdk/utils/formatters.py +27 -195
  492. autocoder/suffixproject/__init__.py +28 -25
  493. autocoder/terminal/__init__.py +14 -0
  494. autocoder/terminal/app.py +454 -0
  495. autocoder/terminal/args.py +32 -0
  496. autocoder/terminal/bootstrap.py +178 -0
  497. autocoder/terminal/command_processor.py +521 -0
  498. autocoder/terminal/command_registry.py +57 -0
  499. autocoder/terminal/help.py +97 -0
  500. autocoder/terminal/tasks/__init__.py +5 -0
  501. autocoder/terminal/tasks/background.py +77 -0
  502. autocoder/terminal/tasks/task_event.py +70 -0
  503. autocoder/terminal/ui/__init__.py +13 -0
  504. autocoder/terminal/ui/completer.py +268 -0
  505. autocoder/terminal/ui/keybindings.py +75 -0
  506. autocoder/terminal/ui/session.py +41 -0
  507. autocoder/terminal/ui/toolbar.py +64 -0
  508. autocoder/terminal/utils/__init__.py +13 -0
  509. autocoder/terminal/utils/errors.py +18 -0
  510. autocoder/terminal/utils/paths.py +19 -0
  511. autocoder/terminal/utils/shell.py +43 -0
  512. autocoder/terminal_v3/__init__.py +10 -0
  513. autocoder/terminal_v3/app.py +201 -0
  514. autocoder/terminal_v3/handlers/__init__.py +5 -0
  515. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  516. autocoder/terminal_v3/models/__init__.py +6 -0
  517. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  518. autocoder/terminal_v3/models/message.py +50 -0
  519. autocoder/terminal_v3/models/tool_display.py +247 -0
  520. autocoder/terminal_v3/ui/__init__.py +7 -0
  521. autocoder/terminal_v3/ui/keybindings.py +56 -0
  522. autocoder/terminal_v3/ui/layout.py +141 -0
  523. autocoder/terminal_v3/ui/styles.py +43 -0
  524. autocoder/tsproject/__init__.py +23 -23
  525. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  526. autocoder/utils/llms.py +88 -80
  527. autocoder/utils/math_utils.py +101 -0
  528. autocoder/utils/model_provider_selector.py +16 -4
  529. autocoder/utils/operate_config_api.py +33 -5
  530. autocoder/utils/thread_utils.py +2 -2
  531. autocoder/version.py +4 -2
  532. autocoder/workflow_agents/__init__.py +84 -0
  533. autocoder/workflow_agents/agent.py +143 -0
  534. autocoder/workflow_agents/exceptions.py +573 -0
  535. autocoder/workflow_agents/executor.py +665 -0
  536. autocoder/workflow_agents/loader.py +749 -0
  537. autocoder/workflow_agents/runner.py +267 -0
  538. autocoder/workflow_agents/types.py +173 -0
  539. autocoder/workflow_agents/utils.py +434 -0
  540. autocoder/workflow_agents/workflow_manager.py +211 -0
  541. auto_coder-1.0.0.dist-info/METADATA +0 -396
  542. auto_coder-1.0.0.dist-info/RECORD +0 -442
  543. auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
  544. autocoder/auto_coder_server.py +0 -672
  545. autocoder/benchmark.py +0 -138
  546. autocoder/common/ac_style_command_parser/example.py +0 -7
  547. autocoder/common/cleaner.py +0 -31
  548. autocoder/common/command_completer_v2.py +0 -615
  549. autocoder/common/context_pruner.py +0 -477
  550. autocoder/common/conversation_pruner.py +0 -132
  551. autocoder/common/directory_cache/__init__.py +0 -1
  552. autocoder/common/directory_cache/cache.py +0 -192
  553. autocoder/common/directory_cache/test_cache.py +0 -190
  554. autocoder/common/file_checkpoint/examples.py +0 -217
  555. autocoder/common/llm_friendly_package_example.py +0 -138
  556. autocoder/common/llm_friendly_package_test.py +0 -63
  557. autocoder/common/pull_requests/test_module.py +0 -1
  558. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  559. autocoder/common/text.py +0 -30
  560. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  561. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  562. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  563. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  564. autocoder/plugins/dynamic_completion_example.py +0 -148
  565. autocoder/plugins/sample_plugin.py +0 -160
  566. autocoder/sdk/cli/__main__.py +0 -26
  567. autocoder/sdk/cli/completion_wrapper.py +0 -38
  568. autocoder/sdk/cli/install_completion.py +0 -301
  569. autocoder/sdk/models/messages.py +0 -209
  570. autocoder/sdk/session/__init__.py +0 -32
  571. autocoder/sdk/session/session.py +0 -106
  572. autocoder/sdk/session/session_manager.py +0 -56
  573. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/top_level.txt +0 -0
  574. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,923 @@
1
+ import os
2
+ import uuid
3
+ import yaml
4
+ import json
5
+ import byzerllm
6
+ from typing import List, Dict, Any, Optional, Tuple, Union, Generator
7
+ from rich.console import Console
8
+ from rich.panel import Panel
9
+ from rich.markdown import Markdown
10
+ from copy import deepcopy
11
+ from loguru import logger as global_logger
12
+ from byzerllm.utils.str2model import to_model
13
+ from autocoder.index.filter.agentic_filter import AgenticFilterResponse
14
+
15
+ from autocoder.common import AutoCoderArgs
16
+ from autocoder.common.autocoderargs_parser import AutoCoderArgsParser
17
+ from autocoder.common.v2.agent.agentic_edit import AgenticEditRequest
18
+ from autocoder.common.v2.agent.agentic_edit_types import (
19
+ AgenticEditConversationConfig,
20
+ ConversationAction,
21
+ )
22
+ from autocoder.common.conversations.get_conversation_manager import (
23
+ get_conversation_manager,
24
+ )
25
+ from autocoder.common.v2.agent.runner import (
26
+ TerminalRunner,
27
+ FileBasedEventRunner,
28
+ )
29
+ from autocoder.utils.llms import get_single_llm
30
+ from autocoder.common.ac_style_command_parser import parse_query
31
+ from autocoder.common.core_config import get_memory_manager
32
+ from autocoder.utils import get_last_yaml_file
33
+ from autocoder.auto_coder import main as auto_coder_main
34
+ from byzerllm.utils.nontext import Image
35
+ from autocoder.chat_auto_coder_lang import get_message as get_i18n_message
36
+
37
+ from autocoder.inner.async_command_handler import AsyncCommandHandler
38
+ from autocoder.inner.queue_command_handler import QueueCommandHandler
39
+ from autocoder.inner.merge_command_handler import MergeCommandHandler
40
+ from autocoder.inner.conversation_command_handlers import (
41
+ ConversationNewCommandHandler,
42
+ ConversationResumeCommandHandler,
43
+ ConversationListCommandHandler,
44
+ ConversationRenameCommandHandler,
45
+ ConversationCommandCommandHandler,
46
+ )
47
+
48
+
49
+ class RunAgentic:
50
+ """处理 /auto 指令的核心类"""
51
+
52
+ def __init__(self):
53
+ """初始化 RunAgentic 类"""
54
+ self._console = Console()
55
+ self._conversation_config = AgenticEditConversationConfig(
56
+ action=ConversationAction.CONTINUE
57
+ )
58
+
59
+ def run(
60
+ self,
61
+ query: str,
62
+ cancel_token: Optional[str] = None,
63
+ conversation_history: Optional[List[Dict[str, Any]]] = None,
64
+ ) -> Optional[str]:
65
+ """
66
+ 处理/auto指令
67
+
68
+ Args:
69
+ query: 用户查询
70
+ cancel_token: 取消令牌
71
+ conversation_history: 对话历史
72
+
73
+ Returns:
74
+ conversation_id: 对话ID
75
+ """
76
+ # 1. 检查是否是 /help 命令
77
+ if self._handle_help_command(query):
78
+ return None
79
+
80
+ # 2. 初始化上下文
81
+ args, llm = self._initialize_context(query)
82
+ if llm is None:
83
+ return None
84
+
85
+ # 3. 解析命令信息
86
+ command_infos = parse_query(query)
87
+
88
+ # 3. 处理命令链
89
+ should_terminate, conversation_config = self._process_command_chain(
90
+ query, args, command_infos, llm, cancel_token
91
+ )
92
+ if should_terminate:
93
+ # 如果命令已处理,返回相应的值
94
+ if conversation_config is None:
95
+ return None # async/queue/merge 命令已处理
96
+ else:
97
+ return conversation_config.conversation_id # conversation 命令已处理
98
+
99
+ # 4. 设置任务查询
100
+ task_query = conversation_config.query if conversation_config.query else query
101
+ if not conversation_config.query:
102
+ conversation_config.query = task_query
103
+
104
+ # 5. 确保对话ID存在
105
+ self._ensure_conversation_id(conversation_config)
106
+
107
+ # 6. 执行任务
108
+ self._execute_runner(llm, args, conversation_config, task_query, cancel_token)
109
+
110
+ # 7. 刷新文件列表
111
+ self._refresh_completer()
112
+
113
+ return conversation_config.conversation_id
114
+
115
+ @byzerllm.prompt()
116
+ def _filter_query_reminder(self) -> str:
117
+ """
118
+ ---
119
+ [[REMINDER: You are in context discovery mode. Analyze the request above to identify relevant files, but DO NOT implement the request. Focus on thorough file discovery and understanding the codebase context.
120
+
121
+ You must output a JSON string with the following format in attempt_completion tool:
122
+ ```json
123
+ {
124
+ "files": [
125
+ {"path": "/path/to/file1.py", "operation": "MODIFY"},
126
+ {"path": "/path/to/file2.md", "operation": "REFERENCE"},
127
+ {"path": "/path/to/new_file.txt", "operation": "ADD"},
128
+ {"path": "/path/to/old_file.log", "operation": "REMOVE"}
129
+ ],
130
+ "reasoning": "Detailed explanation of your analysis process: what you searched for, what patterns you found, how you identified these files as relevant, and why each file would be involved in the context of the user's request."
131
+ }
132
+ ```
133
+ Never stop unless you think you have found the enough files to satisfy the user's request.
134
+ ]]
135
+ """
136
+
137
+ @byzerllm.prompt()
138
+ def _filter_plan(self) -> str:
139
+ """
140
+ You are a context discovery assistant. Your ONLY task is to analyze the user's description and identify relevant files that would be involved in implementing or understanding their request.
141
+
142
+ IMPORTANT: You should NOT implement the user's request. Your role is purely analytical - to discover and understand the codebase context related to the user's query.
143
+
144
+ Even if the user says "modify XXX" or "implement YYY", you should:
145
+ 1. Understand what files would be involved in such changes
146
+ 2. Identify related components, dependencies, and configuration files
147
+ 3. Find existing similar implementations for reference
148
+ 4. Locate test files and documentation that would be relevant
149
+
150
+ Your analysis should be thorough but focused on FILE DISCOVERY, not task execution.
151
+
152
+ You must output a JSON string in the attempt_completion tool with this exact format:
153
+ ```json
154
+ {
155
+ "files": [
156
+ {"path": "/path/to/file1.py", "operation": "MODIFY"},
157
+ {"path": "/path/to/file2.md", "operation": "REFERENCE"},
158
+ {"path": "/path/to/new_file.txt", "operation": "ADD"},
159
+ {"path": "/path/to/old_file.log", "operation": "REMOVE"}
160
+ ],
161
+ "reasoning": "Detailed explanation of your analysis process: what you searched for, what patterns you found, how you identified these files as relevant, and why each file would be involved in the context of the user's request."
162
+ }
163
+ ```
164
+
165
+ Operation types:
166
+ - MODIFY: Files that would need changes
167
+ - REFERENCE: Files to understand for context (dependencies, similar implementations, interfaces)
168
+ - ADD: New files that would need to be created
169
+ - REMOVE: Files that might need to be deleted or replaced
170
+ """
171
+
172
+ def filter(
173
+ self, query: str, cancel_token: Optional[str] = None
174
+ ) -> Optional[AgenticFilterResponse]:
175
+ """
176
+ 处理/auto指令的过滤模式(用于发现相关文件)
177
+
178
+ Args:
179
+ query: 用户查询
180
+ cancel_token: 取消令牌
181
+
182
+ Returns:
183
+ AgenticFilterResponse: 过滤结果
184
+ """
185
+ # 1. 初始化配置和LLM
186
+ args = self._get_final_config()
187
+ execute_file, _ = self._generate_new_yaml(query)
188
+ args.file = execute_file
189
+
190
+ llm = self._get_llm(args)
191
+ if llm is None:
192
+ return
193
+
194
+ # 2. 创建对话配置
195
+ conversation_config = self._ensure_conversation_id(self._conversation_config)
196
+ conversation_config.query = query
197
+
198
+ # 3. 处理特殊对话操作
199
+ if self._handle_conversation_actions(conversation_config):
200
+ return conversation_config.conversation_id
201
+
202
+ # 5. 配置过滤模式参数
203
+ args_copy = deepcopy(args)
204
+ args_copy.agentic_mode = "plan"
205
+ args_copy.code_model = args.index_filter_model or args.model
206
+
207
+ # 6. 执行文件发现
208
+ runner = TerminalRunner(
209
+ llm=llm,
210
+ args=args_copy,
211
+ conversation_config=conversation_config,
212
+ cancel_token=cancel_token,
213
+ system_prompt=self._filter_plan.prompt(),
214
+ )
215
+
216
+ # 执行并重试逻辑(最多重试3次)
217
+ max_retries = args_copy.agentic_filter_retries
218
+ last_exception = None
219
+
220
+ for attempt in range(max_retries):
221
+ try:
222
+ if attempt == 0:
223
+ # 第一次执行
224
+ result = runner.run(
225
+ AgenticEditRequest(
226
+ user_input=query
227
+ + "\n"
228
+ + self._filter_query_reminder.prompt(),
229
+ )
230
+ )
231
+ else:
232
+ # 重试执行,将异常信息传递给模型
233
+ exception_message = f"<异常>\n{str(last_exception)}\n\n根据异常修正错误,重新使用 attempt_completion 进行输出"
234
+ global_logger.warning(
235
+ f"Filter method retry attempt {attempt + 1}/{max_retries}, error: {last_exception}"
236
+ )
237
+ result = runner.run(
238
+ AgenticEditRequest(
239
+ user_input=exception_message,
240
+ )
241
+ )
242
+
243
+ # 尝试转换为模型
244
+ return to_model(result, AgenticFilterResponse)
245
+
246
+ except Exception as e:
247
+ last_exception = e
248
+ global_logger.error(
249
+ f"Filter method failed on attempt {attempt + 1}/{max_retries}: {e}"
250
+ )
251
+
252
+ # 如果是最后一次尝试,抛出异常
253
+ if attempt == max_retries - 1:
254
+ global_logger.error(
255
+ f"Filter method failed after {max_retries} attempts"
256
+ )
257
+ raise
258
+
259
+ # 理论上不会到达这里,但为了类型安全
260
+ raise RuntimeError("Filter method failed unexpectedly")
261
+
262
+ def run_with_events(
263
+ self,
264
+ query: str,
265
+ pre_commit: bool = False,
266
+ post_commit: bool = False,
267
+ pr: bool = False,
268
+ extra_args: Dict[str, Any] = {},
269
+ cancel_token: Optional[str] = None,
270
+ conversation_history: Optional[List[Dict[str, Any]]] = None,
271
+ system_prompt: Optional[str] = None,
272
+ conversation_action: ConversationAction = ConversationAction.NEW,
273
+ conversation_id: Optional[str] = None,
274
+ is_sub_agent: bool = False,
275
+ ) -> Generator[Any, None, None]:
276
+ """
277
+ 处理/auto指令(事件流模式)
278
+
279
+ Args:
280
+ query: 用户查询
281
+ pre_commit: 是否预提交
282
+ post_commit: 是否后提交
283
+ pr: 是否创建PR
284
+ extra_args: 额外参数
285
+ cancel_token: 取消令牌
286
+ conversation_history: 对话历史
287
+ system_prompt: 系统提示
288
+ conversation_action: 对话动作
289
+ conversation_id: 对话ID
290
+ is_sub_agent: 是否为子代理
291
+
292
+ Yields:
293
+ event: 执行事件
294
+ """
295
+ # 1. 初始化配置和LLM
296
+ args = self._get_final_config()
297
+
298
+ # 覆盖默认配置,但不做持久化
299
+ args.agentic_max_rounds = extra_args.get("max_turns", args.agentic_max_rounds)
300
+ args.model = extra_args.get("model", args.model)
301
+ args.code_model = args.model
302
+ args.include_rules = extra_args.get("include_rules", False)
303
+
304
+ global_logger.info(args)
305
+
306
+ execute_file, _ = self._generate_new_yaml(query)
307
+ args.file = execute_file
308
+
309
+ llm = self._get_llm(args)
310
+ if llm is None:
311
+ return
312
+
313
+ # 2. 创建对话配置
314
+ conversation_config = AgenticEditConversationConfig(
315
+ action=conversation_action,
316
+ conversation_id=conversation_id,
317
+ is_sub_agent=is_sub_agent,
318
+ )
319
+
320
+ # 3. 设置提交和PR选项
321
+ if pre_commit:
322
+ conversation_config.commit = True
323
+ if post_commit:
324
+ conversation_config.commit = True
325
+
326
+ conversation_config.query = query
327
+ conversation_config.pull_request = pr
328
+
329
+ # 4. 处理对话管理
330
+ self._setup_conversation_for_events(conversation_config, is_sub_agent)
331
+
332
+ # 5. 注册取消令牌
333
+ if cancel_token:
334
+ from autocoder.common.global_cancel import global_cancel
335
+
336
+ global_cancel.register_token(cancel_token)
337
+
338
+ try:
339
+ # 6. 执行事件流
340
+ from autocoder.common.v2.agent.runner import SdkRunner
341
+
342
+ runner = SdkRunner(
343
+ llm=llm,
344
+ args=args,
345
+ conversation_config=conversation_config,
346
+ system_prompt=system_prompt,
347
+ cancel_token=cancel_token,
348
+ )
349
+
350
+ events = runner.run(AgenticEditRequest(user_input=query))
351
+
352
+ for event in events:
353
+ yield event
354
+
355
+ finally:
356
+ # 7. 清理
357
+ self._refresh_completer()
358
+ if cancel_token:
359
+ from autocoder.common.global_cancel import global_cancel
360
+
361
+ global_cancel.reset_token(cancel_token)
362
+
363
+ # ==================== 内部辅助方法 ====================
364
+
365
+ def _handle_help_command(self, query: str) -> bool:
366
+ """
367
+ 处理 /help 命令
368
+
369
+ Args:
370
+ query: 用户查询
371
+
372
+ Returns:
373
+ bool: 如果是 /help 命令返回 True,否则返回 False
374
+ """
375
+ # 去除前后空格并检查是否是 /help 命令
376
+ query_stripped = query.strip()
377
+ if query_stripped == "/help" or query_stripped == "":
378
+ help_text = get_i18n_message("auto_help_text")
379
+ print(help_text)
380
+ return True
381
+ return False
382
+
383
+ def _show_llm_error(self, error: Exception) -> None:
384
+ """显示LLM配置错误"""
385
+ self._console.print(
386
+ Panel(
387
+ f"[red]LLM Configuration Error:[/red]\n\n{str(error)}",
388
+ title="[red]Error[/red]",
389
+ border_style="red",
390
+ padding=(1, 2),
391
+ )
392
+ )
393
+
394
+ def _get_llm(self, args: AutoCoderArgs) -> Optional[Any]:
395
+ """获取LLM实例"""
396
+ try:
397
+ return get_single_llm(
398
+ args.code_model or args.model, product_mode=args.product_mode
399
+ )
400
+ except ValueError as e:
401
+ self._show_llm_error(e)
402
+ return None
403
+
404
+ def _initialize_context(
405
+ self, query: str
406
+ ) -> Tuple[Optional[AutoCoderArgs], Optional[Any]]:
407
+ """
408
+ 初始化运行上下文
409
+
410
+ Args:
411
+ query: 用户查询
412
+
413
+ Returns:
414
+ tuple: (args, llm) 如果成功,否则 (None, None)
415
+ """
416
+ args = self._get_final_config()
417
+
418
+ execute_file, _ = self._generate_new_yaml(query)
419
+ args.file = execute_file
420
+
421
+ llm = self._get_llm(args)
422
+ if llm is None:
423
+ return None, None
424
+ return args, llm
425
+
426
+ def _process_command_chain(
427
+ self, query: str, args: AutoCoderArgs, command_infos: Any, llm: Any = None, cancel_token: Optional[str] = None
428
+ ) -> Tuple[bool, Optional[AgenticEditConversationConfig]]:
429
+ """
430
+ 处理命令链,使用责任链模式
431
+
432
+ Args:
433
+ query: 用户查询
434
+ args: 配置参数
435
+ command_infos: 命令信息
436
+ llm: LLM实例
437
+ cancel_token: 取消令牌
438
+
439
+ Returns:
440
+ tuple: (should_terminate, conversation_config)
441
+ - should_terminate=True, conversation_config=None: async/queue/merge已处理,返回None
442
+ - should_terminate=True, conversation_config=obj: conversation handler已处理,返回conversation_id
443
+ - should_terminate=False, conversation_config=obj: 继续执行后续逻辑
444
+ """
445
+ # 初始化对话配置
446
+ conversation_config = AgenticEditConversationConfig(
447
+ action=ConversationAction.CONTINUE
448
+ )
449
+
450
+ # 处理 async 指令
451
+ async_handler = AsyncCommandHandler()
452
+ async_result = async_handler.handle_async_command(query, args)
453
+ if async_result is None:
454
+ return True, None
455
+
456
+ # 处理 queue 指令
457
+ queue_handler = QueueCommandHandler()
458
+ queue_result = queue_handler.handle_queue_command(query, args)
459
+ if queue_result is None:
460
+ return True, None
461
+
462
+ # 处理 merge 指令(需要 llm 和 conversation_config)
463
+ if llm is not None:
464
+ # 确保对话ID存在
465
+ self._ensure_conversation_id(conversation_config)
466
+ merge_handler = MergeCommandHandler()
467
+ merge_result = merge_handler.handle_merge_command(
468
+ query, args, llm, conversation_config, cancel_token
469
+ )
470
+ if merge_result is None:
471
+ return True, None
472
+
473
+ # 处理 conversation handlers
474
+ conversation_new_handler = ConversationNewCommandHandler()
475
+ new_handler_result = conversation_new_handler.handle_new_command(
476
+ query, conversation_config
477
+ )
478
+ if new_handler_result is None:
479
+ return True, conversation_config
480
+
481
+ conversation_resume_handler = ConversationResumeCommandHandler()
482
+ resume_handler_result = conversation_resume_handler.handle_resume_command(
483
+ query, conversation_config
484
+ )
485
+ if resume_handler_result is None:
486
+ return True, conversation_config
487
+
488
+ conversation_list_handler = ConversationListCommandHandler()
489
+ list_handler_result = conversation_list_handler.handle_list_command(
490
+ query, conversation_config
491
+ )
492
+ if list_handler_result is None:
493
+ return True, conversation_config
494
+
495
+ conversation_rename_handler = ConversationRenameCommandHandler()
496
+ rename_handler_result = conversation_rename_handler.handle_rename_command(
497
+ query, conversation_config
498
+ )
499
+ if rename_handler_result is None:
500
+ return True, conversation_config
501
+
502
+ # 处理 command 指令
503
+
504
+ command_handler = ConversationCommandCommandHandler()
505
+ command_result = command_handler.handle_command_command(
506
+ query, conversation_config, command_infos
507
+ )
508
+
509
+ if command_result is None:
510
+ return True, conversation_config
511
+
512
+ return False, conversation_config
513
+
514
+ def _ensure_conversation_id(
515
+ self, conversation_config: AgenticEditConversationConfig
516
+ ) -> AgenticEditConversationConfig:
517
+ """
518
+ 确保对话ID存在
519
+
520
+ Args:
521
+ conversation_config: 对话配置
522
+
523
+ Returns:
524
+ str: 对话ID
525
+ """
526
+ if conversation_config.action == ConversationAction.CONTINUE:
527
+ conversation_manager = get_conversation_manager()
528
+ conversation_id = conversation_manager.get_current_conversation_id()
529
+ if not conversation_id:
530
+ conversation_id = conversation_manager.create_conversation(
531
+ name=conversation_config.query or "New Conversation",
532
+ description=conversation_config.query or "New Conversation",
533
+ )
534
+ conversation_config.conversation_id = conversation_id
535
+
536
+ if (
537
+ conversation_config.action == ConversationAction.RESUME
538
+ and not conversation_config.conversation_id
539
+ ):
540
+ conversation_manager = get_conversation_manager()
541
+ conversation_id = conversation_manager.get_current_conversation_id()
542
+ if not conversation_id:
543
+ conversation_id = conversation_manager.create_conversation(
544
+ name=conversation_config.query or "New Conversation",
545
+ description=conversation_config.query or "New Conversation",
546
+ )
547
+ conversation_config.conversation_id = conversation_id
548
+
549
+ if conversation_config.action == ConversationAction.NEW:
550
+ conversation_manager = get_conversation_manager()
551
+ conversation_id = conversation_manager.create_conversation(
552
+ name=conversation_config.query or "New Conversation",
553
+ description=conversation_config.query or "New Conversation",
554
+ )
555
+ conversation_manager.set_current_conversation(conversation_id)
556
+ conversation_config.conversation_id = conversation_id
557
+
558
+ self._conversation_config = conversation_config
559
+ return self._conversation_config
560
+
561
+ def _execute_runner(
562
+ self,
563
+ llm: Any,
564
+ args: AutoCoderArgs,
565
+ conversation_config: AgenticEditConversationConfig,
566
+ task_query: str,
567
+ cancel_token: Optional[str],
568
+ ) -> None:
569
+ """
570
+ 根据运行模式执行相应的runner
571
+
572
+ Args:
573
+ llm: LLM实例
574
+ args: 配置参数
575
+ conversation_config: 对话配置
576
+ task_query: 任务查询
577
+ cancel_token: 取消令牌
578
+ """
579
+ from autocoder.run_context import get_run_context, RunMode
580
+
581
+ runner_class = {
582
+ RunMode.WEB: FileBasedEventRunner,
583
+ RunMode.TERMINAL: TerminalRunner,
584
+ }.get(get_run_context().mode)
585
+
586
+ if runner_class:
587
+ runner = runner_class(
588
+ llm=llm,
589
+ args=args,
590
+ conversation_config=conversation_config,
591
+ cancel_token=cancel_token,
592
+ )
593
+ runner.run(AgenticEditRequest(user_input=task_query))
594
+
595
+ def _setup_conversation_for_events(
596
+ self, conversation_config: AgenticEditConversationConfig, is_sub_agent: bool
597
+ ) -> None:
598
+ """
599
+ 为事件流模式设置对话管理
600
+
601
+ Args:
602
+ conversation_config: 对话配置
603
+ is_sub_agent: 是否为子代理
604
+ """
605
+ conversation_manager = get_conversation_manager()
606
+
607
+ # 处理 NEW 动作
608
+ if conversation_config.action == ConversationAction.NEW:
609
+ conversation_id = conversation_manager.create_conversation(
610
+ name=conversation_config.query or "New Conversation",
611
+ description=conversation_config.query or "New Conversation",
612
+ )
613
+ if not is_sub_agent:
614
+ conversation_manager.set_current_conversation(conversation_id)
615
+ conversation_config.conversation_id = conversation_id
616
+
617
+ # 处理 RESUME 动作(有 conversation_id)
618
+ elif (
619
+ conversation_config.action == ConversationAction.RESUME
620
+ and conversation_config.conversation_id
621
+ ):
622
+ if not is_sub_agent:
623
+ conversation_manager.set_current_conversation(
624
+ conversation_config.conversation_id
625
+ )
626
+
627
+ # 处理 RESUME 动作(无 conversation_id,使用当前对话)
628
+ elif (
629
+ conversation_config.action == ConversationAction.RESUME
630
+ and not conversation_config.conversation_id
631
+ and conversation_manager.get_current_conversation_id()
632
+ ):
633
+ conversation_config.conversation_id = (
634
+ conversation_manager.get_current_conversation_id()
635
+ )
636
+ if not is_sub_agent:
637
+ conversation_manager.set_current_conversation(
638
+ conversation_config.conversation_id
639
+ )
640
+
641
+ # 处理 CONTINUE 动作
642
+ elif conversation_config.action == ConversationAction.CONTINUE:
643
+ conversation_config.conversation_id = (
644
+ conversation_manager.get_current_conversation_id()
645
+ )
646
+ if not is_sub_agent:
647
+ if conversation_config.conversation_id:
648
+ conversation_manager.set_current_conversation(
649
+ conversation_config.conversation_id
650
+ )
651
+ else:
652
+ conversation_id = conversation_manager.create_conversation(
653
+ name=conversation_config.query or "New Conversation",
654
+ description=conversation_config.query or "New Conversation",
655
+ )
656
+ conversation_manager.set_current_conversation(conversation_id)
657
+ conversation_config.conversation_id = conversation_id
658
+
659
+ # 确保有 conversation_id
660
+ if not conversation_config.conversation_id:
661
+ conversation_id = conversation_manager.create_conversation(
662
+ name=conversation_config.query or "New Conversation",
663
+ description=conversation_config.query or "New Conversation",
664
+ )
665
+ if not is_sub_agent:
666
+ conversation_manager.set_current_conversation(conversation_id)
667
+ conversation_config.conversation_id = conversation_id
668
+
669
+ def _get_memory(self) -> Dict[str, Any]:
670
+ """获取内存配置"""
671
+ memory_manager = get_memory_manager()
672
+ return memory_manager.get_memory_dict()
673
+
674
+ def _get_final_config(self) -> AutoCoderArgs:
675
+ """获取最终配置"""
676
+ from autocoder.common.core_config import get_memory_manager
677
+
678
+ memory_manager = get_memory_manager()
679
+ conf = memory_manager.get_all_config()
680
+ yaml_config = {
681
+ "include_file": ["./base/base.yml"],
682
+ "auto_merge": conf.get("auto_merge", "editblock"),
683
+ "human_as_model": conf.get("human_as_model", "false") == "true",
684
+ "skip_build_index": conf.get("skip_build_index", "true") == "true",
685
+ "skip_confirm": conf.get("skip_confirm", "true") == "true",
686
+ "silence": conf.get("silence", "true") == "true",
687
+ "include_project_structure": conf.get("include_project_structure", "false")
688
+ == "true",
689
+ "exclude_files": memory_manager.get_exclude_files(),
690
+ }
691
+ for key, value in conf.items():
692
+ converted_value = self._convert_config_value(key, value)
693
+ if converted_value is not None:
694
+ yaml_config[key] = converted_value
695
+
696
+ temp_yaml = os.path.join("actions", f"{uuid.uuid4()}.yml")
697
+ try:
698
+ with open(temp_yaml, "w", encoding="utf-8") as f:
699
+ f.write(self._convert_yaml_config_to_str(yaml_config=yaml_config))
700
+ args = self._convert_yaml_to_config(temp_yaml)
701
+ finally:
702
+ if os.path.exists(temp_yaml):
703
+ os.remove(temp_yaml)
704
+ return args
705
+
706
+ def _convert_config_value(self, key: str, value: Any) -> Any:
707
+ """转换配置值"""
708
+ # 定义需要使用 token 解析的字段
709
+ token_fields = {
710
+ "conversation_prune_safe_zone_tokens",
711
+ "context_prune_safe_zone_tokens",
712
+ "context_prune_sliding_window_size",
713
+ "context_prune_sliding_window_overlap",
714
+ "rag_params_max_tokens",
715
+ "rag_context_window_limit",
716
+ "rag_duckdb_vector_dim",
717
+ "rag_duckdb_query_top_k",
718
+ "rag_emb_dim",
719
+ "rag_emb_text_size",
720
+ "hybrid_index_max_output_tokens",
721
+ "data_cells_max_num",
722
+ }
723
+
724
+ field_info = AutoCoderArgs.model_fields.get(key)
725
+ if field_info:
726
+ # 对于需要 token 解析的字段,使用 AutoCoderArgsParser
727
+ if key in token_fields:
728
+ try:
729
+ parser = AutoCoderArgsParser()
730
+ return parser.parse_token_field(key, value)
731
+ except Exception as e:
732
+ print(
733
+ f"Warning: Failed to parse token field '{key}' with value '{value}': {e}"
734
+ )
735
+ # 如果解析失败,fallback 到原有逻辑
736
+ pass
737
+
738
+ # 原有的类型转换逻辑
739
+ if isinstance(value, str) and value.lower() in ["true", "false"]:
740
+ return value.lower() == "true"
741
+ elif "float" in str(field_info.annotation):
742
+ return float(value)
743
+ elif "int" in str(field_info.annotation):
744
+ return int(value)
745
+ else:
746
+ return value
747
+ else:
748
+ print(f"Invalid configuration key: {key}")
749
+ return None
750
+
751
+ def _convert_yaml_config_to_str(self, yaml_config: Dict[str, Any]) -> str:
752
+ """将YAML配置转换为字符串"""
753
+ yaml_content = yaml.safe_dump(
754
+ yaml_config,
755
+ allow_unicode=True,
756
+ default_flow_style=False,
757
+ default_style=None,
758
+ )
759
+ return yaml_content
760
+
761
+ def _convert_yaml_to_config(self, yaml_file: str) -> AutoCoderArgs:
762
+ """将YAML文件转换为配置对象"""
763
+ from autocoder.auto_coder import AutoCoderArgs, load_include_files, Template
764
+
765
+ args = AutoCoderArgs()
766
+ with open(yaml_file, "r", encoding="utf-8") as f:
767
+ config = yaml.safe_load(f)
768
+ config = load_include_files(config, yaml_file)
769
+ for key, value in config.items():
770
+ if key != "file": # 排除 --file 参数本身
771
+ # key: ENV {{VARIABLE_NAME}}
772
+ if isinstance(value, str) and value.startswith("ENV"):
773
+ template = Template(value.removeprefix("ENV").strip())
774
+ value = template.render(os.environ)
775
+ setattr(args, key, value)
776
+ return args
777
+
778
+ def _generate_new_yaml(self, query: str) -> Tuple[str, AutoCoderArgs]:
779
+ """生成新的YAML配置文件"""
780
+ memory = self._get_memory()
781
+ conf = memory.get("conf", {})
782
+ current_files = memory.get("current_files", {}).get("files", [])
783
+ auto_coder_main(["next", "chat_action"])
784
+ latest_yaml_file = get_last_yaml_file("actions")
785
+ if latest_yaml_file:
786
+ yaml_config = {
787
+ "include_file": ["./base/base.yml"],
788
+ "auto_merge": conf.get("auto_merge", "editblock"),
789
+ "human_as_model": conf.get("human_as_model", "false") == "true",
790
+ "skip_build_index": conf.get("skip_build_index", "true") == "true",
791
+ "skip_confirm": conf.get("skip_confirm", "true") == "true",
792
+ "silence": conf.get("silence", "true") == "true",
793
+ "include_project_structure": conf.get(
794
+ "include_project_structure", "false"
795
+ )
796
+ == "true",
797
+ "exclude_files": memory.get("exclude_files", []),
798
+ }
799
+ yaml_config["context"] = ""
800
+ for key, value in conf.items():
801
+ converted_value = self._convert_config_value(key, value)
802
+ if converted_value is not None:
803
+ yaml_config[key] = converted_value
804
+
805
+ yaml_config["urls"] = current_files + self._get_llm_friendly_package_docs(
806
+ return_paths=True
807
+ )
808
+ # handle image
809
+ v = Image.convert_image_paths_from(query)
810
+ yaml_config["query"] = v
811
+
812
+ yaml_content = self._convert_yaml_config_to_str(yaml_config=yaml_config)
813
+
814
+ execute_file = os.path.join("actions", latest_yaml_file)
815
+ with open(os.path.join(execute_file), "w", encoding="utf-8") as f:
816
+ f.write(yaml_content)
817
+ return execute_file, self._convert_yaml_to_config(execute_file)
818
+
819
+ def _get_llm_friendly_package_docs(
820
+ self, package_name: Optional[str] = None, return_paths: bool = False
821
+ ) -> List[str]:
822
+ """获取LLM友好的包文档"""
823
+ from autocoder.common.llm_friendly_package import get_package_manager
824
+
825
+ package_manager = get_package_manager()
826
+ return package_manager.get_docs(package_name, return_paths)
827
+
828
+ def _handle_conversation_actions(
829
+ self, conversation_config: AgenticEditConversationConfig
830
+ ) -> bool:
831
+ """
832
+ 处理对话列表和创建新对话的操作
833
+
834
+ Args:
835
+ conversation_config: 对话配置对象
836
+
837
+ Returns:
838
+ bool: 如果处理了特殊操作(LIST或NEW without input)返回True,否则返回False
839
+ """
840
+ if not conversation_config:
841
+ return False
842
+
843
+ console = Console()
844
+
845
+ # 处理LIST操作
846
+ if conversation_config.action == ConversationAction.LIST:
847
+ conversation_manager = get_conversation_manager()
848
+ conversations = conversation_manager.list_conversations()
849
+ # 只保留 conversation_id 和 name 字段
850
+ filtered_conversations = []
851
+ for conv in conversations:
852
+ filtered_conv = {
853
+ "conversation_id": conv.get("conversation_id"),
854
+ "name": conv.get("name"),
855
+ }
856
+ filtered_conversations.append(filtered_conv)
857
+
858
+ # 格式化 JSON 输出,使用 JSON 格式渲染而不是 Markdown
859
+ json_str = json.dumps(filtered_conversations, ensure_ascii=False, indent=4)
860
+ console.print(
861
+ Panel(
862
+ json_str,
863
+ title="🏁 Task Completion",
864
+ border_style="green",
865
+ title_align="left",
866
+ )
867
+ )
868
+ return True
869
+
870
+ # 处理NEW操作且没有用户输入
871
+ if (
872
+ conversation_config.action == ConversationAction.NEW
873
+ and not conversation_config.query.strip()
874
+ ):
875
+ conversation_manager = get_conversation_manager()
876
+ conversation_id = conversation_manager.create_conversation(
877
+ name=conversation_config.query or "New Conversation",
878
+ description=conversation_config.query or "New Conversation",
879
+ )
880
+ conversation_manager.set_current_conversation(conversation_id)
881
+ conversation_message = f"New conversation created: {conversation_manager.get_current_conversation_id()}"
882
+
883
+ # 使用safe console print的简单版本
884
+ try:
885
+ console.print(
886
+ Panel(
887
+ Markdown(conversation_message),
888
+ title="🏁 Task Completion",
889
+ border_style="green",
890
+ title_align="left",
891
+ )
892
+ )
893
+ except Exception:
894
+ # fallback to plain text
895
+ safe_content = conversation_message.replace("[", "\\[").replace(
896
+ "]", "\\]"
897
+ )
898
+ console.print(
899
+ Panel(
900
+ safe_content,
901
+ title="🏁 Task Completion",
902
+ border_style="green",
903
+ title_align="left",
904
+ )
905
+ )
906
+ return True
907
+
908
+ return False
909
+
910
+ def _refresh_completer(self) -> None:
911
+ """刷新命令补全器"""
912
+ try:
913
+ # 延迟导入,避免循环依赖
914
+
915
+ # 获取全局 completer 实例
916
+ # 注意:这里需要访问 auto_coder_runner 模块的全局变量
917
+ # 由于我们不能修改 auto_coder_runner.py,所以这里直接导入
918
+ import autocoder.auto_coder_runner as runner_module
919
+
920
+ if hasattr(runner_module, "completer"):
921
+ runner_module.completer.refresh_files()
922
+ except Exception as e:
923
+ global_logger.warning(f"Failed to refresh completer: {e}")