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,34 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ RuleFiles 工具函数
4
+
5
+ 包含解析器、监控器和其他实用工具。
6
+ """
7
+
8
+ from .parser import (
9
+ parse_rule_file,
10
+ extract_yaml_metadata,
11
+ validate_rule_file_format,
12
+ get_rule_directories,
13
+ find_existing_rule_directories,
14
+ )
15
+ from .monitor import (
16
+ setup_file_monitor,
17
+ is_rule_related_change,
18
+ cleanup_file_monitor,
19
+ create_rule_change_callback,
20
+ )
21
+
22
+
23
+ __all__ = [
24
+ 'parse_rule_file',
25
+ 'extract_yaml_metadata',
26
+ 'validate_rule_file_format',
27
+ 'get_rule_directories',
28
+ 'find_existing_rule_directories',
29
+ 'setup_file_monitor',
30
+ 'is_rule_related_change',
31
+ 'cleanup_file_monitor',
32
+ 'create_rule_change_callback',
33
+
34
+ ]
@@ -0,0 +1,86 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 监控工具 - 已弃用
4
+
5
+ 注意:此模块已弃用。RuleFiles 模块现在使用基于文件 MD5 的缓存失效机制,
6
+ 不再依赖文件监控。为了保持向后兼容性,此模块提供空的实现。
7
+ """
8
+
9
+ import os
10
+ from typing import Optional, List, Callable, Any
11
+ from loguru import logger
12
+
13
+
14
+ def setup_file_monitor(
15
+ project_root: str,
16
+ monitored_dirs: List[str],
17
+ callback: Callable[[Any, str], None]
18
+ ) -> Optional[Any]:
19
+ """
20
+ 设置文件监控 - 已弃用
21
+
22
+ 注意:此函数已弃用,不再提供实际的监控功能。
23
+ RuleFiles 模块现在使用基于文件 MD5 的缓存失效机制。
24
+
25
+ Args:
26
+ project_root: 项目根目录
27
+ monitored_dirs: 要监控的目录列表
28
+ callback: 文件变化时的回调函数
29
+
30
+ Returns:
31
+ None: 不再返回 FileMonitor 实例
32
+ """
33
+ logger.warning("setup_file_monitor 已弃用,RuleFiles 模块现在使用基于 MD5 的缓存失效机制")
34
+ return None
35
+
36
+
37
+ def is_rule_related_change(changed_path: str, monitored_dirs: List[str]) -> bool:
38
+ """
39
+ 检查变更是否与规则相关 - 已弃用
40
+
41
+ 注意:此函数已弃用,不再提供实际的检查功能。
42
+
43
+ Args:
44
+ changed_path: 发生变化的文件路径
45
+ monitored_dirs: 监控的目录列表
46
+
47
+ Returns:
48
+ False: 始终返回 False
49
+ """
50
+ logger.warning("is_rule_related_change 已弃用")
51
+ return False
52
+
53
+
54
+ def cleanup_file_monitor(file_monitor: Optional[Any], monitored_dirs: List[str]) -> None:
55
+ """
56
+ 清理文件监控 - 已弃用
57
+
58
+ 注意:此函数已弃用,不再提供实际的清理功能。
59
+
60
+ Args:
61
+ file_monitor: FileMonitor 实例(忽略)
62
+ monitored_dirs: 监控的目录列表(忽略)
63
+ """
64
+ logger.warning("cleanup_file_monitor 已弃用")
65
+ pass
66
+
67
+
68
+ def create_rule_change_callback(reload_rules_func: Callable[[], None]) -> Callable[[Any, str], None]:
69
+ """
70
+ 创建规则变化回调函数 - 已弃用
71
+
72
+ 注意:此函数已弃用,不再提供实际的回调功能。
73
+
74
+ Args:
75
+ reload_rules_func: 重新加载规则的函数(忽略)
76
+
77
+ Returns:
78
+ Callable: 空的回调函数
79
+ """
80
+ logger.warning("create_rule_change_callback 已弃用")
81
+
82
+ def dummy_callback(change_type: Any, changed_path: str):
83
+ """空的回调函数"""
84
+ pass
85
+
86
+ return dummy_callback
@@ -0,0 +1,230 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 规则文件解析工具
4
+
5
+ 提供规则文件解析相关的实用工具函数。
6
+ """
7
+
8
+ import os
9
+ import re
10
+ import yaml
11
+ from typing import Dict, Any
12
+ from loguru import logger
13
+
14
+ from ..models.rule_file import RuleFile
15
+
16
+ # 导入优先级目录查找器
17
+ from autocoder.common.priority_directory_finder import (
18
+ PriorityDirectoryFinder, FinderConfig, SearchStrategy,
19
+ ValidationMode, create_file_filter
20
+ )
21
+
22
+
23
+ def parse_rule_file(file_path: str) -> RuleFile:
24
+ """
25
+ 解析规则文件并返回结构化的Pydantic模型对象
26
+
27
+ Args:
28
+ file_path: 规则文件的路径
29
+
30
+ Returns:
31
+ RuleFile: 包含规则文件结构化内容的Pydantic模型
32
+
33
+ Raises:
34
+ FileNotFoundError: 当文件不存在时
35
+ ValueError: 当文件格式无效时
36
+ """
37
+ if not os.path.exists(file_path):
38
+ logger.error(f"规则文件不存在: {file_path}")
39
+ raise FileNotFoundError(f"规则文件不存在: {file_path}")
40
+
41
+ if not file_path.endswith('.md'):
42
+ logger.error(f"无效的规则文件格式,必须是.md文件: {file_path}")
43
+ raise ValueError(f"无效的规则文件格式,必须是.md文件: {file_path}")
44
+
45
+ try:
46
+ with open(file_path, 'r', encoding='utf-8') as f:
47
+ content = f.read()
48
+
49
+ # 解析YAML头部和Markdown内容
50
+ yaml_pattern = re.compile(r'^---\s*\n(.*?)\n---\s*\n', re.DOTALL)
51
+ yaml_match = yaml_pattern.search(content)
52
+
53
+ metadata = {}
54
+ markdown_content = content
55
+
56
+ if yaml_match:
57
+ yaml_content = yaml_match.group(1)
58
+ try:
59
+ metadata = yaml.safe_load(yaml_content)
60
+ # 移除YAML部分,仅保留Markdown内容
61
+ markdown_content = content[yaml_match.end():]
62
+ except Exception as e:
63
+ logger.warning(f"解析规则文件YAML头部时出错: {e}")
64
+
65
+ # 创建并返回Pydantic模型
66
+ rule = RuleFile(
67
+ description=metadata.get('description', ''),
68
+ globs=metadata.get('globs', []),
69
+ always_apply=metadata.get('alwaysApply', False),
70
+ content=markdown_content.strip(),
71
+ file_path=file_path
72
+ )
73
+ return rule
74
+
75
+ except (FileNotFoundError, ValueError):
76
+ # 重新抛出已知的异常
77
+ raise
78
+ except Exception as e:
79
+ logger.error(f"解析规则文件时出现未知错误: {file_path}, 错误: {e}")
80
+ raise RuntimeError(f"解析规则文件失败: {file_path}") from e
81
+
82
+
83
+ def extract_yaml_metadata(content: str) -> tuple[Dict[str, Any], str]:
84
+ """
85
+ 从文件内容中提取 YAML 前置元数据和 Markdown 内容
86
+
87
+ Args:
88
+ content: 文件内容
89
+
90
+ Returns:
91
+ tuple: (元数据字典, Markdown内容)
92
+ """
93
+ yaml_pattern = re.compile(r'^---\s*\n(.*?)\n---\s*\n', re.DOTALL)
94
+ yaml_match = yaml_pattern.search(content)
95
+
96
+ metadata = {}
97
+ markdown_content = content
98
+
99
+ if yaml_match:
100
+ yaml_content = yaml_match.group(1)
101
+ try:
102
+ metadata = yaml.safe_load(yaml_content) or {}
103
+ # 移除YAML部分,仅保留Markdown内容
104
+ markdown_content = content[yaml_match.end():]
105
+ except Exception as e:
106
+ logger.warning(f"解析YAML头部时出错: {e}")
107
+
108
+ return metadata, markdown_content.strip()
109
+
110
+
111
+ def validate_rule_file_format(file_path: str) -> bool:
112
+ """
113
+ 验证规则文件格式是否正确
114
+
115
+ Args:
116
+ file_path: 规则文件路径
117
+
118
+ Returns:
119
+ bool: 是否为有效的规则文件格式
120
+ """
121
+ if not os.path.exists(file_path):
122
+ return False
123
+
124
+ if not file_path.endswith('.md'):
125
+ return False
126
+
127
+ try:
128
+ with open(file_path, 'r', encoding='utf-8') as f:
129
+ content = f.read()
130
+
131
+ # 检查是否可以正常解析
132
+ metadata, markdown_content = extract_yaml_metadata(content)
133
+
134
+ # 基本验证:确保有内容
135
+ if not markdown_content.strip():
136
+ return False
137
+
138
+ return True
139
+
140
+ except Exception:
141
+ return False
142
+
143
+
144
+ def get_rule_directories(project_root: str) -> list[str]:
145
+ """
146
+ 获取所有可能的规则目录路径(按优先级排序)
147
+
148
+ Args:
149
+ project_root: 项目根目录
150
+
151
+ Returns:
152
+ list[str]: 规则目录路径列表(按优先级排序)
153
+ """
154
+ return [
155
+ os.path.join(project_root, ".autocoderrules"),
156
+ os.path.join(project_root, ".auto-coder", ".autocoderrules"),
157
+ os.path.join(project_root, ".auto-coder", "autocoderrules")
158
+ ]
159
+
160
+
161
+ def find_existing_rule_directories(project_root: str) -> list[str]:
162
+ """
163
+ 使用优先级目录查找器查找实际存在且包含规则文件的目录。
164
+
165
+ Args:
166
+ project_root: 项目根目录
167
+
168
+ Returns:
169
+ list[str]: 实际存在且包含规则文件的目录路径列表
170
+ """
171
+ try:
172
+ # 创建文件过滤器,只查找.md文件
173
+ md_filter = create_file_filter(extensions=[".md"], recursive=True)
174
+
175
+ # 创建查找器配置,使用LIST_ALL策略返回所有有效目录
176
+ config = FinderConfig(strategy=SearchStrategy.LIST_ALL)
177
+
178
+ # 按优先级添加目录配置
179
+ config.add_directory(
180
+ path=os.path.join(project_root, ".autocoderrules"),
181
+ priority=1,
182
+ validation_mode=ValidationMode.HAS_SPECIFIC_FILES,
183
+ file_filter=md_filter,
184
+ description="项目级规则目录"
185
+ )
186
+ config.add_directory(
187
+ path=os.path.join(project_root, ".auto-coder", ".autocoderrules"),
188
+ priority=2,
189
+ validation_mode=ValidationMode.HAS_SPECIFIC_FILES,
190
+ file_filter=md_filter,
191
+ description="项目.auto-coder规则目录"
192
+ )
193
+ config.add_directory(
194
+ path=os.path.join(project_root, ".auto-coder", "autocoderrules"),
195
+ priority=3,
196
+ validation_mode=ValidationMode.HAS_SPECIFIC_FILES,
197
+ file_filter=md_filter,
198
+ description="项目.auto-coder/autocoderrules目录"
199
+ )
200
+
201
+ # 执行查找
202
+ finder = PriorityDirectoryFinder(config)
203
+ result = finder.find_directories()
204
+
205
+ if result.success:
206
+ logger.info(f"使用优先级查找器找到 {len(result.selected_directories)} 个有效规则目录")
207
+ return result.selected_directories
208
+ else:
209
+ logger.info("优先级查找器未找到包含规则文件的目录")
210
+ return []
211
+
212
+ except Exception as e:
213
+ logger.error(f"使用优先级查找器查找规则目录时出错: {e}")
214
+ # 回退到传统方法
215
+ return _find_existing_rule_directories_fallback(project_root)
216
+
217
+
218
+ def _find_existing_rule_directories_fallback(project_root: str) -> list[str]:
219
+ """
220
+ 回退到传统的目录查找方法。
221
+
222
+ Args:
223
+ project_root: 项目根目录
224
+
225
+ Returns:
226
+ list[str]: 实际存在的规则目录路径列表
227
+ """
228
+ logger.info("回退到传统的规则目录查找方法")
229
+ potential_dirs = get_rule_directories(project_root)
230
+ return [d for d in potential_dirs if os.path.isdir(d)]
@@ -4,6 +4,7 @@ import json
4
4
  import uuid
5
5
  from datetime import datetime
6
6
  from loguru import logger # Added import
7
+ from typing import Optional
7
8
 
8
9
  # New helper function for cleaning up logs
9
10
  def _cleanup_logs(logs_dir: str, max_files: int = 100):
@@ -21,9 +22,10 @@ def _cleanup_logs(logs_dir: str, max_files: int = 100):
21
22
  if filename.endswith(".md"):
22
23
  parts = filename.split('_')
23
24
  # Expected format: <YYYYmmdd_HHMMSS>_<uuid>_<suffix>.md
24
- # parts[0] should be the full timestamp string "YYYYmmdd_HHMMSS"
25
- if len(parts) >= 2: # At least timestamp and uuid part (suffix might be empty or complex)
26
- timestamp_str = parts[0]
25
+ # parts[0] should be date part "YYYYmmdd" and parts[1] should be time part "HHMMSS"
26
+ if len(parts) >= 3: # At least date, time, and uuid parts
27
+ # Reconstruct the full timestamp from first two parts
28
+ timestamp_str = parts[0] + '_' + parts[1]
27
29
  try:
28
30
  # Validate the timestamp format
29
31
  datetime.strptime(timestamp_str, "%Y%m%d_%H%M%S")
@@ -33,7 +35,7 @@ def _cleanup_logs(logs_dir: str, max_files: int = 100):
33
35
  continue
34
36
  else:
35
37
  # Log the parts for better debugging if needed
36
- logger.debug(f"文件名 {filename} (分割后: {parts}) 不符合预期的下划线分割数量 (至少需要 <timestamp>_<uuid>_...),跳过。")
38
+ logger.debug(f"文件名 {filename} (分割后: {parts}) 不符合预期的下划线分割数量 (至少需要 <date>_<time>_<uuid>_...),跳过。")
37
39
 
38
40
  # Sort by timestamp (oldest first)
39
41
  log_files.sort(key=lambda x: x[0])
@@ -53,18 +55,20 @@ def _cleanup_logs(logs_dir: str, max_files: int = 100):
53
55
  logger.debug(f"日志文件数量 ({len(log_files)}) 未超过限制 ({max_files}),无需删除。")
54
56
 
55
57
 
56
- def save_formatted_log(project_root, json_text, suffix):
58
+ def save_formatted_log(project_root, json_text, suffix, conversation_id:Optional[str]=None, log_subdir:str="agentic"):
57
59
  """
58
- Save a JSON log as a formatted markdown file under project_root/.auto-coder/logs/agentic.
60
+ Save a JSON log as a formatted markdown file under project_root/.auto-coder/logs/{log_subdir}.
59
61
  Filename: <YYYYmmdd_HHMMSS>_<uuid>_<suffix>.md
60
62
  Also cleans up old logs in the directory, keeping the latest 100.
61
63
  Args:
62
64
  project_root (str): The root directory of the project.
63
65
  json_text (str): The JSON string to be formatted and saved.
64
66
  suffix (str): The suffix for the filename.
67
+ conversation_id (str, optional): If provided, use this as unique_id and search for existing files to overwrite.
68
+ log_subdir (str): The subdirectory under .auto-coder/logs/ to save the file. Default is "agentic".
65
69
  """
66
70
  # Prepare directory (logs_dir is needed for cleanup first)
67
- logs_dir = os.path.join(project_root, ".auto-coder", "logs", "agentic")
71
+ logs_dir = os.path.join(project_root, ".auto-coder", "logs", log_subdir)
68
72
 
69
73
  # Cleanup old logs BEFORE saving the new one
70
74
  try:
@@ -82,6 +86,38 @@ def save_formatted_log(project_root, json_text, suffix):
82
86
  logger.exception(e) # Log stack trace
83
87
  raise ValueError(f"Invalid JSON provided: {e}")
84
88
 
89
+ # Filter out system role entries
90
+ def filter_system_role(obj):
91
+ """Recursively filter out entries where role equals 'system'"""
92
+ if isinstance(obj, dict):
93
+ # If this dict has role='system', skip it entirely
94
+ if obj.get('role') == 'system':
95
+ return None
96
+ # Otherwise, recursively filter all values
97
+ filtered_dict = {}
98
+ for key, value in obj.items():
99
+ filtered_value = filter_system_role(value)
100
+ if filtered_value is not None:
101
+ filtered_dict[key] = filtered_value
102
+ return filtered_dict if filtered_dict else None
103
+ elif isinstance(obj, list):
104
+ # Filter list items, keeping only non-None results
105
+ filtered_list = []
106
+ for item in obj:
107
+ filtered_item = filter_system_role(item)
108
+ if filtered_item is not None:
109
+ filtered_list.append(filtered_item)
110
+ return filtered_list if filtered_list else None
111
+ else:
112
+ # For primitive types, return as-is
113
+ return obj
114
+
115
+ # Apply the filter
116
+ data = filter_system_role(data)
117
+ if data is None:
118
+ logger.warning("过滤后的数据为空,将保存空日志")
119
+ data = {}
120
+
85
121
  # Format as markdown with recursive depth
86
122
  def to_markdown(obj, level=1):
87
123
  lines = []
@@ -108,9 +144,30 @@ def save_formatted_log(project_root, json_text, suffix):
108
144
 
109
145
  # Prepare filename
110
146
  now = datetime.now().strftime("%Y%m%d_%H%M%S")
111
- unique_id = str(uuid.uuid4())
112
- filename = f"{now}_{unique_id}_{suffix}.md"
113
- filepath = os.path.join(logs_dir, filename)
147
+
148
+ # Handle conversation_id logic
149
+ if conversation_id is not None:
150
+ unique_id = conversation_id
151
+
152
+ # Search for existing files with this conversation_id
153
+ existing_file = None
154
+ if os.path.isdir(logs_dir):
155
+ for filename in os.listdir(logs_dir):
156
+ if filename.endswith(".md") and conversation_id in filename and suffix in filename:
157
+ existing_file = os.path.join(logs_dir, filename)
158
+ logger.info(f"找到包含 conversation_id ({conversation_id}) 的现有文件: {filename},将覆盖该文件")
159
+ break
160
+
161
+ if existing_file:
162
+ filepath = existing_file
163
+ else:
164
+ filename = f"{now}_{unique_id}_{suffix}.md"
165
+ filepath = os.path.join(logs_dir, filename)
166
+ logger.info(f"未找到包含 conversation_id ({conversation_id}) 的文件,将创建新文件: {filename}")
167
+ else:
168
+ unique_id = str(uuid.uuid4())
169
+ filename = f"{now}_{unique_id}_{suffix}.md"
170
+ filepath = os.path.join(logs_dir, filename)
114
171
 
115
172
  # Save file
116
173
  try:
@@ -3,7 +3,14 @@
3
3
  import sys
4
4
  from pathlib import Path
5
5
 
6
- import git
6
+ # 延迟导入git模块以避免启动异常
7
+ try:
8
+ import git
9
+ GIT_AVAILABLE = True
10
+ except ImportError:
11
+ print("Warning: Git module not available. Some git features will be disabled.")
12
+ GIT_AVAILABLE = False
13
+ git = None
7
14
  from diff_match_patch import diff_match_patch
8
15
  from tqdm import tqdm
9
16
  import json
@@ -0,0 +1,24 @@
1
+ """
2
+ Search Replace Patch Module
3
+
4
+ 提供三种文本替换策略:
5
+ 1. 正则表达式替换 (RegexReplacer)
6
+ 2. 补丁库替换 (PatchReplacer)
7
+ 3. 文本相似度替换 (SimilarityReplacer)
8
+ """
9
+
10
+ from .base import BaseReplacer, ReplaceResult, ReplaceStrategy
11
+ from .string_replacer import StringReplacer
12
+ from .patch_replacer import PatchReplacer
13
+ from .similarity_replacer import SimilarityReplacer
14
+ from .manager import SearchReplaceManager
15
+
16
+ __all__ = [
17
+ 'BaseReplacer',
18
+ 'ReplaceResult',
19
+ 'ReplaceStrategy',
20
+ 'StringReplacer',
21
+ 'PatchReplacer',
22
+ 'SimilarityReplacer',
23
+ 'SearchReplaceManager',
24
+ ]
@@ -0,0 +1,115 @@
1
+ """
2
+ Base classes for search replace patch operations
3
+ """
4
+
5
+ from abc import ABC, abstractmethod
6
+ from enum import Enum
7
+ from typing import Optional, Dict, Any, List, Tuple
8
+ from dataclasses import dataclass, field
9
+
10
+
11
+ class ReplaceStrategy(Enum):
12
+ """替换策略枚举"""
13
+ STRING = "string"
14
+ PATCH = "patch"
15
+ SIMILARITY = "similarity"
16
+
17
+
18
+ @dataclass
19
+ class ReplaceResult:
20
+ """替换结果"""
21
+ success: bool
22
+ message: str
23
+ new_content: Optional[str] = None
24
+ applied_count: int = 0
25
+ total_count: int = 0
26
+ errors: List[str] = field(default_factory=list)
27
+ metadata: Dict[str, Any] = field(default_factory=dict)
28
+
29
+
30
+ class BaseReplacer(ABC):
31
+ """文本替换器的抽象基类"""
32
+
33
+ def __init__(self, strategy: ReplaceStrategy):
34
+ self.strategy = strategy
35
+
36
+ @abstractmethod
37
+ def replace(self, content: str, search_blocks: List[Tuple[str, str]]) -> ReplaceResult:
38
+ """
39
+ 执行文本替换操作
40
+
41
+ Args:
42
+ content: 原始文件内容
43
+ search_blocks: 搜索替换块列表 [(search_text, replace_text), ...]
44
+
45
+ Returns:
46
+ ReplaceResult: 替换结果
47
+ """
48
+ pass
49
+
50
+ @abstractmethod
51
+ def can_handle(self, content: str, search_blocks: List[Tuple[str, str]]) -> bool:
52
+ """
53
+ 检查当前替换器是否能处理给定的内容和搜索块
54
+
55
+ Args:
56
+ content: 原始文件内容
57
+ search_blocks: 搜索替换块列表
58
+
59
+ Returns:
60
+ bool: 是否能处理
61
+ """
62
+ pass
63
+
64
+ def get_strategy_name(self) -> str:
65
+ """获取策略名称"""
66
+ return self.strategy.value
67
+
68
+ def validate_search_blocks(self, search_blocks: List[Tuple[str, str]]) -> bool:
69
+ """
70
+ 验证搜索替换块的有效性
71
+
72
+ Args:
73
+ search_blocks: 搜索替换块列表
74
+
75
+ Returns:
76
+ bool: 是否有效
77
+ """
78
+ if not search_blocks:
79
+ return False
80
+
81
+ for search_text, replace_text in search_blocks:
82
+ if not isinstance(search_text, str) or not isinstance(replace_text, str):
83
+ return False
84
+
85
+ # 允许空 search_text,表示"插入"操作(行级插入)
86
+ if search_text == "":
87
+ continue
88
+
89
+ # 其他空白搜索文本仍然无效
90
+ if not search_text.strip():
91
+ return False
92
+
93
+ # 硬约束:只支持行级替换,不支持行内替换
94
+ if not self._is_line_level_replacement(search_text):
95
+ return False
96
+
97
+ return True
98
+
99
+ def _is_line_level_replacement(self, search_text: str) -> bool:
100
+ """
101
+ 检查是否为行级替换
102
+
103
+ Args:
104
+ search_text: 搜索文本
105
+
106
+ Returns:
107
+ bool: 是否为行级替换
108
+ """
109
+ # 如果搜索文本包含换行符,认为是多行替换,允许
110
+ if '\n' in search_text:
111
+ return True
112
+
113
+ # 如果是单行文本,必须是完整的行(以换行符结尾)
114
+ # 但我们放宽条件:允许不以换行符结尾的文本,但在实际替换时会按整行处理
115
+ return True # 暂时放宽,在具体替换器中实施严格约束