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,77 @@
1
+ """后台任务:监控全局状态或执行其他后台逻辑"""
2
+
3
+ import asyncio
4
+ from pathlib import Path
5
+
6
+
7
+ async def background_task(stop_event: asyncio.Event, session=None, debug=False):
8
+ """后台任务:可以用于监控系统状态、清理任务等"""
9
+ counter = 0
10
+ toolbar_refresh_counter = 0
11
+ last_async_task_count = 0
12
+
13
+ # 配置刷新频率(秒)
14
+ TOOLBAR_REFRESH_INTERVAL = 5 # 默认5秒刷新一次
15
+ FAST_REFRESH_INTERVAL = 1 # 有异步任务时1秒刷新一次
16
+
17
+ while not stop_event.is_set():
18
+ try:
19
+ # 检查是否有需要处理的后台任务
20
+ # 这里可以添加系统监控逻辑
21
+ counter += 1
22
+ toolbar_refresh_counter += 1
23
+
24
+ # 检查当前异步任务状态,决定刷新频率
25
+ current_async_task_count = 0
26
+ try:
27
+ from autocoder.sdk.async_runner.task_metadata import (
28
+ TaskMetadataManager,
29
+ )
30
+
31
+ async_agent_dir = Path.home() / ".auto-coder" / "async_agent"
32
+ meta_dir = async_agent_dir / "meta"
33
+
34
+ if meta_dir.exists():
35
+ metadata_manager = TaskMetadataManager(str(meta_dir))
36
+ summary = metadata_manager.get_task_summary()
37
+ current_async_task_count = summary.get("running", 0)
38
+ except Exception:
39
+ # 静默处理异常
40
+ pass
41
+
42
+ # 智能刷新:有异步任务时更频繁刷新,无任务时降低刷新频率
43
+ should_refresh = False
44
+ if current_async_task_count > 0:
45
+ # 有异步任务时,每秒刷新
46
+ should_refresh = toolbar_refresh_counter >= FAST_REFRESH_INTERVAL
47
+ else:
48
+ # 无异步任务时,每5秒刷新
49
+ should_refresh = toolbar_refresh_counter >= TOOLBAR_REFRESH_INTERVAL
50
+
51
+ # 任务数量变化时立即刷新
52
+ if current_async_task_count != last_async_task_count:
53
+ should_refresh = True
54
+ last_async_task_count = current_async_task_count
55
+
56
+ # 执行工具栏刷新
57
+ if should_refresh and session and hasattr(session, "app"):
58
+ try:
59
+ session.app.invalidate()
60
+ toolbar_refresh_counter = 0
61
+ except Exception:
62
+ # 静默处理刷新异常,不影响后台任务运行
63
+ pass
64
+
65
+ # 每60秒执行一次清理
66
+ if counter % 60 == 0:
67
+ # 执行一些后台清理任务
68
+ pass
69
+
70
+ await asyncio.sleep(1)
71
+ except asyncio.CancelledError:
72
+ break
73
+ except Exception as e:
74
+ # 后台任务出错时,不要让整个应用崩溃
75
+ if debug:
76
+ print(f"Background task error: {e}")
77
+ await asyncio.sleep(5) # 出错后等待5秒再继续
@@ -0,0 +1,70 @@
1
+ """任务事件和取消注册表"""
2
+
3
+ import asyncio
4
+ from typing import Dict
5
+
6
+
7
+ class TaskEvent:
8
+ """任务事件状态管理器"""
9
+
10
+ def __init__(self):
11
+ self.state = "idle" # idle, pending, started, running, completed
12
+ self._event = asyncio.Event()
13
+ self._event.set() # 初始状态为可用
14
+
15
+ def set_state(self, state: str):
16
+ """设置任务状态"""
17
+ self.state = state
18
+ if state == "completed":
19
+ self._event.set()
20
+ else:
21
+ self._event.clear()
22
+
23
+ def get_state(self) -> str:
24
+ """获取当前状态"""
25
+ return self.state
26
+
27
+ def is_completed(self) -> bool:
28
+ """检查是否完成"""
29
+ return self.state == "completed"
30
+
31
+ def is_running(self) -> bool:
32
+ """检查是否正在运行"""
33
+ return self.state in ["started", "running"]
34
+
35
+ async def wait(self):
36
+ """等待任务完成"""
37
+ await self._event.wait()
38
+
39
+ def clear(self):
40
+ """清除完成状态,重置为pending"""
41
+ self.set_state("idle")
42
+
43
+
44
+ class CancellationRegistry:
45
+ """任务取消注册表,用于集中管理和取消活跃的异步任务"""
46
+
47
+ def __init__(self) -> None:
48
+ self._tasks: Dict[str, asyncio.Task] = {}
49
+
50
+ def register(self, token: str, task: asyncio.Task) -> None:
51
+ """注册一个任务"""
52
+ self._tasks[token] = task
53
+
54
+ def unregister(self, token: str) -> None:
55
+ """注销一个任务"""
56
+ self._tasks.pop(token, None)
57
+
58
+ async def cancel_all(self) -> None:
59
+ """取消所有活跃任务"""
60
+ for t in list(self._tasks.values()):
61
+ if not t.done():
62
+ t.cancel()
63
+ # 等待所有任务完成(吞掉 CancelledError)
64
+ for token, t in list(self._tasks.items()):
65
+ try:
66
+ await t
67
+ except asyncio.CancelledError:
68
+ pass
69
+ finally:
70
+ self._tasks.pop(token, None)
@@ -0,0 +1,13 @@
1
+ """UI 组件模块"""
2
+
3
+ from .completer import EnhancedCompleter
4
+ from .keybindings import setup_keybindings
5
+ from .toolbar import get_bottom_toolbar_func
6
+ from .session import create_session
7
+
8
+ __all__ = [
9
+ "EnhancedCompleter",
10
+ "setup_keybindings",
11
+ "get_bottom_toolbar_func",
12
+ "create_session",
13
+ ]
@@ -0,0 +1,268 @@
1
+ """增强的命令补全器"""
2
+
3
+ import asyncio
4
+ from concurrent.futures import ThreadPoolExecutor
5
+ from prompt_toolkit.completion import Completer, Completion
6
+ from typing import List, Set
7
+ import os
8
+
9
+
10
+ class EnhancedCompleter(Completer):
11
+ """结合内置补全器和插件补全功能的增强补全器"""
12
+
13
+ def __init__(self, base_completer: Completer, plugin_manager):
14
+ self.base_completer: Completer = base_completer
15
+ self.plugin_manager = plugin_manager
16
+ self._custom_commands_cache: Set[str] = set()
17
+ self._cache_valid = False
18
+
19
+ def _get_custom_commands(self) -> List[str]:
20
+ """获取自定义命令列表(从 .autocodercommands 目录)"""
21
+ if self._cache_valid and self._custom_commands_cache:
22
+ return sorted(list(self._custom_commands_cache))
23
+
24
+ try:
25
+ from autocoder.common.command_file_manager.manager import CommandManager
26
+
27
+ # 创建命令管理器
28
+ command_manager = CommandManager()
29
+
30
+ # 列出所有命令文件
31
+ result = command_manager.list_command_files(recursive=True)
32
+
33
+ if result.success:
34
+ commands = set()
35
+ for file_name in result.command_files:
36
+ # 去掉 .md 后缀和路径前缀,只保留命令名
37
+ command_name = os.path.basename(file_name)
38
+ if command_name.endswith('.md'):
39
+ command_name = command_name[:-3]
40
+ # 添加 / 前缀形成完整命令
41
+ commands.add(f"/{command_name}")
42
+
43
+ self._custom_commands_cache = commands
44
+ self._cache_valid = True
45
+ return sorted(list(commands))
46
+ except Exception as e:
47
+ # 静默处理异常,返回空列表
48
+ pass
49
+
50
+ return []
51
+
52
+ def get_completions(self, document, complete_event):
53
+ # 获取当前输入的文本
54
+ text_before_cursor = document.text_before_cursor.lstrip()
55
+
56
+ # 只有当我们需要处理命令补全时才进行处理
57
+ if text_before_cursor.startswith("/"):
58
+
59
+ # 获取当前输入的命令前缀
60
+ current_input = text_before_cursor
61
+ # 检查是否需要动态补全
62
+ if " " in current_input:
63
+ # 将连续的空格替换为单个空格
64
+ _input_one_space = " ".join(current_input.split())
65
+ # 先尝试动态补全特定命令
66
+ dynamic_cmds = self.plugin_manager.get_dynamic_cmds()
67
+ for dynamic_cmd in dynamic_cmds:
68
+ if _input_one_space.startswith(dynamic_cmd):
69
+ # 使用 PluginManager 处理动态补全,通常是用于命令或子命令动态的参数值列表的补全
70
+ completions = self.plugin_manager.process_dynamic_completions(
71
+ dynamic_cmd, current_input
72
+ )
73
+ for completion_text, display_text in completions:
74
+ yield Completion(
75
+ completion_text,
76
+ start_position=0,
77
+ display=display_text,
78
+ )
79
+ return
80
+
81
+ # 如果不是特定命令,检查一般命令 + 空格的情况, 通常是用于固定的下级子命令列表的补全
82
+ cmd_parts = current_input.split(maxsplit=1)
83
+ base_cmd = cmd_parts[0]
84
+
85
+ # 获取插件命令补全
86
+ plugin_completions_dict = self.plugin_manager.get_plugin_completions()
87
+
88
+ # 如果命令存在于补全字典中,进行处理
89
+ if base_cmd in plugin_completions_dict:
90
+ yield from self._process_command_completions(
91
+ base_cmd, current_input, plugin_completions_dict[base_cmd]
92
+ )
93
+ return
94
+ # 处理直接命令补全 - 如果输入不包含空格,匹配整个命令
95
+ # 1. 插件和内置命令
96
+ for command in self.plugin_manager.get_all_commands_with_prefix(
97
+ current_input
98
+ ):
99
+ yield Completion(
100
+ command[len(current_input) :],
101
+ start_position=0,
102
+ display=command,
103
+ )
104
+
105
+ # 2. 自定义命令(从 .autocodercommands 目录)
106
+ custom_commands = self._get_custom_commands()
107
+ for command in custom_commands:
108
+ if command.startswith(current_input):
109
+ yield Completion(
110
+ command[len(current_input) :],
111
+ start_position=0,
112
+ display=command,
113
+ )
114
+
115
+ # 获取并返回基础补全器的补全
116
+ if self.base_completer:
117
+ for completion in self.base_completer.get_completions(
118
+ document, complete_event
119
+ ):
120
+ yield completion
121
+
122
+ def _process_command_completions(self, command, current_input, completions):
123
+ """处理通用命令补全"""
124
+ # 提取子命令前缀
125
+ parts = current_input.split(maxsplit=1)
126
+ cmd_prefix = ""
127
+ if len(parts) > 1:
128
+ cmd_prefix = parts[1].strip()
129
+
130
+ # 对于任何命令,当子命令前缀为空或与补全选项匹配时,都显示补全
131
+ for completion in completions:
132
+ if cmd_prefix == "" or completion.startswith(cmd_prefix):
133
+ # 只提供未输入部分作为补全
134
+ remaining_text = completion[len(cmd_prefix) :]
135
+ # 修复:设置 start_position 为 0,这样不会覆盖用户已输入的部分
136
+ start_position = 0
137
+ yield Completion(
138
+ remaining_text,
139
+ start_position=start_position,
140
+ display=completion,
141
+ )
142
+
143
+ async def get_completions_async(self, document, complete_event):
144
+ """异步获取补全内容。
145
+
146
+ 使用 asyncio.run_in_executor 来异步执行耗时的补全操作,
147
+ 避免阻塞主线程导致输入卡顿。
148
+ """
149
+ # 获取当前输入的文本
150
+ text_before_cursor = document.text_before_cursor.lstrip()
151
+
152
+ # 只有当我们需要处理命令补全时才进行处理
153
+ if text_before_cursor.startswith("/"):
154
+ # 获取当前输入的命令前缀
155
+ current_input = text_before_cursor
156
+
157
+ # 使用线程池执行器来异步执行耗时操作
158
+ loop = asyncio.get_event_loop()
159
+ executor = ThreadPoolExecutor(max_workers=1)
160
+
161
+ try:
162
+ # 检查是否需要动态补全
163
+ if " " in current_input:
164
+ # 将连续的空格替换为单个空格
165
+ _input_one_space = " ".join(current_input.split())
166
+
167
+ # 异步获取动态命令列表
168
+ dynamic_cmds = await loop.run_in_executor(
169
+ executor, self.plugin_manager.get_dynamic_cmds
170
+ )
171
+
172
+ for dynamic_cmd in dynamic_cmds:
173
+ if _input_one_space.startswith(dynamic_cmd):
174
+ # 异步处理动态补全
175
+ completions = await loop.run_in_executor(
176
+ executor,
177
+ self.plugin_manager.process_dynamic_completions,
178
+ dynamic_cmd,
179
+ current_input,
180
+ )
181
+ for completion_text, display_text in completions:
182
+ yield Completion(
183
+ completion_text,
184
+ start_position=0,
185
+ display=display_text,
186
+ )
187
+ return
188
+
189
+ # 如果不是特定命令,检查一般命令 + 空格的情况
190
+ cmd_parts = current_input.split(maxsplit=1)
191
+ base_cmd = cmd_parts[0]
192
+
193
+ # 异步获取插件命令补全
194
+ plugin_completions_dict = await loop.run_in_executor(
195
+ executor, self.plugin_manager.get_plugin_completions
196
+ )
197
+
198
+ # 如果命令存在于补全字典中,进行处理
199
+ if base_cmd in plugin_completions_dict:
200
+ # 异步处理命令补全
201
+ completions_list = await loop.run_in_executor(
202
+ executor,
203
+ self._get_command_completions_list,
204
+ base_cmd,
205
+ current_input,
206
+ plugin_completions_dict[base_cmd],
207
+ )
208
+ for completion in completions_list:
209
+ yield completion
210
+ return
211
+ else:
212
+ # 处理直接命令补全 - 异步获取所有匹配的命令
213
+ # 1. 插件和内置命令
214
+ commands = await loop.run_in_executor(
215
+ executor,
216
+ self.plugin_manager.get_all_commands_with_prefix,
217
+ current_input,
218
+ )
219
+ for command in commands:
220
+ yield Completion(
221
+ command[len(current_input) :],
222
+ start_position=0,
223
+ display=command,
224
+ )
225
+
226
+ # 2. 自定义命令(从 .autocodercommands 目录)
227
+ custom_commands = await loop.run_in_executor(
228
+ executor,
229
+ self._get_custom_commands,
230
+ )
231
+ for command in custom_commands:
232
+ if command.startswith(current_input):
233
+ yield Completion(
234
+ command[len(current_input) :],
235
+ start_position=0,
236
+ display=command,
237
+ )
238
+ finally:
239
+ executor.shutdown(wait=False)
240
+
241
+ # 异步获取基础补全器的补全
242
+ if self.base_completer:
243
+ # 如果基础补全器支持异步方法,优先使用
244
+ if hasattr(self.base_completer, "get_completions_async"):
245
+ async for completion in self.base_completer.get_completions_async(
246
+ document, complete_event
247
+ ):
248
+ yield completion
249
+ else:
250
+ # 否则在线程池中运行同步方法
251
+ loop = asyncio.get_event_loop()
252
+ executor = ThreadPoolExecutor(max_workers=1)
253
+ try:
254
+ completions = await loop.run_in_executor(
255
+ executor,
256
+ list,
257
+ self.base_completer.get_completions(document, complete_event),
258
+ )
259
+ for completion in completions:
260
+ yield completion
261
+ finally:
262
+ executor.shutdown(wait=False)
263
+
264
+ def _get_command_completions_list(self, command, current_input, completions):
265
+ """获取命令补全列表(用于异步执行)"""
266
+ return list(
267
+ self._process_command_completions(command, current_input, completions)
268
+ )
@@ -0,0 +1,75 @@
1
+ """键盘绑定设置"""
2
+
3
+ from prompt_toolkit.key_binding import KeyBindings
4
+ from autocoder.common.terminal_paste import register_paste_handler
5
+
6
+
7
+ def setup_keybindings(
8
+ plugin_manager,
9
+ voice_input_func,
10
+ cycle_mode_func,
11
+ toggle_human_as_model_func,
12
+ toggle_agentic_mode_func,
13
+ configure_func,
14
+ ):
15
+ """设置所有键盘绑定
16
+
17
+ Args:
18
+ plugin_manager: 插件管理器
19
+ voice_input_func: 语音输入函数
20
+ cycle_mode_func: 模式切换函数
21
+ toggle_human_as_model_func: 切换 human_as_model 函数
22
+ toggle_agentic_mode_func: 切换 agentic_mode 函数
23
+ configure_func: 配置函数
24
+
25
+ Returns:
26
+ KeyBindings: 配置好的键盘绑定对象
27
+ """
28
+ kb = KeyBindings()
29
+
30
+ # 捕获 Ctrl+C 和 Ctrl+D
31
+ @kb.add("c-c")
32
+ def _(event):
33
+ # 如果正在搜索,只重置搜索状态
34
+ if event.app.layout.is_searching:
35
+ event.app.current_buffer.history_search_text = None
36
+ event.app.current_buffer.reset()
37
+
38
+
39
+ @kb.add("c-d")
40
+ def _(event):
41
+ event.app.exit(exception=EOFError)
42
+
43
+ @kb.add("tab")
44
+ def _(event):
45
+ b = event.current_buffer
46
+ if b.complete_state:
47
+ b.complete_next()
48
+ else:
49
+ b.start_completion(select_first=False)
50
+
51
+ @kb.add("c-g")
52
+ def _(event):
53
+ transcription = voice_input_func()
54
+ if transcription:
55
+ event.app.current_buffer.insert_text(transcription)
56
+
57
+ @kb.add("c-k")
58
+ def _(event):
59
+ cycle_mode_func()
60
+ event.app.invalidate()
61
+
62
+ @kb.add("c-n")
63
+ def _(event):
64
+ new_status_bool = toggle_human_as_model_func()
65
+ new_status = "true" if new_status_bool else "false"
66
+ configure_func(f"human_as_model:{new_status}", skip_print=True)
67
+ event.app.invalidate()
68
+
69
+ # 注册粘贴处理器
70
+ register_paste_handler(kb)
71
+
72
+ # 应用插件的键盘绑定
73
+ plugin_manager.apply_keybindings(kb)
74
+
75
+ return kb
@@ -0,0 +1,41 @@
1
+ """会话管理"""
2
+
3
+ from pathlib import Path
4
+ from prompt_toolkit import PromptSession
5
+ from prompt_toolkit.history import FileHistory
6
+ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
7
+
8
+
9
+ def create_session(completer, key_bindings, bottom_toolbar_func):
10
+ """创建 PromptSession
11
+
12
+ Args:
13
+ completer: 补全器
14
+ key_bindings: 键盘绑定
15
+ bottom_toolbar_func: 底部工具栏函数
16
+
17
+ Returns:
18
+ PromptSession: 配置好的会话对象
19
+ """
20
+ # 定义历史文件路径,使用 pathlib
21
+ history_file_path = (
22
+ Path.cwd()
23
+ / ".auto-coder"
24
+ / "auto-coder.chat"
25
+ / "history"
26
+ / "command_history.txt"
27
+ )
28
+ history_file_path.parent.mkdir(parents=True, exist_ok=True)
29
+
30
+ # 创建会话
31
+ session = PromptSession(
32
+ history=FileHistory(str(history_file_path)),
33
+ auto_suggest=AutoSuggestFromHistory(),
34
+ enable_history_search=False,
35
+ completer=completer,
36
+ complete_while_typing=False,
37
+ key_bindings=key_bindings,
38
+ bottom_toolbar=bottom_toolbar_func,
39
+ )
40
+
41
+ return session
@@ -0,0 +1,64 @@
1
+ """底部工具栏"""
2
+
3
+ import os
4
+ from pathlib import Path
5
+
6
+
7
+ def get_bottom_toolbar_func(
8
+ get_mode_func, get_human_as_model_string_func, get_agentic_mode_string_func, plugin_manager
9
+ ):
10
+ """创建底部工具栏函数
11
+
12
+ Args:
13
+ get_mode_func: 获取当前模式的函数
14
+ get_human_as_model_string_func: 获取 human_as_model 字符串的函数
15
+ get_agentic_mode_string_func: 获取 agentic_mode 字符串的函数
16
+ plugin_manager: 插件管理器
17
+
18
+ Returns:
19
+ callable: 返回工具栏内容的函数
20
+ """
21
+
22
+ def get_bottom_toolbar():
23
+ mode = get_mode_func()
24
+ human_as_model = get_human_as_model_string_func()
25
+ agentic_mode = get_agentic_mode_string_func()
26
+ MODES = {
27
+ "normal": "normal",
28
+ "auto_detect": "nature language auto detect",
29
+ "voice_input": "voice input",
30
+ "shell": "shell",
31
+ }
32
+ if mode not in MODES:
33
+ mode = "auto_detect"
34
+ pwd = os.getcwd()
35
+ pwd_parts = pwd.split(os.sep)
36
+ if len(pwd_parts) > 3:
37
+ pwd = os.sep.join(pwd_parts[-3:])
38
+
39
+ plugin_info = (
40
+ f"Plugins: {len(plugin_manager.plugins)}" if plugin_manager.plugins else ""
41
+ )
42
+
43
+ # 获取正在运行的 async 任务数量
44
+ async_tasks_info = ""
45
+ try:
46
+ from autocoder.sdk.async_runner.task_metadata import TaskMetadataManager
47
+
48
+ async_agent_dir = Path.home() / ".auto-coder" / "async_agent"
49
+ meta_dir = async_agent_dir / "meta"
50
+
51
+ if meta_dir.exists():
52
+ metadata_manager = TaskMetadataManager(str(meta_dir))
53
+ summary = metadata_manager.get_task_summary()
54
+ running_count = summary.get("running", 0)
55
+
56
+ if running_count > 0:
57
+ async_tasks_info = f" | Async Tasks: 🔄 {running_count}"
58
+ except Exception:
59
+ # 静默处理异常,不影响底部工具栏的显示
60
+ pass
61
+
62
+ return f"PWD: {pwd} \nInput: {MODES[mode]} | Human as Model: {human_as_model} | Agentic Mode: {agentic_mode} | {plugin_info}{async_tasks_info}"
63
+
64
+ return get_bottom_toolbar
@@ -0,0 +1,13 @@
1
+ """工具函数模块"""
2
+
3
+ from .paths import get_history_path, get_async_agent_meta_dir
4
+ from .shell import get_shell, run_shell_command_async
5
+ from .errors import print_error
6
+
7
+ __all__ = [
8
+ "get_history_path",
9
+ "get_async_agent_meta_dir",
10
+ "get_shell",
11
+ "run_shell_command_async",
12
+ "print_error",
13
+ ]
@@ -0,0 +1,18 @@
1
+ """错误处理工具函数"""
2
+
3
+ import traceback
4
+
5
+
6
+ def print_error(tag: str, exc: Exception, debug: bool = False):
7
+ """统一的错误打印函数
8
+
9
+ Args:
10
+ tag: 错误标签(如 "1", "2", "3")
11
+ exc: 异常对象
12
+ debug: 是否打印详细堆栈
13
+ """
14
+ print(
15
+ f"\033[91m {tag}. An error occurred:\033[0m \033[93m{type(exc).__name__}\033[0m - {str(exc)}"
16
+ )
17
+ if debug:
18
+ traceback.print_exc()
@@ -0,0 +1,19 @@
1
+ """路径相关工具函数,使用 pathlib 确保跨平台兼容"""
2
+
3
+ from pathlib import Path
4
+
5
+
6
+ def get_history_path(cwd: Path = None) -> Path:
7
+ """获取命令历史文件路径"""
8
+ if cwd is None:
9
+ cwd = Path.cwd()
10
+ history_path = (
11
+ cwd / ".auto-coder" / "auto-coder.chat" / "history" / "command_history.txt"
12
+ )
13
+ history_path.parent.mkdir(parents=True, exist_ok=True)
14
+ return history_path
15
+
16
+
17
+ def get_async_agent_meta_dir() -> Path:
18
+ """获取异步代理元数据目录"""
19
+ return Path.home() / ".auto-coder" / "async_agent" / "meta"