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.
- auto_coder-2.0.1.dist-info/LICENSE +158 -0
- auto_coder-2.0.1.dist-info/METADATA +558 -0
- auto_coder-2.0.1.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/entry_points.txt +3 -3
- autocoder/__init__.py +31 -0
- autocoder/agent/auto_filegroup.py +32 -13
- autocoder/agent/auto_learn_from_commit.py +9 -1
- autocoder/agent/base_agentic/__init__.py +3 -0
- autocoder/agent/base_agentic/agent_hub.py +1 -1
- autocoder/agent/base_agentic/base_agent.py +235 -136
- autocoder/agent/base_agentic/default_tools.py +119 -118
- autocoder/agent/base_agentic/test_base_agent.py +1 -1
- autocoder/agent/base_agentic/tool_registry.py +32 -20
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
- autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
- autocoder/agent/base_agentic/types.py +42 -0
- autocoder/agent/entry_command_agent/chat.py +77 -73
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +962 -2345
- autocoder/auto_coder_terminal.py +26 -0
- autocoder/auto_coder_terminal_v3.py +190 -0
- autocoder/chat/conf_command.py +224 -124
- autocoder/chat/models_command.py +361 -299
- autocoder/chat/rules_command.py +79 -31
- autocoder/chat_auto_coder.py +988 -398
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +25 -8
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +44 -44
- autocoder/common/__init__.py +150 -128
- autocoder/common/ac_style_command_parser/__init__.py +39 -2
- autocoder/common/ac_style_command_parser/config.py +422 -0
- autocoder/common/ac_style_command_parser/parser.py +292 -78
- autocoder/common/ac_style_command_parser/test_parser.py +241 -16
- autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
- autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
- autocoder/common/action_yml_file_manager.py +25 -13
- autocoder/common/agent_events/__init__.py +52 -0
- autocoder/common/agent_events/agent_event_emitter.py +193 -0
- autocoder/common/agent_events/event_factory.py +177 -0
- autocoder/common/agent_events/examples.py +307 -0
- autocoder/common/agent_events/types.py +113 -0
- autocoder/common/agent_events/utils.py +68 -0
- autocoder/common/agent_hooks/__init__.py +44 -0
- autocoder/common/agent_hooks/examples.py +582 -0
- autocoder/common/agent_hooks/hook_executor.py +217 -0
- autocoder/common/agent_hooks/hook_manager.py +288 -0
- autocoder/common/agent_hooks/types.py +133 -0
- autocoder/common/agent_hooks/utils.py +99 -0
- autocoder/common/agent_query_queue/queue_executor.py +324 -0
- autocoder/common/agent_query_queue/queue_manager.py +325 -0
- autocoder/common/agents/__init__.py +11 -0
- autocoder/common/agents/agent_manager.py +323 -0
- autocoder/common/agents/agent_parser.py +189 -0
- autocoder/common/agents/example_usage.py +344 -0
- autocoder/common/agents/integration_example.py +330 -0
- autocoder/common/agents/test_agent_parser.py +545 -0
- autocoder/common/async_utils.py +101 -0
- autocoder/common/auto_coder_lang.py +23 -972
- autocoder/common/autocoderargs_parser/__init__.py +14 -0
- autocoder/common/autocoderargs_parser/parser.py +184 -0
- autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
- autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
- autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
- autocoder/common/autocoderargs_parser/token_parser.py +290 -0
- autocoder/common/buildin_tokenizer.py +2 -4
- autocoder/common/code_auto_generate.py +149 -74
- autocoder/common/code_auto_generate_diff.py +163 -70
- autocoder/common/code_auto_generate_editblock.py +179 -89
- autocoder/common/code_auto_generate_strict_diff.py +167 -72
- autocoder/common/code_auto_merge_editblock.py +13 -6
- autocoder/common/code_modification_ranker.py +1 -1
- autocoder/common/command_completer.py +3 -3
- autocoder/common/command_file_manager/manager.py +183 -47
- autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
- autocoder/common/command_templates.py +1 -1
- autocoder/common/conf_utils.py +2 -4
- autocoder/common/conversations/config.py +11 -3
- autocoder/common/conversations/get_conversation_manager.py +100 -2
- autocoder/common/conversations/llm_stats_models.py +264 -0
- autocoder/common/conversations/manager.py +112 -28
- autocoder/common/conversations/models.py +16 -2
- autocoder/common/conversations/storage/index_manager.py +134 -10
- autocoder/common/core_config/__init__.py +63 -0
- autocoder/common/core_config/agentic_mode_manager.py +109 -0
- autocoder/common/core_config/base_manager.py +123 -0
- autocoder/common/core_config/compatibility.py +151 -0
- autocoder/common/core_config/config_manager.py +156 -0
- autocoder/common/core_config/conversation_manager.py +31 -0
- autocoder/common/core_config/exclude_manager.py +72 -0
- autocoder/common/core_config/file_manager.py +177 -0
- autocoder/common/core_config/human_as_model_manager.py +129 -0
- autocoder/common/core_config/lib_manager.py +54 -0
- autocoder/common/core_config/main_manager.py +81 -0
- autocoder/common/core_config/mode_manager.py +126 -0
- autocoder/common/core_config/models.py +70 -0
- autocoder/common/core_config/test_memory_manager.py +1056 -0
- autocoder/common/env_manager.py +282 -0
- autocoder/common/env_manager_usage_example.py +211 -0
- autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
- autocoder/common/file_checkpoint/manager.py +264 -48
- autocoder/common/file_checkpoint/test_backup.py +1 -18
- autocoder/common/file_checkpoint/test_manager.py +270 -1
- autocoder/common/file_checkpoint/test_store.py +1 -17
- autocoder/common/file_handler/__init__.py +23 -0
- autocoder/common/file_handler/active_context_handler.py +159 -0
- autocoder/common/file_handler/add_files_handler.py +409 -0
- autocoder/common/file_handler/chat_handler.py +180 -0
- autocoder/common/file_handler/coding_handler.py +409 -0
- autocoder/common/file_handler/commit_handler.py +200 -0
- autocoder/common/file_handler/lib_handler.py +156 -0
- autocoder/common/file_handler/list_files_handler.py +111 -0
- autocoder/common/file_handler/mcp_handler.py +268 -0
- autocoder/common/file_handler/models_handler.py +493 -0
- autocoder/common/file_handler/remove_files_handler.py +172 -0
- autocoder/common/git_utils.py +44 -8
- autocoder/common/global_cancel.py +15 -6
- autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
- autocoder/common/international/__init__.py +31 -0
- autocoder/common/international/demo_international.py +92 -0
- autocoder/common/international/message_manager.py +157 -0
- autocoder/common/international/messages/__init__.py +56 -0
- autocoder/common/international/messages/async_command_messages.py +507 -0
- autocoder/common/international/messages/auto_coder_messages.py +2208 -0
- autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
- autocoder/common/international/messages/command_help_messages.py +986 -0
- autocoder/common/international/messages/conversation_command_messages.py +191 -0
- autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
- autocoder/common/international/messages/queue_command_messages.py +751 -0
- autocoder/common/international/messages/rules_command_messages.py +77 -0
- autocoder/common/international/messages/sdk_messages.py +1707 -0
- autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
- autocoder/common/international/messages/tool_display_messages.py +1212 -0
- autocoder/common/international/messages/workflow_exception_messages.py +473 -0
- autocoder/common/international/test_international.py +612 -0
- autocoder/common/linter_core/__init__.py +28 -0
- autocoder/common/linter_core/base_linter.py +61 -0
- autocoder/common/linter_core/config_loader.py +271 -0
- autocoder/common/linter_core/formatters/__init__.py +0 -0
- autocoder/common/linter_core/formatters/base_formatter.py +38 -0
- autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
- autocoder/common/linter_core/linter.py +166 -0
- autocoder/common/linter_core/linter_factory.py +216 -0
- autocoder/common/linter_core/linter_manager.py +333 -0
- autocoder/common/linter_core/linters/__init__.py +9 -0
- autocoder/common/linter_core/linters/java_linter.py +342 -0
- autocoder/common/linter_core/linters/python_linter.py +115 -0
- autocoder/common/linter_core/linters/typescript_linter.py +119 -0
- autocoder/common/linter_core/models/__init__.py +7 -0
- autocoder/common/linter_core/models/lint_result.py +91 -0
- autocoder/common/linter_core/models.py +33 -0
- autocoder/common/linter_core/tests/__init__.py +3 -0
- autocoder/common/linter_core/tests/test_config_loader.py +323 -0
- autocoder/common/linter_core/tests/test_config_loading.py +308 -0
- autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
- autocoder/common/linter_core/tests/test_formatters.py +147 -0
- autocoder/common/linter_core/tests/test_integration.py +317 -0
- autocoder/common/linter_core/tests/test_java_linter.py +496 -0
- autocoder/common/linter_core/tests/test_linters.py +265 -0
- autocoder/common/linter_core/tests/test_models.py +81 -0
- autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
- autocoder/common/linter_core/tests/verify_fixes.py +183 -0
- autocoder/common/llm_friendly_package/__init__.py +31 -0
- autocoder/common/llm_friendly_package/base_manager.py +102 -0
- autocoder/common/llm_friendly_package/docs_manager.py +121 -0
- autocoder/common/llm_friendly_package/library_manager.py +171 -0
- autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
- autocoder/common/llm_friendly_package/models.py +40 -0
- autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
- autocoder/common/llms/__init__.py +15 -0
- autocoder/common/llms/demo_error_handling.py +85 -0
- autocoder/common/llms/factory.py +142 -0
- autocoder/common/llms/manager.py +264 -0
- autocoder/common/llms/pricing.py +121 -0
- autocoder/common/llms/registry.py +316 -0
- autocoder/common/llms/schema.py +77 -0
- autocoder/common/llms/simple_demo.py +45 -0
- autocoder/common/llms/test_quick_model.py +116 -0
- autocoder/common/llms/test_remove_functionality.py +182 -0
- autocoder/common/llms/tests/__init__.py +1 -0
- autocoder/common/llms/tests/test_manager.py +330 -0
- autocoder/common/llms/tests/test_registry.py +364 -0
- autocoder/common/mcp_tools/__init__.py +62 -0
- autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
- autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
- autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
- autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
- autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
- autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
- autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
- autocoder/common/mcp_tools/verify_functionality.py +202 -0
- autocoder/common/model_speed_tester.py +32 -26
- autocoder/common/priority_directory_finder/__init__.py +142 -0
- autocoder/common/priority_directory_finder/examples.py +230 -0
- autocoder/common/priority_directory_finder/finder.py +283 -0
- autocoder/common/priority_directory_finder/models.py +236 -0
- autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
- autocoder/common/project_scanner/__init__.py +18 -0
- autocoder/common/project_scanner/compat.py +77 -0
- autocoder/common/project_scanner/scanner.py +436 -0
- autocoder/common/project_tracker/__init__.py +27 -0
- autocoder/common/project_tracker/api.py +228 -0
- autocoder/common/project_tracker/demo.py +272 -0
- autocoder/common/project_tracker/tracker.py +487 -0
- autocoder/common/project_tracker/types.py +53 -0
- autocoder/common/pruner/__init__.py +67 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
- autocoder/common/pruner/conversation_message_ids_api.py +386 -0
- autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
- autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
- autocoder/common/pruner/conversation_normalizer.py +347 -0
- autocoder/common/pruner/conversation_pruner.py +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
- autocoder/common/pruner/test_conversation_normalizer.py +502 -0
- autocoder/common/pruner/test_tool_content_detector.py +324 -0
- autocoder/common/pruner/tool_content_detector.py +227 -0
- autocoder/common/pruner/tools/__init__.py +18 -0
- autocoder/common/pruner/tools/query_message_ids.py +264 -0
- autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
- autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
- autocoder/common/pull_requests/__init__.py +9 -1
- autocoder/common/pull_requests/utils.py +122 -1
- autocoder/common/rag_manager/rag_manager.py +36 -40
- autocoder/common/rulefiles/__init__.py +53 -1
- autocoder/common/rulefiles/api.py +250 -0
- autocoder/common/rulefiles/core/__init__.py +14 -0
- autocoder/common/rulefiles/core/manager.py +241 -0
- autocoder/common/rulefiles/core/selector.py +805 -0
- autocoder/common/rulefiles/models/__init__.py +20 -0
- autocoder/common/rulefiles/models/index.py +16 -0
- autocoder/common/rulefiles/models/init_rule.py +18 -0
- autocoder/common/rulefiles/models/rule_file.py +18 -0
- autocoder/common/rulefiles/models/rule_relevance.py +14 -0
- autocoder/common/rulefiles/models/summary.py +16 -0
- autocoder/common/rulefiles/test_rulefiles.py +776 -0
- autocoder/common/rulefiles/utils/__init__.py +34 -0
- autocoder/common/rulefiles/utils/monitor.py +86 -0
- autocoder/common/rulefiles/utils/parser.py +230 -0
- autocoder/common/save_formatted_log.py +67 -10
- autocoder/common/search_replace.py +8 -1
- autocoder/common/search_replace_patch/__init__.py +24 -0
- autocoder/common/search_replace_patch/base.py +115 -0
- autocoder/common/search_replace_patch/manager.py +248 -0
- autocoder/common/search_replace_patch/patch_replacer.py +304 -0
- autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
- autocoder/common/search_replace_patch/string_replacer.py +181 -0
- autocoder/common/search_replace_patch/tests/__init__.py +3 -0
- autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
- autocoder/common/search_replace_patch/tests/test_base.py +188 -0
- autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
- autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
- autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
- autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
- autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
- autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
- autocoder/common/shell_commands/__init__.py +197 -0
- autocoder/common/shell_commands/background_process_notifier.py +346 -0
- autocoder/common/shell_commands/command_executor.py +1127 -0
- autocoder/common/shell_commands/error_recovery.py +541 -0
- autocoder/common/shell_commands/exceptions.py +120 -0
- autocoder/common/shell_commands/interactive_executor.py +476 -0
- autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
- autocoder/common/shell_commands/interactive_process.py +744 -0
- autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
- autocoder/common/shell_commands/monitoring.py +529 -0
- autocoder/common/shell_commands/process_cleanup.py +386 -0
- autocoder/common/shell_commands/process_manager.py +606 -0
- autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
- autocoder/common/shell_commands/tests/__init__.py +6 -0
- autocoder/common/shell_commands/tests/conftest.py +118 -0
- autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
- autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
- autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
- autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
- autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
- autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
- autocoder/common/shell_commands/tests/test_integration.py +664 -0
- autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
- autocoder/common/shell_commands/tests/test_performance.py +632 -0
- autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
- autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
- autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
- autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
- autocoder/common/shell_commands/timeout_config.py +315 -0
- autocoder/common/shell_commands/timeout_manager.py +352 -0
- autocoder/common/terminal_paste/__init__.py +14 -0
- autocoder/common/terminal_paste/demo.py +145 -0
- autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
- autocoder/common/terminal_paste/paste_handler.py +200 -0
- autocoder/common/terminal_paste/paste_manager.py +118 -0
- autocoder/common/terminal_paste/tests/__init__.py +1 -0
- autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
- autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
- autocoder/common/terminal_paste/utils.py +163 -0
- autocoder/common/test_autocoder_args.py +232 -0
- autocoder/common/test_env_manager.py +173 -0
- autocoder/common/test_env_manager_integration.py +159 -0
- autocoder/common/text_similarity/__init__.py +9 -0
- autocoder/common/text_similarity/demo.py +216 -0
- autocoder/common/text_similarity/examples.py +266 -0
- autocoder/common/text_similarity/test_text_similarity.py +306 -0
- autocoder/common/text_similarity/text_similarity.py +194 -0
- autocoder/common/text_similarity/utils.py +125 -0
- autocoder/common/todos/__init__.py +61 -0
- autocoder/common/todos/cache/__init__.py +16 -0
- autocoder/common/todos/cache/base_cache.py +89 -0
- autocoder/common/todos/cache/cache_manager.py +228 -0
- autocoder/common/todos/cache/memory_cache.py +225 -0
- autocoder/common/todos/config.py +155 -0
- autocoder/common/todos/exceptions.py +35 -0
- autocoder/common/todos/get_todo_manager.py +161 -0
- autocoder/common/todos/manager.py +537 -0
- autocoder/common/todos/models.py +239 -0
- autocoder/common/todos/storage/__init__.py +14 -0
- autocoder/common/todos/storage/base_storage.py +76 -0
- autocoder/common/todos/storage/file_storage.py +278 -0
- autocoder/common/tokens/counter.py +24 -2
- autocoder/common/tools_manager/__init__.py +17 -0
- autocoder/common/tools_manager/examples.py +162 -0
- autocoder/common/tools_manager/manager.py +385 -0
- autocoder/common/tools_manager/models.py +39 -0
- autocoder/common/tools_manager/test_tools_manager.py +303 -0
- autocoder/common/tools_manager/utils.py +191 -0
- autocoder/common/v2/agent/agentic_callbacks.py +270 -0
- autocoder/common/v2/agent/agentic_edit.py +2699 -1856
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
- autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
- autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
- autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
- autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
- autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
- autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +356 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
- autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
- autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
- autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
- autocoder/common/v2/agent/agentic_edit_types.py +343 -9
- autocoder/common/v2/agent/runner/__init__.py +3 -3
- autocoder/common/v2/agent/runner/base_runner.py +12 -26
- autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
- autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
- autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
- autocoder/common/v2/agent/runner/tool_display.py +557 -159
- autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
- autocoder/common/v2/agent/test_agentic_edit.py +194 -0
- autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
- autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
- autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
- autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
- autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
- autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
- autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
- autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
- autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
- autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
- autocoder/common/v2/code_auto_generate.py +136 -78
- autocoder/common/v2/code_auto_generate_diff.py +135 -79
- autocoder/common/v2/code_auto_generate_editblock.py +174 -99
- autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
- autocoder/common/v2/code_auto_merge.py +1 -1
- autocoder/common/v2/code_auto_merge_editblock.py +13 -1
- autocoder/common/v2/code_diff_manager.py +3 -3
- autocoder/common/v2/code_editblock_manager.py +4 -14
- autocoder/common/v2/code_manager.py +1 -1
- autocoder/common/v2/code_strict_diff_manager.py +2 -2
- autocoder/common/wrap_llm_hint/__init__.py +10 -0
- autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
- autocoder/common/wrap_llm_hint/utils.py +432 -0
- autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
- autocoder/completer/__init__.py +8 -0
- autocoder/completer/command_completer_v2.py +1094 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +400 -129
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- autocoder/{agent → index/filter}/agentic_filter.py +322 -333
- autocoder/index/filter/normal_filter.py +5 -11
- autocoder/index/filter/quick_filter.py +1 -1
- autocoder/index/index.py +36 -9
- autocoder/index/tests/__init__.py +1 -0
- autocoder/index/tests/run_tests.py +195 -0
- autocoder/index/tests/test_entry.py +303 -0
- autocoder/index/tests/test_index_manager.py +314 -0
- autocoder/index/tests/test_module_integration.py +300 -0
- autocoder/index/tests/test_symbols_utils.py +183 -0
- autocoder/inner/__init__.py +4 -0
- autocoder/inner/agentic.py +923 -0
- autocoder/inner/async_command_handler.py +992 -0
- autocoder/inner/conversation_command_handlers.py +623 -0
- autocoder/inner/merge_command_handler.py +213 -0
- autocoder/inner/queue_command_handler.py +684 -0
- autocoder/models.py +95 -266
- autocoder/plugins/git_helper_plugin.py +31 -29
- autocoder/plugins/token_helper_plugin.py +65 -46
- autocoder/pyproject/__init__.py +32 -29
- autocoder/rag/agentic_rag.py +215 -75
- autocoder/rag/cache/simple_cache.py +1 -2
- autocoder/rag/loaders/image_loader.py +1 -1
- autocoder/rag/long_context_rag.py +42 -26
- autocoder/rag/qa_conversation_strategy.py +1 -1
- autocoder/rag/terminal/__init__.py +17 -0
- autocoder/rag/terminal/args.py +581 -0
- autocoder/rag/terminal/bootstrap.py +61 -0
- autocoder/rag/terminal/command_handlers.py +653 -0
- autocoder/rag/terminal/formatters/__init__.py +20 -0
- autocoder/rag/terminal/formatters/base.py +70 -0
- autocoder/rag/terminal/formatters/json_format.py +66 -0
- autocoder/rag/terminal/formatters/stream_json.py +95 -0
- autocoder/rag/terminal/formatters/text.py +28 -0
- autocoder/rag/terminal/init.py +120 -0
- autocoder/rag/terminal/utils.py +106 -0
- autocoder/rag/test_agentic_rag.py +389 -0
- autocoder/rag/test_doc_filter.py +3 -3
- autocoder/rag/test_long_context_rag.py +1 -1
- autocoder/rag/test_token_limiter.py +517 -10
- autocoder/rag/token_counter.py +3 -0
- autocoder/rag/token_limiter.py +19 -15
- autocoder/rag/tools/__init__.py +26 -2
- autocoder/rag/tools/bochaai_example.py +343 -0
- autocoder/rag/tools/bochaai_sdk.py +541 -0
- autocoder/rag/tools/metaso_example.py +268 -0
- autocoder/rag/tools/metaso_sdk.py +417 -0
- autocoder/rag/tools/recall_tool.py +28 -7
- autocoder/rag/tools/run_integration_tests.py +204 -0
- autocoder/rag/tools/test_all_providers.py +318 -0
- autocoder/rag/tools/test_bochaai_integration.py +482 -0
- autocoder/rag/tools/test_final_integration.py +215 -0
- autocoder/rag/tools/test_metaso_integration.py +424 -0
- autocoder/rag/tools/test_metaso_real.py +171 -0
- autocoder/rag/tools/test_web_crawl_tool.py +639 -0
- autocoder/rag/tools/test_web_search_tool.py +509 -0
- autocoder/rag/tools/todo_read_tool.py +202 -0
- autocoder/rag/tools/todo_write_tool.py +412 -0
- autocoder/rag/tools/web_crawl_tool.py +634 -0
- autocoder/rag/tools/web_search_tool.py +558 -0
- autocoder/rag/tools/web_tools_example.py +119 -0
- autocoder/rag/types.py +16 -0
- autocoder/rag/variable_holder.py +4 -2
- autocoder/rags.py +86 -79
- autocoder/regexproject/__init__.py +23 -21
- autocoder/sdk/__init__.py +46 -190
- autocoder/sdk/api.py +370 -0
- autocoder/sdk/async_runner/__init__.py +26 -0
- autocoder/sdk/async_runner/async_executor.py +650 -0
- autocoder/sdk/async_runner/async_handler.py +356 -0
- autocoder/sdk/async_runner/markdown_processor.py +595 -0
- autocoder/sdk/async_runner/task_metadata.py +284 -0
- autocoder/sdk/async_runner/worktree_manager.py +438 -0
- autocoder/sdk/cli/__init__.py +2 -5
- autocoder/sdk/cli/formatters.py +28 -204
- autocoder/sdk/cli/handlers.py +77 -44
- autocoder/sdk/cli/main.py +154 -171
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -109
- autocoder/sdk/core/bridge.py +297 -115
- autocoder/sdk/exceptions.py +18 -12
- autocoder/sdk/formatters/__init__.py +19 -0
- autocoder/sdk/formatters/input.py +64 -0
- autocoder/sdk/formatters/output.py +247 -0
- autocoder/sdk/formatters/stream.py +54 -0
- autocoder/sdk/models/__init__.py +6 -5
- autocoder/sdk/models/options.py +55 -18
- autocoder/sdk/utils/formatters.py +27 -195
- autocoder/suffixproject/__init__.py +28 -25
- autocoder/terminal/__init__.py +14 -0
- autocoder/terminal/app.py +454 -0
- autocoder/terminal/args.py +32 -0
- autocoder/terminal/bootstrap.py +178 -0
- autocoder/terminal/command_processor.py +521 -0
- autocoder/terminal/command_registry.py +57 -0
- autocoder/terminal/help.py +97 -0
- autocoder/terminal/tasks/__init__.py +5 -0
- autocoder/terminal/tasks/background.py +77 -0
- autocoder/terminal/tasks/task_event.py +70 -0
- autocoder/terminal/ui/__init__.py +13 -0
- autocoder/terminal/ui/completer.py +268 -0
- autocoder/terminal/ui/keybindings.py +75 -0
- autocoder/terminal/ui/session.py +41 -0
- autocoder/terminal/ui/toolbar.py +64 -0
- autocoder/terminal/utils/__init__.py +13 -0
- autocoder/terminal/utils/errors.py +18 -0
- autocoder/terminal/utils/paths.py +19 -0
- autocoder/terminal/utils/shell.py +43 -0
- autocoder/terminal_v3/__init__.py +10 -0
- autocoder/terminal_v3/app.py +201 -0
- autocoder/terminal_v3/handlers/__init__.py +5 -0
- autocoder/terminal_v3/handlers/command_handler.py +131 -0
- autocoder/terminal_v3/models/__init__.py +6 -0
- autocoder/terminal_v3/models/conversation_buffer.py +214 -0
- autocoder/terminal_v3/models/message.py +50 -0
- autocoder/terminal_v3/models/tool_display.py +247 -0
- autocoder/terminal_v3/ui/__init__.py +7 -0
- autocoder/terminal_v3/ui/keybindings.py +56 -0
- autocoder/terminal_v3/ui/layout.py +141 -0
- autocoder/terminal_v3/ui/styles.py +43 -0
- autocoder/tsproject/__init__.py +23 -23
- autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
- autocoder/utils/llms.py +88 -80
- autocoder/utils/math_utils.py +101 -0
- autocoder/utils/model_provider_selector.py +16 -4
- autocoder/utils/operate_config_api.py +33 -5
- autocoder/utils/thread_utils.py +2 -2
- autocoder/version.py +4 -2
- autocoder/workflow_agents/__init__.py +84 -0
- autocoder/workflow_agents/agent.py +143 -0
- autocoder/workflow_agents/exceptions.py +573 -0
- autocoder/workflow_agents/executor.py +665 -0
- autocoder/workflow_agents/loader.py +749 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +173 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-1.0.0.dist-info/METADATA +0 -396
- auto_coder-1.0.0.dist-info/RECORD +0 -442
- auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
- autocoder/auto_coder_server.py +0 -672
- autocoder/benchmark.py +0 -138
- autocoder/common/ac_style_command_parser/example.py +0 -7
- autocoder/common/cleaner.py +0 -31
- autocoder/common/command_completer_v2.py +0 -615
- autocoder/common/context_pruner.py +0 -477
- autocoder/common/conversation_pruner.py +0 -132
- autocoder/common/directory_cache/__init__.py +0 -1
- autocoder/common/directory_cache/cache.py +0 -192
- autocoder/common/directory_cache/test_cache.py +0 -190
- autocoder/common/file_checkpoint/examples.py +0 -217
- autocoder/common/llm_friendly_package_example.py +0 -138
- autocoder/common/llm_friendly_package_test.py +0 -63
- autocoder/common/pull_requests/test_module.py +0 -1
- autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
- autocoder/common/text.py +0 -30
- autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
- autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
- autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
- autocoder/common/v2/agent/agentic_tool_display.py +0 -183
- autocoder/plugins/dynamic_completion_example.py +0 -148
- autocoder/plugins/sample_plugin.py +0 -160
- autocoder/sdk/cli/__main__.py +0 -26
- autocoder/sdk/cli/completion_wrapper.py +0 -38
- autocoder/sdk/cli/install_completion.py +0 -301
- autocoder/sdk/models/messages.py +0 -209
- autocoder/sdk/session/__init__.py +0 -32
- autocoder/sdk/session/session.py +0 -106
- autocoder/sdk/session/session_manager.py +0 -56
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simple data models for lint results.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Optional, List, Dict, Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class LintResult:
|
|
11
|
+
"""Simple result from linting a file."""
|
|
12
|
+
|
|
13
|
+
file_path: str
|
|
14
|
+
success: bool
|
|
15
|
+
output: str = "" # Raw output from the linter tool
|
|
16
|
+
error: Optional[str] = None # Error message if linting failed
|
|
17
|
+
tool: str = "" # Tool that generated this result (e.g., "flake8", "mypy")
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def has_issues(self) -> bool:
|
|
21
|
+
"""Check if there are any issues (non-empty output usually means issues)."""
|
|
22
|
+
return bool(self.output.strip())
|
|
23
|
+
|
|
24
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
25
|
+
"""Convert to dictionary for serialization."""
|
|
26
|
+
return {
|
|
27
|
+
'file_path': self.file_path,
|
|
28
|
+
'success': self.success,
|
|
29
|
+
'output': self.output,
|
|
30
|
+
'error': self.error,
|
|
31
|
+
'tool': self.tool,
|
|
32
|
+
'has_issues': self.has_issues
|
|
33
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the centralized configuration loader.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import json
|
|
7
|
+
import tempfile
|
|
8
|
+
import pytest
|
|
9
|
+
from unittest.mock import patch, Mock
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from autocoder.common.linter_core.config_loader import LinterConfigLoader, load_linter_config
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestLinterConfigLoader:
|
|
16
|
+
"""Test cases for LinterConfigLoader."""
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def temp_dir(self):
|
|
20
|
+
"""Create a temporary directory for test files."""
|
|
21
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
22
|
+
yield Path(temp_dir)
|
|
23
|
+
|
|
24
|
+
@pytest.fixture
|
|
25
|
+
def config_loader(self, temp_dir):
|
|
26
|
+
"""Create a config loader instance."""
|
|
27
|
+
return LinterConfigLoader(source_dir=str(temp_dir))
|
|
28
|
+
|
|
29
|
+
def test_default_config(self, config_loader):
|
|
30
|
+
"""Test that default configuration is returned when no config files exist."""
|
|
31
|
+
config = config_loader.load_config()
|
|
32
|
+
|
|
33
|
+
assert config == LinterConfigLoader.DEFAULT_CONFIG
|
|
34
|
+
assert config['enabled'] is False
|
|
35
|
+
assert config['mode'] == 'warning'
|
|
36
|
+
assert config['check_after_modification'] is True
|
|
37
|
+
assert config['report']['format'] == 'simple'
|
|
38
|
+
assert config['report']['include_in_result'] is True
|
|
39
|
+
|
|
40
|
+
def test_load_from_explicit_path_json(self, config_loader, temp_dir):
|
|
41
|
+
"""Test loading configuration from explicit JSON file path."""
|
|
42
|
+
config_data = {
|
|
43
|
+
'enabled': True,
|
|
44
|
+
'mode': 'blocking',
|
|
45
|
+
'report': {'format': 'detailed'}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
config_file = temp_dir / 'custom_config.json'
|
|
49
|
+
with open(config_file, 'w') as f:
|
|
50
|
+
json.dump(config_data, f)
|
|
51
|
+
|
|
52
|
+
config = config_loader.load_config(config_path=str(config_file))
|
|
53
|
+
|
|
54
|
+
assert config == config_data
|
|
55
|
+
|
|
56
|
+
def test_load_from_explicit_path_yaml(self, config_loader, temp_dir):
|
|
57
|
+
"""Test loading configuration from explicit YAML file path."""
|
|
58
|
+
config_data = {
|
|
59
|
+
'enabled': True,
|
|
60
|
+
'mode': 'silent',
|
|
61
|
+
'report': {'format': 'json'}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
config_file = temp_dir / 'custom_config.yaml'
|
|
65
|
+
|
|
66
|
+
# Create YAML content manually (to avoid yaml dependency in test)
|
|
67
|
+
yaml_content = """
|
|
68
|
+
enabled: true
|
|
69
|
+
mode: silent
|
|
70
|
+
report:
|
|
71
|
+
format: json
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
with open(config_file, 'w') as f:
|
|
75
|
+
f.write(yaml_content)
|
|
76
|
+
|
|
77
|
+
# Mock yaml.safe_load
|
|
78
|
+
with patch('yaml.safe_load') as mock_yaml:
|
|
79
|
+
mock_yaml.return_value = config_data
|
|
80
|
+
|
|
81
|
+
config = config_loader.load_config(config_path=str(config_file))
|
|
82
|
+
|
|
83
|
+
assert config == config_data
|
|
84
|
+
|
|
85
|
+
def test_load_from_explicit_path_with_nested_key(self, config_loader, temp_dir):
|
|
86
|
+
"""Test loading configuration with nested key extraction."""
|
|
87
|
+
full_config = {
|
|
88
|
+
'linter': {
|
|
89
|
+
'enabled': True,
|
|
90
|
+
'mode': 'warning'
|
|
91
|
+
},
|
|
92
|
+
'other_section': {
|
|
93
|
+
'key': 'value'
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
config_file = temp_dir / 'nested_config.json'
|
|
98
|
+
with open(config_file, 'w') as f:
|
|
99
|
+
json.dump(full_config, f)
|
|
100
|
+
|
|
101
|
+
config = config_loader.load_config(config_path=str(config_file), config_key='linter')
|
|
102
|
+
|
|
103
|
+
assert config == full_config['linter']
|
|
104
|
+
|
|
105
|
+
@patch.dict(os.environ, {'AUTOCODER_LINTER_CONFIG': '{"enabled": true, "mode": "blocking"}'})
|
|
106
|
+
def test_load_from_environment(self, config_loader):
|
|
107
|
+
"""Test loading configuration from environment variable."""
|
|
108
|
+
config = config_loader.load_config()
|
|
109
|
+
|
|
110
|
+
assert config['enabled'] is True
|
|
111
|
+
assert config['mode'] == 'blocking'
|
|
112
|
+
|
|
113
|
+
@patch.dict(os.environ, {'AUTOCODER_LINTER_CONFIG': 'invalid json'})
|
|
114
|
+
def test_load_from_environment_invalid_json(self, config_loader):
|
|
115
|
+
"""Test handling invalid JSON in environment variable."""
|
|
116
|
+
config = config_loader.load_config()
|
|
117
|
+
|
|
118
|
+
# Should fall back to default config
|
|
119
|
+
assert config == LinterConfigLoader.DEFAULT_CONFIG
|
|
120
|
+
|
|
121
|
+
def test_load_from_project_config_json(self, config_loader, temp_dir):
|
|
122
|
+
"""Test loading configuration from project .autocoderlinters directory."""
|
|
123
|
+
config_data = {
|
|
124
|
+
'enabled': True,
|
|
125
|
+
'mode': 'warning',
|
|
126
|
+
'custom_field': 'project_value'
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# Create project config directory and file
|
|
130
|
+
project_config_dir = temp_dir / '.autocoderlinters'
|
|
131
|
+
project_config_dir.mkdir()
|
|
132
|
+
|
|
133
|
+
config_file = project_config_dir / 'config.json'
|
|
134
|
+
with open(config_file, 'w') as f:
|
|
135
|
+
json.dump(config_data, f)
|
|
136
|
+
|
|
137
|
+
config = config_loader.load_config()
|
|
138
|
+
|
|
139
|
+
assert config == config_data
|
|
140
|
+
|
|
141
|
+
def test_load_from_project_config_priority(self, config_loader, temp_dir):
|
|
142
|
+
"""Test that config.json has priority over linter.yaml in project config."""
|
|
143
|
+
# Create project config directory
|
|
144
|
+
project_config_dir = temp_dir / '.autocoderlinters'
|
|
145
|
+
project_config_dir.mkdir()
|
|
146
|
+
|
|
147
|
+
# Create both config.json and linter.yaml
|
|
148
|
+
json_config = {'enabled': True, 'source': 'json'}
|
|
149
|
+
yaml_config = {'enabled': False, 'source': 'yaml'}
|
|
150
|
+
|
|
151
|
+
with open(project_config_dir / 'config.json', 'w') as f:
|
|
152
|
+
json.dump(json_config, f)
|
|
153
|
+
|
|
154
|
+
with open(project_config_dir / 'linter.yaml', 'w') as f:
|
|
155
|
+
f.write('enabled: false\nsource: yaml\n')
|
|
156
|
+
|
|
157
|
+
config = config_loader.load_config()
|
|
158
|
+
|
|
159
|
+
# Should load JSON config (higher priority)
|
|
160
|
+
assert config == json_config
|
|
161
|
+
assert config['source'] == 'json'
|
|
162
|
+
|
|
163
|
+
def test_load_from_global_config(self, config_loader, temp_dir):
|
|
164
|
+
"""Test loading configuration from global user config directory."""
|
|
165
|
+
config_data = {
|
|
166
|
+
'enabled': True,
|
|
167
|
+
'mode': 'silent',
|
|
168
|
+
'global_setting': True
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# Mock the global config directory path to point to our temp dir
|
|
172
|
+
fake_global_dir = temp_dir / '.auto-coder' / '.autocoderlinters'
|
|
173
|
+
fake_global_dir.mkdir(parents=True)
|
|
174
|
+
|
|
175
|
+
config_file = fake_global_dir / 'config.json'
|
|
176
|
+
with open(config_file, 'w') as f:
|
|
177
|
+
json.dump(config_data, f)
|
|
178
|
+
|
|
179
|
+
# Mock os.path.expanduser to return our temp dir
|
|
180
|
+
with patch('os.path.expanduser', return_value=str(temp_dir)):
|
|
181
|
+
config = config_loader.load_config()
|
|
182
|
+
|
|
183
|
+
assert config == config_data
|
|
184
|
+
|
|
185
|
+
def test_config_priority_order(self, config_loader, temp_dir):
|
|
186
|
+
"""Test configuration priority order: explicit > env > project > global > default."""
|
|
187
|
+
# Create project config
|
|
188
|
+
project_config_dir = temp_dir / '.autocoderlinters'
|
|
189
|
+
project_config_dir.mkdir()
|
|
190
|
+
|
|
191
|
+
project_config = {'enabled': False, 'source': 'project'}
|
|
192
|
+
with open(project_config_dir / 'config.json', 'w') as f:
|
|
193
|
+
json.dump(project_config, f)
|
|
194
|
+
|
|
195
|
+
# Create explicit config file
|
|
196
|
+
explicit_config = {'enabled': True, 'source': 'explicit'}
|
|
197
|
+
explicit_file = temp_dir / 'explicit.json'
|
|
198
|
+
with open(explicit_file, 'w') as f:
|
|
199
|
+
json.dump(explicit_config, f)
|
|
200
|
+
|
|
201
|
+
# Test explicit config has highest priority
|
|
202
|
+
config = config_loader.load_config(config_path=str(explicit_file))
|
|
203
|
+
assert config['source'] == 'explicit'
|
|
204
|
+
|
|
205
|
+
# Test project config is used when no explicit config
|
|
206
|
+
config = config_loader.load_config()
|
|
207
|
+
assert config['source'] == 'project'
|
|
208
|
+
|
|
209
|
+
def test_validate_config(self, config_loader):
|
|
210
|
+
"""Test configuration validation and normalization."""
|
|
211
|
+
# Test with valid config
|
|
212
|
+
valid_config = {
|
|
213
|
+
'enabled': True,
|
|
214
|
+
'mode': 'blocking',
|
|
215
|
+
'report': {
|
|
216
|
+
'format': 'detailed',
|
|
217
|
+
'include_in_result': False
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
validated = config_loader.validate_config(valid_config)
|
|
222
|
+
|
|
223
|
+
assert validated['enabled'] is True
|
|
224
|
+
assert validated['mode'] == 'blocking'
|
|
225
|
+
assert validated['report']['format'] == 'detailed'
|
|
226
|
+
assert validated['report']['include_in_result'] is False
|
|
227
|
+
# Should still have default values for missing keys
|
|
228
|
+
assert 'check_after_modification' in validated
|
|
229
|
+
|
|
230
|
+
def test_validate_config_invalid_mode(self, config_loader):
|
|
231
|
+
"""Test validation with invalid mode value."""
|
|
232
|
+
invalid_config = {
|
|
233
|
+
'enabled': True,
|
|
234
|
+
'mode': 'invalid_mode' # Invalid mode
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
validated = config_loader.validate_config(invalid_config)
|
|
238
|
+
|
|
239
|
+
assert validated['mode'] == 'warning' # Should fallback to default
|
|
240
|
+
|
|
241
|
+
def test_validate_config_invalid_report_format(self, config_loader):
|
|
242
|
+
"""Test validation with invalid report format."""
|
|
243
|
+
invalid_config = {
|
|
244
|
+
'enabled': True,
|
|
245
|
+
'report': {
|
|
246
|
+
'format': 'invalid_format' # Invalid format
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
validated = config_loader.validate_config(invalid_config)
|
|
251
|
+
|
|
252
|
+
assert validated['report']['format'] == 'simple' # Should fallback to default
|
|
253
|
+
|
|
254
|
+
def test_validate_config_non_dict(self, config_loader):
|
|
255
|
+
"""Test validation with non-dictionary input."""
|
|
256
|
+
validated = config_loader.validate_config("not a dict")
|
|
257
|
+
|
|
258
|
+
assert validated == LinterConfigLoader.DEFAULT_CONFIG
|
|
259
|
+
|
|
260
|
+
def test_load_manager_config(self, temp_dir):
|
|
261
|
+
"""Test loading full configuration for LinterManager."""
|
|
262
|
+
full_config = {
|
|
263
|
+
'max_workers': 8,
|
|
264
|
+
'timeout': 600,
|
|
265
|
+
'linter': {
|
|
266
|
+
'enabled': True,
|
|
267
|
+
'mode': 'warning'
|
|
268
|
+
},
|
|
269
|
+
'python_config': {
|
|
270
|
+
'use_mypy': True
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
# Create project config
|
|
275
|
+
project_config_dir = temp_dir / '.autocoderlinters'
|
|
276
|
+
project_config_dir.mkdir()
|
|
277
|
+
|
|
278
|
+
with open(project_config_dir / 'config.json', 'w') as f:
|
|
279
|
+
json.dump(full_config, f)
|
|
280
|
+
|
|
281
|
+
config = LinterConfigLoader.load_manager_config(source_dir=str(temp_dir))
|
|
282
|
+
|
|
283
|
+
assert config == full_config
|
|
284
|
+
assert config['max_workers'] == 8
|
|
285
|
+
assert config['linter']['enabled'] is True
|
|
286
|
+
assert config['python_config']['use_mypy'] is True
|
|
287
|
+
|
|
288
|
+
def test_load_manager_config_empty(self):
|
|
289
|
+
"""Test loading manager config when no config files exist."""
|
|
290
|
+
config = LinterConfigLoader.load_manager_config(source_dir='/nonexistent')
|
|
291
|
+
|
|
292
|
+
assert config == {}
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
class TestConvenienceFunction:
|
|
296
|
+
"""Test the convenience function."""
|
|
297
|
+
|
|
298
|
+
def test_load_linter_config_function(self):
|
|
299
|
+
"""Test the load_linter_config convenience function."""
|
|
300
|
+
config = load_linter_config()
|
|
301
|
+
|
|
302
|
+
# Should return default config when no files exist
|
|
303
|
+
assert isinstance(config, dict)
|
|
304
|
+
assert 'enabled' in config
|
|
305
|
+
assert 'mode' in config
|
|
306
|
+
assert 'report' in config
|
|
307
|
+
|
|
308
|
+
def test_load_linter_config_with_params(self):
|
|
309
|
+
"""Test convenience function with parameters."""
|
|
310
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
311
|
+
config_data = {'enabled': True, 'mode': 'blocking'}
|
|
312
|
+
config_file = Path(temp_dir) / 'test_config.json'
|
|
313
|
+
|
|
314
|
+
with open(config_file, 'w') as f:
|
|
315
|
+
json.dump(config_data, f)
|
|
316
|
+
|
|
317
|
+
config = load_linter_config(
|
|
318
|
+
config_path=str(config_file),
|
|
319
|
+
source_dir=temp_dir
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
assert config['enabled'] is True
|
|
323
|
+
assert config['mode'] == 'blocking'
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
|
|
2
|
+
"""
|
|
3
|
+
测试 LinterManager 的配置文件自动加载功能
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import json
|
|
8
|
+
import yaml
|
|
9
|
+
import tempfile
|
|
10
|
+
import pytest
|
|
11
|
+
from unittest.mock import patch, Mock
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from autocoder.common.linter_core.linter_manager import LinterManager
|
|
15
|
+
from autocoder.common.priority_directory_finder import SearchResult
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestConfigLoading:
|
|
19
|
+
"""测试配置文件加载功能"""
|
|
20
|
+
|
|
21
|
+
def test_init_with_explicit_config(self):
|
|
22
|
+
"""测试:使用显式配置初始化"""
|
|
23
|
+
config = {
|
|
24
|
+
'max_workers': 8,
|
|
25
|
+
'timeout': 600,
|
|
26
|
+
'python_config': {'use_mypy': True}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
manager = LinterManager(config)
|
|
30
|
+
|
|
31
|
+
assert manager.global_config == config
|
|
32
|
+
assert manager.max_workers == 8
|
|
33
|
+
assert manager.timeout == 600
|
|
34
|
+
|
|
35
|
+
def test_init_without_config_no_files_found(self):
|
|
36
|
+
"""测试:没有配置文件时的初始化"""
|
|
37
|
+
# Mock QuickFinder 返回未找到配置文件
|
|
38
|
+
mock_result = SearchResult(
|
|
39
|
+
strategy=None,
|
|
40
|
+
success=False,
|
|
41
|
+
selected_directories=[],
|
|
42
|
+
all_valid_directories=[]
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
46
|
+
manager = LinterManager()
|
|
47
|
+
|
|
48
|
+
assert manager.global_config == {}
|
|
49
|
+
assert manager.max_workers == 4 # 默认值
|
|
50
|
+
assert manager.timeout == 300 # 默认值
|
|
51
|
+
|
|
52
|
+
def test_load_json_config_file(self):
|
|
53
|
+
"""测试:加载 JSON 配置文件"""
|
|
54
|
+
config_data = {
|
|
55
|
+
'max_workers': 6,
|
|
56
|
+
'timeout': 500,
|
|
57
|
+
'python_config': {
|
|
58
|
+
'use_mypy': True,
|
|
59
|
+
'flake8_args': ['--max-line-length=120']
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
64
|
+
# 创建配置文件
|
|
65
|
+
config_file = os.path.join(temp_dir, 'config.json')
|
|
66
|
+
with open(config_file, 'w') as f:
|
|
67
|
+
json.dump(config_data, f)
|
|
68
|
+
|
|
69
|
+
# Mock QuickFinder 返回找到的目录
|
|
70
|
+
mock_result = SearchResult(
|
|
71
|
+
strategy=None,
|
|
72
|
+
success=True,
|
|
73
|
+
selected_directories=[temp_dir],
|
|
74
|
+
all_valid_directories=[temp_dir]
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
78
|
+
manager = LinterManager()
|
|
79
|
+
|
|
80
|
+
assert manager.global_config == config_data
|
|
81
|
+
assert manager.max_workers == 6
|
|
82
|
+
assert manager.timeout == 500
|
|
83
|
+
|
|
84
|
+
def test_load_yaml_config_file(self):
|
|
85
|
+
"""测试:加载 YAML 配置文件"""
|
|
86
|
+
config_data = {
|
|
87
|
+
'max_workers': 12,
|
|
88
|
+
'timeout': 800,
|
|
89
|
+
'typescript_config': {
|
|
90
|
+
'use_eslint': True,
|
|
91
|
+
'tsc_args': ['--strict']
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
96
|
+
# 创建配置文件
|
|
97
|
+
config_file = os.path.join(temp_dir, 'config.yaml')
|
|
98
|
+
with open(config_file, 'w') as f:
|
|
99
|
+
yaml.dump(config_data, f)
|
|
100
|
+
|
|
101
|
+
# Mock QuickFinder 返回找到的目录
|
|
102
|
+
mock_result = SearchResult(
|
|
103
|
+
strategy=None,
|
|
104
|
+
success=True,
|
|
105
|
+
selected_directories=[temp_dir],
|
|
106
|
+
all_valid_directories=[temp_dir]
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
110
|
+
manager = LinterManager()
|
|
111
|
+
|
|
112
|
+
assert manager.global_config == config_data
|
|
113
|
+
assert manager.max_workers == 12
|
|
114
|
+
assert manager.timeout == 800
|
|
115
|
+
|
|
116
|
+
def test_config_file_priority_order(self):
|
|
117
|
+
"""测试:配置文件优先级顺序"""
|
|
118
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
119
|
+
# 创建多个配置文件,config.json 应该优先
|
|
120
|
+
config_json = {'max_workers': 10, 'source': 'json'}
|
|
121
|
+
config_yaml = {'max_workers': 20, 'source': 'yaml'}
|
|
122
|
+
|
|
123
|
+
with open(os.path.join(temp_dir, 'config.json'), 'w') as f:
|
|
124
|
+
json.dump(config_json, f)
|
|
125
|
+
|
|
126
|
+
with open(os.path.join(temp_dir, 'linter.yaml'), 'w') as f:
|
|
127
|
+
yaml.dump(config_yaml, f)
|
|
128
|
+
|
|
129
|
+
# Mock QuickFinder 返回找到的目录
|
|
130
|
+
mock_result = SearchResult(
|
|
131
|
+
strategy=None,
|
|
132
|
+
success=True,
|
|
133
|
+
selected_directories=[temp_dir],
|
|
134
|
+
all_valid_directories=[temp_dir]
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
138
|
+
manager = LinterManager()
|
|
139
|
+
|
|
140
|
+
# 应该加载 config.json(优先级更高)
|
|
141
|
+
assert manager.global_config == config_json
|
|
142
|
+
assert manager.global_config['source'] == 'json'
|
|
143
|
+
|
|
144
|
+
def test_config_file_fallback_order(self):
|
|
145
|
+
"""测试:配置文件回退顺序"""
|
|
146
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
147
|
+
# 只创建 linter.yml 文件
|
|
148
|
+
config_data = {'max_workers': 15, 'source': 'yml'}
|
|
149
|
+
|
|
150
|
+
with open(os.path.join(temp_dir, 'linter.yml'), 'w') as f:
|
|
151
|
+
yaml.dump(config_data, f)
|
|
152
|
+
|
|
153
|
+
# Mock QuickFinder 返回找到的目录
|
|
154
|
+
mock_result = SearchResult(
|
|
155
|
+
strategy=None,
|
|
156
|
+
success=True,
|
|
157
|
+
selected_directories=[temp_dir],
|
|
158
|
+
all_valid_directories=[temp_dir]
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
162
|
+
manager = LinterManager()
|
|
163
|
+
|
|
164
|
+
# 应该加载 linter.yml(唯一可用的配置文件)
|
|
165
|
+
assert manager.global_config == config_data
|
|
166
|
+
assert manager.global_config['source'] == 'yml'
|
|
167
|
+
|
|
168
|
+
def test_invalid_config_file_handling(self):
|
|
169
|
+
"""测试:处理无效的配置文件"""
|
|
170
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
171
|
+
# 创建无效的 JSON 文件
|
|
172
|
+
invalid_json = os.path.join(temp_dir, 'config.json')
|
|
173
|
+
with open(invalid_json, 'w') as f:
|
|
174
|
+
f.write('{ invalid json content }')
|
|
175
|
+
|
|
176
|
+
# 创建有效的 YAML 文件作为备选
|
|
177
|
+
valid_yaml = os.path.join(temp_dir, 'config.yaml')
|
|
178
|
+
config_data = {'max_workers': 8, 'source': 'yaml_backup'}
|
|
179
|
+
with open(valid_yaml, 'w') as f:
|
|
180
|
+
yaml.dump(config_data, f)
|
|
181
|
+
|
|
182
|
+
# Mock QuickFinder 返回找到的目录
|
|
183
|
+
mock_result = SearchResult(
|
|
184
|
+
strategy=None,
|
|
185
|
+
success=True,
|
|
186
|
+
selected_directories=[temp_dir],
|
|
187
|
+
all_valid_directories=[temp_dir]
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
191
|
+
# 应该捕获 JSON 解析错误,然后加载 YAML 文件
|
|
192
|
+
manager = LinterManager()
|
|
193
|
+
|
|
194
|
+
assert manager.global_config == config_data
|
|
195
|
+
assert manager.global_config['source'] == 'yaml_backup'
|
|
196
|
+
|
|
197
|
+
def test_priority_directory_finder_integration(self):
|
|
198
|
+
"""测试:与 priority_directory_finder 的集成"""
|
|
199
|
+
# 这个测试验证 QuickFinder.find_standard_directories 被正确调用
|
|
200
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories') as mock_finder:
|
|
201
|
+
mock_result = SearchResult(
|
|
202
|
+
strategy=None,
|
|
203
|
+
success=False,
|
|
204
|
+
selected_directories=[],
|
|
205
|
+
all_valid_directories=[]
|
|
206
|
+
)
|
|
207
|
+
mock_finder.return_value = mock_result
|
|
208
|
+
|
|
209
|
+
manager = LinterManager()
|
|
210
|
+
|
|
211
|
+
# 验证 QuickFinder 被正确调用
|
|
212
|
+
mock_finder.assert_called_once()
|
|
213
|
+
call_args = mock_finder.call_args
|
|
214
|
+
|
|
215
|
+
assert call_args[1]['base_name'] == '.autocoderlinters'
|
|
216
|
+
assert call_args[1]['current_dir'] is None
|
|
217
|
+
assert call_args[1]['file_extensions'] == ['json', 'yaml', 'yml']
|
|
218
|
+
|
|
219
|
+
def test_load_config_file_unsupported_format(self):
|
|
220
|
+
"""测试:加载不支持的配置文件格式"""
|
|
221
|
+
manager = LinterManager({}) # 创建一个实例来测试 _load_config_file 方法
|
|
222
|
+
|
|
223
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
224
|
+
unsupported_file = os.path.join(temp_dir, 'config.txt')
|
|
225
|
+
with open(unsupported_file, 'w') as f:
|
|
226
|
+
f.write('some content')
|
|
227
|
+
|
|
228
|
+
with pytest.raises(ValueError, match="Unsupported configuration file format"):
|
|
229
|
+
manager._load_config_file(unsupported_file)
|
|
230
|
+
|
|
231
|
+
def test_empty_yaml_config_file(self):
|
|
232
|
+
"""测试:空的 YAML 配置文件"""
|
|
233
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
234
|
+
# 创建空的 YAML 文件
|
|
235
|
+
config_file = os.path.join(temp_dir, 'config.yaml')
|
|
236
|
+
with open(config_file, 'w') as f:
|
|
237
|
+
f.write('') # 空文件
|
|
238
|
+
|
|
239
|
+
# Mock QuickFinder 返回找到的目录
|
|
240
|
+
mock_result = SearchResult(
|
|
241
|
+
strategy=None,
|
|
242
|
+
success=True,
|
|
243
|
+
selected_directories=[temp_dir],
|
|
244
|
+
all_valid_directories=[temp_dir]
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
248
|
+
manager = LinterManager()
|
|
249
|
+
|
|
250
|
+
# 空的 YAML 文件应该返回空字典
|
|
251
|
+
assert manager.global_config == {}
|
|
252
|
+
|
|
253
|
+
def test_config_file_with_complex_structure(self):
|
|
254
|
+
"""测试:复杂结构的配置文件"""
|
|
255
|
+
complex_config = {
|
|
256
|
+
'max_workers': 16,
|
|
257
|
+
'timeout': 1200,
|
|
258
|
+
'python_config': {
|
|
259
|
+
'use_mypy': True,
|
|
260
|
+
'flake8_args': ['--max-line-length=120', '--ignore=E501'],
|
|
261
|
+
'mypy_args': ['--strict', '--no-implicit-optional'],
|
|
262
|
+
'flake8_timeout': 60,
|
|
263
|
+
'mypy_timeout': 90
|
|
264
|
+
},
|
|
265
|
+
'typescript_config': {
|
|
266
|
+
'use_eslint': True,
|
|
267
|
+
'tsc_args': ['--noEmit', '--strict'],
|
|
268
|
+
'eslint_args': ['--ext', '.ts,.tsx'],
|
|
269
|
+
'tsconfig_path': './tsconfig.json'
|
|
270
|
+
},
|
|
271
|
+
'java_config': {
|
|
272
|
+
'javac_args': ['-Xlint:all', '-Werror'],
|
|
273
|
+
'javac_timeout': 45
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
278
|
+
config_file = os.path.join(temp_dir, 'config.json')
|
|
279
|
+
with open(config_file, 'w') as f:
|
|
280
|
+
json.dump(complex_config, f, indent=2)
|
|
281
|
+
|
|
282
|
+
# Mock QuickFinder 返回找到的目录
|
|
283
|
+
mock_result = SearchResult(
|
|
284
|
+
strategy=None,
|
|
285
|
+
success=True,
|
|
286
|
+
selected_directories=[temp_dir],
|
|
287
|
+
all_valid_directories=[temp_dir]
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
with patch('autocoder.common.linter_core.linter_manager.QuickFinder.find_standard_directories', return_value=mock_result):
|
|
291
|
+
manager = LinterManager()
|
|
292
|
+
|
|
293
|
+
assert manager.global_config == complex_config
|
|
294
|
+
assert manager.max_workers == 16
|
|
295
|
+
assert manager.timeout == 1200
|
|
296
|
+
|
|
297
|
+
# 验证嵌套配置被正确加载
|
|
298
|
+
python_config = manager.global_config.get('python_config', {})
|
|
299
|
+
assert python_config.get('use_mypy') is True
|
|
300
|
+
assert python_config.get('flake8_timeout') == 60
|
|
301
|
+
|
|
302
|
+
typescript_config = manager.global_config.get('typescript_config', {})
|
|
303
|
+
assert typescript_config.get('use_eslint') is True
|
|
304
|
+
assert typescript_config.get('tsconfig_path') == './tsconfig.json'
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
if __name__ == '__main__':
|
|
308
|
+
pytest.main([__file__, '-v'])
|