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,43 @@
1
+ """Shell 相关工具函数"""
2
+
3
+ import platform
4
+ import subprocess
5
+ import asyncio
6
+
7
+
8
+ def get_shell() -> str:
9
+ """获取当前系统的默认 shell"""
10
+ return "/bin/bash" if platform.system() != "Windows" else "cmd.exe"
11
+
12
+
13
+ async def run_shell_command_async(command: str, session=None) -> bool:
14
+ """异步运行 shell 命令
15
+
16
+ Args:
17
+ command: 要执行的命令
18
+ session: PromptSession 对象,如果提供则使用其 app.run_system_command
19
+
20
+ Returns:
21
+ bool: 是否成功执行
22
+ """
23
+ shell = get_shell()
24
+
25
+ if session and hasattr(session, "app"):
26
+ try:
27
+ await session.app.run_system_command(command, wait_for_enter=False)
28
+ return True
29
+ except Exception:
30
+ # 如果异步调用失败,回退到同步方式
31
+ pass
32
+
33
+ # 回退到同步方式
34
+ try:
35
+ if command == shell:
36
+ # 直接启动 shell
37
+ subprocess.call([shell])
38
+ else:
39
+ # 执行命令
40
+ subprocess.call([shell, "-c", command])
41
+ return True
42
+ except Exception:
43
+ return False
@@ -0,0 +1,10 @@
1
+ """
2
+ Terminal V3 - 重构的终端交互模块
3
+
4
+ 这个模块提供了类似 Claude Code 的 TUI 界面,
5
+ 同时支持所有 auto-coder 的功能命令。
6
+ """
7
+
8
+ from .app import AutoCoderChatApp
9
+
10
+ __all__ = ["AutoCoderChatApp"]
@@ -0,0 +1,201 @@
1
+ """主应用类"""
2
+
3
+ import asyncio
4
+ from prompt_toolkit import Application
5
+ from prompt_toolkit.buffer import Buffer
6
+ from prompt_toolkit.history import InMemoryHistory
7
+ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
8
+
9
+ from .models import ConversationBuffer
10
+ from .handlers import CommandHandler
11
+ from .ui import get_styles, create_layout, create_key_bindings
12
+ from autocoder.plugins import PluginManager
13
+
14
+
15
+ class AutoCoderChatApp:
16
+ """Auto-Coder 聊天式 TUI 应用程序"""
17
+
18
+ def __init__(self,plugin_manager: PluginManager):
19
+ # 初始化状态
20
+ self.conversation_buffer = ConversationBuffer()
21
+ self.is_processing = False
22
+ self.current_task = ""
23
+ self.show_shortcuts = False
24
+ self.animation_counter = 0
25
+ self.plugin_manager = plugin_manager
26
+
27
+ # 创建命令处理器
28
+ self.command_handler = CommandHandler(self.conversation_buffer, self)
29
+
30
+ # 创建输入缓冲区
31
+ self.input_buffer = Buffer(
32
+ history=InMemoryHistory(),
33
+ auto_suggest=AutoSuggestFromHistory(),
34
+ enable_history_search=True,
35
+ multiline=False,
36
+ accept_handler=self._handle_input_sync,
37
+ )
38
+
39
+ # 创建布局
40
+ self.layout = create_layout(
41
+ conversation_buffer=self.conversation_buffer,
42
+ input_buffer=self.input_buffer,
43
+ get_prompt_text=self._get_prompt_text,
44
+ get_right_hint=self._get_right_hint,
45
+ get_tips_text=self._get_tips_text,
46
+ get_shortcuts_help_text=self._get_shortcuts_help_text,
47
+ show_shortcuts_condition=lambda: self.show_shortcuts,
48
+ input_has_text_condition=lambda: bool(self.input_buffer.text.strip()),
49
+ )
50
+
51
+ # 创建键绑定
52
+ self.key_bindings = create_key_bindings(self, self.input_buffer, self.plugin_manager)
53
+
54
+ # 创建样式
55
+ self.style = get_styles()
56
+
57
+ # 创建应用程序
58
+ self.app = Application(
59
+ layout=self.layout,
60
+ key_bindings=self.key_bindings,
61
+ style=self.style,
62
+ full_screen=True,
63
+ mouse_support=False,
64
+ color_depth=None,
65
+ refresh_interval=0.5,
66
+ )
67
+
68
+ def _get_tips_text(self):
69
+ """获取提示文本"""
70
+ return [
71
+ ("class:tips", "Tips for getting started:\n\n"),
72
+ (
73
+ "class:tips",
74
+ "1. Type your questions or tasks directly - Auto-Coder will help!\n",
75
+ ),
76
+ ("class:tips", "2. Use /auto <query> for explicit auto command\n"),
77
+ ("class:tips", "3. Use /exit or Ctrl+D to exit the application\n"),
78
+ ("class:tips", "4. Be as specific as possible for the best results\n"),
79
+ ]
80
+
81
+ def _get_prompt_text(self):
82
+ """获取提示符文本"""
83
+ if self.is_processing:
84
+ # 转圈圈动画字符
85
+ spinner_chars = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
86
+ spinner_index = (self.animation_counter // 3) % len(spinner_chars)
87
+ return f"{spinner_chars[spinner_index]} "
88
+ else:
89
+ return "> "
90
+
91
+ def _get_right_hint(self):
92
+ """获取右侧提示信息"""
93
+ if self.show_shortcuts:
94
+ return "Press ? again to hide shortcuts"
95
+ else:
96
+ return "? for shortcuts"
97
+
98
+ def _get_shortcuts_help_text(self):
99
+ """底部快捷键帮助文本"""
100
+ return [
101
+ (
102
+ "class:shortcuts-help",
103
+ "┌─────────────────────── Keyboard Shortcuts ───────────────────────┐\n",
104
+ ),
105
+ (
106
+ "class:shortcuts-help",
107
+ "│ ? Toggle this help Enter Submit command │\n",
108
+ ),
109
+ (
110
+ "class:shortcuts-help",
111
+ "│ Ctrl+C Cancel current task ↑/↓ Navigate history │\n",
112
+ ),
113
+ (
114
+ "class:shortcuts-help",
115
+ "│ Ctrl+D Exit application Ctrl+L Clear conversation │\n",
116
+ ),
117
+ (
118
+ "class:shortcuts-help",
119
+ "└──────────────────────────────────────────────────────────────────┘",
120
+ ),
121
+ ]
122
+
123
+ def invalidate(self):
124
+ """刷新界面 - 转发到内部的 prompt_toolkit Application"""
125
+ self.app.invalidate()
126
+
127
+ def exit(self):
128
+ """退出应用 - 转发到内部的 prompt_toolkit Application"""
129
+ self.app.exit()
130
+
131
+ def _handle_input_sync(self, buffer: Buffer) -> bool:
132
+ """处理用户输入(同步版本)"""
133
+ command = buffer.text.strip()
134
+ buffer.reset()
135
+
136
+ if not command:
137
+ return True
138
+
139
+ # 一旦用户输入了内容,隐藏底部帮助
140
+ if self.show_shortcuts:
141
+ self.show_shortcuts = False
142
+
143
+ # 添加用户消息到对话
144
+ self.conversation_buffer.add_user_message(command)
145
+ self.app.invalidate()
146
+
147
+ # 创建后台任务
148
+ self.app.create_background_task(self._execute_command(command))
149
+
150
+ return True
151
+
152
+ async def _execute_command(self, command: str):
153
+ """执行用户命令"""
154
+ self.is_processing = True
155
+ self.current_task = command[:30] + "..." if len(command) > 30 else command
156
+
157
+ # 开始处理时刷新界面显示转圈圈动画
158
+ self.app.invalidate()
159
+ await asyncio.sleep(0.05)
160
+
161
+ try:
162
+ await self.command_handler.handle_command(command)
163
+ except Exception as e:
164
+ self.conversation_buffer.add_system_message(f"Error: {str(e)}")
165
+ finally:
166
+ self.is_processing = False
167
+ self.current_task = ""
168
+ self.animation_counter = 0
169
+ self.app.invalidate()
170
+
171
+ async def _animation_loop(self):
172
+ """动画循环,定期更新界面以显示转圈圈效果"""
173
+ while True:
174
+ try:
175
+ if self.is_processing:
176
+ self.animation_counter += 1
177
+ self.app.invalidate()
178
+ await asyncio.sleep(0.2)
179
+ else:
180
+ await asyncio.sleep(1.0)
181
+ except asyncio.CancelledError:
182
+ break
183
+ except Exception:
184
+ await asyncio.sleep(1.0)
185
+
186
+ async def run(self):
187
+ """运行 TUI 应用"""
188
+ try:
189
+ # 创建动画更新任务
190
+ animation_task = asyncio.create_task(self._animation_loop())
191
+
192
+ # 运行应用
193
+ await self.app.run_async()
194
+ finally:
195
+ # 确保清理资源
196
+ if "animation_task" in locals():
197
+ animation_task.cancel()
198
+ try:
199
+ await animation_task
200
+ except asyncio.CancelledError:
201
+ pass
@@ -0,0 +1,5 @@
1
+ """命令处理器"""
2
+
3
+ from .command_handler import CommandHandler
4
+
5
+ __all__ = ["CommandHandler"]
@@ -0,0 +1,131 @@
1
+ """统一的命令处理器"""
2
+
3
+ import asyncio
4
+ from typing import TYPE_CHECKING
5
+ from concurrent.futures import ThreadPoolExecutor
6
+ from autocoder.common.global_cancel import global_cancel, CancelRequestedException
7
+ from autocoder.events.event_manager_singleton import gengerate_event_file_path
8
+ from autocoder.auto_coder_runner import configure
9
+ from autocoder.inner.agentic import RunAgentic
10
+ from autocoder.common.v2.agent.agentic_edit_types import ConversationAction
11
+ from ..models import ConversationBuffer
12
+
13
+ if TYPE_CHECKING:
14
+ from ..app import AutoCoderChatApp
15
+
16
+
17
+ class CommandHandler:
18
+ """处理所有命令的统一处理器"""
19
+
20
+ def __init__(
21
+ self, conversation_buffer: ConversationBuffer, app_instance: "AutoCoderChatApp"
22
+ ):
23
+ self.conversation_buffer = conversation_buffer
24
+ self.app = app_instance
25
+ # 创建线程池用于执行同步生成器
26
+ self.executor = ThreadPoolExecutor(
27
+ max_workers=1, thread_name_prefix="agentic-worker"
28
+ )
29
+
30
+ async def handle_command(self, command: str):
31
+ """处理命令"""
32
+ try:
33
+ # 退出命令
34
+ if command in ["exit", "/exit"]:
35
+ self.app.exit()
36
+
37
+ # /auto 命令或直接输入查询
38
+ elif command.startswith("/auto") or not command.startswith("/"):
39
+ # 处理 /auto 命令或直接的查询
40
+ if not command:
41
+ self.conversation_buffer.add_system_message(
42
+ "Please provide a query"
43
+ )
44
+ else:
45
+ await self._execute_auto_command(command)
46
+
47
+ # 未知命令
48
+ else:
49
+ self.conversation_buffer.add_system_message(
50
+ f"Unknown command: {command}. Use /auto <query> or /exit"
51
+ )
52
+
53
+ except Exception as e:
54
+ self.conversation_buffer.add_system_message(f"Error: {str(e)}")
55
+
56
+ async def _execute_auto_command(self, query: str):
57
+ """执行 /auto 命令(使用线程池避免阻塞事件循环)"""
58
+ event_file, _ = gengerate_event_file_path()
59
+ global_cancel.register_token(event_file)
60
+ configure(f"event_file:{event_file}")
61
+
62
+ self.app.invalidate()
63
+
64
+ # 创建事件队列用于线程和协程之间通信
65
+ event_queue = asyncio.Queue()
66
+ loop = asyncio.get_event_loop()
67
+
68
+ def run_agentic_in_thread():
69
+ """在线程中运行同步生成器"""
70
+ try:
71
+ agentic = RunAgentic()
72
+ for event in agentic.run_with_events(
73
+ query=query,
74
+ pre_commit=False,
75
+ post_commit=False,
76
+ pr=False,
77
+ cancel_token=event_file,
78
+ conversation_action=ConversationAction.RESUME,
79
+ ):
80
+ # 将事件放入队列(线程安全)
81
+ asyncio.run_coroutine_threadsafe(
82
+ event_queue.put(("event", event)), loop
83
+ )
84
+ except CancelRequestedException:
85
+ # 取消请求异常
86
+ asyncio.run_coroutine_threadsafe(
87
+ event_queue.put(("cancelled", None)), loop
88
+ )
89
+ except Exception as e:
90
+ # 其他异常
91
+ asyncio.run_coroutine_threadsafe(event_queue.put(("error", e)), loop)
92
+ finally:
93
+ # 发送结束信号
94
+ asyncio.run_coroutine_threadsafe(event_queue.put(("done", None)), loop)
95
+
96
+ try:
97
+ # 在线程池中启动生成器
98
+ loop.run_in_executor(self.executor, run_agentic_in_thread)
99
+
100
+ # 异步消费事件队列
101
+ while True:
102
+ msg_type, data = await event_queue.get()
103
+
104
+ if msg_type == "event":
105
+ # 处理事件
106
+ self.conversation_buffer.add_event(data)
107
+ self.app.invalidate()
108
+ # 让出控制权,确保 Ctrl+C 能被及时处理
109
+ await asyncio.sleep(0)
110
+
111
+ elif msg_type == "cancelled":
112
+ # 任务被取消
113
+ self.conversation_buffer.add_system_message("Task cancelled")
114
+ self.app.invalidate()
115
+ break
116
+
117
+ elif msg_type == "error":
118
+ # 发生错误
119
+ self.conversation_buffer.add_system_message(f"Error: {str(data)}")
120
+ self.app.invalidate()
121
+ break
122
+
123
+ elif msg_type == "done":
124
+ # 正常结束
125
+ break
126
+
127
+ except Exception as e:
128
+ self.conversation_buffer.add_system_message(f"Error: {str(e)}")
129
+ finally:
130
+ global_cancel.reset_token(event_file)
131
+ self.app.invalidate()
@@ -0,0 +1,6 @@
1
+ """消息和数据模型"""
2
+
3
+ from .message import ChatMessage
4
+ from .conversation_buffer import ConversationBuffer
5
+
6
+ __all__ = ["ChatMessage", "ConversationBuffer"]
@@ -0,0 +1,214 @@
1
+ """对话缓冲区管理"""
2
+
3
+ import os
4
+ from typing import List, Optional
5
+ from .message import ChatMessage
6
+ from autocoder.common.v2.agent.agentic_edit_types import (
7
+ ConversationIdEvent,
8
+ TokenUsageEvent,
9
+ WindowLengthChangeEvent,
10
+ LLMThinkingEvent,
11
+ LLMOutputEvent,
12
+ ToolCallEvent,
13
+ ToolResultEvent,
14
+ PlanModeRespondEvent,
15
+ PreCommitEvent,
16
+ CommitEvent,
17
+ PullRequestEvent,
18
+ CompletionEvent,
19
+ ErrorEvent,
20
+ )
21
+
22
+
23
+ class ConversationBuffer:
24
+ """对话缓冲区,类似聊天应用的消息列表"""
25
+
26
+ def __init__(self, max_messages: int = 200):
27
+ self.max_messages = max_messages
28
+ self.messages: List[ChatMessage] = []
29
+ self.welcome_messages: List[ChatMessage] = []
30
+ self.token_stats = {"input_tokens": 0, "output_tokens": 0, "model": ""}
31
+
32
+ # 强类型属性定义
33
+ self._thinking_buffer: Optional[str] = None
34
+ self._current_response: Optional[str] = None
35
+
36
+ self._init_welcome_messages()
37
+
38
+ def _init_welcome_messages(self):
39
+ """初始化欢迎消息"""
40
+ self.welcome_messages.append(
41
+ ChatMessage("✦ Welcome to Auto-Coder.Chat!", "welcome")
42
+ )
43
+ self.welcome_messages.append(ChatMessage("", "welcome"))
44
+ self.welcome_messages.append(
45
+ ChatMessage("/help for help, /status to view current setup", "welcome")
46
+ )
47
+ self.welcome_messages.append(ChatMessage("", "welcome"))
48
+ cwd = os.getcwd()
49
+ self.welcome_messages.append(ChatMessage(f"cwd: {cwd}", "welcome"))
50
+ self.welcome_messages.append(ChatMessage("", "welcome"))
51
+
52
+ def get_welcome_text(self):
53
+ """获取欢迎消息的格式化文本"""
54
+ result = []
55
+ for msg in self.welcome_messages:
56
+ result.extend(msg.to_formatted_text())
57
+ return result
58
+
59
+ def add_user_message(self, content: str):
60
+ """添加用户消息"""
61
+ self.messages.append(ChatMessage(content, "user"))
62
+ self._trim_messages()
63
+
64
+ def add_assistant_message(self, content: str):
65
+ """添加助手消息"""
66
+ self.messages.append(ChatMessage(content, "assistant"))
67
+ self._trim_messages()
68
+
69
+ def add_system_message(self, content: str, ansi: bool = False):
70
+ """添加系统消息"""
71
+ self.messages.append(ChatMessage(content, "system", ansi=ansi))
72
+ self._trim_messages()
73
+
74
+ def add_event(self, event):
75
+ """处理 SdkRunner 事件 - 参考 terminal_runner.py 的格式化方式"""
76
+ if isinstance(event, ConversationIdEvent):
77
+ # 对话ID事件静默处理,不显示
78
+ pass
79
+
80
+ elif isinstance(event, TokenUsageEvent):
81
+ meta = event.usage
82
+ self.token_stats["input_tokens"] += meta.input_tokens_count
83
+ self.token_stats["output_tokens"] += meta.generated_tokens_count
84
+ # SingleOutputMeta 没有 model_name 属性,保持原有逻辑
85
+ # 模型名称通过其他方式获取
86
+
87
+ elif isinstance(event, WindowLengthChangeEvent):
88
+ # 显示 token 使用情况
89
+ if event.tokens_used > event.pruned_tokens_used:
90
+ self.add_system_message(
91
+ f"Conversation tokens: {event.tokens_used} -> {event.pruned_tokens_used} "
92
+ f"(round: {event.conversation_round})"
93
+ )
94
+
95
+ elif isinstance(event, LLMThinkingEvent):
96
+ # 实时显示思考过程(灰色显示)
97
+ if self._thinking_buffer is not None:
98
+ self._thinking_buffer += event.text
99
+ # 更新最后一条思考消息
100
+ if self.messages and self.messages[-1]._is_thinking:
101
+ self.messages[-1].content = self._thinking_buffer
102
+ else:
103
+ msg = ChatMessage(self._thinking_buffer, "system")
104
+ msg._is_thinking = True
105
+ self.messages.append(msg)
106
+ else:
107
+ self._thinking_buffer = event.text
108
+ msg = ChatMessage(self._thinking_buffer, "system")
109
+ msg._is_thinking = True
110
+ self.messages.append(msg)
111
+
112
+ elif isinstance(event, LLMOutputEvent):
113
+ # 清除思考缓冲区(如果有)
114
+ if self._thinking_buffer is not None:
115
+ self._thinking_buffer = None
116
+
117
+ # LLM 输出直接添加为助手消息(流式更新)
118
+ if self._current_response is not None:
119
+ self._current_response += event.text
120
+ if self.messages and self.messages[-1].role == "assistant":
121
+ self.messages[-1].content = self._current_response
122
+ else:
123
+ self.messages.append(
124
+ ChatMessage(self._current_response, "assistant")
125
+ )
126
+ else:
127
+ self._current_response = event.text
128
+ self.messages.append(ChatMessage(self._current_response, "assistant"))
129
+
130
+ elif isinstance(event, ToolCallEvent):
131
+ # 使用简洁的工具调用显示
132
+ from .tool_display import get_tool_simple_display
133
+
134
+ tool_display = get_tool_simple_display(event.tool)
135
+ self.add_system_message(f"🔧 {tool_display}")
136
+
137
+ elif isinstance(event, ToolResultEvent):
138
+ # 显示工具结果(简洁版本)
139
+ from .tool_display import get_tool_result_display
140
+
141
+ result = event.result
142
+ result_display = get_tool_result_display(
143
+ event.tool_name,
144
+ result.success,
145
+ result.message if not result.success else None,
146
+ )
147
+ self.add_system_message(result_display)
148
+
149
+ elif isinstance(event, PlanModeRespondEvent):
150
+ try:
151
+ response_text = event.completion.response
152
+ if response_text:
153
+ self.add_assistant_message(response_text)
154
+ except Exception:
155
+ pass
156
+
157
+ elif isinstance(event, PreCommitEvent):
158
+ if event.commit_result:
159
+ self.add_system_message("📦 Changes staged")
160
+
161
+ elif isinstance(event, CommitEvent):
162
+ if event.commit_result and event.commit_result.success:
163
+ self.add_system_message(
164
+ f"✅ Committed: {event.commit_result.commit_hash[:8]}"
165
+ )
166
+
167
+ elif isinstance(event, PullRequestEvent):
168
+ if event.pull_request_result and event.pull_request_result.success:
169
+ self.add_system_message(
170
+ f"🎉 PR #{event.pull_request_result.pr_number} created"
171
+ )
172
+
173
+ elif isinstance(event, CompletionEvent):
174
+ # 清除思考和响应缓冲区
175
+ if self._thinking_buffer is not None:
176
+ self._thinking_buffer = None
177
+
178
+ if self._current_response is not None:
179
+ if self.messages and self.messages[-1].role == "assistant":
180
+ self.messages[-1].content = self._current_response
181
+ else:
182
+ self.add_assistant_message(self._current_response)
183
+ self._current_response = None
184
+ else:
185
+ try:
186
+ result_text = event.completion.result
187
+ if result_text:
188
+ self.add_assistant_message(result_text)
189
+ except Exception:
190
+ pass
191
+
192
+ elif isinstance(event, ErrorEvent):
193
+ self.add_system_message(f"❌ Error: {event.message}")
194
+
195
+ def _trim_messages(self):
196
+ """保持消息数量在限制内"""
197
+ if len(self.messages) > self.max_messages:
198
+ self.messages = self.messages[-self.max_messages :]
199
+
200
+ def get_formatted_text(self):
201
+ """获取格式化的文本用于显示"""
202
+ if not self.messages:
203
+ return [("", "")]
204
+
205
+ result = []
206
+ for message in self.messages:
207
+ result.extend(message.to_formatted_text())
208
+ return result
209
+
210
+ def clear_conversation(self):
211
+ """清空对话历史"""
212
+ self.messages = []
213
+ self._current_response = None
214
+ self._thinking_buffer = None
@@ -0,0 +1,50 @@
1
+ """聊天消息模型"""
2
+
3
+ from datetime import datetime
4
+ from typing import List, Tuple
5
+ from prompt_toolkit.formatted_text import ANSI, to_formatted_text
6
+
7
+
8
+ class ChatMessage:
9
+ """聊天消息类"""
10
+
11
+ def __init__(
12
+ self,
13
+ content: str,
14
+ role: str = "assistant",
15
+ timestamp: datetime = None,
16
+ ansi: bool = False,
17
+ ):
18
+ self.content = content
19
+ self.role = role # user, assistant, system, welcome
20
+ self.timestamp = timestamp or datetime.now()
21
+ self.is_ansi = ansi
22
+ self._is_thinking: bool = False
23
+
24
+ def to_formatted_text(self) -> List[Tuple[str, str]]:
25
+ """转换为 FormattedText 格式"""
26
+ if self.is_ansi:
27
+ # 直接使用 ANSI 渲染(不加前缀圆点,避免破坏颜色布局)
28
+ return list(to_formatted_text(ANSI(self.content))) + [("", "\n")]
29
+
30
+ if self.role == "welcome":
31
+ # 欢迎消息不显示时间戳
32
+ return [("class:welcome", self.content), ("", "\n")]
33
+ elif self.role == "system":
34
+ return [
35
+ ("class:system", "● "),
36
+ ("class:system-text", self.content),
37
+ ("", "\n"),
38
+ ]
39
+ elif self.role == "user":
40
+ return [
41
+ ("class:user-prompt", "> "),
42
+ ("class:user-text", self.content),
43
+ ("", "\n"),
44
+ ]
45
+ else: # assistant
46
+ return [
47
+ ("class:assistant", "● "),
48
+ ("class:assistant-text", self.content),
49
+ ("", "\n"),
50
+ ]