auto-coder 0.1.400__py3-none-any.whl → 2.0.0__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 (579) hide show
  1. auto_coder-2.0.0.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.0.dist-info/METADATA +558 -0
  3. auto_coder-2.0.0.dist-info/RECORD +795 -0
  4. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
  5. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.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 +25 -4
  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 +73 -59
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +1029 -2310
  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 +1021 -372
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +26 -9
  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 +401 -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/file_monitor/test_file_monitor.py +307 -0
  119. autocoder/common/git_utils.py +51 -10
  120. autocoder/common/global_cancel.py +15 -6
  121. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  122. autocoder/common/international/__init__.py +31 -0
  123. autocoder/common/international/demo_international.py +92 -0
  124. autocoder/common/international/message_manager.py +157 -0
  125. autocoder/common/international/messages/__init__.py +56 -0
  126. autocoder/common/international/messages/async_command_messages.py +507 -0
  127. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  128. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  129. autocoder/common/international/messages/command_help_messages.py +986 -0
  130. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  131. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  132. autocoder/common/international/messages/queue_command_messages.py +751 -0
  133. autocoder/common/international/messages/rules_command_messages.py +77 -0
  134. autocoder/common/international/messages/sdk_messages.py +1707 -0
  135. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  136. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  137. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  138. autocoder/common/international/test_international.py +612 -0
  139. autocoder/common/linter_core/__init__.py +28 -0
  140. autocoder/common/linter_core/base_linter.py +61 -0
  141. autocoder/common/linter_core/config_loader.py +271 -0
  142. autocoder/common/linter_core/formatters/__init__.py +0 -0
  143. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  144. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  145. autocoder/common/linter_core/linter.py +166 -0
  146. autocoder/common/linter_core/linter_factory.py +216 -0
  147. autocoder/common/linter_core/linter_manager.py +333 -0
  148. autocoder/common/linter_core/linters/__init__.py +9 -0
  149. autocoder/common/linter_core/linters/java_linter.py +342 -0
  150. autocoder/common/linter_core/linters/python_linter.py +115 -0
  151. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  152. autocoder/common/linter_core/models/__init__.py +7 -0
  153. autocoder/common/linter_core/models/lint_result.py +91 -0
  154. autocoder/common/linter_core/models.py +33 -0
  155. autocoder/common/linter_core/tests/__init__.py +3 -0
  156. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  157. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  158. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  159. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  160. autocoder/common/linter_core/tests/test_integration.py +317 -0
  161. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  162. autocoder/common/linter_core/tests/test_linters.py +265 -0
  163. autocoder/common/linter_core/tests/test_models.py +81 -0
  164. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  165. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  166. autocoder/common/llm_friendly_package/__init__.py +31 -0
  167. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  168. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  169. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  170. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  171. autocoder/common/llm_friendly_package/models.py +40 -0
  172. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  173. autocoder/common/llms/__init__.py +15 -0
  174. autocoder/common/llms/demo_error_handling.py +85 -0
  175. autocoder/common/llms/factory.py +142 -0
  176. autocoder/common/llms/manager.py +264 -0
  177. autocoder/common/llms/pricing.py +121 -0
  178. autocoder/common/llms/registry.py +288 -0
  179. autocoder/common/llms/schema.py +77 -0
  180. autocoder/common/llms/simple_demo.py +45 -0
  181. autocoder/common/llms/test_quick_model.py +116 -0
  182. autocoder/common/llms/test_remove_functionality.py +182 -0
  183. autocoder/common/llms/tests/__init__.py +1 -0
  184. autocoder/common/llms/tests/test_manager.py +330 -0
  185. autocoder/common/llms/tests/test_registry.py +364 -0
  186. autocoder/common/mcp_tools/__init__.py +62 -0
  187. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  188. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  189. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  190. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  191. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  192. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  193. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  194. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  195. autocoder/common/model_speed_tester.py +32 -26
  196. autocoder/common/priority_directory_finder/__init__.py +142 -0
  197. autocoder/common/priority_directory_finder/examples.py +230 -0
  198. autocoder/common/priority_directory_finder/finder.py +283 -0
  199. autocoder/common/priority_directory_finder/models.py +236 -0
  200. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  201. autocoder/common/project_scanner/__init__.py +18 -0
  202. autocoder/common/project_scanner/compat.py +77 -0
  203. autocoder/common/project_scanner/scanner.py +436 -0
  204. autocoder/common/project_tracker/__init__.py +27 -0
  205. autocoder/common/project_tracker/api.py +228 -0
  206. autocoder/common/project_tracker/demo.py +272 -0
  207. autocoder/common/project_tracker/tracker.py +487 -0
  208. autocoder/common/project_tracker/types.py +53 -0
  209. autocoder/common/pruner/__init__.py +67 -0
  210. autocoder/common/pruner/agentic_conversation_pruner.py +746 -0
  211. autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
  212. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  213. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  214. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  215. autocoder/common/pruner/conversation_normalizer.py +347 -0
  216. autocoder/common/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
  217. autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
  218. autocoder/common/pruner/test_context_pruner.py +546 -0
  219. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  220. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  221. autocoder/common/pruner/tool_content_detector.py +227 -0
  222. autocoder/common/pruner/tools/__init__.py +18 -0
  223. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  224. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  225. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  226. autocoder/common/pull_requests/__init__.py +9 -1
  227. autocoder/common/pull_requests/utils.py +122 -1
  228. autocoder/common/rag_manager/rag_manager.py +36 -40
  229. autocoder/common/rulefiles/__init__.py +53 -1
  230. autocoder/common/rulefiles/api.py +250 -0
  231. autocoder/common/rulefiles/core/__init__.py +14 -0
  232. autocoder/common/rulefiles/core/manager.py +241 -0
  233. autocoder/common/rulefiles/core/selector.py +805 -0
  234. autocoder/common/rulefiles/models/__init__.py +20 -0
  235. autocoder/common/rulefiles/models/index.py +16 -0
  236. autocoder/common/rulefiles/models/init_rule.py +18 -0
  237. autocoder/common/rulefiles/models/rule_file.py +18 -0
  238. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  239. autocoder/common/rulefiles/models/summary.py +16 -0
  240. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  241. autocoder/common/rulefiles/utils/__init__.py +34 -0
  242. autocoder/common/rulefiles/utils/monitor.py +86 -0
  243. autocoder/common/rulefiles/utils/parser.py +230 -0
  244. autocoder/common/save_formatted_log.py +67 -10
  245. autocoder/common/search_replace.py +8 -1
  246. autocoder/common/search_replace_patch/__init__.py +24 -0
  247. autocoder/common/search_replace_patch/base.py +115 -0
  248. autocoder/common/search_replace_patch/manager.py +248 -0
  249. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  250. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  251. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  252. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  253. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  254. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  255. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  256. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  257. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  258. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  259. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  260. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  261. autocoder/common/shell_commands/__init__.py +197 -0
  262. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  263. autocoder/common/shell_commands/command_executor.py +1127 -0
  264. autocoder/common/shell_commands/error_recovery.py +541 -0
  265. autocoder/common/shell_commands/exceptions.py +120 -0
  266. autocoder/common/shell_commands/interactive_executor.py +476 -0
  267. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  268. autocoder/common/shell_commands/interactive_process.py +744 -0
  269. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  270. autocoder/common/shell_commands/monitoring.py +529 -0
  271. autocoder/common/shell_commands/process_cleanup.py +386 -0
  272. autocoder/common/shell_commands/process_manager.py +606 -0
  273. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  274. autocoder/common/shell_commands/tests/__init__.py +6 -0
  275. autocoder/common/shell_commands/tests/conftest.py +118 -0
  276. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  277. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  278. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  279. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  280. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  281. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  282. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  283. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  284. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  285. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  286. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  287. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  288. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  289. autocoder/common/shell_commands/timeout_config.py +315 -0
  290. autocoder/common/shell_commands/timeout_manager.py +352 -0
  291. autocoder/common/terminal_paste/__init__.py +14 -0
  292. autocoder/common/terminal_paste/demo.py +145 -0
  293. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  294. autocoder/common/terminal_paste/paste_handler.py +200 -0
  295. autocoder/common/terminal_paste/paste_manager.py +118 -0
  296. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  297. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  298. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  299. autocoder/common/terminal_paste/utils.py +163 -0
  300. autocoder/common/test_autocoder_args.py +232 -0
  301. autocoder/common/test_env_manager.py +173 -0
  302. autocoder/common/test_env_manager_integration.py +159 -0
  303. autocoder/common/text_similarity/__init__.py +9 -0
  304. autocoder/common/text_similarity/demo.py +216 -0
  305. autocoder/common/text_similarity/examples.py +266 -0
  306. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  307. autocoder/common/text_similarity/text_similarity.py +194 -0
  308. autocoder/common/text_similarity/utils.py +125 -0
  309. autocoder/common/todos/__init__.py +61 -0
  310. autocoder/common/todos/cache/__init__.py +16 -0
  311. autocoder/common/todos/cache/base_cache.py +89 -0
  312. autocoder/common/todos/cache/cache_manager.py +228 -0
  313. autocoder/common/todos/cache/memory_cache.py +225 -0
  314. autocoder/common/todos/config.py +155 -0
  315. autocoder/common/todos/exceptions.py +35 -0
  316. autocoder/common/todos/get_todo_manager.py +161 -0
  317. autocoder/common/todos/manager.py +537 -0
  318. autocoder/common/todos/models.py +239 -0
  319. autocoder/common/todos/storage/__init__.py +14 -0
  320. autocoder/common/todos/storage/base_storage.py +76 -0
  321. autocoder/common/todos/storage/file_storage.py +278 -0
  322. autocoder/common/tokens/__init__.py +15 -0
  323. autocoder/common/tokens/counter.py +44 -2
  324. autocoder/common/tools_manager/__init__.py +17 -0
  325. autocoder/common/tools_manager/examples.py +162 -0
  326. autocoder/common/tools_manager/manager.py +385 -0
  327. autocoder/common/tools_manager/models.py +39 -0
  328. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  329. autocoder/common/tools_manager/utils.py +191 -0
  330. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  331. autocoder/common/v2/agent/agentic_edit.py +2729 -2052
  332. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
  338. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  340. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +565 -30
  344. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  346. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  347. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  349. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  350. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +244 -51
  352. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  353. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  354. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +409 -140
  355. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  356. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +209 -194
  359. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
  360. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
  361. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  362. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  363. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  364. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  365. autocoder/common/v2/agent/agentic_edit_types.py +386 -10
  366. autocoder/common/v2/agent/runner/__init__.py +31 -0
  367. autocoder/common/v2/agent/runner/base_runner.py +92 -0
  368. autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
  369. autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
  370. autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
  371. autocoder/common/v2/agent/runner/tool_display.py +589 -0
  372. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  373. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  374. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  375. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  376. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  377. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  378. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  379. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  380. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  381. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  382. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  383. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  384. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  385. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  386. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  387. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  388. autocoder/common/v2/code_auto_generate.py +136 -78
  389. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  390. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  391. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  392. autocoder/common/v2/code_auto_merge.py +1 -1
  393. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  394. autocoder/common/v2/code_diff_manager.py +3 -3
  395. autocoder/common/v2/code_editblock_manager.py +4 -14
  396. autocoder/common/v2/code_manager.py +1 -1
  397. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  398. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  399. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  400. autocoder/common/wrap_llm_hint/utils.py +432 -0
  401. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  402. autocoder/completer/__init__.py +8 -0
  403. autocoder/completer/command_completer_v2.py +1051 -0
  404. autocoder/default_project/__init__.py +501 -0
  405. autocoder/dispacher/__init__.py +4 -12
  406. autocoder/dispacher/actions/action.py +165 -7
  407. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  408. autocoder/index/entry.py +117 -125
  409. autocoder/{agent → index/filter}/agentic_filter.py +323 -334
  410. autocoder/index/filter/normal_filter.py +5 -11
  411. autocoder/index/filter/quick_filter.py +1 -1
  412. autocoder/index/index.py +36 -9
  413. autocoder/index/tests/__init__.py +1 -0
  414. autocoder/index/tests/run_tests.py +195 -0
  415. autocoder/index/tests/test_entry.py +303 -0
  416. autocoder/index/tests/test_index_manager.py +314 -0
  417. autocoder/index/tests/test_module_integration.py +300 -0
  418. autocoder/index/tests/test_symbols_utils.py +183 -0
  419. autocoder/inner/__init__.py +4 -0
  420. autocoder/inner/agentic.py +932 -0
  421. autocoder/inner/async_command_handler.py +992 -0
  422. autocoder/inner/conversation_command_handlers.py +623 -0
  423. autocoder/inner/merge_command_handler.py +213 -0
  424. autocoder/inner/queue_command_handler.py +684 -0
  425. autocoder/models.py +95 -266
  426. autocoder/plugins/git_helper_plugin.py +31 -29
  427. autocoder/plugins/token_helper_plugin.py +156 -37
  428. autocoder/pyproject/__init__.py +32 -29
  429. autocoder/rag/agentic_rag.py +215 -75
  430. autocoder/rag/cache/simple_cache.py +1 -2
  431. autocoder/rag/loaders/image_loader.py +1 -1
  432. autocoder/rag/long_context_rag.py +42 -26
  433. autocoder/rag/qa_conversation_strategy.py +1 -1
  434. autocoder/rag/terminal/__init__.py +17 -0
  435. autocoder/rag/terminal/args.py +581 -0
  436. autocoder/rag/terminal/bootstrap.py +61 -0
  437. autocoder/rag/terminal/command_handlers.py +653 -0
  438. autocoder/rag/terminal/formatters/__init__.py +20 -0
  439. autocoder/rag/terminal/formatters/base.py +70 -0
  440. autocoder/rag/terminal/formatters/json_format.py +66 -0
  441. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  442. autocoder/rag/terminal/formatters/text.py +28 -0
  443. autocoder/rag/terminal/init.py +120 -0
  444. autocoder/rag/terminal/utils.py +106 -0
  445. autocoder/rag/test_agentic_rag.py +389 -0
  446. autocoder/rag/test_doc_filter.py +3 -3
  447. autocoder/rag/test_long_context_rag.py +1 -1
  448. autocoder/rag/test_token_limiter.py +517 -10
  449. autocoder/rag/token_counter.py +3 -0
  450. autocoder/rag/token_limiter.py +19 -15
  451. autocoder/rag/tools/__init__.py +26 -2
  452. autocoder/rag/tools/bochaai_example.py +343 -0
  453. autocoder/rag/tools/bochaai_sdk.py +541 -0
  454. autocoder/rag/tools/metaso_example.py +268 -0
  455. autocoder/rag/tools/metaso_sdk.py +417 -0
  456. autocoder/rag/tools/recall_tool.py +28 -7
  457. autocoder/rag/tools/run_integration_tests.py +204 -0
  458. autocoder/rag/tools/test_all_providers.py +318 -0
  459. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  460. autocoder/rag/tools/test_final_integration.py +215 -0
  461. autocoder/rag/tools/test_metaso_integration.py +424 -0
  462. autocoder/rag/tools/test_metaso_real.py +171 -0
  463. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  464. autocoder/rag/tools/test_web_search_tool.py +509 -0
  465. autocoder/rag/tools/todo_read_tool.py +202 -0
  466. autocoder/rag/tools/todo_write_tool.py +412 -0
  467. autocoder/rag/tools/web_crawl_tool.py +634 -0
  468. autocoder/rag/tools/web_search_tool.py +558 -0
  469. autocoder/rag/tools/web_tools_example.py +119 -0
  470. autocoder/rag/types.py +16 -0
  471. autocoder/rag/variable_holder.py +4 -2
  472. autocoder/rags.py +86 -79
  473. autocoder/regexproject/__init__.py +23 -21
  474. autocoder/run_context.py +9 -0
  475. autocoder/sdk/__init__.py +50 -161
  476. autocoder/sdk/api.py +370 -0
  477. autocoder/sdk/async_runner/__init__.py +26 -0
  478. autocoder/sdk/async_runner/async_executor.py +650 -0
  479. autocoder/sdk/async_runner/async_handler.py +356 -0
  480. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  481. autocoder/sdk/async_runner/task_metadata.py +284 -0
  482. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  483. autocoder/sdk/cli/__init__.py +2 -5
  484. autocoder/sdk/cli/formatters.py +28 -204
  485. autocoder/sdk/cli/handlers.py +77 -44
  486. autocoder/sdk/cli/main.py +158 -170
  487. autocoder/sdk/cli/options.py +95 -22
  488. autocoder/sdk/constants.py +139 -51
  489. autocoder/sdk/core/auto_coder_core.py +484 -267
  490. autocoder/sdk/core/bridge.py +298 -118
  491. autocoder/sdk/exceptions.py +18 -12
  492. autocoder/sdk/formatters/__init__.py +19 -0
  493. autocoder/sdk/formatters/input.py +64 -0
  494. autocoder/sdk/formatters/output.py +247 -0
  495. autocoder/sdk/formatters/stream.py +54 -0
  496. autocoder/sdk/models/__init__.py +6 -5
  497. autocoder/sdk/models/options.py +55 -18
  498. autocoder/sdk/utils/formatters.py +27 -195
  499. autocoder/suffixproject/__init__.py +28 -25
  500. autocoder/terminal/__init__.py +14 -0
  501. autocoder/terminal/app.py +454 -0
  502. autocoder/terminal/args.py +32 -0
  503. autocoder/terminal/bootstrap.py +178 -0
  504. autocoder/terminal/command_processor.py +521 -0
  505. autocoder/terminal/command_registry.py +57 -0
  506. autocoder/terminal/help.py +97 -0
  507. autocoder/terminal/tasks/__init__.py +5 -0
  508. autocoder/terminal/tasks/background.py +77 -0
  509. autocoder/terminal/tasks/task_event.py +70 -0
  510. autocoder/terminal/ui/__init__.py +13 -0
  511. autocoder/terminal/ui/completer.py +268 -0
  512. autocoder/terminal/ui/keybindings.py +75 -0
  513. autocoder/terminal/ui/session.py +41 -0
  514. autocoder/terminal/ui/toolbar.py +64 -0
  515. autocoder/terminal/utils/__init__.py +13 -0
  516. autocoder/terminal/utils/errors.py +18 -0
  517. autocoder/terminal/utils/paths.py +19 -0
  518. autocoder/terminal/utils/shell.py +43 -0
  519. autocoder/terminal_v3/__init__.py +10 -0
  520. autocoder/terminal_v3/app.py +201 -0
  521. autocoder/terminal_v3/handlers/__init__.py +5 -0
  522. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  523. autocoder/terminal_v3/models/__init__.py +6 -0
  524. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  525. autocoder/terminal_v3/models/message.py +50 -0
  526. autocoder/terminal_v3/models/tool_display.py +247 -0
  527. autocoder/terminal_v3/ui/__init__.py +7 -0
  528. autocoder/terminal_v3/ui/keybindings.py +56 -0
  529. autocoder/terminal_v3/ui/layout.py +141 -0
  530. autocoder/terminal_v3/ui/styles.py +43 -0
  531. autocoder/tsproject/__init__.py +23 -23
  532. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  533. autocoder/utils/llms.py +88 -80
  534. autocoder/utils/math_utils.py +101 -0
  535. autocoder/utils/model_provider_selector.py +16 -4
  536. autocoder/utils/operate_config_api.py +33 -5
  537. autocoder/utils/thread_utils.py +2 -2
  538. autocoder/version.py +4 -2
  539. autocoder/workflow_agents/__init__.py +84 -0
  540. autocoder/workflow_agents/agent.py +143 -0
  541. autocoder/workflow_agents/exceptions.py +573 -0
  542. autocoder/workflow_agents/executor.py +489 -0
  543. autocoder/workflow_agents/loader.py +737 -0
  544. autocoder/workflow_agents/runner.py +267 -0
  545. autocoder/workflow_agents/types.py +172 -0
  546. autocoder/workflow_agents/utils.py +434 -0
  547. autocoder/workflow_agents/workflow_manager.py +211 -0
  548. auto_coder-0.1.400.dist-info/METADATA +0 -396
  549. auto_coder-0.1.400.dist-info/RECORD +0 -425
  550. auto_coder-0.1.400.dist-info/licenses/LICENSE +0 -201
  551. autocoder/auto_coder_server.py +0 -672
  552. autocoder/benchmark.py +0 -138
  553. autocoder/common/ac_style_command_parser/example.py +0 -7
  554. autocoder/common/cleaner.py +0 -31
  555. autocoder/common/command_completer_v2.py +0 -615
  556. autocoder/common/directory_cache/__init__.py +0 -1
  557. autocoder/common/directory_cache/cache.py +0 -192
  558. autocoder/common/directory_cache/test_cache.py +0 -190
  559. autocoder/common/file_checkpoint/examples.py +0 -217
  560. autocoder/common/llm_friendly_package_example.py +0 -138
  561. autocoder/common/llm_friendly_package_test.py +0 -63
  562. autocoder/common/pull_requests/test_module.py +0 -1
  563. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  564. autocoder/common/text.py +0 -30
  565. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  566. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  567. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  568. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  569. autocoder/plugins/dynamic_completion_example.py +0 -148
  570. autocoder/plugins/sample_plugin.py +0 -160
  571. autocoder/sdk/cli/__main__.py +0 -26
  572. autocoder/sdk/cli/completion_wrapper.py +0 -38
  573. autocoder/sdk/cli/install_completion.py +0 -301
  574. autocoder/sdk/models/messages.py +0 -209
  575. autocoder/sdk/session/__init__.py +0 -32
  576. autocoder/sdk/session/session.py +0 -106
  577. autocoder/sdk/session/session_manager.py +0 -56
  578. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
  579. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,265 @@
1
+ """
2
+ Tests for specific linter implementations.
3
+ """
4
+
5
+ import pytest
6
+ from unittest.mock import Mock, patch, MagicMock
7
+ import subprocess
8
+ from pathlib import Path
9
+
10
+ from autocoder.common.linter_core.linters.python_linter import PythonLinter
11
+ from autocoder.common.linter_core.linters.typescript_linter import TypeScriptLinter
12
+ from autocoder.common.linter_core.models.lint_result import LintResult
13
+
14
+
15
+ class TestPythonLinter:
16
+ """Test cases for PythonLinter."""
17
+
18
+ @pytest.fixture
19
+ def python_linter(self):
20
+ """Create a PythonLinter instance."""
21
+ return PythonLinter()
22
+
23
+ def test_init_default_config(self):
24
+ """Test PythonLinter initialization with default config."""
25
+ linter = PythonLinter()
26
+ assert linter.use_mypy is True
27
+ assert linter.flake8_args == []
28
+ assert linter.mypy_args == []
29
+ assert linter.flake8_timeout_secs == 30
30
+ assert linter.mypy_timeout_secs == 30
31
+
32
+ def test_init_custom_config(self):
33
+ """Test PythonLinter initialization with custom config."""
34
+ config = {
35
+ 'use_mypy': False,
36
+ 'flake8_args': ['--max-line-length=120'],
37
+ 'mypy_args': ['--strict'],
38
+ 'flake8_timeout': 60,
39
+ 'mypy_timeout': 45
40
+ }
41
+ linter = PythonLinter(config)
42
+ assert linter.use_mypy is False
43
+ assert linter.flake8_args == ['--max-line-length=120']
44
+ assert linter.mypy_args == ['--strict']
45
+ assert linter.flake8_timeout_secs == 60
46
+ assert linter.mypy_timeout_secs == 45
47
+
48
+ def test_supported_extensions(self, python_linter):
49
+ """Test supported file extensions."""
50
+ assert python_linter.supported_extensions == ['.py', '.pyx', '.pyi']
51
+
52
+ def test_language_name(self, python_linter):
53
+ """Test language name property."""
54
+ assert python_linter.language_name == "Python"
55
+
56
+ @patch('subprocess.run')
57
+ def test_is_available_true(self, mock_run, python_linter):
58
+ """Test is_available when flake8 is installed."""
59
+ mock_run.return_value = MagicMock(returncode=0)
60
+ assert python_linter.is_available() is True
61
+ mock_run.assert_called_once_with(
62
+ ['flake8', '--version'],
63
+ capture_output=True,
64
+ check=True,
65
+ timeout=10
66
+ )
67
+
68
+ @patch('subprocess.run')
69
+ def test_is_available_false(self, mock_run, python_linter):
70
+ """Test is_available when flake8 is not installed."""
71
+ mock_run.side_effect = FileNotFoundError()
72
+ assert python_linter.is_available() is False
73
+
74
+ @patch('subprocess.run')
75
+ def test_lint_file_flake8_only(self, mock_run):
76
+ """Test linting a file with only flake8."""
77
+ # Setup
78
+ linter = PythonLinter({'use_mypy': False})
79
+ mock_run.return_value = MagicMock(
80
+ stdout="test.py:1:1: E302 expected 2 blank lines, found 1",
81
+ stderr=""
82
+ )
83
+
84
+ # Execute
85
+ result = linter.lint_file('test.py')
86
+
87
+ # Verify
88
+ assert result.linter_name == "PythonLinter"
89
+ assert result.file_name == "test.py"
90
+ assert "=== flake8 ===" in result.lint_result
91
+ assert "E302 expected 2 blank lines" in result.lint_result
92
+ assert result.metadata['mypy_enabled'] is False
93
+ assert result.metadata['tools_used'] == ['flake8']
94
+
95
+ @patch('subprocess.run')
96
+ def test_lint_file_with_mypy(self, mock_run):
97
+ """Test linting a file with both flake8 and mypy."""
98
+ # Setup
99
+ linter = PythonLinter({'use_mypy': True})
100
+
101
+ # Mock flake8 and mypy calls
102
+ mock_run.side_effect = [
103
+ # flake8 call
104
+ MagicMock(stdout="test.py:1:1: E302 expected 2 blank lines", stderr=""),
105
+ # mypy availability check
106
+ MagicMock(returncode=0),
107
+ # mypy call
108
+ MagicMock(stdout="test.py:5: error: Name 'foo' is not defined", stderr="")
109
+ ]
110
+
111
+ # Execute
112
+ result = linter.lint_file('test.py')
113
+
114
+ # Verify
115
+ assert "=== flake8 ===" in result.lint_result
116
+ assert "=== mypy ===" in result.lint_result
117
+ assert "E302 expected 2 blank lines" in result.lint_result
118
+ assert "Name 'foo' is not defined" in result.lint_result
119
+ assert result.metadata['mypy_enabled'] is True
120
+ assert result.metadata['tools_used'] == ['flake8', 'mypy']
121
+
122
+ @patch('subprocess.run')
123
+ def test_lint_file_timeout(self, mock_run):
124
+ """Test handling of timeout during linting."""
125
+ linter = PythonLinter()
126
+ mock_run.side_effect = subprocess.TimeoutExpired(['flake8'], 30)
127
+
128
+ result = linter.lint_file('test.py')
129
+ assert "Error: flake8 execution timed out" in result.lint_result
130
+ assert result.metadata.get('error') is True
131
+
132
+
133
+ class TestTypeScriptLinter:
134
+ """Test cases for TypeScriptLinter."""
135
+
136
+ @pytest.fixture
137
+ def ts_linter(self):
138
+ """Create a TypeScriptLinter instance."""
139
+ return TypeScriptLinter()
140
+
141
+ def test_init_default_config(self):
142
+ """Test TypeScriptLinter initialization with default config."""
143
+ linter = TypeScriptLinter()
144
+ assert linter.use_eslint is True
145
+ assert linter.tsc_args == ['--noEmit', '--strict']
146
+ assert linter.eslint_args == []
147
+ assert linter.tsconfig_path is None
148
+ assert linter.tsc_timeout_secs == 60
149
+ assert linter.eslint_timeout_secs == 30
150
+
151
+ def test_init_custom_config(self):
152
+ """Test TypeScriptLinter initialization with custom config."""
153
+ config = {
154
+ 'use_eslint': False,
155
+ 'tsc_args': ['--noEmit'],
156
+ 'eslint_args': ['--fix'],
157
+ 'tsconfig_path': './tsconfig.json',
158
+ 'tsc_timeout': 90,
159
+ 'eslint_timeout': 45
160
+ }
161
+ linter = TypeScriptLinter(config)
162
+ assert linter.use_eslint is False
163
+ assert linter.tsc_args == ['--noEmit']
164
+ assert linter.eslint_args == ['--fix']
165
+ assert linter.tsconfig_path == './tsconfig.json'
166
+ assert linter.tsc_timeout_secs == 90
167
+ assert linter.eslint_timeout_secs == 45
168
+
169
+ def test_supported_extensions(self, ts_linter):
170
+ """Test supported file extensions."""
171
+ assert ts_linter.supported_extensions == ['.ts', '.tsx', '.js', '.jsx']
172
+
173
+ def test_language_name(self, ts_linter):
174
+ """Test language name property."""
175
+ assert ts_linter.language_name == "TypeScript"
176
+
177
+ @patch('subprocess.run')
178
+ def test_is_available_true(self, mock_run, ts_linter):
179
+ """Test is_available when tsc is installed."""
180
+ mock_run.return_value = MagicMock(returncode=0)
181
+ assert ts_linter.is_available() is True
182
+ mock_run.assert_called_once_with(
183
+ ['tsc', '--version'],
184
+ capture_output=True,
185
+ check=True,
186
+ timeout=10
187
+ )
188
+
189
+ @patch('subprocess.run')
190
+ def test_is_available_false(self, mock_run, ts_linter):
191
+ """Test is_available when tsc is not installed."""
192
+ mock_run.side_effect = FileNotFoundError()
193
+ assert ts_linter.is_available() is False
194
+
195
+ @patch('subprocess.run')
196
+ @patch('time.time')
197
+ def test_lint_file_tsc_only(self, mock_time, mock_run):
198
+ """Test linting a file with only tsc."""
199
+ # Setup
200
+ mock_time.side_effect = [0, 1] # Start and end time
201
+ linter = TypeScriptLinter({'use_eslint': False})
202
+ mock_run.return_value = MagicMock(
203
+ stdout="",
204
+ stderr="test.ts(1,5): error TS2322: Type 'string' is not assignable to type 'number'."
205
+ )
206
+
207
+ # Execute
208
+ result = linter.lint_file('test.ts')
209
+
210
+ # Verify
211
+ assert result.linter_name == "TypeScriptLinter"
212
+ assert len(result.files_checked) == 1
213
+ assert 'test.ts' in result.files_checked[0]
214
+ assert result.has_issues
215
+ assert "=== tsc ===" in result.lint_output
216
+ assert "Type 'string' is not assignable" in result.lint_output
217
+ assert result.metadata['eslint_enabled'] is False
218
+ assert result.metadata['tools_used'] == ['tsc']
219
+ assert result.execution_time == 1
220
+
221
+ @patch('subprocess.run')
222
+ @patch('time.time')
223
+ def test_lint_file_with_eslint(self, mock_time, mock_run):
224
+ """Test linting a file with both tsc and eslint."""
225
+ # Setup
226
+ mock_time.side_effect = [0, 2] # Start and end time
227
+ linter = TypeScriptLinter({'use_eslint': True})
228
+
229
+ # Mock tsc and eslint calls
230
+ mock_run.side_effect = [
231
+ # tsc call
232
+ MagicMock(stdout="", stderr="test.ts(1,5): error TS2322: Type error"),
233
+ # eslint availability check
234
+ MagicMock(returncode=0),
235
+ # eslint call
236
+ MagicMock(stdout="test.ts:2:10 warning Missing semicolon", stderr="")
237
+ ]
238
+
239
+ # Execute
240
+ result = linter.lint_file('test.ts')
241
+
242
+ # Verify
243
+ assert result.has_issues
244
+ assert "=== tsc ===" in result.lint_output
245
+ assert "=== eslint ===" in result.lint_output
246
+ assert "Type error" in result.lint_output
247
+ assert "Missing semicolon" in result.lint_output
248
+ assert result.metadata['eslint_enabled'] is True
249
+ assert result.metadata['tools_used'] == ['tsc', 'eslint']
250
+
251
+ @patch('subprocess.run')
252
+ def test_lint_file_with_tsconfig(self, mock_run):
253
+ """Test linting with custom tsconfig path."""
254
+ linter = TypeScriptLinter({
255
+ 'tsconfig_path': './custom-tsconfig.json',
256
+ 'use_eslint': False # Disable eslint to test only tsc
257
+ })
258
+ mock_run.return_value = MagicMock(stdout="", stderr="")
259
+
260
+ linter.lint_file('test.ts')
261
+
262
+ # Verify tsc was called with --project argument
263
+ call_args = mock_run.call_args[0][0]
264
+ assert '--project' in call_args
265
+ assert './custom-tsconfig.json' in call_args
@@ -0,0 +1,81 @@
1
+ """
2
+ Tests for lint result models.
3
+ """
4
+
5
+ import pytest
6
+ from autocoder.common.linter_core.models.lint_result import LintResult
7
+
8
+
9
+ class TestLintResult:
10
+ """Test cases for LintResult model."""
11
+
12
+ def test_lint_result_creation(self):
13
+ """Test creating a LintResult instance."""
14
+ result = LintResult(
15
+ linter_name="TestLinter",
16
+ files_checked=["test.py"],
17
+ metadata={"key": "value"}
18
+ )
19
+ # Set lint_result using property for backward compatibility
20
+ result.lint_result = "Some lint output"
21
+
22
+ assert result.linter_name == "TestLinter"
23
+ assert result.file_name == "test.py"
24
+ assert result.lint_result == "Some lint output"
25
+ assert result.metadata == {"key": "value"}
26
+
27
+ def test_lint_result_defaults(self):
28
+ """Test LintResult with default values."""
29
+ result = LintResult(
30
+ linter_name="TestLinter",
31
+ files_checked=["test.py"]
32
+ )
33
+
34
+ assert result.lint_result == ""
35
+ assert result.metadata == {}
36
+
37
+ def test_to_dict(self):
38
+ """Test converting LintResult to dictionary."""
39
+ result = LintResult(
40
+ linter_name="TestLinter",
41
+ files_checked=["test.py"],
42
+ metadata={"tool": "flake8"}
43
+ )
44
+ result.lint_result = "Lint output"
45
+
46
+ data = result.to_dict()
47
+ expected_keys = {
48
+ 'linter_name', 'files_checked', 'lint_output', 'execution_time',
49
+ 'success', 'error_message', 'metadata', 'file_name', 'lint_result'
50
+ }
51
+ assert set(data.keys()) == expected_keys
52
+ assert data['linter_name'] == 'TestLinter'
53
+ assert data['file_name'] == 'test.py'
54
+ assert data['lint_result'] == 'Lint output'
55
+ assert data['metadata'] == {'tool': 'flake8'}
56
+
57
+ def test_from_dict(self):
58
+ """Test creating LintResult from dictionary."""
59
+ data = {
60
+ 'linter_name': 'TestLinter',
61
+ 'file_name': 'test.py',
62
+ 'lint_result': 'Lint output',
63
+ 'metadata': {'tool': 'mypy'}
64
+ }
65
+
66
+ result = LintResult.from_dict(data)
67
+ assert result.linter_name == "TestLinter"
68
+ assert result.file_name == "test.py"
69
+ assert result.lint_result == "Lint output"
70
+ assert result.metadata == {"tool": "mypy"}
71
+
72
+ def test_from_dict_missing_fields(self):
73
+ """Test creating LintResult from incomplete dictionary."""
74
+ data = {
75
+ 'linter_name': 'TestLinter',
76
+ 'file_name': 'test.py'
77
+ }
78
+
79
+ result = LintResult.from_dict(data)
80
+ assert result.lint_result == ""
81
+ assert result.metadata == {}
@@ -0,0 +1,296 @@
1
+
2
+
3
+ """
4
+ 验证 LinterManager 配置文件自动加载功能的脚本
5
+
6
+ 这个脚本演示了如何使用新的配置文件自动加载功能,
7
+ 并测试不同的配置文件位置和格式。
8
+ """
9
+
10
+ import os
11
+ import json
12
+ import yaml
13
+ import tempfile
14
+ import shutil
15
+ from pathlib import Path
16
+
17
+ from autocoder.common.linter_core.linter_manager import LinterManager
18
+
19
+
20
+ def create_test_config_directories():
21
+ """创建测试配置目录结构"""
22
+ print("=== 创建测试配置目录结构 ===")
23
+
24
+ # 创建临时目录作为项目根目录
25
+ project_root = tempfile.mkdtemp(prefix="linter_test_")
26
+ print(f"项目根目录: {project_root}")
27
+
28
+ # 创建不同优先级的配置目录
29
+ config_dirs = {
30
+ "project_level": os.path.join(project_root, ".autocoderlinters"),
31
+ "project_auto_coder": os.path.join(project_root, ".auto-coder", ".autocoderlinters"),
32
+ "global_level": os.path.expanduser("~/.auto-coder/.autocoderlinters")
33
+ }
34
+
35
+ for name, path in config_dirs.items():
36
+ os.makedirs(path, exist_ok=True)
37
+ print(f"创建目录: {name} -> {path}")
38
+
39
+ return project_root, config_dirs
40
+
41
+
42
+ def create_sample_configs(config_dirs):
43
+ """创建示例配置文件"""
44
+ print("\n=== 创建示例配置文件 ===")
45
+
46
+ # 项目级配置(最高优先级)
47
+ project_config = {
48
+ "max_workers": 8,
49
+ "timeout": 600,
50
+ "python_config": {
51
+ "use_mypy": True,
52
+ "flake8_args": ["--max-line-length=120"]
53
+ },
54
+ "source": "project_level"
55
+ }
56
+
57
+ project_config_file = os.path.join(config_dirs["project_level"], "config.json")
58
+ with open(project_config_file, 'w') as f:
59
+ json.dump(project_config, f, indent=2)
60
+ print(f"创建项目级配置: {project_config_file}")
61
+
62
+ # .auto-coder 级配置(中等优先级)
63
+ auto_coder_config = {
64
+ "max_workers": 6,
65
+ "timeout": 500,
66
+ "typescript_config": {
67
+ "use_eslint": True,
68
+ "tsc_args": ["--strict"]
69
+ },
70
+ "source": "auto_coder_level"
71
+ }
72
+
73
+ auto_coder_config_file = os.path.join(config_dirs["project_auto_coder"], "config.yaml")
74
+ with open(auto_coder_config_file, 'w') as f:
75
+ yaml.dump(auto_coder_config, f)
76
+ print(f"创建 .auto-coder 级配置: {auto_coder_config_file}")
77
+
78
+ # 全局配置(最低优先级)
79
+ global_config = {
80
+ "max_workers": 4,
81
+ "timeout": 300,
82
+ "java_config": {
83
+ "javac_args": ["-Xlint:all"]
84
+ },
85
+ "source": "global_level"
86
+ }
87
+
88
+ global_config_file = os.path.join(config_dirs["global_level"], "config.yaml")
89
+ with open(global_config_file, 'w') as f:
90
+ yaml.dump(global_config, f)
91
+ print(f"创建全局配置: {global_config_file}")
92
+
93
+ return {
94
+ "project": project_config,
95
+ "auto_coder": auto_coder_config,
96
+ "global": global_config
97
+ }
98
+
99
+
100
+ def test_config_loading_priority(project_root, config_dirs, sample_configs):
101
+ """测试配置加载优先级"""
102
+ print("\n=== 测试配置加载优先级 ===")
103
+
104
+ # 保存当前工作目录
105
+ original_cwd = os.getcwd()
106
+
107
+ try:
108
+ # 切换到项目目录
109
+ os.chdir(project_root)
110
+
111
+ # 测试1: 所有配置文件都存在,应该加载项目级配置
112
+ print("\n1. 测试所有配置文件都存在的情况:")
113
+ manager = LinterManager()
114
+ print(f" 加载的配置源: {manager.global_config.get('source', 'unknown')}")
115
+ print(f" max_workers: {manager.max_workers}")
116
+ print(f" timeout: {manager.timeout}")
117
+ assert manager.global_config['source'] == 'project_level', "应该加载项目级配置"
118
+
119
+ # 测试2: 删除项目级配置,应该加载 .auto-coder 级配置
120
+ print("\n2. 测试删除项目级配置后:")
121
+ os.remove(os.path.join(config_dirs["project_level"], "config.json"))
122
+ manager = LinterManager()
123
+ print(f" 加载的配置源: {manager.global_config.get('source', 'unknown')}")
124
+ print(f" max_workers: {manager.max_workers}")
125
+ print(f" timeout: {manager.timeout}")
126
+ assert manager.global_config['source'] == 'auto_coder_level', "应该加载 .auto-coder 级配置"
127
+
128
+ # 测试3: 删除 .auto-coder 级配置,应该加载全局配置
129
+ print("\n3. 测试删除 .auto-coder 级配置后:")
130
+ os.remove(os.path.join(config_dirs["project_auto_coder"], "config.yaml"))
131
+ manager = LinterManager()
132
+ print(f" 加载的配置源: {manager.global_config.get('source', 'unknown')}")
133
+ print(f" max_workers: {manager.max_workers}")
134
+ print(f" timeout: {manager.timeout}")
135
+ assert manager.global_config['source'] == 'global_level', "应该加载全局配置"
136
+
137
+ # 测试4: 删除所有配置文件,应该使用默认配置
138
+ print("\n4. 测试删除所有配置文件后:")
139
+ os.remove(os.path.join(config_dirs["global_level"], "config.yaml"))
140
+ manager = LinterManager()
141
+ print(f" 配置为空: {manager.global_config == {}}")
142
+ print(f" max_workers (默认): {manager.max_workers}")
143
+ print(f" timeout (默认): {manager.timeout}")
144
+ assert manager.global_config == {}, "应该使用空配置"
145
+ assert manager.max_workers == 4, "应该使用默认 max_workers"
146
+ assert manager.timeout == 300, "应该使用默认 timeout"
147
+
148
+ finally:
149
+ # 恢复原始工作目录
150
+ os.chdir(original_cwd)
151
+
152
+
153
+ def test_different_config_formats(project_root):
154
+ """测试不同的配置文件格式"""
155
+ print("\n=== 测试不同的配置文件格式 ===")
156
+
157
+ original_cwd = os.getcwd()
158
+
159
+ try:
160
+ os.chdir(project_root)
161
+
162
+ # 创建配置目录
163
+ config_dir = os.path.join(project_root, ".autocoderlinters")
164
+ os.makedirs(config_dir, exist_ok=True)
165
+
166
+ # 测试 JSON 格式
167
+ print("\n1. 测试 JSON 格式:")
168
+ json_config = {
169
+ "max_workers": 10,
170
+ "format": "json",
171
+ "python_config": {"use_mypy": True}
172
+ }
173
+
174
+ json_file = os.path.join(config_dir, "config.json")
175
+ with open(json_file, 'w') as f:
176
+ json.dump(json_config, f)
177
+
178
+ manager = LinterManager()
179
+ print(f" 格式: {manager.global_config.get('format')}")
180
+ print(f" max_workers: {manager.max_workers}")
181
+ assert manager.global_config['format'] == 'json'
182
+
183
+ # 清理并测试 YAML 格式
184
+ os.remove(json_file)
185
+
186
+ print("\n2. 测试 YAML 格式:")
187
+ yaml_config = {
188
+ "max_workers": 12,
189
+ "format": "yaml",
190
+ "typescript_config": {"use_eslint": True}
191
+ }
192
+
193
+ yaml_file = os.path.join(config_dir, "config.yaml")
194
+ with open(yaml_file, 'w') as f:
195
+ yaml.dump(yaml_config, f)
196
+
197
+ manager = LinterManager()
198
+ print(f" 格式: {manager.global_config.get('format')}")
199
+ print(f" max_workers: {manager.max_workers}")
200
+ assert manager.global_config['format'] == 'yaml'
201
+
202
+ # 清理并测试 YML 格式
203
+ os.remove(yaml_file)
204
+
205
+ print("\n3. 测试 YML 格式:")
206
+ yml_config = {
207
+ "max_workers": 14,
208
+ "format": "yml",
209
+ "java_config": {"javac_args": ["-Xlint:all"]}
210
+ }
211
+
212
+ yml_file = os.path.join(config_dir, "config.yml")
213
+ with open(yml_file, 'w') as f:
214
+ yaml.dump(yml_config, f)
215
+
216
+ manager = LinterManager()
217
+ print(f" 格式: {manager.global_config.get('format')}")
218
+ print(f" max_workers: {manager.max_workers}")
219
+ assert manager.global_config['format'] == 'yml'
220
+
221
+ finally:
222
+ os.chdir(original_cwd)
223
+
224
+
225
+ def test_explicit_config_override():
226
+ """测试显式配置覆盖自动加载"""
227
+ print("\n=== 测试显式配置覆盖自动加载 ===")
228
+
229
+ explicit_config = {
230
+ "max_workers": 20,
231
+ "timeout": 1000,
232
+ "source": "explicit"
233
+ }
234
+
235
+ manager = LinterManager(explicit_config)
236
+ print(f"配置源: {manager.global_config.get('source')}")
237
+ print(f"max_workers: {manager.max_workers}")
238
+ print(f"timeout: {manager.timeout}")
239
+
240
+ assert manager.global_config['source'] == 'explicit'
241
+ assert manager.max_workers == 20
242
+ assert manager.timeout == 1000
243
+
244
+
245
+ def cleanup_test_directories(project_root, config_dirs):
246
+ """清理测试目录"""
247
+ print("\n=== 清理测试目录 ===")
248
+
249
+ # 删除项目根目录
250
+ if os.path.exists(project_root):
251
+ shutil.rmtree(project_root)
252
+ print(f"删除项目目录: {project_root}")
253
+
254
+ # 删除全局配置目录(如果是我们创建的)
255
+ global_dir = config_dirs["global_level"]
256
+ if os.path.exists(global_dir):
257
+ try:
258
+ shutil.rmtree(global_dir)
259
+ print(f"删除全局配置目录: {global_dir}")
260
+ except OSError:
261
+ print(f"无法删除全局配置目录: {global_dir} (可能有其他文件)")
262
+
263
+
264
+ def main():
265
+ """主函数"""
266
+ print("开始验证 LinterManager 配置文件自动加载功能")
267
+ print("=" * 60)
268
+
269
+ try:
270
+ # 创建测试环境
271
+ project_root, config_dirs = create_test_config_directories()
272
+ sample_configs = create_sample_configs(config_dirs)
273
+
274
+ # 运行测试
275
+ test_config_loading_priority(project_root, config_dirs, sample_configs)
276
+ test_different_config_formats(project_root)
277
+ test_explicit_config_override()
278
+
279
+ print("\n" + "=" * 60)
280
+ print("✅ 所有测试通过!配置文件自动加载功能工作正常。")
281
+
282
+ except Exception as e:
283
+ print(f"\n❌ 测试失败: {e}")
284
+ raise
285
+
286
+ finally:
287
+ # 清理测试环境
288
+ if 'project_root' in locals() and 'config_dirs' in locals():
289
+ cleanup_test_directories(project_root, config_dirs)
290
+
291
+ print("\n验证完成!")
292
+
293
+
294
+ if __name__ == '__main__':
295
+ main()
296
+