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.
- auto_coder-2.0.0.dist-info/LICENSE +158 -0
- auto_coder-2.0.0.dist-info/METADATA +558 -0
- auto_coder-2.0.0.dist-info/RECORD +795 -0
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.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 +25 -4
- 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 +73 -59
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +1029 -2310
- 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 +1021 -372
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +26 -9
- 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 +401 -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/file_monitor/test_file_monitor.py +307 -0
- autocoder/common/git_utils.py +51 -10
- 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 +288 -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 +746 -0
- autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
- 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/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
- autocoder/common/pruner/test_context_pruner.py +546 -0
- 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/__init__.py +15 -0
- autocoder/common/tokens/counter.py +44 -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 +2729 -2052
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
- autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
- 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 +565 -30
- 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 +349 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +244 -51
- 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 +409 -140
- 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 +209 -194
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
- 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 +386 -10
- autocoder/common/v2/agent/runner/__init__.py +31 -0
- autocoder/common/v2/agent/runner/base_runner.py +92 -0
- autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
- autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
- autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
- autocoder/common/v2/agent/runner/tool_display.py +589 -0
- 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 +1051 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +165 -7
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- autocoder/{agent → index/filter}/agentic_filter.py +323 -334
- 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 +932 -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 +156 -37
- 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/run_context.py +9 -0
- autocoder/sdk/__init__.py +50 -161
- 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 +158 -170
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -267
- autocoder/sdk/core/bridge.py +298 -118
- 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 +489 -0
- autocoder/workflow_agents/loader.py +737 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +172 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-0.1.400.dist-info/METADATA +0 -396
- auto_coder-0.1.400.dist-info/RECORD +0 -425
- auto_coder-0.1.400.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/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-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for batch command execution functionality.
|
|
3
|
+
|
|
4
|
+
This module tests the execute_commands and execute_batch functions
|
|
5
|
+
for both parallel and serial execution modes.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
import time
|
|
10
|
+
import platform
|
|
11
|
+
from typing import List, Dict, Any
|
|
12
|
+
import json
|
|
13
|
+
|
|
14
|
+
from ..command_executor import CommandExecutor, execute_commands
|
|
15
|
+
from ..timeout_config import TimeoutConfig
|
|
16
|
+
from ..exceptions import CommandTimeoutError, CommandExecutionError
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestExecuteBatch:
|
|
20
|
+
"""Test cases for execute_batch method."""
|
|
21
|
+
|
|
22
|
+
def setup_method(self):
|
|
23
|
+
"""Set up test fixtures."""
|
|
24
|
+
self.config = TimeoutConfig(default_timeout=10.0)
|
|
25
|
+
self.executor = CommandExecutor(self.config, verbose=False)
|
|
26
|
+
|
|
27
|
+
def teardown_method(self):
|
|
28
|
+
"""Clean up after tests."""
|
|
29
|
+
self.executor.cleanup()
|
|
30
|
+
|
|
31
|
+
def test_empty_commands_list(self):
|
|
32
|
+
"""Test execution with empty commands list."""
|
|
33
|
+
results = self.executor.execute_batch([])
|
|
34
|
+
assert results == []
|
|
35
|
+
|
|
36
|
+
def test_single_command_serial(self):
|
|
37
|
+
"""Test executing a single command serially."""
|
|
38
|
+
if platform.system() == "Windows":
|
|
39
|
+
commands = ["echo Hello"]
|
|
40
|
+
else:
|
|
41
|
+
commands = ["echo 'Hello'"]
|
|
42
|
+
|
|
43
|
+
results = self.executor.execute_batch(commands, parallel=False)
|
|
44
|
+
|
|
45
|
+
assert len(results) == 1
|
|
46
|
+
assert results[0]["index"] == 0
|
|
47
|
+
assert results[0]["exit_code"] == 0
|
|
48
|
+
assert "Hello" in results[0]["output"]
|
|
49
|
+
assert results[0]["timed_out"] is False
|
|
50
|
+
|
|
51
|
+
def test_multiple_commands_serial(self):
|
|
52
|
+
"""Test executing multiple commands serially."""
|
|
53
|
+
if platform.system() == "Windows":
|
|
54
|
+
commands = ["echo One", "echo Two", "echo Three"]
|
|
55
|
+
else:
|
|
56
|
+
commands = ["echo 'One'", "echo 'Two'", "echo 'Three'"]
|
|
57
|
+
|
|
58
|
+
start_time = time.time()
|
|
59
|
+
results = self.executor.execute_batch(commands, parallel=False)
|
|
60
|
+
duration = time.time() - start_time
|
|
61
|
+
|
|
62
|
+
assert len(results) == 3
|
|
63
|
+
for i, result in enumerate(results):
|
|
64
|
+
assert result["index"] == i
|
|
65
|
+
assert result["exit_code"] == 0
|
|
66
|
+
assert result["timed_out"] is False
|
|
67
|
+
|
|
68
|
+
assert "One" in results[0]["output"]
|
|
69
|
+
assert "Two" in results[1]["output"]
|
|
70
|
+
assert "Three" in results[2]["output"]
|
|
71
|
+
|
|
72
|
+
def test_multiple_commands_parallel(self):
|
|
73
|
+
"""Test executing multiple commands in parallel."""
|
|
74
|
+
if platform.system() == "Windows":
|
|
75
|
+
commands = ["echo Alpha", "echo Beta", "echo Gamma"]
|
|
76
|
+
else:
|
|
77
|
+
commands = ["echo 'Alpha'", "echo 'Beta'", "echo 'Gamma'"]
|
|
78
|
+
|
|
79
|
+
start_time = time.time()
|
|
80
|
+
results = self.executor.execute_batch(commands, parallel=True)
|
|
81
|
+
duration = time.time() - start_time
|
|
82
|
+
|
|
83
|
+
assert len(results) == 3
|
|
84
|
+
|
|
85
|
+
# Results should maintain order even when executed in parallel
|
|
86
|
+
assert results[0]["index"] == 0
|
|
87
|
+
assert results[1]["index"] == 1
|
|
88
|
+
assert results[2]["index"] == 2
|
|
89
|
+
|
|
90
|
+
assert "Alpha" in results[0]["output"]
|
|
91
|
+
assert "Beta" in results[1]["output"]
|
|
92
|
+
assert "Gamma" in results[2]["output"]
|
|
93
|
+
|
|
94
|
+
def test_command_failure_serial(self):
|
|
95
|
+
"""Test handling of failed commands in serial execution."""
|
|
96
|
+
if platform.system() == "Windows":
|
|
97
|
+
commands = ["echo Success", "exit 1", "echo After"]
|
|
98
|
+
else:
|
|
99
|
+
commands = ["echo Success", "false", "echo After"]
|
|
100
|
+
|
|
101
|
+
results = self.executor.execute_batch(commands, parallel=False)
|
|
102
|
+
|
|
103
|
+
assert len(results) == 3
|
|
104
|
+
assert results[0]["exit_code"] == 0
|
|
105
|
+
assert results[1]["exit_code"] != 0
|
|
106
|
+
assert results[2]["exit_code"] == 0 # Should continue after failure
|
|
107
|
+
|
|
108
|
+
def test_command_failure_parallel(self):
|
|
109
|
+
"""Test handling of failed commands in parallel execution."""
|
|
110
|
+
if platform.system() == "Windows":
|
|
111
|
+
commands = ["echo OK1", "exit 1", "echo OK2"]
|
|
112
|
+
else:
|
|
113
|
+
commands = ["echo OK1", "false", "echo OK2"]
|
|
114
|
+
|
|
115
|
+
results = self.executor.execute_batch(commands, parallel=True)
|
|
116
|
+
|
|
117
|
+
assert len(results) == 3
|
|
118
|
+
assert results[0]["exit_code"] == 0
|
|
119
|
+
assert results[1]["exit_code"] != 0
|
|
120
|
+
assert results[2]["exit_code"] == 0
|
|
121
|
+
|
|
122
|
+
def test_per_command_timeout(self):
|
|
123
|
+
"""Test per-command timeout in serial execution."""
|
|
124
|
+
if platform.system() == "Windows":
|
|
125
|
+
commands = ["echo Quick", "ping -n 10 127.0.0.1", "echo Done"]
|
|
126
|
+
else:
|
|
127
|
+
commands = ["echo Quick", "sleep 10", "echo Done"]
|
|
128
|
+
|
|
129
|
+
results = self.executor.execute_batch(
|
|
130
|
+
commands,
|
|
131
|
+
per_command_timeout=0.5,
|
|
132
|
+
parallel=False
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
assert len(results) == 3
|
|
136
|
+
assert results[0]["exit_code"] == 0
|
|
137
|
+
assert results[0]["timed_out"] is False
|
|
138
|
+
|
|
139
|
+
assert results[1]["exit_code"] == -1
|
|
140
|
+
assert results[1]["timed_out"] is True
|
|
141
|
+
assert "timed out" in results[1]["error"].lower()
|
|
142
|
+
|
|
143
|
+
# Should continue after timeout
|
|
144
|
+
assert results[2]["exit_code"] == 0
|
|
145
|
+
assert results[2]["timed_out"] is False
|
|
146
|
+
|
|
147
|
+
def test_overall_timeout_serial(self):
|
|
148
|
+
"""Test overall timeout in serial execution."""
|
|
149
|
+
if platform.system() == "Windows":
|
|
150
|
+
commands = ["ping -n 2 127.0.0.1"] * 5
|
|
151
|
+
else:
|
|
152
|
+
commands = ["sleep 1"] * 5
|
|
153
|
+
|
|
154
|
+
start_time = time.time()
|
|
155
|
+
results = self.executor.execute_batch(
|
|
156
|
+
commands,
|
|
157
|
+
timeout=2.0, # Overall timeout shorter than total execution
|
|
158
|
+
parallel=False
|
|
159
|
+
)
|
|
160
|
+
duration = time.time() - start_time
|
|
161
|
+
|
|
162
|
+
assert duration < 3.0 # Should timeout before all complete
|
|
163
|
+
|
|
164
|
+
# Some commands should have executed
|
|
165
|
+
executed_count = sum(1 for r in results if not r["timed_out"])
|
|
166
|
+
timed_out_count = sum(1 for r in results if r["timed_out"])
|
|
167
|
+
|
|
168
|
+
assert executed_count > 0
|
|
169
|
+
assert timed_out_count > 0
|
|
170
|
+
assert len(results) == 5
|
|
171
|
+
|
|
172
|
+
def test_overall_timeout_parallel(self):
|
|
173
|
+
"""Test overall timeout in parallel execution."""
|
|
174
|
+
if platform.system() == "Windows":
|
|
175
|
+
commands = ["ping -n 5 127.0.0.1"] * 4
|
|
176
|
+
else:
|
|
177
|
+
commands = ["sleep 3"] * 4
|
|
178
|
+
|
|
179
|
+
start_time = time.time()
|
|
180
|
+
results = self.executor.execute_batch(
|
|
181
|
+
commands,
|
|
182
|
+
timeout=1.0, # Overall timeout
|
|
183
|
+
parallel=True
|
|
184
|
+
)
|
|
185
|
+
duration = time.time() - start_time
|
|
186
|
+
|
|
187
|
+
assert duration < 3.0 # Should timeout quickly (allowing for cleanup time)
|
|
188
|
+
assert len(results) == 4
|
|
189
|
+
|
|
190
|
+
# All should timeout since they're running in parallel
|
|
191
|
+
for result in results:
|
|
192
|
+
assert result["timed_out"] is True
|
|
193
|
+
|
|
194
|
+
def test_mixed_success_and_failure(self):
|
|
195
|
+
"""Test batch with mix of successful and failing commands."""
|
|
196
|
+
if platform.system() == "Windows":
|
|
197
|
+
commands = [
|
|
198
|
+
"echo Start",
|
|
199
|
+
"exit 0",
|
|
200
|
+
"exit 1",
|
|
201
|
+
"ping -n 10 127.0.0.1", # Will timeout
|
|
202
|
+
"echo End"
|
|
203
|
+
]
|
|
204
|
+
else:
|
|
205
|
+
commands = [
|
|
206
|
+
"echo Start",
|
|
207
|
+
"true",
|
|
208
|
+
"false",
|
|
209
|
+
"sleep 10", # Will timeout
|
|
210
|
+
"echo End"
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
results = self.executor.execute_batch(
|
|
214
|
+
commands,
|
|
215
|
+
per_command_timeout=0.5,
|
|
216
|
+
parallel=False
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
assert len(results) == 5
|
|
220
|
+
assert results[0]["exit_code"] == 0 # echo Start
|
|
221
|
+
assert results[1]["exit_code"] == 0 # exit 0 / true
|
|
222
|
+
assert results[2]["exit_code"] != 0 # exit 1 / false
|
|
223
|
+
assert results[3]["timed_out"] is True # timeout
|
|
224
|
+
assert results[4]["exit_code"] == 0 # echo End
|
|
225
|
+
|
|
226
|
+
def test_result_structure(self):
|
|
227
|
+
"""Test that results have the expected structure."""
|
|
228
|
+
commands = ["echo Test"]
|
|
229
|
+
results = self.executor.execute_batch(commands)
|
|
230
|
+
|
|
231
|
+
assert len(results) == 1
|
|
232
|
+
result = results[0]
|
|
233
|
+
|
|
234
|
+
# Check all expected fields
|
|
235
|
+
assert "command" in result
|
|
236
|
+
assert "index" in result
|
|
237
|
+
assert "exit_code" in result
|
|
238
|
+
assert "output" in result
|
|
239
|
+
assert "error" in result
|
|
240
|
+
assert "timed_out" in result
|
|
241
|
+
assert "duration" in result
|
|
242
|
+
assert "start_time" in result
|
|
243
|
+
assert "end_time" in result
|
|
244
|
+
|
|
245
|
+
# Check types
|
|
246
|
+
assert isinstance(result["command"], str)
|
|
247
|
+
assert isinstance(result["index"], int)
|
|
248
|
+
assert isinstance(result["exit_code"], int)
|
|
249
|
+
assert isinstance(result["output"], str)
|
|
250
|
+
assert result["error"] is None or isinstance(result["error"], str)
|
|
251
|
+
assert isinstance(result["timed_out"], bool)
|
|
252
|
+
assert isinstance(result["duration"], float)
|
|
253
|
+
assert isinstance(result["start_time"], float)
|
|
254
|
+
assert isinstance(result["end_time"], float)
|
|
255
|
+
|
|
256
|
+
def test_command_ordering_preserved(self):
|
|
257
|
+
"""Test that command order is preserved in results."""
|
|
258
|
+
commands = [f"echo 'Command {i}'" for i in range(10)]
|
|
259
|
+
|
|
260
|
+
# Test both serial and parallel
|
|
261
|
+
for parallel in [False, True]:
|
|
262
|
+
results = self.executor.execute_batch(commands, parallel=parallel)
|
|
263
|
+
|
|
264
|
+
assert len(results) == 10
|
|
265
|
+
for i, result in enumerate(results):
|
|
266
|
+
assert result["index"] == i
|
|
267
|
+
assert f"Command {i}" in result["output"]
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class TestExecuteCommands:
|
|
271
|
+
"""Test cases for the convenience execute_commands function."""
|
|
272
|
+
|
|
273
|
+
def test_basic_parallel_execution(self):
|
|
274
|
+
"""Test basic parallel execution with convenience function."""
|
|
275
|
+
if platform.system() == "Windows":
|
|
276
|
+
commands = ["echo A", "echo B", "echo C"]
|
|
277
|
+
else:
|
|
278
|
+
commands = ["echo A", "echo B", "echo C"]
|
|
279
|
+
|
|
280
|
+
results = execute_commands(commands, parallel=True)
|
|
281
|
+
|
|
282
|
+
assert len(results) == 3
|
|
283
|
+
assert all(r["exit_code"] == 0 for r in results)
|
|
284
|
+
assert "A" in results[0]["output"]
|
|
285
|
+
assert "B" in results[1]["output"]
|
|
286
|
+
assert "C" in results[2]["output"]
|
|
287
|
+
|
|
288
|
+
def test_basic_serial_execution(self):
|
|
289
|
+
"""Test basic serial execution with convenience function."""
|
|
290
|
+
commands = ["echo 1", "echo 2", "echo 3"]
|
|
291
|
+
|
|
292
|
+
results = execute_commands(commands, parallel=False)
|
|
293
|
+
|
|
294
|
+
assert len(results) == 3
|
|
295
|
+
assert all(r["exit_code"] == 0 for r in results)
|
|
296
|
+
|
|
297
|
+
def test_with_timeout_options(self):
|
|
298
|
+
"""Test convenience function with timeout options."""
|
|
299
|
+
if platform.system() == "Windows":
|
|
300
|
+
commands = ["echo Fast", "ping -n 5 127.0.0.1"]
|
|
301
|
+
else:
|
|
302
|
+
commands = ["echo Fast", "sleep 3"]
|
|
303
|
+
|
|
304
|
+
results = execute_commands(
|
|
305
|
+
commands,
|
|
306
|
+
per_command_timeout=1.0,
|
|
307
|
+
parallel=False
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
assert results[0]["timed_out"] is False
|
|
311
|
+
assert results[1]["timed_out"] is True
|
|
312
|
+
|
|
313
|
+
def test_with_working_directory(self):
|
|
314
|
+
"""Test execution with custom working directory."""
|
|
315
|
+
import tempfile
|
|
316
|
+
import os
|
|
317
|
+
|
|
318
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
319
|
+
# Create a test file in temp directory
|
|
320
|
+
test_file = os.path.join(temp_dir, "test.txt")
|
|
321
|
+
with open(test_file, "w") as f:
|
|
322
|
+
f.write("test content")
|
|
323
|
+
|
|
324
|
+
if platform.system() == "Windows":
|
|
325
|
+
commands = ["dir", "type test.txt"]
|
|
326
|
+
else:
|
|
327
|
+
commands = ["ls", "cat test.txt"]
|
|
328
|
+
|
|
329
|
+
results = execute_commands(commands, cwd=temp_dir, parallel=False)
|
|
330
|
+
|
|
331
|
+
assert all(r["exit_code"] == 0 for r in results)
|
|
332
|
+
assert "test.txt" in results[0]["output"]
|
|
333
|
+
assert "test content" in results[1]["output"]
|
|
334
|
+
|
|
335
|
+
def test_empty_commands(self):
|
|
336
|
+
"""Test with empty command list."""
|
|
337
|
+
results = execute_commands([])
|
|
338
|
+
assert results == []
|
|
339
|
+
|
|
340
|
+
def test_verbose_mode(self):
|
|
341
|
+
"""Test verbose mode doesn't break functionality."""
|
|
342
|
+
commands = ["echo Verbose"]
|
|
343
|
+
results = execute_commands(commands, verbose=True)
|
|
344
|
+
|
|
345
|
+
assert len(results) == 1
|
|
346
|
+
assert results[0]["exit_code"] == 0
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
class TestBatchExecutionEdgeCases:
|
|
350
|
+
"""Test edge cases for batch execution."""
|
|
351
|
+
|
|
352
|
+
def test_very_large_batch(self):
|
|
353
|
+
"""Test execution of a large number of commands."""
|
|
354
|
+
# Create 50 simple commands
|
|
355
|
+
commands = [f"echo 'Item {i}'" for i in range(50)]
|
|
356
|
+
|
|
357
|
+
results = execute_commands(commands, parallel=True)
|
|
358
|
+
|
|
359
|
+
assert len(results) == 50
|
|
360
|
+
assert all(r["exit_code"] == 0 for r in results)
|
|
361
|
+
|
|
362
|
+
def test_invalid_commands(self):
|
|
363
|
+
"""Test batch with invalid commands."""
|
|
364
|
+
commands = [
|
|
365
|
+
"echo Valid",
|
|
366
|
+
"this_command_does_not_exist_12345",
|
|
367
|
+
"echo Also Valid"
|
|
368
|
+
]
|
|
369
|
+
|
|
370
|
+
results = execute_commands(commands, parallel=False)
|
|
371
|
+
|
|
372
|
+
assert len(results) == 3
|
|
373
|
+
assert results[0]["exit_code"] == 0
|
|
374
|
+
assert results[1]["exit_code"] != 0
|
|
375
|
+
assert results[2]["exit_code"] == 0
|
|
376
|
+
|
|
377
|
+
def test_mixed_command_types(self):
|
|
378
|
+
"""Test batch with different command formats."""
|
|
379
|
+
commands = [
|
|
380
|
+
"echo String command",
|
|
381
|
+
["echo", "List", "command"],
|
|
382
|
+
"echo Another string"
|
|
383
|
+
]
|
|
384
|
+
|
|
385
|
+
results = execute_commands(commands, parallel=False)
|
|
386
|
+
|
|
387
|
+
assert len(results) == 3
|
|
388
|
+
assert all(r["exit_code"] == 0 for r in results)
|
|
389
|
+
assert "String command" in results[0]["output"]
|
|
390
|
+
assert "List command" in results[1]["output"]
|
|
391
|
+
assert "Another string" in results[2]["output"]
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
class TestExecuteBatchViaResolver:
|
|
395
|
+
"""Test cases for batch execution via ExecuteCommandToolResolver."""
|
|
396
|
+
|
|
397
|
+
def test_json_array_batch(self):
|
|
398
|
+
"""Test batch execution using JSON array format."""
|
|
399
|
+
from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool
|
|
400
|
+
from autocoder.common.v2.agent.agentic_edit_tools.execute_command_tool_resolver import ExecuteCommandToolResolver
|
|
401
|
+
from autocoder.common import AutoCoderArgs
|
|
402
|
+
|
|
403
|
+
# Create tool with JSON array
|
|
404
|
+
tool = ExecuteCommandTool(
|
|
405
|
+
command='["echo Hello", "echo World", "echo Done"]',
|
|
406
|
+
requires_approval=False,
|
|
407
|
+
timeout=30
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
args = AutoCoderArgs(
|
|
411
|
+
source_dir=".",
|
|
412
|
+
enable_agentic_dangerous_command_check=False,
|
|
413
|
+
enable_agentic_auto_approve=True,
|
|
414
|
+
use_shell_commands=True
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
resolver = ExecuteCommandToolResolver(None, tool, args)
|
|
418
|
+
result = resolver.resolve()
|
|
419
|
+
|
|
420
|
+
assert result.success is True
|
|
421
|
+
assert 'batch_results' in result.content
|
|
422
|
+
assert len(result.content['batch_results']) == 3
|
|
423
|
+
assert all(r['exit_code'] == 0 for r in result.content['batch_results'])
|
|
424
|
+
|
|
425
|
+
def test_yaml_serial_mode(self):
|
|
426
|
+
"""Test batch execution using YAML format with serial mode."""
|
|
427
|
+
from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool
|
|
428
|
+
from autocoder.common.v2.agent.agentic_edit_tools.execute_command_tool_resolver import ExecuteCommandToolResolver
|
|
429
|
+
from autocoder.common import AutoCoderArgs
|
|
430
|
+
|
|
431
|
+
yaml_command = """mode: serial
|
|
432
|
+
cmds:
|
|
433
|
+
- echo "Step 1"
|
|
434
|
+
- echo "Step 2"
|
|
435
|
+
- echo "Step 3"
|
|
436
|
+
"""
|
|
437
|
+
|
|
438
|
+
tool = ExecuteCommandTool(
|
|
439
|
+
command=yaml_command,
|
|
440
|
+
requires_approval=False,
|
|
441
|
+
timeout=30
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
args = AutoCoderArgs(
|
|
445
|
+
source_dir=".",
|
|
446
|
+
enable_agentic_dangerous_command_check=False,
|
|
447
|
+
enable_agentic_auto_approve=True,
|
|
448
|
+
use_shell_commands=True
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
resolver = ExecuteCommandToolResolver(None, tool, args)
|
|
452
|
+
result = resolver.resolve()
|
|
453
|
+
|
|
454
|
+
assert result.success is True
|
|
455
|
+
assert result.content['summary']['execution_mode'] == 'serial'
|
|
456
|
+
assert result.content['summary']['total'] == 3
|
|
457
|
+
|
|
458
|
+
def test_newline_separated_batch(self):
|
|
459
|
+
"""Test batch execution using newline-separated format."""
|
|
460
|
+
from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool
|
|
461
|
+
from autocoder.common.v2.agent.agentic_edit_tools.execute_command_tool_resolver import ExecuteCommandToolResolver
|
|
462
|
+
from autocoder.common import AutoCoderArgs
|
|
463
|
+
|
|
464
|
+
commands = """echo "Line 1"
|
|
465
|
+
echo "Line 2"
|
|
466
|
+
echo "Line 3"
|
|
467
|
+
"""
|
|
468
|
+
|
|
469
|
+
tool = ExecuteCommandTool(
|
|
470
|
+
command=commands,
|
|
471
|
+
requires_approval=False,
|
|
472
|
+
timeout=30
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
args = AutoCoderArgs(
|
|
476
|
+
source_dir=".",
|
|
477
|
+
enable_agentic_dangerous_command_check=False,
|
|
478
|
+
enable_agentic_auto_approve=True,
|
|
479
|
+
use_shell_commands=True
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
resolver = ExecuteCommandToolResolver(None, tool, args)
|
|
483
|
+
result = resolver.resolve()
|
|
484
|
+
|
|
485
|
+
assert result.success is True
|
|
486
|
+
# In newline separated mode, it's treated as single command output
|
|
487
|
+
if isinstance(result.content, str):
|
|
488
|
+
# Single command output
|
|
489
|
+
assert "Line 1" in result.content
|
|
490
|
+
assert "Line 2" in result.content
|
|
491
|
+
assert "Line 3" in result.content
|
|
492
|
+
else:
|
|
493
|
+
# Batch mode
|
|
494
|
+
assert 'batch_results' in result.content
|
|
495
|
+
assert len(result.content['batch_results']) == 3
|
|
496
|
+
|
|
497
|
+
def test_single_command_fallback(self):
|
|
498
|
+
"""Test that single commands still work normally."""
|
|
499
|
+
from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool
|
|
500
|
+
from autocoder.common.v2.agent.agentic_edit_tools.execute_command_tool_resolver import ExecuteCommandToolResolver
|
|
501
|
+
from autocoder.common import AutoCoderArgs
|
|
502
|
+
|
|
503
|
+
tool = ExecuteCommandTool(
|
|
504
|
+
command='echo "Single command"',
|
|
505
|
+
requires_approval=False,
|
|
506
|
+
timeout=30
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
args = AutoCoderArgs(
|
|
510
|
+
source_dir=".",
|
|
511
|
+
enable_agentic_dangerous_command_check=False,
|
|
512
|
+
enable_agentic_auto_approve=True,
|
|
513
|
+
use_shell_commands=True
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
resolver = ExecuteCommandToolResolver(None, tool, args)
|
|
517
|
+
result = resolver.resolve()
|
|
518
|
+
|
|
519
|
+
assert result.success is True
|
|
520
|
+
# Single command should not have batch_results
|
|
521
|
+
assert 'batch_results' not in result.content or result.content is None or isinstance(result.content, str)
|
|
522
|
+
|
|
523
|
+
def test_serial_with_comment(self):
|
|
524
|
+
"""Test serial execution with comment prefix."""
|
|
525
|
+
from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool
|
|
526
|
+
from autocoder.common.v2.agent.agentic_edit_tools.execute_command_tool_resolver import ExecuteCommandToolResolver
|
|
527
|
+
from autocoder.common import AutoCoderArgs
|
|
528
|
+
|
|
529
|
+
commands = """# serial
|
|
530
|
+
echo "First"
|
|
531
|
+
echo "Second"
|
|
532
|
+
echo "Third"
|
|
533
|
+
"""
|
|
534
|
+
|
|
535
|
+
tool = ExecuteCommandTool(
|
|
536
|
+
command=commands,
|
|
537
|
+
requires_approval=False,
|
|
538
|
+
timeout=30
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
args = AutoCoderArgs(
|
|
542
|
+
source_dir=".",
|
|
543
|
+
enable_agentic_dangerous_command_check=False,
|
|
544
|
+
enable_agentic_auto_approve=True,
|
|
545
|
+
use_shell_commands=True
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
resolver = ExecuteCommandToolResolver(None, tool, args)
|
|
549
|
+
result = resolver.resolve()
|
|
550
|
+
|
|
551
|
+
assert result.success is True
|
|
552
|
+
assert result.content['summary']['execution_mode'] == 'serial'
|
|
553
|
+
|
|
554
|
+
def test_batch_with_failure(self):
|
|
555
|
+
"""Test batch execution with some commands failing."""
|
|
556
|
+
from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool
|
|
557
|
+
from autocoder.common.v2.agent.agentic_edit_tools.execute_command_tool_resolver import ExecuteCommandToolResolver
|
|
558
|
+
from autocoder.common import AutoCoderArgs
|
|
559
|
+
|
|
560
|
+
if platform.system() == "Windows":
|
|
561
|
+
commands = ['echo "Success"', 'exit 1', 'echo "After failure"']
|
|
562
|
+
else:
|
|
563
|
+
commands = ['echo "Success"', 'false', 'echo "After failure"']
|
|
564
|
+
|
|
565
|
+
tool = ExecuteCommandTool(
|
|
566
|
+
command=json.dumps(commands),
|
|
567
|
+
requires_approval=False,
|
|
568
|
+
timeout=30
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
args = AutoCoderArgs(
|
|
572
|
+
source_dir=".",
|
|
573
|
+
enable_agentic_dangerous_command_check=False,
|
|
574
|
+
enable_agentic_auto_approve=True,
|
|
575
|
+
use_shell_commands=True
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
resolver = ExecuteCommandToolResolver(None, tool, args)
|
|
579
|
+
result = resolver.resolve()
|
|
580
|
+
|
|
581
|
+
# Overall result should be False due to failure
|
|
582
|
+
assert result.success is False
|
|
583
|
+
assert result.content['summary']['failed'] == 1
|
|
584
|
+
assert result.content['summary']['successful'] == 2
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
if __name__ == "__main__":
|
|
588
|
+
pytest.main([__file__, "-v"])
|