auto-coder 1.0.0__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-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.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 +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 +73 -59
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +970 -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 +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/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 +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 +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 +349 -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 +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 +116 -124
- 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 +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 +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 +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-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.0.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for monitoring functionality.
|
|
3
|
+
|
|
4
|
+
This module tests the monitoring capabilities used in shell command execution.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
import time
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from unittest.mock import Mock, patch
|
|
11
|
+
|
|
12
|
+
from autocoder.common.shell_commands.monitoring import (
|
|
13
|
+
CommandExecutionLogger,
|
|
14
|
+
PerformanceMonitor,
|
|
15
|
+
CommandExecutionMetrics,
|
|
16
|
+
get_logger,
|
|
17
|
+
get_global_monitor,
|
|
18
|
+
reset_global_instances
|
|
19
|
+
)
|
|
20
|
+
from autocoder.common.shell_commands.exceptions import (
|
|
21
|
+
CommandExecutionError,
|
|
22
|
+
CommandTimeoutError
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TestCommandExecutionMetrics:
|
|
27
|
+
"""Test cases for CommandExecutionMetrics class."""
|
|
28
|
+
|
|
29
|
+
def test_initialization(self):
|
|
30
|
+
"""Test metrics initialization."""
|
|
31
|
+
command = "echo hello"
|
|
32
|
+
start_time = datetime.now()
|
|
33
|
+
|
|
34
|
+
metrics = CommandExecutionMetrics(command, start_time)
|
|
35
|
+
|
|
36
|
+
assert metrics.command == command
|
|
37
|
+
assert metrics.start_time == start_time
|
|
38
|
+
assert metrics.end_time is None
|
|
39
|
+
assert metrics.duration is None
|
|
40
|
+
assert metrics.exit_code is None
|
|
41
|
+
assert metrics.timeout is None
|
|
42
|
+
assert metrics.timed_out is False
|
|
43
|
+
assert metrics.pid is None
|
|
44
|
+
assert metrics.output_length == 0
|
|
45
|
+
assert metrics.error_count == 0
|
|
46
|
+
assert metrics.recovery_attempts == 0
|
|
47
|
+
|
|
48
|
+
def test_finalize_with_default_end_time(self):
|
|
49
|
+
"""Test metrics finalization with default end time."""
|
|
50
|
+
command = "echo hello"
|
|
51
|
+
start_time = datetime.now()
|
|
52
|
+
|
|
53
|
+
metrics = CommandExecutionMetrics(command, start_time)
|
|
54
|
+
|
|
55
|
+
# Wait a bit to ensure duration is measurable
|
|
56
|
+
time.sleep(0.001)
|
|
57
|
+
|
|
58
|
+
metrics.finalize()
|
|
59
|
+
|
|
60
|
+
assert metrics.end_time is not None
|
|
61
|
+
assert metrics.duration is not None
|
|
62
|
+
assert metrics.duration > 0
|
|
63
|
+
assert metrics.end_time > start_time
|
|
64
|
+
|
|
65
|
+
def test_finalize_with_custom_end_time(self):
|
|
66
|
+
"""Test metrics finalization with custom end time."""
|
|
67
|
+
command = "echo hello"
|
|
68
|
+
start_time = datetime.now()
|
|
69
|
+
end_time = datetime.now()
|
|
70
|
+
|
|
71
|
+
metrics = CommandExecutionMetrics(command, start_time)
|
|
72
|
+
metrics.finalize(end_time)
|
|
73
|
+
|
|
74
|
+
assert metrics.end_time == end_time
|
|
75
|
+
assert metrics.duration is not None
|
|
76
|
+
assert metrics.duration >= 0
|
|
77
|
+
|
|
78
|
+
def test_string_representation(self):
|
|
79
|
+
"""Test string representation of metrics."""
|
|
80
|
+
command = "echo hello"
|
|
81
|
+
start_time = datetime.now()
|
|
82
|
+
|
|
83
|
+
metrics = CommandExecutionMetrics(command, start_time)
|
|
84
|
+
metrics.exit_code = 0
|
|
85
|
+
metrics.duration = 1.5
|
|
86
|
+
|
|
87
|
+
str_repr = str(metrics)
|
|
88
|
+
assert command in str_repr
|
|
89
|
+
assert "0" in str_repr # exit code
|
|
90
|
+
assert "1.5" in str_repr # duration
|
|
91
|
+
|
|
92
|
+
def test_metrics_with_timeout(self):
|
|
93
|
+
"""Test metrics with timeout information."""
|
|
94
|
+
command = "sleep 10"
|
|
95
|
+
start_time = datetime.now()
|
|
96
|
+
|
|
97
|
+
metrics = CommandExecutionMetrics(command, start_time)
|
|
98
|
+
metrics.timeout = 5.0
|
|
99
|
+
metrics.timed_out = True
|
|
100
|
+
metrics.pid = 1234
|
|
101
|
+
|
|
102
|
+
assert metrics.timeout == 5.0
|
|
103
|
+
assert metrics.timed_out is True
|
|
104
|
+
assert metrics.pid == 1234
|
|
105
|
+
|
|
106
|
+
def test_metrics_with_error_tracking(self):
|
|
107
|
+
"""Test metrics with error tracking."""
|
|
108
|
+
command = "failing_command"
|
|
109
|
+
start_time = datetime.now()
|
|
110
|
+
|
|
111
|
+
metrics = CommandExecutionMetrics(command, start_time)
|
|
112
|
+
metrics.error_count = 2
|
|
113
|
+
metrics.recovery_attempts = 3
|
|
114
|
+
|
|
115
|
+
assert metrics.error_count == 2
|
|
116
|
+
assert metrics.recovery_attempts == 3
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class TestCommandExecutionLogger:
|
|
120
|
+
"""Test cases for CommandExecutionLogger class."""
|
|
121
|
+
|
|
122
|
+
def test_initialization(self):
|
|
123
|
+
"""Test logger initialization."""
|
|
124
|
+
logger = CommandExecutionLogger(verbose=True)
|
|
125
|
+
assert logger.verbose is True
|
|
126
|
+
|
|
127
|
+
def test_log_command_start(self):
|
|
128
|
+
"""Test logging command start."""
|
|
129
|
+
logger = CommandExecutionLogger(verbose=False)
|
|
130
|
+
|
|
131
|
+
metrics = logger.log_command_start("echo hello", 5.0, 1234, "/tmp")
|
|
132
|
+
|
|
133
|
+
assert metrics.command == "echo hello"
|
|
134
|
+
assert metrics.timeout == 5.0
|
|
135
|
+
assert metrics.pid == 1234
|
|
136
|
+
assert metrics.start_time is not None
|
|
137
|
+
|
|
138
|
+
def test_log_command_start_without_optional_params(self):
|
|
139
|
+
"""Test logging command start without optional parameters."""
|
|
140
|
+
logger = CommandExecutionLogger()
|
|
141
|
+
|
|
142
|
+
metrics = logger.log_command_start("test command")
|
|
143
|
+
|
|
144
|
+
assert metrics.command == "test command"
|
|
145
|
+
assert metrics.timeout is None
|
|
146
|
+
assert metrics.pid is None
|
|
147
|
+
|
|
148
|
+
def test_log_command_complete_success(self):
|
|
149
|
+
"""Test logging successful command completion."""
|
|
150
|
+
logger = CommandExecutionLogger()
|
|
151
|
+
|
|
152
|
+
metrics = CommandExecutionMetrics("test command", datetime.now())
|
|
153
|
+
metrics.pid = 1234
|
|
154
|
+
|
|
155
|
+
logger.log_command_complete(metrics, 0, "output text")
|
|
156
|
+
|
|
157
|
+
assert metrics.exit_code == 0
|
|
158
|
+
assert metrics.output_length == len("output text")
|
|
159
|
+
assert metrics.end_time is not None
|
|
160
|
+
assert metrics.duration is not None
|
|
161
|
+
|
|
162
|
+
def test_log_command_complete_failure(self):
|
|
163
|
+
"""Test logging failed command completion."""
|
|
164
|
+
logger = CommandExecutionLogger()
|
|
165
|
+
|
|
166
|
+
metrics = CommandExecutionMetrics("test command", datetime.now())
|
|
167
|
+
metrics.pid = 1234
|
|
168
|
+
|
|
169
|
+
error = CommandExecutionError("Command failed")
|
|
170
|
+
logger.log_command_complete(metrics, 1, "", error)
|
|
171
|
+
|
|
172
|
+
assert metrics.exit_code == 1
|
|
173
|
+
assert metrics.output_length == 0
|
|
174
|
+
assert metrics.error_count == 1
|
|
175
|
+
assert metrics.end_time is not None
|
|
176
|
+
|
|
177
|
+
def test_log_command_complete_timeout(self):
|
|
178
|
+
"""Test logging command timeout."""
|
|
179
|
+
logger = CommandExecutionLogger()
|
|
180
|
+
|
|
181
|
+
metrics = CommandExecutionMetrics("sleep 10", datetime.now())
|
|
182
|
+
metrics.pid = 1234
|
|
183
|
+
metrics.timeout = 5.0
|
|
184
|
+
|
|
185
|
+
timeout_error = CommandTimeoutError("sleep 10", 5.0, 1234)
|
|
186
|
+
logger.log_command_complete(metrics, -1, "", timeout_error)
|
|
187
|
+
|
|
188
|
+
assert metrics.exit_code == -1
|
|
189
|
+
assert metrics.timed_out is True
|
|
190
|
+
assert metrics.error_count == 1
|
|
191
|
+
|
|
192
|
+
def test_get_execution_history(self):
|
|
193
|
+
"""Test getting command execution history."""
|
|
194
|
+
logger = CommandExecutionLogger()
|
|
195
|
+
|
|
196
|
+
# Log a few commands
|
|
197
|
+
metrics1 = logger.log_command_start("echo 1")
|
|
198
|
+
logger.log_command_complete(metrics1, 0, "output1")
|
|
199
|
+
|
|
200
|
+
metrics2 = logger.log_command_start("echo 2")
|
|
201
|
+
logger.log_command_complete(metrics2, 0, "output2")
|
|
202
|
+
|
|
203
|
+
history = logger.get_execution_history()
|
|
204
|
+
|
|
205
|
+
assert len(history) == 2
|
|
206
|
+
assert history[0].command == "echo 1"
|
|
207
|
+
assert history[1].command == "echo 2"
|
|
208
|
+
|
|
209
|
+
def test_get_summary_stats(self):
|
|
210
|
+
"""Test getting summary statistics."""
|
|
211
|
+
logger = CommandExecutionLogger()
|
|
212
|
+
|
|
213
|
+
# Log successful command
|
|
214
|
+
metrics1 = logger.log_command_start("echo success")
|
|
215
|
+
logger.log_command_complete(metrics1, 0, "output")
|
|
216
|
+
|
|
217
|
+
# Log failed command
|
|
218
|
+
metrics2 = logger.log_command_start("false")
|
|
219
|
+
logger.log_command_complete(metrics2, 1, "")
|
|
220
|
+
|
|
221
|
+
# Log timeout command
|
|
222
|
+
metrics3 = logger.log_command_start("sleep 10")
|
|
223
|
+
metrics3.timeout = 5.0
|
|
224
|
+
timeout_error = CommandTimeoutError("sleep 10", 5.0, 1234)
|
|
225
|
+
logger.log_command_complete(metrics3, -1, "", timeout_error)
|
|
226
|
+
|
|
227
|
+
stats = logger.get_summary_stats()
|
|
228
|
+
|
|
229
|
+
assert stats['total_commands'] == 3
|
|
230
|
+
assert stats['completed_commands'] == 3
|
|
231
|
+
assert stats['successful_commands'] == 1
|
|
232
|
+
assert stats['failed_commands'] == 1
|
|
233
|
+
assert stats['timed_out_commands'] == 1
|
|
234
|
+
assert stats['success_rate'] == 1/3
|
|
235
|
+
assert stats['timeout_rate'] == 1/3
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class TestPerformanceMonitor:
|
|
239
|
+
"""Test cases for PerformanceMonitor class."""
|
|
240
|
+
|
|
241
|
+
def test_initialization(self):
|
|
242
|
+
"""Test monitor initialization."""
|
|
243
|
+
monitor = PerformanceMonitor()
|
|
244
|
+
assert len(monitor.metrics_history) == 0
|
|
245
|
+
assert len(monitor.performance_alerts) == 0
|
|
246
|
+
|
|
247
|
+
def test_record_execution(self):
|
|
248
|
+
"""Test recording command execution."""
|
|
249
|
+
monitor = PerformanceMonitor()
|
|
250
|
+
|
|
251
|
+
metrics = CommandExecutionMetrics("echo test", datetime.now())
|
|
252
|
+
metrics.exit_code = 0
|
|
253
|
+
metrics.duration = 1.5
|
|
254
|
+
|
|
255
|
+
monitor.record_execution(metrics)
|
|
256
|
+
|
|
257
|
+
recent_metrics = monitor.get_recent_metrics(1)
|
|
258
|
+
assert len(recent_metrics) == 1
|
|
259
|
+
assert recent_metrics[0].command == "echo test"
|
|
260
|
+
assert recent_metrics[0].duration == 1.5
|
|
261
|
+
|
|
262
|
+
def test_record_execution_performance_alert(self):
|
|
263
|
+
"""Test recording execution that triggers performance alert."""
|
|
264
|
+
monitor = PerformanceMonitor()
|
|
265
|
+
|
|
266
|
+
# Create a slow command
|
|
267
|
+
metrics = CommandExecutionMetrics("slow_command", datetime.now())
|
|
268
|
+
metrics.duration = 30.0 # Very slow command
|
|
269
|
+
metrics.exit_code = 0
|
|
270
|
+
|
|
271
|
+
monitor.record_execution(metrics)
|
|
272
|
+
|
|
273
|
+
alerts = monitor.get_alerts(1)
|
|
274
|
+
assert len(alerts) >= 0 # May or may not trigger alert depending on implementation
|
|
275
|
+
|
|
276
|
+
def test_record_execution_timeout_alert(self):
|
|
277
|
+
"""Test recording execution that triggers timeout alert."""
|
|
278
|
+
monitor = PerformanceMonitor()
|
|
279
|
+
|
|
280
|
+
metrics = CommandExecutionMetrics("timeout_command", datetime.now())
|
|
281
|
+
metrics.timed_out = True
|
|
282
|
+
metrics.timeout = 5.0
|
|
283
|
+
|
|
284
|
+
monitor.record_execution(metrics)
|
|
285
|
+
|
|
286
|
+
alerts = monitor.get_alerts(1)
|
|
287
|
+
assert len(alerts) >= 0 # May or may not trigger alert depending on implementation
|
|
288
|
+
|
|
289
|
+
def test_record_execution_error_alert(self):
|
|
290
|
+
"""Test recording execution that triggers error alert."""
|
|
291
|
+
monitor = PerformanceMonitor()
|
|
292
|
+
|
|
293
|
+
metrics = CommandExecutionMetrics("error_command", datetime.now())
|
|
294
|
+
metrics.exit_code = 1
|
|
295
|
+
metrics.error_count = 1
|
|
296
|
+
|
|
297
|
+
monitor.record_execution(metrics)
|
|
298
|
+
|
|
299
|
+
alerts = monitor.get_alerts(1)
|
|
300
|
+
assert len(alerts) >= 0 # May or may not trigger alert depending on implementation
|
|
301
|
+
|
|
302
|
+
def test_get_recent_metrics(self):
|
|
303
|
+
"""Test getting recent metrics."""
|
|
304
|
+
monitor = PerformanceMonitor()
|
|
305
|
+
|
|
306
|
+
# Record multiple executions
|
|
307
|
+
for i in range(5):
|
|
308
|
+
metrics = CommandExecutionMetrics(f"echo {i}", datetime.now())
|
|
309
|
+
metrics.exit_code = 0
|
|
310
|
+
monitor.record_execution(metrics)
|
|
311
|
+
|
|
312
|
+
recent = monitor.get_recent_metrics(3)
|
|
313
|
+
assert len(recent) == 3
|
|
314
|
+
# Check that we get some of the recent commands
|
|
315
|
+
assert any(f"echo {i}" in m.command for m in recent for i in range(2, 5))
|
|
316
|
+
|
|
317
|
+
def test_get_command_stats(self):
|
|
318
|
+
"""Test getting command statistics."""
|
|
319
|
+
monitor = PerformanceMonitor()
|
|
320
|
+
|
|
321
|
+
# Record multiple echo commands
|
|
322
|
+
for i in range(3):
|
|
323
|
+
metrics = CommandExecutionMetrics(f"echo {i}", datetime.now())
|
|
324
|
+
metrics.exit_code = 0
|
|
325
|
+
metrics.duration = 1.0 + i * 0.5
|
|
326
|
+
monitor.record_execution(metrics)
|
|
327
|
+
|
|
328
|
+
# Record a different command
|
|
329
|
+
metrics = CommandExecutionMetrics("ls", datetime.now())
|
|
330
|
+
metrics.exit_code = 0
|
|
331
|
+
metrics.duration = 0.5
|
|
332
|
+
monitor.record_execution(metrics)
|
|
333
|
+
|
|
334
|
+
echo_stats = monitor.get_command_stats("echo")
|
|
335
|
+
assert echo_stats['total_executions'] == 3
|
|
336
|
+
assert echo_stats['completed_executions'] == 3
|
|
337
|
+
assert echo_stats['successful_executions'] == 3
|
|
338
|
+
assert echo_stats['success_rate'] == 1.0
|
|
339
|
+
assert echo_stats['average_duration'] == 1.5 # (1.0 + 1.5 + 2.0) / 3
|
|
340
|
+
|
|
341
|
+
def test_get_performance_summary(self):
|
|
342
|
+
"""Test getting performance summary."""
|
|
343
|
+
monitor = PerformanceMonitor()
|
|
344
|
+
|
|
345
|
+
# Record some commands
|
|
346
|
+
for i in range(5):
|
|
347
|
+
metrics = CommandExecutionMetrics(f"echo {i}", datetime.now())
|
|
348
|
+
metrics.exit_code = 0 if i < 3 else 1
|
|
349
|
+
metrics.duration = 1.0
|
|
350
|
+
monitor.record_execution(metrics)
|
|
351
|
+
|
|
352
|
+
summary = monitor.get_performance_summary()
|
|
353
|
+
|
|
354
|
+
assert summary['total_commands'] == 5
|
|
355
|
+
assert summary['recent_commands'] == 5
|
|
356
|
+
assert summary['success_rate'] == 0.6 # 3/5
|
|
357
|
+
assert summary['timeout_rate'] == 0.0
|
|
358
|
+
assert summary['average_duration'] == 1.0
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class TestGlobalMonitoringInstances:
|
|
362
|
+
"""Test cases for global monitoring instances."""
|
|
363
|
+
|
|
364
|
+
def test_get_global_logger(self):
|
|
365
|
+
"""Test getting global logger instance."""
|
|
366
|
+
logger1 = get_logger()
|
|
367
|
+
logger2 = get_logger()
|
|
368
|
+
|
|
369
|
+
assert logger1 is logger2 # Should be the same instance
|
|
370
|
+
assert isinstance(logger1, CommandExecutionLogger)
|
|
371
|
+
|
|
372
|
+
def test_get_global_monitor(self):
|
|
373
|
+
"""Test getting global monitor instance."""
|
|
374
|
+
monitor1 = get_global_monitor()
|
|
375
|
+
monitor2 = get_global_monitor()
|
|
376
|
+
|
|
377
|
+
assert monitor1 is monitor2 # Should be the same instance
|
|
378
|
+
assert isinstance(monitor1, PerformanceMonitor)
|
|
379
|
+
|
|
380
|
+
def test_reset_global_instances(self):
|
|
381
|
+
"""Test resetting global instances."""
|
|
382
|
+
logger1 = get_logger()
|
|
383
|
+
monitor1 = get_global_monitor()
|
|
384
|
+
|
|
385
|
+
reset_global_instances()
|
|
386
|
+
|
|
387
|
+
logger2 = get_logger()
|
|
388
|
+
monitor2 = get_global_monitor()
|
|
389
|
+
|
|
390
|
+
assert logger1 is not logger2 # Should be different instances
|
|
391
|
+
assert monitor1 is not monitor2
|
|
392
|
+
|
|
393
|
+
def test_global_logger_with_verbose_flag(self):
|
|
394
|
+
"""Test global logger with verbose flag."""
|
|
395
|
+
logger = get_logger(verbose=True)
|
|
396
|
+
assert logger.verbose is True
|
|
397
|
+
|
|
398
|
+
# Reset and test with verbose=False
|
|
399
|
+
reset_global_instances()
|
|
400
|
+
logger = get_logger(verbose=False)
|
|
401
|
+
assert logger.verbose is False
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
class TestMonitoringIntegration:
|
|
405
|
+
"""Test cases for monitoring integration scenarios."""
|
|
406
|
+
|
|
407
|
+
def test_logger_monitor_integration(self):
|
|
408
|
+
"""Test integration between logger and monitor."""
|
|
409
|
+
logger = CommandExecutionLogger()
|
|
410
|
+
monitor = PerformanceMonitor()
|
|
411
|
+
|
|
412
|
+
# Log command execution
|
|
413
|
+
metrics = logger.log_command_start("echo test", 5.0, 1234)
|
|
414
|
+
logger.log_command_complete(metrics, 0, "output")
|
|
415
|
+
|
|
416
|
+
# Record in monitor
|
|
417
|
+
monitor.record_execution(metrics)
|
|
418
|
+
|
|
419
|
+
# Verify both have the execution recorded
|
|
420
|
+
history = logger.get_execution_history()
|
|
421
|
+
recent = monitor.get_recent_metrics(1)
|
|
422
|
+
|
|
423
|
+
assert len(history) == 1
|
|
424
|
+
assert len(recent) == 1
|
|
425
|
+
assert history[0].command == recent[0].command
|
|
426
|
+
|
|
427
|
+
def test_monitoring_with_errors(self):
|
|
428
|
+
"""Test monitoring with error conditions."""
|
|
429
|
+
logger = CommandExecutionLogger()
|
|
430
|
+
monitor = PerformanceMonitor()
|
|
431
|
+
|
|
432
|
+
# Log failed command
|
|
433
|
+
metrics = logger.log_command_start("false")
|
|
434
|
+
error = CommandExecutionError("Command failed")
|
|
435
|
+
logger.log_command_complete(metrics, 1, "", error)
|
|
436
|
+
|
|
437
|
+
monitor.record_execution(metrics)
|
|
438
|
+
|
|
439
|
+
# Check statistics
|
|
440
|
+
stats = logger.get_summary_stats()
|
|
441
|
+
alerts = monitor.get_alerts(1)
|
|
442
|
+
|
|
443
|
+
assert stats['failed_commands'] == 1
|
|
444
|
+
assert len(alerts) >= 0 # May or may not trigger alert
|
|
445
|
+
|
|
446
|
+
def test_monitoring_with_timeout(self):
|
|
447
|
+
"""Test monitoring with timeout conditions."""
|
|
448
|
+
logger = CommandExecutionLogger()
|
|
449
|
+
monitor = PerformanceMonitor()
|
|
450
|
+
|
|
451
|
+
# Log timeout command
|
|
452
|
+
metrics = logger.log_command_start("sleep 10")
|
|
453
|
+
metrics.timeout = 5.0
|
|
454
|
+
timeout_error = CommandTimeoutError("sleep 10", 5.0, 1234)
|
|
455
|
+
logger.log_command_complete(metrics, -1, "", timeout_error)
|
|
456
|
+
|
|
457
|
+
monitor.record_execution(metrics)
|
|
458
|
+
|
|
459
|
+
# Check statistics
|
|
460
|
+
stats = logger.get_summary_stats()
|
|
461
|
+
alerts = monitor.get_alerts(1)
|
|
462
|
+
|
|
463
|
+
assert stats['timed_out_commands'] == 1
|
|
464
|
+
assert len(alerts) >= 0 # May or may not trigger alert
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
class TestMonitoringEdgeCases:
|
|
468
|
+
"""Test cases for monitoring edge cases."""
|
|
469
|
+
|
|
470
|
+
def test_empty_command_logging(self):
|
|
471
|
+
"""Test logging with empty command."""
|
|
472
|
+
logger = CommandExecutionLogger()
|
|
473
|
+
|
|
474
|
+
metrics = logger.log_command_start("")
|
|
475
|
+
logger.log_command_complete(metrics, 0, "")
|
|
476
|
+
|
|
477
|
+
assert metrics.command == ""
|
|
478
|
+
assert metrics.exit_code == 0
|
|
479
|
+
|
|
480
|
+
def test_very_long_command_logging(self):
|
|
481
|
+
"""Test logging with very long command."""
|
|
482
|
+
logger = CommandExecutionLogger()
|
|
483
|
+
|
|
484
|
+
long_command = "echo " + "a" * 1000
|
|
485
|
+
metrics = logger.log_command_start(long_command)
|
|
486
|
+
logger.log_command_complete(metrics, 0, "output")
|
|
487
|
+
|
|
488
|
+
assert metrics.command == long_command
|
|
489
|
+
assert len(metrics.command) > 1000
|
|
490
|
+
|
|
491
|
+
def test_negative_duration_handling(self):
|
|
492
|
+
"""Test handling of negative duration."""
|
|
493
|
+
monitor = PerformanceMonitor()
|
|
494
|
+
|
|
495
|
+
metrics = CommandExecutionMetrics("echo test", datetime.now())
|
|
496
|
+
metrics.duration = -1.0 # Invalid duration
|
|
497
|
+
|
|
498
|
+
# Should handle gracefully
|
|
499
|
+
monitor.record_execution(metrics)
|
|
500
|
+
|
|
501
|
+
recent = monitor.get_recent_metrics(1)
|
|
502
|
+
assert len(recent) == 1
|
|
503
|
+
|
|
504
|
+
def test_error_values_handling(self):
|
|
505
|
+
"""Test handling of error values in metrics."""
|
|
506
|
+
logger = CommandExecutionLogger()
|
|
507
|
+
|
|
508
|
+
metrics = logger.log_command_start("echo test")
|
|
509
|
+
# Set valid exit code and output
|
|
510
|
+
logger.log_command_complete(metrics, 0, "output")
|
|
511
|
+
|
|
512
|
+
assert metrics.exit_code == 0
|
|
513
|
+
assert metrics.output_length == len("output")
|
|
514
|
+
|
|
515
|
+
def test_concurrent_monitoring(self):
|
|
516
|
+
"""Test concurrent access to monitoring instances."""
|
|
517
|
+
import threading
|
|
518
|
+
|
|
519
|
+
logger = get_logger()
|
|
520
|
+
monitor = get_global_monitor()
|
|
521
|
+
|
|
522
|
+
results = []
|
|
523
|
+
|
|
524
|
+
def log_command(i):
|
|
525
|
+
metrics = logger.log_command_start(f"echo {i}")
|
|
526
|
+
logger.log_command_complete(metrics, 0, f"output {i}")
|
|
527
|
+
monitor.record_execution(metrics)
|
|
528
|
+
results.append(i)
|
|
529
|
+
|
|
530
|
+
threads = []
|
|
531
|
+
for i in range(5):
|
|
532
|
+
thread = threading.Thread(target=log_command, args=(i,))
|
|
533
|
+
threads.append(thread)
|
|
534
|
+
thread.start()
|
|
535
|
+
|
|
536
|
+
for thread in threads:
|
|
537
|
+
thread.join()
|
|
538
|
+
|
|
539
|
+
# All commands should be logged
|
|
540
|
+
assert len(results) == 5
|
|
541
|
+
assert len(logger.get_execution_history()) == 5
|
|
542
|
+
assert len(monitor.get_recent_metrics(5)) == 5
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
if __name__ == "__main__":
|
|
546
|
+
pytest.main([__file__, "-v"])
|