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
@@ -1,192 +0,0 @@
1
- from __future__ import annotations
2
- import os, fnmatch, asyncio
3
- from watchfiles import Change
4
- from autocoder.common.ignorefiles.ignore_file_utils import should_ignore
5
- from autocoder.common.file_monitor.monitor import get_file_monitor
6
- import logging
7
- import functools
8
-
9
- logger = logging.getLogger(__name__)
10
-
11
- class DirectoryCache:
12
- _instance: "DirectoryCache|None" = None
13
-
14
- def __init__(self, root: str):
15
- self.root = os.path.abspath(root)
16
- self.files_set: set[str] = set()
17
- self.lock = asyncio.Lock()
18
- self._main_loop = asyncio.get_event_loop() # 保存主事件循环引用
19
- logger.info(f"Initializing DirectoryCache for root: {self.root}")
20
-
21
- # ---------- 单例获取 ----------
22
- @classmethod
23
- def get_instance(cls, root: str | None = None) -> "DirectoryCache":
24
- if cls._instance is None:
25
- if root is None:
26
- raise ValueError("root is required when initializing DirectoryCache for the first time")
27
- logger.info("Creating new DirectoryCache instance.")
28
- cls._instance = cls(root)
29
- cls._instance._build() # 同步首扫
30
- cls._instance._register_monitor()
31
- elif root is not None and os.path.abspath(root) != cls._instance.root:
32
- # 如果请求的 root 与已存在的实例 root 不同,可以选择抛出错误或重新初始化
33
- logger.warning(f"Requested root {os.path.abspath(root)} differs from existing instance root {cls._instance.root}. Re-initializing cache.")
34
- cls._instance = cls(root)
35
- cls._instance._build()
36
- cls._instance._register_monitor()
37
-
38
- return cls._instance
39
-
40
- # ---------- 构建 ----------
41
- def _build(self) -> None:
42
- logger.info(f"Building initial file cache for {self.root}...")
43
- count = 0
44
- for r, ds, fs in os.walk(self.root, followlinks=True):
45
- # 过滤掉需要忽略的目录
46
- ds[:] = [d for d in ds if not should_ignore(os.path.join(r, d))]
47
- for f in fs:
48
- fp = os.path.join(r, f)
49
- abs_fp = os.path.abspath(fp)
50
- if not should_ignore(abs_fp):
51
- self.files_set.add(abs_fp)
52
- count += 1
53
- logger.info(f"Initial cache build complete. Found {count} files.")
54
-
55
-
56
- # ---------- 监控回调 ----------
57
- def _register_monitor(self) -> None:
58
- try:
59
- logger.info(f"Registering file monitor for {self.root}")
60
- mon = get_file_monitor(self.root)
61
- # 使用 functools.partial 包装异步回调
62
- async_callback_wrapper = functools.partial(self._on_change_wrapper)
63
- mon.register("**/*", async_callback_wrapper) # 监听所有文件变化
64
- if not mon.is_running():
65
- logger.info("Starting file monitor...")
66
- mon.start()
67
- logger.info("File monitor registered and running.")
68
- except Exception as e:
69
- logger.error(f"Failed to register or start file monitor: {e}", exc_info=True)
70
-
71
- # Wrapper to run the async callback in the event loop
72
- def _on_change_wrapper(self, change: Change, path: str):
73
- try:
74
- # 使用run_coroutine_threadsafe在主事件循环中运行协程
75
- # 注意:主事件循环必须在其他地方运行,如主线程中
76
- asyncio.run_coroutine_threadsafe(self._on_change(change, path), self._main_loop)
77
- except Exception as e:
78
- logger.error(f"Error executing _on_change_wrapper: {e}", exc_info=True)
79
- # 如果run_coroutine_threadsafe失败,可以考虑一个同步的备用处理方法
80
- try:
81
- # 同步备份处理
82
- ap = os.path.abspath(path)
83
- if should_ignore(ap):
84
- return
85
-
86
- if change is Change.added:
87
- self.files_set.add(ap)
88
- elif change is Change.deleted:
89
- self.files_set.discard(ap)
90
- # Change.modified不需要更新集合
91
- except Exception as backup_error:
92
- logger.error(f"Backup handler also failed: {backup_error}", exc_info=True)
93
-
94
-
95
- async def _on_change(self, change: Change, path: str) -> None:
96
- ap = os.path.abspath(path)
97
- # Check ignore status again, as gitignore might change
98
- if should_ignore(ap):
99
- # If a previously tracked file becomes ignored, remove it
100
- async with self.lock:
101
- if ap in self.files_set:
102
- logger.debug(f"File became ignored, removing from cache: {ap}")
103
- self.files_set.discard(ap)
104
- return
105
-
106
- async with self.lock:
107
- if change is Change.added:
108
- logger.debug(f"File added, adding to cache: {ap}")
109
- self.files_set.add(ap)
110
- elif change is Change.deleted:
111
- logger.debug(f"File deleted, removing from cache: {ap}")
112
- self.files_set.discard(ap)
113
- elif change is Change.modified:
114
- # Modification doesn't change existence, but we might want to log or handle metadata updates if needed
115
- logger.debug(f"File modified: {ap} (ignored in cache set)")
116
- pass # No change needed for the set itself
117
-
118
- # ---------- 查询 ----------
119
- async def query(self, patterns: list[str]) -> list[str]:
120
- logger.debug(f"Querying cache with patterns: {patterns}")
121
- async with self.lock:
122
- # Make a copy to avoid issues if the set is modified during iteration (though lock prevents this here)
123
- current_files = list(self.files_set)
124
-
125
- if not patterns or patterns == [""] or patterns == ["*"]:
126
- logger.debug(f"Returning all {len(current_files)} cached files.")
127
- return current_files
128
-
129
- out: set[str] = set()
130
-
131
- for p in patterns:
132
- pattern_abs = os.path.abspath(os.path.join(self.root, p)) if not os.path.isabs(p) else p
133
- is_glob = "*" in p or "?" in p or "[" in p # More robust glob check
134
-
135
- try:
136
- if is_glob:
137
- # fnmatch expects relative paths for matching within a root usually,
138
- # but here we match against absolute paths in files_set.
139
- # We need a pattern that works with absolute paths.
140
- # If pattern 'p' is like '*.py', we need to match '/path/to/root/**/*.py'
141
- # Let's adjust the pattern logic or filtering logic.
142
-
143
- # Option 1: Match relative paths within the root
144
- # Convert absolute paths in files_set to relative for matching
145
- # relative_files = [os.path.relpath(f, self.root) for f in current_files]
146
- # matched_relative = fnmatch.filter(relative_files, p)
147
- # out.update(os.path.join(self.root, rel_f) for rel_f in matched_relative)
148
-
149
- # Option 2: Match absolute paths directly (might need careful pattern construction)
150
- # If p is relative, make it absolute based on root for matching
151
- # Example: p = "src/*.py" -> effective_pattern = "/path/to/root/src/*.py"
152
- # This requires fnmatch to handle absolute paths correctly or custom logic.
153
-
154
- # Option 3: Simplified wildcard matching on absolute paths
155
- # Treat '*' as a general wildcard anywhere in the path.
156
- # fnmatch.filter might work if the pattern is constructed like `*pattern*`
157
- # Let's stick to the user's original logic first, assuming it worked for their case
158
- # The original `*{p}*` suggests substring matching with wildcards? Let's refine.
159
-
160
- # Refined Glob Matching:
161
- # If p contains wildcards, assume it's a glob pattern relative to root.
162
- # Convert files_set paths to relative for matching.
163
- for f_abs in current_files:
164
- f_rel = os.path.relpath(f_abs, self.root)
165
- if fnmatch.fnmatch(f_rel, p) or fnmatch.fnmatch(os.path.basename(f_abs), p):
166
- out.add(f_abs)
167
-
168
- else:
169
- # Exact or substring matching for non-glob patterns
170
- # Match against filename or full path segment
171
- p_lower = p.lower()
172
- for f_abs in current_files:
173
- if p_lower in os.path.basename(f_abs).lower() or p_lower in f_abs.lower():
174
- out.add(f_abs)
175
-
176
- except Exception as e:
177
- logger.error(f"Error during pattern matching for '{p}': {e}", exc_info=True)
178
-
179
-
180
- result = sorted(list(out)) # Sort for consistent output
181
- logger.debug(f"Query returned {len(result)} files.")
182
- return result
183
-
184
- # Helper function (optional, could be integrated into get_instance)
185
- def initialize_cache(root_path: str):
186
- """Initializes the DirectoryCache singleton."""
187
- try:
188
- DirectoryCache.get_instance(root_path)
189
- logger.info("DirectoryCache initialized successfully.")
190
- except Exception as e:
191
- logger.error(f"Failed to initialize DirectoryCache: {e}", exc_info=True)
192
-
@@ -1,190 +0,0 @@
1
- import pytest
2
- import os
3
- import tempfile
4
- import shutil
5
- import asyncio
6
- from unittest.mock import patch, MagicMock
7
-
8
- # 导入被测模块
9
- from autocoder.common.directory_cache.cache import DirectoryCache
10
-
11
- # 测试环境辅助函数
12
- def create_test_environment(base_dir, structure):
13
- """创建测试所需的文件/目录结构"""
14
- for path, content in structure.items():
15
- full_path = os.path.join(base_dir, path)
16
- os.makedirs(os.path.dirname(full_path), exist_ok=True)
17
- with open(full_path, 'w', encoding='utf-8') as f:
18
- f.write(content)
19
-
20
- # Pytest Fixture: 临时目录
21
- @pytest.fixture(scope="function")
22
- def temp_test_dir():
23
- """提供一个临时的、测试后自动清理的目录"""
24
- temp_dir = tempfile.mkdtemp()
25
- print(f"创建测试临时目录: {temp_dir}")
26
- yield temp_dir
27
- print(f"清理测试临时目录: {temp_dir}")
28
- shutil.rmtree(temp_dir)
29
-
30
- # Pytest Fixture: 重置单例
31
- @pytest.fixture(autouse=True)
32
- def reset_singleton():
33
- """每次测试前重置DirectoryCache单例"""
34
- DirectoryCache._instance = None
35
- yield
36
- DirectoryCache._instance = None
37
-
38
- # Pytest Fixture: 文件监视器模拟
39
- @pytest.fixture
40
- def mock_file_monitor():
41
- """模拟文件监视器"""
42
- mock_monitor = MagicMock()
43
- mock_monitor.register = MagicMock()
44
- mock_monitor.is_running = MagicMock(return_value=False)
45
- mock_monitor.start = MagicMock()
46
-
47
- with patch('autocoder.common.directory_cache.cache.get_file_monitor', return_value=mock_monitor):
48
- yield mock_monitor
49
-
50
- # --- 测试用例 ---
51
-
52
- @pytest.mark.asyncio
53
- async def test_initialization(temp_test_dir, mock_file_monitor):
54
- """测试DirectoryCache的初始化和单例模式"""
55
- # 创建测试文件结构
56
- create_test_environment(temp_test_dir, {
57
- "file1.txt": "测试内容1",
58
- "subdir/file2.txt": "测试内容2",
59
- ".gitignore": "*.ignored"
60
- })
61
- create_test_environment(temp_test_dir, {
62
- "file3.ignored": "这个文件应该被忽略"
63
- })
64
-
65
- # 获取实例
66
- cache = DirectoryCache.get_instance(temp_test_dir)
67
-
68
- # 验证单例模式
69
- assert DirectoryCache.get_instance() is cache
70
- assert cache.root == os.path.abspath(temp_test_dir)
71
-
72
- # 验证文件缓存构建
73
- assert len(cache.files_set) == 3 # file1.txt, subdir/file2.txt, .gitignore
74
- assert os.path.join(temp_test_dir, "file1.txt") in [os.path.normpath(f) for f in cache.files_set]
75
- assert os.path.join(temp_test_dir, "subdir/file2.txt") in [os.path.normpath(f) for f in cache.files_set]
76
-
77
- # 验证监视器注册
78
- mock_file_monitor.register.assert_called_once()
79
- mock_file_monitor.start.assert_called_once()
80
-
81
- @pytest.mark.asyncio
82
- async def test_query_all_files(temp_test_dir, mock_file_monitor):
83
- """测试查询所有文件"""
84
- # 创建测试文件结构
85
- create_test_environment(temp_test_dir, {
86
- "file1.py": "def test(): pass",
87
- "file2.txt": "text content",
88
- "subdir/file3.py": "class Test: pass"
89
- })
90
-
91
- # 获取实例并查询所有文件
92
- cache = DirectoryCache.get_instance(temp_test_dir)
93
- result = await cache.query(["*"])
94
-
95
- # 验证结果
96
- assert len(result) == 3
97
- assert sorted([os.path.basename(f) for f in result]) == ["file1.py", "file2.txt", "file3.py"]
98
-
99
- @pytest.mark.asyncio
100
- async def test_query_with_pattern(temp_test_dir, mock_file_monitor):
101
- """测试使用模式查询文件"""
102
- # 创建测试文件结构
103
- create_test_environment(temp_test_dir, {
104
- "file1.py": "def test(): pass",
105
- "file2.txt": "text content",
106
- "subdir/file3.py": "class Test: pass",
107
- "another.doc": "document"
108
- })
109
-
110
- # 获取实例
111
- cache = DirectoryCache.get_instance(temp_test_dir)
112
-
113
- # 测试不同的查询模式
114
- py_files = await cache.query(["*.py"])
115
- assert len(py_files) == 2
116
- assert all(f.endswith('.py') for f in py_files)
117
-
118
- txt_files = await cache.query(["*.txt"])
119
- assert len(txt_files) == 1
120
- assert txt_files[0].endswith('file2.txt')
121
-
122
- # 测试多模式查询
123
- mixed_files = await cache.query(["*.py", "*.txt"])
124
- assert len(mixed_files) == 3
125
- assert len([f for f in mixed_files if f.endswith('.py')]) == 2
126
- assert len([f for f in mixed_files if f.endswith('.txt')]) == 1
127
-
128
- @pytest.mark.asyncio
129
- async def test_file_change_events(temp_test_dir, mock_file_monitor):
130
- """测试文件变更事件处理"""
131
- from watchfiles import Change
132
-
133
- # 创建测试文件结构
134
- create_test_environment(temp_test_dir, {
135
- "file1.txt": "初始内容"
136
- })
137
-
138
- # 获取实例
139
- cache = DirectoryCache.get_instance(temp_test_dir)
140
-
141
- # 初始状态
142
- file_path = os.path.join(temp_test_dir, "file1.txt")
143
- abs_file_path = os.path.abspath(file_path)
144
- assert abs_file_path in cache.files_set
145
-
146
- # 测试删除事件
147
- await cache._on_change(Change.deleted, abs_file_path)
148
- assert abs_file_path not in cache.files_set
149
-
150
- # 测试添加事件
151
- await cache._on_change(Change.added, abs_file_path)
152
- assert abs_file_path in cache.files_set
153
-
154
- # 测试修改事件 (不应改变集合)
155
- initial_set_size = len(cache.files_set)
156
- await cache._on_change(Change.modified, abs_file_path)
157
- assert len(cache.files_set) == initial_set_size
158
- assert abs_file_path in cache.files_set
159
-
160
- # 测试新文件
161
- new_file_path = os.path.join(temp_test_dir, "newfile.txt")
162
- abs_new_file_path = os.path.abspath(new_file_path)
163
- await cache._on_change(Change.added, abs_new_file_path)
164
- assert abs_new_file_path in cache.files_set
165
-
166
- @pytest.mark.asyncio
167
- async def test_reinitialization_with_different_root(temp_test_dir, mock_file_monitor):
168
- """测试使用不同根目录重新初始化缓存"""
169
- # 创建第一个测试目录
170
- first_dir = os.path.join(temp_test_dir, "first")
171
- os.makedirs(first_dir)
172
- create_test_environment(first_dir, {"test.txt": "first directory"})
173
-
174
- # 初始化缓存
175
- cache1 = DirectoryCache.get_instance(first_dir)
176
- assert cache1.root == os.path.abspath(first_dir)
177
-
178
- # 创建第二个测试目录
179
- second_dir = os.path.join(temp_test_dir, "second")
180
- os.makedirs(second_dir)
181
- create_test_environment(second_dir, {"other.txt": "second directory"})
182
-
183
- # 使用新目录重新初始化
184
- cache2 = DirectoryCache.get_instance(second_dir)
185
- assert cache2.root == os.path.abspath(second_dir)
186
-
187
- # 验证文件集合已更新
188
- all_files = await cache2.query(["*"])
189
- assert len(all_files) == 1
190
- assert all_files[0].endswith('other.txt')
@@ -1,217 +0,0 @@
1
- """
2
- 文件变更管理模块的使用示例
3
-
4
- 展示如何使用文件变更管理模块进行文件变更的应用和撤销。
5
- """
6
-
7
- import os
8
- import sys
9
- import json
10
- from typing import Dict, Any
11
-
12
- from autocoder.common.file_checkpoint.models import FileChange
13
- from autocoder.common.file_checkpoint.manager import FileChangeManager
14
-
15
-
16
- def example_apply_changes(project_dir: str):
17
- """
18
- 示例:应用文件变更
19
-
20
- Args:
21
- project_dir: 项目目录
22
- """
23
- print(f"示例:应用文件变更到项目 {project_dir}")
24
-
25
- # 创建文件变更管理器
26
- manager = FileChangeManager(project_dir)
27
-
28
- # 准备文件变更
29
- changes = {
30
- "example.txt": FileChange(
31
- file_path="example.txt",
32
- content="这是一个示例文件\n用于演示文件变更管理模块的功能\n",
33
- is_new=True
34
- ),
35
- "README.md": FileChange(
36
- file_path="README.md",
37
- content="# 示例项目\n\n这是一个用于演示文件变更管理模块的示例项目。\n",
38
- is_new=True
39
- )
40
- }
41
-
42
- # 应用变更
43
- result = manager.apply_changes(changes)
44
-
45
- # 输出结果
46
- if result.success:
47
- print(f"成功应用了 {len(result.change_ids)} 个文件变更")
48
- for change_id in result.change_ids:
49
- print(f" - 变更ID: {change_id}")
50
- else:
51
- print("应用变更失败")
52
- for file_path, error in result.errors.items():
53
- print(f" - {file_path}: {error}")
54
-
55
-
56
- def example_preview_changes(project_dir: str):
57
- """
58
- 示例:预览文件变更
59
-
60
- Args:
61
- project_dir: 项目目录
62
- """
63
- print(f"示例:预览文件变更")
64
-
65
- # 创建文件变更管理器
66
- manager = FileChangeManager(project_dir)
67
-
68
- # 准备文件变更
69
- changes = {
70
- "example.txt": FileChange(
71
- file_path="example.txt",
72
- content="这是一个修改后的示例文件\n用于演示文件变更管理模块的功能\n新增的一行\n",
73
- is_new=False
74
- )
75
- }
76
-
77
- # 预览变更
78
- diff_results = manager.preview_changes(changes)
79
-
80
- # 输出差异
81
- for file_path, diff_result in diff_results.items():
82
- print(f"\n文件: {file_path}")
83
- print(diff_result.get_diff_summary())
84
- if diff_result.old_content is not None and not diff_result.is_new and not diff_result.is_deletion:
85
- diff_text = manager.get_diff_text(diff_result.old_content, diff_result.new_content)
86
- print("\n差异:")
87
- print(diff_text)
88
-
89
-
90
- def example_undo_changes(project_dir: str):
91
- """
92
- 示例:撤销文件变更
93
-
94
- Args:
95
- project_dir: 项目目录
96
- """
97
- print(f"示例:撤销文件变更")
98
-
99
- # 创建文件变更管理器
100
- manager = FileChangeManager(project_dir)
101
-
102
- # 撤销最近的变更
103
- result = manager.undo_last_change()
104
-
105
- # 输出结果
106
- if result.success:
107
- print(f"成功撤销了变更,恢复了 {len(result.restored_files)} 个文件")
108
- for file_path in result.restored_files:
109
- print(f" - {file_path}")
110
- else:
111
- print("撤销变更失败")
112
- for file_path, error in result.errors.items():
113
- print(f" - {file_path}: {error}")
114
-
115
-
116
- def example_get_history(project_dir: str):
117
- """
118
- 示例:获取变更历史
119
-
120
- Args:
121
- project_dir: 项目目录
122
- """
123
- print(f"示例:获取变更历史")
124
-
125
- # 创建文件变更管理器
126
- manager = FileChangeManager(project_dir)
127
-
128
- # 获取变更历史
129
- changes = manager.get_change_history(limit=5)
130
-
131
- # 输出历史记录
132
- print(f"最近 {len(changes)} 条变更记录:")
133
- for change in changes:
134
- timestamp = change.timestamp
135
- file_path = change.file_path
136
- change_type = "新建" if change.is_new else "删除" if change.is_deletion else "修改"
137
- print(f" - [{timestamp}] {change_type} {file_path} (ID: {change.change_id})")
138
-
139
-
140
- def example_integration_with_agentic_edit():
141
- """
142
- 示例:与 AgenticEdit 集成
143
-
144
- 展示如何将文件变更管理模块集成到 AgenticEdit 中
145
- """
146
- print("示例:与 AgenticEdit 集成")
147
-
148
- # 这是一个伪代码示例,展示如何修改 AgenticEdit.apply_changes 方法
149
- code = """
150
- def apply_changes(self):
151
- \"\"\"
152
- Apply all tracked file changes to the original project directory.
153
- \"\"\"
154
- from autocoder.common.file_checkpoint.models import FileChange
155
- from autocoder.common.file_checkpoint.manager import FileChangeManager
156
-
157
- # 创建文件变更管理器
158
- manager = FileChangeManager(self.args.source_dir)
159
-
160
- # 将影子系统的变更转换为 FileChange 对象
161
- changes = {}
162
- for file_path, change in self.get_all_file_changes().items():
163
- changes[file_path] = FileChange(
164
- file_path=file_path,
165
- content=change.content,
166
- is_new=not os.path.exists(file_path)
167
- )
168
-
169
- # 应用变更
170
- result = manager.apply_changes(changes)
171
-
172
- # 处理结果
173
- if result.success:
174
- # 继续执行原有的 Git 提交等逻辑
175
- if not self.args.skip_commit:
176
- try:
177
- # ... 原有的 Git 提交代码 ...
178
- except Exception as e:
179
- # ... 原有的错误处理 ...
180
- else:
181
- # 处理应用变更失败的情况
182
- error_messages = "\\n".join([f"{path}: {error}" for path, error in result.errors.items()])
183
- self.printer.print_str_in_terminal(
184
- f"Failed to apply changes:\\n{error_messages}",
185
- style="red"
186
- )
187
- """
188
-
189
- print(code)
190
-
191
-
192
- def main():
193
- """主函数"""
194
- if len(sys.argv) < 2:
195
- print("用法: python examples.py <项目目录>")
196
- return
197
-
198
- project_dir = sys.argv[1]
199
-
200
- # 运行示例
201
- example_apply_changes(project_dir)
202
- print("\n" + "-" * 50 + "\n")
203
-
204
- example_preview_changes(project_dir)
205
- print("\n" + "-" * 50 + "\n")
206
-
207
- example_get_history(project_dir)
208
- print("\n" + "-" * 50 + "\n")
209
-
210
- example_undo_changes(project_dir)
211
- print("\n" + "-" * 50 + "\n")
212
-
213
- example_integration_with_agentic_edit()
214
-
215
-
216
- if __name__ == "__main__":
217
- main()