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
@@ -4,11 +4,12 @@ Auto-Coder SDK 核心封装类
4
4
  提供统一的查询接口,处理同步和异步调用。
5
5
  """
6
6
 
7
- from typing import AsyncIterator, Optional, Dict, Any, Iterator
7
+ from typing import AsyncIterator, Optional, Dict, Any, Iterator, List
8
8
  import asyncio
9
9
  import os
10
10
  import time
11
11
  from concurrent.futures import ThreadPoolExecutor
12
+ import json
12
13
 
13
14
  # Rich 渲染相关导入
14
15
  from rich.console import Console
@@ -18,10 +19,10 @@ from rich.syntax import Syntax
18
19
  from rich.progress import Progress, SpinnerColumn, TextColumn
19
20
 
20
21
  from ..models.options import AutoCodeOptions
21
- from ..models.messages import Message
22
22
  from ..models.responses import StreamEvent, CodeModificationResult
23
23
  from ..exceptions import BridgeError
24
24
  from .bridge import AutoCoderBridge
25
+ from autocoder.common.wrap_llm_hint.utils import extract_content_from_text, has_hint_in_text
25
26
 
26
27
 
27
28
  class AutoCoderCore:
@@ -59,7 +60,13 @@ class AutoCoderCore:
59
60
  """
60
61
  if not show_terminal:
61
62
  return
63
+
64
+ # 如果输出格式是 JSON 相关,输出 JSON 格式
65
+ if self.options.output_format in ["json", "stream-json"]:
66
+ self._render_json_event(event)
67
+ return
62
68
 
69
+ # 原有的文本渲染逻辑保持不变
63
70
  try:
64
71
  # 处理新的事件类型(动态检查以避免导入依赖)
65
72
  event_class_name = type(event).__name__
@@ -94,8 +101,27 @@ class AutoCoderCore:
94
101
  tool = getattr(event, 'tool', None)
95
102
  if tool and 'AttemptCompletionTool' in type(tool).__name__:
96
103
  return
97
-
104
+
98
105
  tool_name = type(tool).__name__ if tool else "Unknown Tool"
106
+
107
+ # 特殊处理 ConversationMessageIds 工具 - 只显示 compacting 消息
108
+ if tool and tool_name in ['ConversationMessageIdsWriteTool', 'ConversationMessageIdsReadTool']:
109
+ # 使用国际化的 compacting 消息
110
+ try:
111
+ from autocoder.common.auto_coder_lang import get_system_language
112
+ lang = get_system_language()
113
+ compacting_message = "compacting..." if lang == "en" else "压缩中..."
114
+ except:
115
+ compacting_message = "compacting..."
116
+
117
+ self._console.print(Panel(
118
+ f"[dim]{compacting_message}[/dim]",
119
+ title="🗜️ Compacting",
120
+ border_style="yellow",
121
+ title_align="left"
122
+ ))
123
+ return
124
+
99
125
  try:
100
126
  # 尝试使用 get_tool_display_message 函数
101
127
  from autocoder.common.v2.agent.agentic_edit_types import get_tool_display_message
@@ -121,6 +147,10 @@ class AutoCoderCore:
121
147
  tool_name = getattr(event, 'tool_name', 'Unknown')
122
148
  if tool_name in ["AttemptCompletionTool", "PlanModeRespondTool"]:
123
149
  return
150
+
151
+ # 跳过 ConversationMessageIds 工具的结果显示 - 已由 compacting 消息处理
152
+ if tool_name in ["ConversationMessageIdsWriteTool", "ConversationMessageIdsReadTool"]:
153
+ return
124
154
 
125
155
  result = getattr(event, 'result', None)
126
156
  if result:
@@ -190,6 +220,76 @@ class AutoCoderCore:
190
220
  if conversation_id:
191
221
  self._console.print(f"[dim]Conversation ID: {conversation_id}[/dim]")
192
222
  return
223
+
224
+ elif 'PreCommitEvent' in event_class_name:
225
+ # event.commit_result 一定存在
226
+ commit_result = event.commit_result
227
+ success = commit_result.success if hasattr(commit_result, 'success') else False
228
+ message = commit_result.message if hasattr(commit_result, 'message') else 'Pre-commit operation completed'
229
+
230
+ title = "✅ Pre-Commit Success" if success else "❌ Pre-Commit Failed"
231
+ border_style = "yellow" if success else "red"
232
+
233
+ self._console.print(Panel(
234
+ f"[bold]Status:[/bold] {'Success' if success else 'Failed'}\n[bold]Message:[/bold] {message}",
235
+ title=title,
236
+ border_style=border_style,
237
+ title_align="left"
238
+ ))
239
+ return
240
+
241
+ elif 'CommitEvent' in event_class_name:
242
+ # event.commit_result 一定存在
243
+ commit_result = event.commit_result
244
+ success = commit_result.success if hasattr(commit_result, 'success') else False
245
+ message = commit_result.message if hasattr(commit_result, 'message') else 'Commit operation completed'
246
+ commit_hash = commit_result.commit_hash if hasattr(commit_result, 'commit_hash') else ''
247
+
248
+ title = "✅ Commit Success" if success else "❌ Commit Failed"
249
+ border_style = "green" if success else "red"
250
+
251
+ content = f"[bold]Status:[/bold] {'Success' if success else 'Failed'}\n[bold]Message:[/bold] {message}"
252
+ if commit_hash:
253
+ content += f"\n[bold]Commit Hash:[/bold] {commit_hash}"
254
+
255
+ self._console.print(Panel(
256
+ content,
257
+ title=title,
258
+ border_style=border_style,
259
+ title_align="left"
260
+ ))
261
+ return
262
+
263
+ elif 'PullRequestEvent' in event_class_name:
264
+ # event.pull_request_result 一定存在
265
+ pr_result = event.pull_request_result
266
+ success = pr_result.success if hasattr(pr_result, 'success') else False
267
+ pr_number = pr_result.pr_number if hasattr(pr_result, 'pr_number') else None
268
+ pr_url = pr_result.pr_url if hasattr(pr_result, 'pr_url') else ''
269
+ error_message = pr_result.error_message if hasattr(pr_result, 'error_message') else ''
270
+ platform = pr_result.platform if hasattr(pr_result, 'platform') else 'Unknown'
271
+
272
+ title = "✅ Pull Request Created" if success else "❌ Pull Request Failed"
273
+ border_style = "cyan" if success else "red"
274
+
275
+ if success:
276
+ content = f"[bold]Status:[/bold] Success\n[bold]Platform:[/bold] {platform}"
277
+ if pr_number:
278
+ content += f"\n[bold]PR Number:[/bold] #{pr_number}"
279
+ if pr_url:
280
+ content += f"\n[bold]PR URL:[/bold] {pr_url}"
281
+ else:
282
+ content = f"[bold]Status:[/bold] Failed\n[bold]Platform:[/bold] {platform}"
283
+ if error_message:
284
+ content += f"\n[bold]Error:[/bold] {error_message}"
285
+
286
+ self._console.print(Panel(
287
+ content,
288
+ title=title,
289
+ border_style=border_style,
290
+ title_align="left"
291
+ ))
292
+ return
193
293
 
194
294
  # 处理旧格式的事件类型
195
295
  if event.event_type == "start":
@@ -215,17 +315,40 @@ class AutoCoderCore:
215
315
 
216
316
  elif event.event_type == "tool_call":
217
317
  tool_name = event.data.get("tool_name", "Unknown Tool")
218
- tool_args = event.data.get("args", {})
219
- display_content = self._format_tool_display(tool_name, tool_args)
220
- self._console.print(Panel(
221
- display_content,
222
- title=f"🛠️ Action: {tool_name}",
223
- border_style="blue",
224
- title_align="left"
225
- ))
318
+
319
+ # 特殊处理 ConversationMessageIds 工具 - 只显示 compacting 消息
320
+ if tool_name in ['ConversationMessageIdsWriteTool', 'ConversationMessageIdsReadTool']:
321
+ # 使用国际化的 compacting 消息
322
+ try:
323
+ from autocoder.common.auto_coder_lang import get_system_language
324
+ lang = get_system_language()
325
+ compacting_message = "compacting..." if lang == "en" else "压缩中..."
326
+ except:
327
+ compacting_message = "compacting..."
328
+
329
+ self._console.print(Panel(
330
+ f"[dim]{compacting_message}[/dim]",
331
+ title="🗜️ Compacting",
332
+ border_style="yellow",
333
+ title_align="left"
334
+ ))
335
+ else:
336
+ tool_args = event.data.get("args", {})
337
+ display_content = self._format_tool_display(tool_name, tool_args)
338
+ self._console.print(Panel(
339
+ display_content,
340
+ title=f"🛠️ Action: {tool_name}",
341
+ border_style="blue",
342
+ title_align="left"
343
+ ))
226
344
 
227
345
  elif event.event_type == "tool_result":
228
346
  tool_name = event.data.get("tool_name", "Unknown Tool")
347
+
348
+ # 跳过 ConversationMessageIds 工具的结果显示 - 已由 compacting 消息处理
349
+ if tool_name in ["ConversationMessageIdsWriteTool", "ConversationMessageIdsReadTool"]:
350
+ return
351
+
229
352
  success = event.data.get("success", True)
230
353
  message = event.data.get("message", "")
231
354
  content = event.data.get("content")
@@ -343,6 +466,297 @@ class AutoCoderCore:
343
466
  except Exception as e:
344
467
  # 渲染错误不应该影响主流程
345
468
  self._console.print(f"[dim red]Render error: {str(e)}[/dim red]")
469
+
470
+ def _render_json_event(self, event: StreamEvent) -> None:
471
+ """
472
+ 以 JSON 格式渲染流式事件
473
+
474
+ Args:
475
+ event: 流式事件
476
+ """
477
+ try:
478
+ # 构建事件的 JSON 表示
479
+ event_json = self._convert_event_to_json(event)
480
+ print(json.dumps(event_json, ensure_ascii=False), flush=True)
481
+ except Exception as e:
482
+ # 如果 JSON 序列化失败,输出错误事件
483
+ error_json = {
484
+ "event_type": "json_render_error",
485
+ "data": {
486
+ "error": str(e),
487
+ "original_event_type": getattr(event, 'event_type', 'unknown')
488
+ },
489
+ "timestamp": time.time()
490
+ }
491
+ print(json.dumps(error_json, ensure_ascii=False), flush=True)
492
+
493
+ def _convert_event_to_json(self, event: StreamEvent) -> dict:
494
+ """
495
+ 将流式事件转换为 JSON 字典
496
+
497
+ Args:
498
+ event: 流式事件
499
+
500
+ Returns:
501
+ dict: JSON 字典表示
502
+ """
503
+ # 处理新格式的事件类型(动态检查以避免导入依赖)
504
+ event_class_name = type(event).__name__
505
+
506
+ # 基础事件信息
507
+ base_json = {
508
+ "timestamp": time.time(),
509
+ }
510
+
511
+ try:
512
+ if 'TokenUsageEvent' in event_class_name:
513
+ usage = getattr(event, 'usage', None)
514
+ base_json.update({
515
+ "event_type": "token_usage",
516
+ "data": {
517
+ "usage": self._serialize_usage_object(usage) if usage else None
518
+ }
519
+ })
520
+ elif 'WindowLengthChangeEvent' in event_class_name:
521
+ tokens_used = getattr(event, 'tokens_used', 0)
522
+ base_json.update({
523
+ "event_type": "window_change",
524
+ "data": {
525
+ "tokens_used": tokens_used
526
+ }
527
+ })
528
+ elif 'LLMThinkingEvent' in event_class_name:
529
+ text = getattr(event, 'text', '')
530
+ base_json.update({
531
+ "event_type": "llm_thinking",
532
+ "data": {
533
+ "text": text
534
+ }
535
+ })
536
+ elif 'LLMOutputEvent' in event_class_name:
537
+ text = getattr(event, 'text', '')
538
+ base_json.update({
539
+ "event_type": "llm_output",
540
+ "data": {
541
+ "text": text
542
+ }
543
+ })
544
+ elif 'ToolCallEvent' in event_class_name:
545
+ tool = getattr(event, 'tool', None)
546
+ tool_name = type(tool).__name__ if tool else "Unknown Tool"
547
+ tool_args = self._serialize_tool_object(tool) if tool else {}
548
+ base_json.update({
549
+ "event_type": "tool_call",
550
+ "data": {
551
+ "tool_name": tool_name,
552
+ "args": tool_args
553
+ }
554
+ })
555
+ elif 'ToolResultEvent' in event_class_name:
556
+ tool_name = getattr(event, 'tool_name', 'Unknown')
557
+ result = getattr(event, 'result', None)
558
+ result_data = self._serialize_tool_result(result) if result else {}
559
+ base_json.update({
560
+ "event_type": "tool_result",
561
+ "data": {
562
+ "tool_name": tool_name,
563
+ **result_data
564
+ }
565
+ })
566
+ elif 'CompletionEvent' in event_class_name:
567
+ completion = getattr(event, 'completion', None)
568
+ completion_data = self._serialize_completion_object(completion) if completion else {}
569
+ base_json.update({
570
+ "event_type": "completion",
571
+ "data": completion_data
572
+ })
573
+ elif 'PlanModeRespondEvent' in event_class_name:
574
+ completion = getattr(event, 'completion', None)
575
+ response = getattr(completion, 'response', 'Plan completed') if completion else 'Plan completed'
576
+ base_json.update({
577
+ "event_type": "plan_mode_respond",
578
+ "data": {
579
+ "result": response
580
+ }
581
+ })
582
+ elif 'ErrorEvent' in event_class_name:
583
+ message = getattr(event, 'message', 'Unknown error')
584
+ base_json.update({
585
+ "event_type": "error",
586
+ "data": {
587
+ "error": message,
588
+ "error_type": "Error"
589
+ }
590
+ })
591
+ elif 'ConversationIdEvent' in event_class_name:
592
+ conversation_id = getattr(event, 'conversation_id', '')
593
+ base_json.update({
594
+ "event_type": "conversation_id",
595
+ "data": {
596
+ "conversation_id": conversation_id
597
+ }
598
+ })
599
+ elif 'PreCommitEvent' in event_class_name:
600
+ # event.commit_result 和 event.tpe 一定存在
601
+ commit_result = event.commit_result
602
+ commit_data = self._serialize_commit_result(commit_result)
603
+ base_json.update({
604
+ "event_type": "pre_commit",
605
+ "data": {
606
+ "commit_result": commit_data,
607
+ "tpe": event.tpe
608
+ }
609
+ })
610
+ elif 'CommitEvent' in event_class_name:
611
+ # event.commit_result 和 event.tpe 一定存在
612
+ commit_result = event.commit_result
613
+ commit_data = self._serialize_commit_result(commit_result)
614
+ base_json.update({
615
+ "event_type": "commit",
616
+ "data": {
617
+ "commit_result": commit_data,
618
+ "tpe": event.tpe
619
+ }
620
+ })
621
+ elif 'PullRequestEvent' in event_class_name:
622
+ # event.pull_request_result 一定存在
623
+ pr_result = event.pull_request_result
624
+ pr_data = self._serialize_pr_result(pr_result)
625
+ base_json.update({
626
+ "event_type": "pull_request",
627
+ "data": {
628
+ "pull_request_result": pr_data
629
+ }
630
+ })
631
+ else:
632
+ # 处理旧格式的事件(有 event_type 和 data 属性)
633
+ if hasattr(event, 'event_type') and hasattr(event, 'data'):
634
+ base_json.update({
635
+ "event_type": event.event_type,
636
+ "data": event.data if isinstance(event.data, dict) else {"content": str(event.data)}
637
+ })
638
+ else:
639
+ # 未知事件类型,尝试序列化所有属性
640
+ base_json.update({
641
+ "event_type": "unknown",
642
+ "data": self._serialize_object_attributes(event)
643
+ })
644
+ except Exception as e:
645
+ # 如果序列化失败,返回基本信息
646
+ base_json.update({
647
+ "event_type": "serialization_error",
648
+ "data": {
649
+ "error": str(e),
650
+ "original_class": event_class_name
651
+ }
652
+ })
653
+
654
+ return base_json
655
+
656
+ def _serialize_usage_object(self, usage) -> dict:
657
+ """序列化使用情况对象"""
658
+ try:
659
+ return {
660
+ "input_tokens_count": getattr(usage, 'input_tokens_count', 0),
661
+ "generated_tokens_count": getattr(usage, 'generated_tokens_count', 0),
662
+ "total_tokens": getattr(usage, 'input_tokens_count', 0) + getattr(usage, 'generated_tokens_count', 0)
663
+ }
664
+ except:
665
+ return {"error": "Failed to serialize usage object"}
666
+
667
+ def _serialize_tool_object(self, tool) -> dict:
668
+ """序列化工具对象"""
669
+ try:
670
+ if hasattr(tool, '__dict__'):
671
+ result = {}
672
+ for key, value in tool.__dict__.items():
673
+ if not key.startswith('_'):
674
+ try:
675
+ # 尝试序列化值,如果失败则转为字符串
676
+ json.dumps(value)
677
+ result[key] = value
678
+ except:
679
+ result[key] = str(value)
680
+ return result
681
+ else:
682
+ return {"tool": str(tool)}
683
+ except:
684
+ return {"error": "Failed to serialize tool object"}
685
+
686
+ def _serialize_tool_result(self, result) -> dict:
687
+ """序列化工具结果对象"""
688
+ try:
689
+ return {
690
+ "success": getattr(result, 'success', True),
691
+ "message": getattr(result, 'message', ''),
692
+ "content": self._serialize_content(getattr(result, 'content', None))
693
+ }
694
+ except:
695
+ return {"error": "Failed to serialize tool result"}
696
+
697
+ def _serialize_completion_object(self, completion) -> dict:
698
+ """序列化完成对象"""
699
+ try:
700
+ return {
701
+ "result": getattr(completion, 'result', 'Task completed successfully'),
702
+ "command": getattr(completion, 'command', None)
703
+ }
704
+ except:
705
+ return {"error": "Failed to serialize completion object"}
706
+
707
+ def _serialize_content(self, content) -> Any:
708
+ """序列化内容,确保可以 JSON 序列化"""
709
+ try:
710
+ if content is None:
711
+ return None
712
+ # 尝试 JSON 序列化测试
713
+ json.dumps(content)
714
+ return content
715
+ except:
716
+ # 如果不能序列化,转为字符串
717
+ return str(content)
718
+
719
+ def _serialize_object_attributes(self, obj) -> dict:
720
+ """序列化对象的所有属性"""
721
+ try:
722
+ result = {}
723
+ if hasattr(obj, '__dict__'):
724
+ for key, value in obj.__dict__.items():
725
+ if not key.startswith('_'):
726
+ result[key] = self._serialize_content(value)
727
+ return result
728
+ except:
729
+ return {"error": "Failed to serialize object attributes"}
730
+
731
+ def _serialize_commit_result(self, commit_result) -> dict:
732
+ """序列化 Git 提交结果对象"""
733
+ try:
734
+ return {
735
+ "success": commit_result.success if hasattr(commit_result, 'success') else False,
736
+ "message": commit_result.message if hasattr(commit_result, 'message') else '',
737
+ "commit_hash": commit_result.commit_hash if hasattr(commit_result, 'commit_hash') else '',
738
+ "files_changed": commit_result.files_changed if hasattr(commit_result, 'files_changed') else [],
739
+ "error": commit_result.error if hasattr(commit_result, 'error') else None
740
+ }
741
+ except:
742
+ return {"error": "Failed to serialize commit result"}
743
+
744
+ def _serialize_pr_result(self, pr_result) -> dict:
745
+ """序列化 Pull Request 结果对象"""
746
+ try:
747
+ return {
748
+ "success": pr_result.success if hasattr(pr_result, 'success') else False,
749
+ "pr_number": pr_result.pr_number if hasattr(pr_result, 'pr_number') else None,
750
+ "pr_url": pr_result.pr_url if hasattr(pr_result, 'pr_url') else '',
751
+ "pr_id": pr_result.pr_id if hasattr(pr_result, 'pr_id') else None,
752
+ "error_message": pr_result.error_message if hasattr(pr_result, 'error_message') else None,
753
+ "error_code": pr_result.error_code if hasattr(pr_result, 'error_code') else None,
754
+ "platform": pr_result.platform if hasattr(pr_result, 'platform') else None,
755
+ "raw_response": self._serialize_content(pr_result.raw_response if hasattr(pr_result, 'raw_response') else None),
756
+ "retry_after": pr_result.retry_after if hasattr(pr_result, 'retry_after') else None
757
+ }
758
+ except:
759
+ return {"error": "Failed to serialize pull request result"}
346
760
 
347
761
  def _format_tool_display(self, tool_name: str, tool_args: Dict[str, Any]) -> str:
348
762
  """
@@ -471,128 +885,100 @@ class AutoCoderCore:
471
885
  return content_str
472
886
 
473
887
  try:
474
- if isinstance(content, (dict, list)):
888
+ # Remove hints from content before processing
889
+ processed_content = content
890
+ if isinstance(content, str) and has_hint_in_text(content):
891
+ processed_content = extract_content_from_text(content)
892
+
893
+ if isinstance(processed_content, (dict, list)):
475
894
  import json
476
- content_str = json.dumps(content, indent=2, ensure_ascii=False)
895
+ content_str = json.dumps(processed_content, indent=2, ensure_ascii=False)
477
896
  return Syntax(_truncate_content(content_str), "json", theme="default", line_numbers=False)
478
897
 
479
- elif isinstance(content, str):
898
+ elif isinstance(processed_content, str):
480
899
  # 检查是否是多行内容或代码
481
- if '\n' in content or content.strip().startswith('<') or len(content) > 200:
900
+ if '\n' in processed_content or processed_content.strip().startswith('<') or len(processed_content) > 200:
482
901
  # 推断语法类型
483
902
  lexer = "text"
484
903
  if "ReadFile" in tool_name:
485
- if any(ext in content for ext in [".py", "python"]):
904
+ if any(ext in processed_content for ext in [".py", "python"]):
486
905
  lexer = "python"
487
- elif any(ext in content for ext in [".js", "javascript"]):
906
+ elif any(ext in processed_content for ext in [".js", "javascript"]):
488
907
  lexer = "javascript"
489
- elif any(ext in content for ext in [".ts", "typescript"]):
908
+ elif any(ext in processed_content for ext in [".ts", "typescript"]):
490
909
  lexer = "typescript"
491
- elif any(ext in content for ext in [".html", "<!DOCTYPE", "<html"]):
910
+ elif any(ext in processed_content for ext in [".html", "<!DOCTYPE", "<html"]):
492
911
  lexer = "html"
493
- elif any(ext in content for ext in [".css", "{"]):
912
+ elif any(ext in processed_content for ext in [".css", "{"]):
494
913
  lexer = "css"
495
- elif any(ext in content for ext in [".json", "{"]):
914
+ elif any(ext in processed_content for ext in [".json", "{"]):
496
915
  lexer = "json"
497
- elif any(ext in content for ext in [".xml", "<?xml"]):
916
+ elif any(ext in processed_content for ext in [".xml", "<?xml"]):
498
917
  lexer = "xml"
499
- elif any(ext in content for ext in [".md", "#"]):
918
+ elif any(ext in processed_content for ext in [".md", "#"]):
500
919
  lexer = "markdown"
501
920
  elif "ExecuteCommand" in tool_name or "Shell" in tool_name:
502
921
  lexer = "shell"
503
- elif content.strip().startswith('{') or content.strip().startswith('['):
922
+ elif processed_content.strip().startswith('{') or processed_content.strip().startswith('['):
504
923
  lexer = "json"
505
924
 
506
- return Syntax(_truncate_content(content), lexer, theme="default", line_numbers=True)
925
+ return Syntax(_truncate_content(processed_content), lexer, theme="default", line_numbers=True)
507
926
  else:
508
- return _truncate_content(content)
927
+ return _truncate_content(processed_content)
509
928
  else:
510
- return _truncate_content(str(content))
929
+ return _truncate_content(str(processed_content))
511
930
 
512
931
  except Exception:
513
932
  return _truncate_content(str(content))
514
933
 
515
- async def query_stream(self, prompt: str, show_terminal: bool = True) -> AsyncIterator[Message]:
934
+ async def query_stream(self, prompt: str, show_terminal: Optional[bool] = None) -> AsyncIterator[StreamEvent]:
516
935
  """
517
936
  异步流式查询 - 使用 run_auto_command
518
937
 
519
938
  Args:
520
939
  prompt: 查询提示
521
- show_terminal: 是否显示到终端
940
+ show_terminal: 是否显示到终端,None时使用配置中的verbose设置
522
941
 
523
942
  Yields:
524
- Message: 响应消息流
943
+ StreamEvent: 响应事件流
525
944
 
526
945
  Raises:
527
946
  BridgeError: 桥接层错误
528
947
  """
948
+ # 如果没有明确指定show_terminal,使用verbose配置
949
+ if show_terminal is None:
950
+ show_terminal = self.options.verbose
951
+
952
+ # 如果verbose为False,则强制show_terminal为False
953
+ if not self.options.verbose:
954
+ show_terminal = False
955
+
529
956
  try:
530
957
  # 重置累计的 token 使用情况
531
958
  self._reset_token_usage()
532
959
 
533
960
  # 先返回用户消息
534
- user_message = Message(role="user", content=prompt)
961
+ user_message = StreamEvent(event_type="start", data={"query": prompt})
535
962
  yield user_message
536
963
 
537
964
  # 在线程池中执行同步调用
538
965
  loop = asyncio.get_event_loop()
539
966
 
540
- # 使用 run_auto_command 进行代码修改
967
+ # 使用 run_auto_command 进行代码修改,传递 cancel_token
541
968
  event_stream = await loop.run_in_executor(
542
969
  self._executor,
543
970
  self._sync_run_auto_command,
544
- prompt
971
+ prompt,
972
+ False, # pre_commit
973
+ None, # pr (使用默认值)
974
+ None # extra_args
545
975
  )
546
976
 
547
- # 处理事件流并转换为消息
548
- assistant_content = ""
977
+ # 处理事件流并转换为消息
549
978
  for event in event_stream:
550
979
  # 渲染事件到终端
551
- self._render_stream_event(event, show_terminal)
552
-
553
- if event.event_type == "content":
554
- content = event.data.get("content", "")
555
- assistant_content += content
556
-
557
- # 返回增量消息
558
- yield Message(
559
- role="assistant",
560
- content=content,
561
- metadata={
562
- "event_type": event.event_type,
563
- "model": self.options.model,
564
- "temperature": self.options.temperature,
565
- "is_incremental": True
566
- }
567
- )
568
- elif event.event_type == "end":
569
- # 返回最终完整消息
570
- yield Message(
571
- role="assistant",
572
- content=assistant_content,
573
- metadata={
574
- "event_type": event.event_type,
575
- "model": self.options.model,
576
- "temperature": self.options.temperature,
577
- "is_final": True,
578
- "status": event.data.get("status", "completed")
579
- }
580
- )
581
- elif event.event_type == "error":
582
- # 返回错误消息
583
- yield Message(
584
- role="assistant",
585
- content=f"Error: {event.data.get('error', 'Unknown error')}",
586
- metadata={
587
- "event_type": event.event_type,
588
- "error_type": event.data.get("error_type", "Unknown"),
589
- "is_error": True
590
- }
591
- )
592
-
593
- # 添加小延迟以改善视觉效果
594
- if show_terminal:
595
- time.sleep(0.05)
980
+ self._render_stream_event(event, show_terminal)
981
+ yield event
596
982
 
597
983
  # 打印最终的累计 token 使用情况
598
984
  if show_terminal:
@@ -604,52 +990,40 @@ class AutoCoderCore:
604
990
  self._print_final_token_usage()
605
991
  raise e
606
992
 
607
- def query_sync(self, prompt: str, show_terminal: bool = True) -> str:
993
+ def query_sync(self, prompt: str, show_terminal: Optional[bool] = None) -> List[StreamEvent]:
608
994
  """
609
- 同步查询 - 使用 run_auto_command
995
+ 同步查询 - 通过调用 query_stream 实现
610
996
 
611
997
  Args:
612
998
  prompt: 查询提示
613
- show_terminal: 是否显示到终端
999
+ show_terminal: 是否显示到终端,None时使用配置中的verbose设置
614
1000
 
615
1001
  Returns:
616
- str: 响应内容
1002
+ List[StreamEvent]: 事件列表,包含用户查询和响应事件
617
1003
 
618
1004
  Raises:
619
1005
  BridgeError: 桥接层错误
620
1006
  """
621
1007
  try:
622
- # 重置累计的 token 使用情况
623
- self._reset_token_usage()
1008
+ # 收集所有事件
1009
+ events = []
624
1010
 
625
- event_stream = self._sync_run_auto_command(prompt)
1011
+ # 运行异步查询流并收集结果
1012
+ loop = asyncio.new_event_loop()
1013
+ asyncio.set_event_loop(loop)
626
1014
 
627
- # 收集所有内容
628
- content_parts = []
629
- for event in event_stream:
630
- # 渲染事件到终端
631
- self._render_stream_event(event, show_terminal)
632
-
633
- if event.event_type == "content":
634
- content_parts.append(event.data.get("content", ""))
635
- elif event.event_type == "error":
636
- raise BridgeError(f"Query failed: {event.data.get('error', 'Unknown error')}")
1015
+ try:
1016
+ async def collect_events():
1017
+ async for event in self.query_stream(prompt, show_terminal):
1018
+ events.append(event)
637
1019
 
638
- # 添加小延迟以改善视觉效果
639
- if show_terminal:
640
- time.sleep(0.05)
641
-
642
- # 打印最终的累计 token 使用情况
643
- if show_terminal:
644
- self._print_final_token_usage()
1020
+ loop.run_until_complete(collect_events())
1021
+ finally:
1022
+ loop.close()
645
1023
 
646
- return "".join(content_parts)
1024
+ return events
647
1025
 
648
1026
  except Exception as e:
649
- # 在异常时也打印累计的 token 使用情况
650
- if show_terminal:
651
- self._print_final_token_usage()
652
-
653
1027
  raise e
654
1028
 
655
1029
  def _sync_run_auto_command(
@@ -679,6 +1053,7 @@ class AutoCoderCore:
679
1053
  query=prompt,
680
1054
  pre_commit=pre_commit,
681
1055
  pr=pr,
1056
+ cancel_token=self.options.cancel_token,
682
1057
  extra_args=extra_args or {},
683
1058
  stream=True
684
1059
  )