auto-coder 1.0.0__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 (574) 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-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
  5. {auto_coder-1.0.0.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 +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 +73 -59
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +970 -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 +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/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 +288 -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 +349 -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 +1051 -0
  398. autocoder/default_project/__init__.py +501 -0
  399. autocoder/dispacher/__init__.py +4 -12
  400. autocoder/dispacher/actions/action.py +165 -7
  401. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  402. autocoder/index/entry.py +116 -124
  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 +932 -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 +489 -0
  536. autocoder/workflow_agents/loader.py +737 -0
  537. autocoder/workflow_agents/runner.py +267 -0
  538. autocoder/workflow_agents/types.py +172 -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.0.dist-info}/top_level.txt +0 -0
  574. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,932 @@
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
+ # 4. 创建新对话
203
+ conversation_manager = get_conversation_manager()
204
+ conversation_id = conversation_manager.create_conversation(
205
+ name=query or "New Conversation",
206
+ description=query or "New Conversation",
207
+ )
208
+ conversation_manager.set_current_conversation(conversation_id)
209
+ conversation_config.conversation_id = conversation_id
210
+
211
+ # 5. 配置过滤模式参数
212
+ args_copy = deepcopy(args)
213
+ args_copy.agentic_mode = "plan"
214
+ args_copy.code_model = args.index_filter_model or args.model
215
+
216
+ # 6. 执行文件发现
217
+ runner = TerminalRunner(
218
+ llm=llm,
219
+ args=args_copy,
220
+ conversation_config=conversation_config,
221
+ cancel_token=cancel_token,
222
+ system_prompt=self._filter_plan.prompt(),
223
+ )
224
+
225
+ # 执行并重试逻辑(最多重试3次)
226
+ max_retries = args_copy.agentic_filter_retries
227
+ last_exception = None
228
+
229
+ for attempt in range(max_retries):
230
+ try:
231
+ if attempt == 0:
232
+ # 第一次执行
233
+ result = runner.run(
234
+ AgenticEditRequest(
235
+ user_input=query
236
+ + "\n"
237
+ + self._filter_query_reminder.prompt(),
238
+ )
239
+ )
240
+ else:
241
+ # 重试执行,将异常信息传递给模型
242
+ exception_message = f"<异常>\n{str(last_exception)}\n\n根据异常修正错误,重新使用 attempt_completion 进行输出"
243
+ global_logger.warning(
244
+ f"Filter method retry attempt {attempt + 1}/{max_retries}, error: {last_exception}"
245
+ )
246
+ result = runner.run(
247
+ AgenticEditRequest(
248
+ user_input=exception_message,
249
+ )
250
+ )
251
+
252
+ # 尝试转换为模型
253
+ return to_model(result, AgenticFilterResponse)
254
+
255
+ except Exception as e:
256
+ last_exception = e
257
+ global_logger.error(
258
+ f"Filter method failed on attempt {attempt + 1}/{max_retries}: {e}"
259
+ )
260
+
261
+ # 如果是最后一次尝试,抛出异常
262
+ if attempt == max_retries - 1:
263
+ global_logger.error(
264
+ f"Filter method failed after {max_retries} attempts"
265
+ )
266
+ raise
267
+
268
+ # 理论上不会到达这里,但为了类型安全
269
+ raise RuntimeError("Filter method failed unexpectedly")
270
+
271
+ def run_with_events(
272
+ self,
273
+ query: str,
274
+ pre_commit: bool = False,
275
+ post_commit: bool = False,
276
+ pr: bool = False,
277
+ extra_args: Dict[str, Any] = {},
278
+ cancel_token: Optional[str] = None,
279
+ conversation_history: Optional[List[Dict[str, Any]]] = None,
280
+ system_prompt: Optional[str] = None,
281
+ conversation_action: ConversationAction = ConversationAction.NEW,
282
+ conversation_id: Optional[str] = None,
283
+ is_sub_agent: bool = False,
284
+ ) -> Generator[Any, None, None]:
285
+ """
286
+ 处理/auto指令(事件流模式)
287
+
288
+ Args:
289
+ query: 用户查询
290
+ pre_commit: 是否预提交
291
+ post_commit: 是否后提交
292
+ pr: 是否创建PR
293
+ extra_args: 额外参数
294
+ cancel_token: 取消令牌
295
+ conversation_history: 对话历史
296
+ system_prompt: 系统提示
297
+ conversation_action: 对话动作
298
+ conversation_id: 对话ID
299
+ is_sub_agent: 是否为子代理
300
+
301
+ Yields:
302
+ event: 执行事件
303
+ """
304
+ # 1. 初始化配置和LLM
305
+ args = self._get_final_config()
306
+
307
+ # 覆盖默认配置,但不做持久化
308
+ args.agentic_max_rounds = extra_args.get("max_turns", args.agentic_max_rounds)
309
+ args.model = extra_args.get("model", args.model)
310
+ args.code_model = args.model
311
+ args.include_rules = extra_args.get("include_rules", False)
312
+
313
+ global_logger.info(args)
314
+
315
+ execute_file, _ = self._generate_new_yaml(query)
316
+ args.file = execute_file
317
+
318
+ llm = self._get_llm(args)
319
+ if llm is None:
320
+ return
321
+
322
+ # 2. 创建对话配置
323
+ conversation_config = AgenticEditConversationConfig(
324
+ action=conversation_action,
325
+ conversation_id=conversation_id,
326
+ is_sub_agent=is_sub_agent,
327
+ )
328
+
329
+ # 3. 设置提交和PR选项
330
+ if pre_commit:
331
+ conversation_config.commit = True
332
+ if post_commit:
333
+ conversation_config.commit = True
334
+
335
+ conversation_config.query = query
336
+ conversation_config.pull_request = pr
337
+
338
+ # 4. 处理对话管理
339
+ self._setup_conversation_for_events(conversation_config, is_sub_agent)
340
+
341
+ # 5. 注册取消令牌
342
+ if cancel_token:
343
+ from autocoder.common.global_cancel import global_cancel
344
+
345
+ global_cancel.register_token(cancel_token)
346
+
347
+ try:
348
+ # 6. 执行事件流
349
+ from autocoder.common.v2.agent.runner import SdkRunner
350
+
351
+ runner = SdkRunner(
352
+ llm=llm,
353
+ args=args,
354
+ conversation_config=conversation_config,
355
+ system_prompt=system_prompt,
356
+ cancel_token=cancel_token,
357
+ )
358
+
359
+ events = runner.run(AgenticEditRequest(user_input=query))
360
+
361
+ for event in events:
362
+ yield event
363
+
364
+ finally:
365
+ # 7. 清理
366
+ self._refresh_completer()
367
+ if cancel_token:
368
+ from autocoder.common.global_cancel import global_cancel
369
+
370
+ global_cancel.reset_token(cancel_token)
371
+
372
+ # ==================== 内部辅助方法 ====================
373
+
374
+ def _handle_help_command(self, query: str) -> bool:
375
+ """
376
+ 处理 /help 命令
377
+
378
+ Args:
379
+ query: 用户查询
380
+
381
+ Returns:
382
+ bool: 如果是 /help 命令返回 True,否则返回 False
383
+ """
384
+ # 去除前后空格并检查是否是 /help 命令
385
+ query_stripped = query.strip()
386
+ if query_stripped == "/help" or query_stripped == "":
387
+ help_text = get_i18n_message("auto_help_text")
388
+ print(help_text)
389
+ return True
390
+ return False
391
+
392
+ def _show_llm_error(self, error: Exception) -> None:
393
+ """显示LLM配置错误"""
394
+ self._console.print(
395
+ Panel(
396
+ f"[red]LLM Configuration Error:[/red]\n\n{str(error)}",
397
+ title="[red]Error[/red]",
398
+ border_style="red",
399
+ padding=(1, 2),
400
+ )
401
+ )
402
+
403
+ def _get_llm(self, args: AutoCoderArgs) -> Optional[Any]:
404
+ """获取LLM实例"""
405
+ try:
406
+ return get_single_llm(
407
+ args.code_model or args.model, product_mode=args.product_mode
408
+ )
409
+ except ValueError as e:
410
+ self._show_llm_error(e)
411
+ return None
412
+
413
+ def _initialize_context(
414
+ self, query: str
415
+ ) -> Tuple[Optional[AutoCoderArgs], Optional[Any]]:
416
+ """
417
+ 初始化运行上下文
418
+
419
+ Args:
420
+ query: 用户查询
421
+
422
+ Returns:
423
+ tuple: (args, llm) 如果成功,否则 (None, None)
424
+ """
425
+ args = self._get_final_config()
426
+
427
+ execute_file, _ = self._generate_new_yaml(query)
428
+ args.file = execute_file
429
+
430
+ llm = self._get_llm(args)
431
+ if llm is None:
432
+ return None, None
433
+ return args, llm
434
+
435
+ def _process_command_chain(
436
+ self, query: str, args: AutoCoderArgs, command_infos: Any, llm: Any = None, cancel_token: Optional[str] = None
437
+ ) -> Tuple[bool, Optional[AgenticEditConversationConfig]]:
438
+ """
439
+ 处理命令链,使用责任链模式
440
+
441
+ Args:
442
+ query: 用户查询
443
+ args: 配置参数
444
+ command_infos: 命令信息
445
+ llm: LLM实例
446
+ cancel_token: 取消令牌
447
+
448
+ Returns:
449
+ tuple: (should_terminate, conversation_config)
450
+ - should_terminate=True, conversation_config=None: async/queue/merge已处理,返回None
451
+ - should_terminate=True, conversation_config=obj: conversation handler已处理,返回conversation_id
452
+ - should_terminate=False, conversation_config=obj: 继续执行后续逻辑
453
+ """
454
+ # 初始化对话配置
455
+ conversation_config = AgenticEditConversationConfig(
456
+ action=ConversationAction.CONTINUE
457
+ )
458
+
459
+ # 处理 async 指令
460
+ async_handler = AsyncCommandHandler()
461
+ async_result = async_handler.handle_async_command(query, args)
462
+ if async_result is None:
463
+ return True, None
464
+
465
+ # 处理 queue 指令
466
+ queue_handler = QueueCommandHandler()
467
+ queue_result = queue_handler.handle_queue_command(query, args)
468
+ if queue_result is None:
469
+ return True, None
470
+
471
+ # 处理 merge 指令(需要 llm 和 conversation_config)
472
+ if llm is not None:
473
+ # 确保对话ID存在
474
+ self._ensure_conversation_id(conversation_config)
475
+ merge_handler = MergeCommandHandler()
476
+ merge_result = merge_handler.handle_merge_command(
477
+ query, args, llm, conversation_config, cancel_token
478
+ )
479
+ if merge_result is None:
480
+ return True, None
481
+
482
+ # 处理 conversation handlers
483
+ conversation_new_handler = ConversationNewCommandHandler()
484
+ new_handler_result = conversation_new_handler.handle_new_command(
485
+ query, conversation_config
486
+ )
487
+ if new_handler_result is None:
488
+ return True, conversation_config
489
+
490
+ conversation_resume_handler = ConversationResumeCommandHandler()
491
+ resume_handler_result = conversation_resume_handler.handle_resume_command(
492
+ query, conversation_config
493
+ )
494
+ if resume_handler_result is None:
495
+ return True, conversation_config
496
+
497
+ conversation_list_handler = ConversationListCommandHandler()
498
+ list_handler_result = conversation_list_handler.handle_list_command(
499
+ query, conversation_config
500
+ )
501
+ if list_handler_result is None:
502
+ return True, conversation_config
503
+
504
+ conversation_rename_handler = ConversationRenameCommandHandler()
505
+ rename_handler_result = conversation_rename_handler.handle_rename_command(
506
+ query, conversation_config
507
+ )
508
+ if rename_handler_result is None:
509
+ return True, conversation_config
510
+
511
+ # 处理 command 指令
512
+
513
+ command_handler = ConversationCommandCommandHandler()
514
+ command_result = command_handler.handle_command_command(
515
+ query, conversation_config, command_infos
516
+ )
517
+
518
+ if command_result is None:
519
+ return True, conversation_config
520
+
521
+ return False, conversation_config
522
+
523
+ def _ensure_conversation_id(
524
+ self, conversation_config: AgenticEditConversationConfig
525
+ ) -> AgenticEditConversationConfig:
526
+ """
527
+ 确保对话ID存在
528
+
529
+ Args:
530
+ conversation_config: 对话配置
531
+
532
+ Returns:
533
+ str: 对话ID
534
+ """
535
+ if conversation_config.action == ConversationAction.CONTINUE:
536
+ conversation_manager = get_conversation_manager()
537
+ conversation_id = conversation_manager.get_current_conversation_id()
538
+ if not conversation_id:
539
+ conversation_id = conversation_manager.create_conversation(
540
+ name=conversation_config.query or "New Conversation",
541
+ description=conversation_config.query or "New Conversation",
542
+ )
543
+ conversation_config.conversation_id = conversation_id
544
+
545
+ if (
546
+ conversation_config.action == ConversationAction.RESUME
547
+ and not conversation_config.conversation_id
548
+ ):
549
+ conversation_manager = get_conversation_manager()
550
+ conversation_id = conversation_manager.get_current_conversation_id()
551
+ if not conversation_id:
552
+ conversation_id = conversation_manager.create_conversation(
553
+ name=conversation_config.query or "New Conversation",
554
+ description=conversation_config.query or "New Conversation",
555
+ )
556
+ conversation_config.conversation_id = conversation_id
557
+
558
+ if conversation_config.action == ConversationAction.NEW:
559
+ conversation_manager = get_conversation_manager()
560
+ conversation_id = conversation_manager.create_conversation(
561
+ name=conversation_config.query or "New Conversation",
562
+ description=conversation_config.query or "New Conversation",
563
+ )
564
+ conversation_manager.set_current_conversation(conversation_id)
565
+ conversation_config.conversation_id = conversation_id
566
+
567
+ self._conversation_config = conversation_config
568
+ return self._conversation_config
569
+
570
+ def _execute_runner(
571
+ self,
572
+ llm: Any,
573
+ args: AutoCoderArgs,
574
+ conversation_config: AgenticEditConversationConfig,
575
+ task_query: str,
576
+ cancel_token: Optional[str],
577
+ ) -> None:
578
+ """
579
+ 根据运行模式执行相应的runner
580
+
581
+ Args:
582
+ llm: LLM实例
583
+ args: 配置参数
584
+ conversation_config: 对话配置
585
+ task_query: 任务查询
586
+ cancel_token: 取消令牌
587
+ """
588
+ from autocoder.run_context import get_run_context, RunMode
589
+
590
+ runner_class = {
591
+ RunMode.WEB: FileBasedEventRunner,
592
+ RunMode.TERMINAL: TerminalRunner,
593
+ }.get(get_run_context().mode)
594
+
595
+ if runner_class:
596
+ runner = runner_class(
597
+ llm=llm,
598
+ args=args,
599
+ conversation_config=conversation_config,
600
+ cancel_token=cancel_token,
601
+ )
602
+ runner.run(AgenticEditRequest(user_input=task_query))
603
+
604
+ def _setup_conversation_for_events(
605
+ self, conversation_config: AgenticEditConversationConfig, is_sub_agent: bool
606
+ ) -> None:
607
+ """
608
+ 为事件流模式设置对话管理
609
+
610
+ Args:
611
+ conversation_config: 对话配置
612
+ is_sub_agent: 是否为子代理
613
+ """
614
+ conversation_manager = get_conversation_manager()
615
+
616
+ # 处理 NEW 动作
617
+ if conversation_config.action == ConversationAction.NEW:
618
+ conversation_id = conversation_manager.create_conversation(
619
+ name=conversation_config.query or "New Conversation",
620
+ description=conversation_config.query or "New Conversation",
621
+ )
622
+ if not is_sub_agent:
623
+ conversation_manager.set_current_conversation(conversation_id)
624
+ conversation_config.conversation_id = conversation_id
625
+
626
+ # 处理 RESUME 动作(有 conversation_id)
627
+ elif (
628
+ conversation_config.action == ConversationAction.RESUME
629
+ and conversation_config.conversation_id
630
+ ):
631
+ if not is_sub_agent:
632
+ conversation_manager.set_current_conversation(
633
+ conversation_config.conversation_id
634
+ )
635
+
636
+ # 处理 RESUME 动作(无 conversation_id,使用当前对话)
637
+ elif (
638
+ conversation_config.action == ConversationAction.RESUME
639
+ and not conversation_config.conversation_id
640
+ and conversation_manager.get_current_conversation_id()
641
+ ):
642
+ conversation_config.conversation_id = (
643
+ conversation_manager.get_current_conversation_id()
644
+ )
645
+ if not is_sub_agent:
646
+ conversation_manager.set_current_conversation(
647
+ conversation_config.conversation_id
648
+ )
649
+
650
+ # 处理 CONTINUE 动作
651
+ elif conversation_config.action == ConversationAction.CONTINUE:
652
+ conversation_config.conversation_id = (
653
+ conversation_manager.get_current_conversation_id()
654
+ )
655
+ if not is_sub_agent:
656
+ if conversation_config.conversation_id:
657
+ conversation_manager.set_current_conversation(
658
+ conversation_config.conversation_id
659
+ )
660
+ else:
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
+ conversation_manager.set_current_conversation(conversation_id)
666
+ conversation_config.conversation_id = conversation_id
667
+
668
+ # 确保有 conversation_id
669
+ if not conversation_config.conversation_id:
670
+ conversation_id = conversation_manager.create_conversation(
671
+ name=conversation_config.query or "New Conversation",
672
+ description=conversation_config.query or "New Conversation",
673
+ )
674
+ if not is_sub_agent:
675
+ conversation_manager.set_current_conversation(conversation_id)
676
+ conversation_config.conversation_id = conversation_id
677
+
678
+ def _get_memory(self) -> Dict[str, Any]:
679
+ """获取内存配置"""
680
+ memory_manager = get_memory_manager()
681
+ return memory_manager.get_memory_dict()
682
+
683
+ def _get_final_config(self) -> AutoCoderArgs:
684
+ """获取最终配置"""
685
+ from autocoder.common.core_config import get_memory_manager
686
+
687
+ memory_manager = get_memory_manager()
688
+ conf = memory_manager.get_all_config()
689
+ yaml_config = {
690
+ "include_file": ["./base/base.yml"],
691
+ "auto_merge": conf.get("auto_merge", "editblock"),
692
+ "human_as_model": conf.get("human_as_model", "false") == "true",
693
+ "skip_build_index": conf.get("skip_build_index", "true") == "true",
694
+ "skip_confirm": conf.get("skip_confirm", "true") == "true",
695
+ "silence": conf.get("silence", "true") == "true",
696
+ "include_project_structure": conf.get("include_project_structure", "false")
697
+ == "true",
698
+ "exclude_files": memory_manager.get_exclude_files(),
699
+ }
700
+ for key, value in conf.items():
701
+ converted_value = self._convert_config_value(key, value)
702
+ if converted_value is not None:
703
+ yaml_config[key] = converted_value
704
+
705
+ temp_yaml = os.path.join("actions", f"{uuid.uuid4()}.yml")
706
+ try:
707
+ with open(temp_yaml, "w", encoding="utf-8") as f:
708
+ f.write(self._convert_yaml_config_to_str(yaml_config=yaml_config))
709
+ args = self._convert_yaml_to_config(temp_yaml)
710
+ finally:
711
+ if os.path.exists(temp_yaml):
712
+ os.remove(temp_yaml)
713
+ return args
714
+
715
+ def _convert_config_value(self, key: str, value: Any) -> Any:
716
+ """转换配置值"""
717
+ # 定义需要使用 token 解析的字段
718
+ token_fields = {
719
+ "conversation_prune_safe_zone_tokens",
720
+ "context_prune_safe_zone_tokens",
721
+ "context_prune_sliding_window_size",
722
+ "context_prune_sliding_window_overlap",
723
+ "rag_params_max_tokens",
724
+ "rag_context_window_limit",
725
+ "rag_duckdb_vector_dim",
726
+ "rag_duckdb_query_top_k",
727
+ "rag_emb_dim",
728
+ "rag_emb_text_size",
729
+ "hybrid_index_max_output_tokens",
730
+ "data_cells_max_num",
731
+ }
732
+
733
+ field_info = AutoCoderArgs.model_fields.get(key)
734
+ if field_info:
735
+ # 对于需要 token 解析的字段,使用 AutoCoderArgsParser
736
+ if key in token_fields:
737
+ try:
738
+ parser = AutoCoderArgsParser()
739
+ return parser.parse_token_field(key, value)
740
+ except Exception as e:
741
+ print(
742
+ f"Warning: Failed to parse token field '{key}' with value '{value}': {e}"
743
+ )
744
+ # 如果解析失败,fallback 到原有逻辑
745
+ pass
746
+
747
+ # 原有的类型转换逻辑
748
+ if isinstance(value, str) and value.lower() in ["true", "false"]:
749
+ return value.lower() == "true"
750
+ elif "float" in str(field_info.annotation):
751
+ return float(value)
752
+ elif "int" in str(field_info.annotation):
753
+ return int(value)
754
+ else:
755
+ return value
756
+ else:
757
+ print(f"Invalid configuration key: {key}")
758
+ return None
759
+
760
+ def _convert_yaml_config_to_str(self, yaml_config: Dict[str, Any]) -> str:
761
+ """将YAML配置转换为字符串"""
762
+ yaml_content = yaml.safe_dump(
763
+ yaml_config,
764
+ allow_unicode=True,
765
+ default_flow_style=False,
766
+ default_style=None,
767
+ )
768
+ return yaml_content
769
+
770
+ def _convert_yaml_to_config(self, yaml_file: str) -> AutoCoderArgs:
771
+ """将YAML文件转换为配置对象"""
772
+ from autocoder.auto_coder import AutoCoderArgs, load_include_files, Template
773
+
774
+ args = AutoCoderArgs()
775
+ with open(yaml_file, "r", encoding="utf-8") as f:
776
+ config = yaml.safe_load(f)
777
+ config = load_include_files(config, yaml_file)
778
+ for key, value in config.items():
779
+ if key != "file": # 排除 --file 参数本身
780
+ # key: ENV {{VARIABLE_NAME}}
781
+ if isinstance(value, str) and value.startswith("ENV"):
782
+ template = Template(value.removeprefix("ENV").strip())
783
+ value = template.render(os.environ)
784
+ setattr(args, key, value)
785
+ return args
786
+
787
+ def _generate_new_yaml(self, query: str) -> Tuple[str, AutoCoderArgs]:
788
+ """生成新的YAML配置文件"""
789
+ memory = self._get_memory()
790
+ conf = memory.get("conf", {})
791
+ current_files = memory.get("current_files", {}).get("files", [])
792
+ auto_coder_main(["next", "chat_action"])
793
+ latest_yaml_file = get_last_yaml_file("actions")
794
+ if latest_yaml_file:
795
+ yaml_config = {
796
+ "include_file": ["./base/base.yml"],
797
+ "auto_merge": conf.get("auto_merge", "editblock"),
798
+ "human_as_model": conf.get("human_as_model", "false") == "true",
799
+ "skip_build_index": conf.get("skip_build_index", "true") == "true",
800
+ "skip_confirm": conf.get("skip_confirm", "true") == "true",
801
+ "silence": conf.get("silence", "true") == "true",
802
+ "include_project_structure": conf.get(
803
+ "include_project_structure", "false"
804
+ )
805
+ == "true",
806
+ "exclude_files": memory.get("exclude_files", []),
807
+ }
808
+ yaml_config["context"] = ""
809
+ for key, value in conf.items():
810
+ converted_value = self._convert_config_value(key, value)
811
+ if converted_value is not None:
812
+ yaml_config[key] = converted_value
813
+
814
+ yaml_config["urls"] = current_files + self._get_llm_friendly_package_docs(
815
+ return_paths=True
816
+ )
817
+ # handle image
818
+ v = Image.convert_image_paths_from(query)
819
+ yaml_config["query"] = v
820
+
821
+ yaml_content = self._convert_yaml_config_to_str(yaml_config=yaml_config)
822
+
823
+ execute_file = os.path.join("actions", latest_yaml_file)
824
+ with open(os.path.join(execute_file), "w", encoding="utf-8") as f:
825
+ f.write(yaml_content)
826
+ return execute_file, self._convert_yaml_to_config(execute_file)
827
+
828
+ def _get_llm_friendly_package_docs(
829
+ self, package_name: Optional[str] = None, return_paths: bool = False
830
+ ) -> List[str]:
831
+ """获取LLM友好的包文档"""
832
+ from autocoder.common.llm_friendly_package import get_package_manager
833
+
834
+ package_manager = get_package_manager()
835
+ return package_manager.get_docs(package_name, return_paths)
836
+
837
+ def _handle_conversation_actions(
838
+ self, conversation_config: AgenticEditConversationConfig
839
+ ) -> bool:
840
+ """
841
+ 处理对话列表和创建新对话的操作
842
+
843
+ Args:
844
+ conversation_config: 对话配置对象
845
+
846
+ Returns:
847
+ bool: 如果处理了特殊操作(LIST或NEW without input)返回True,否则返回False
848
+ """
849
+ if not conversation_config:
850
+ return False
851
+
852
+ console = Console()
853
+
854
+ # 处理LIST操作
855
+ if conversation_config.action == ConversationAction.LIST:
856
+ conversation_manager = get_conversation_manager()
857
+ conversations = conversation_manager.list_conversations()
858
+ # 只保留 conversation_id 和 name 字段
859
+ filtered_conversations = []
860
+ for conv in conversations:
861
+ filtered_conv = {
862
+ "conversation_id": conv.get("conversation_id"),
863
+ "name": conv.get("name"),
864
+ }
865
+ filtered_conversations.append(filtered_conv)
866
+
867
+ # 格式化 JSON 输出,使用 JSON 格式渲染而不是 Markdown
868
+ json_str = json.dumps(filtered_conversations, ensure_ascii=False, indent=4)
869
+ console.print(
870
+ Panel(
871
+ json_str,
872
+ title="🏁 Task Completion",
873
+ border_style="green",
874
+ title_align="left",
875
+ )
876
+ )
877
+ return True
878
+
879
+ # 处理NEW操作且没有用户输入
880
+ if (
881
+ conversation_config.action == ConversationAction.NEW
882
+ and not conversation_config.query.strip()
883
+ ):
884
+ conversation_manager = get_conversation_manager()
885
+ conversation_id = conversation_manager.create_conversation(
886
+ name=conversation_config.query or "New Conversation",
887
+ description=conversation_config.query or "New Conversation",
888
+ )
889
+ conversation_manager.set_current_conversation(conversation_id)
890
+ conversation_message = f"New conversation created: {conversation_manager.get_current_conversation_id()}"
891
+
892
+ # 使用safe console print的简单版本
893
+ try:
894
+ console.print(
895
+ Panel(
896
+ Markdown(conversation_message),
897
+ title="🏁 Task Completion",
898
+ border_style="green",
899
+ title_align="left",
900
+ )
901
+ )
902
+ except Exception:
903
+ # fallback to plain text
904
+ safe_content = conversation_message.replace("[", "\\[").replace(
905
+ "]", "\\]"
906
+ )
907
+ console.print(
908
+ Panel(
909
+ safe_content,
910
+ title="🏁 Task Completion",
911
+ border_style="green",
912
+ title_align="left",
913
+ )
914
+ )
915
+ return True
916
+
917
+ return False
918
+
919
+ def _refresh_completer(self) -> None:
920
+ """刷新命令补全器"""
921
+ try:
922
+ # 延迟导入,避免循环依赖
923
+
924
+ # 获取全局 completer 实例
925
+ # 注意:这里需要访问 auto_coder_runner 模块的全局变量
926
+ # 由于我们不能修改 auto_coder_runner.py,所以这里直接导入
927
+ import autocoder.auto_coder_runner as runner_module
928
+
929
+ if hasattr(runner_module, "completer"):
930
+ runner_module.completer.refresh_files()
931
+ except Exception as e:
932
+ global_logger.warning(f"Failed to refresh completer: {e}")