auto-coder 1.0.0__py3-none-any.whl → 2.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- auto_coder-2.0.1.dist-info/LICENSE +158 -0
- auto_coder-2.0.1.dist-info/METADATA +558 -0
- auto_coder-2.0.1.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/entry_points.txt +3 -3
- autocoder/__init__.py +31 -0
- autocoder/agent/auto_filegroup.py +32 -13
- autocoder/agent/auto_learn_from_commit.py +9 -1
- autocoder/agent/base_agentic/__init__.py +3 -0
- autocoder/agent/base_agentic/agent_hub.py +1 -1
- autocoder/agent/base_agentic/base_agent.py +235 -136
- autocoder/agent/base_agentic/default_tools.py +119 -118
- autocoder/agent/base_agentic/test_base_agent.py +1 -1
- autocoder/agent/base_agentic/tool_registry.py +32 -20
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
- autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
- autocoder/agent/base_agentic/types.py +42 -0
- autocoder/agent/entry_command_agent/chat.py +77 -73
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +962 -2345
- autocoder/auto_coder_terminal.py +26 -0
- autocoder/auto_coder_terminal_v3.py +190 -0
- autocoder/chat/conf_command.py +224 -124
- autocoder/chat/models_command.py +361 -299
- autocoder/chat/rules_command.py +79 -31
- autocoder/chat_auto_coder.py +988 -398
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +25 -8
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +44 -44
- autocoder/common/__init__.py +150 -128
- autocoder/common/ac_style_command_parser/__init__.py +39 -2
- autocoder/common/ac_style_command_parser/config.py +422 -0
- autocoder/common/ac_style_command_parser/parser.py +292 -78
- autocoder/common/ac_style_command_parser/test_parser.py +241 -16
- autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
- autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
- autocoder/common/action_yml_file_manager.py +25 -13
- autocoder/common/agent_events/__init__.py +52 -0
- autocoder/common/agent_events/agent_event_emitter.py +193 -0
- autocoder/common/agent_events/event_factory.py +177 -0
- autocoder/common/agent_events/examples.py +307 -0
- autocoder/common/agent_events/types.py +113 -0
- autocoder/common/agent_events/utils.py +68 -0
- autocoder/common/agent_hooks/__init__.py +44 -0
- autocoder/common/agent_hooks/examples.py +582 -0
- autocoder/common/agent_hooks/hook_executor.py +217 -0
- autocoder/common/agent_hooks/hook_manager.py +288 -0
- autocoder/common/agent_hooks/types.py +133 -0
- autocoder/common/agent_hooks/utils.py +99 -0
- autocoder/common/agent_query_queue/queue_executor.py +324 -0
- autocoder/common/agent_query_queue/queue_manager.py +325 -0
- autocoder/common/agents/__init__.py +11 -0
- autocoder/common/agents/agent_manager.py +323 -0
- autocoder/common/agents/agent_parser.py +189 -0
- autocoder/common/agents/example_usage.py +344 -0
- autocoder/common/agents/integration_example.py +330 -0
- autocoder/common/agents/test_agent_parser.py +545 -0
- autocoder/common/async_utils.py +101 -0
- autocoder/common/auto_coder_lang.py +23 -972
- autocoder/common/autocoderargs_parser/__init__.py +14 -0
- autocoder/common/autocoderargs_parser/parser.py +184 -0
- autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
- autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
- autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
- autocoder/common/autocoderargs_parser/token_parser.py +290 -0
- autocoder/common/buildin_tokenizer.py +2 -4
- autocoder/common/code_auto_generate.py +149 -74
- autocoder/common/code_auto_generate_diff.py +163 -70
- autocoder/common/code_auto_generate_editblock.py +179 -89
- autocoder/common/code_auto_generate_strict_diff.py +167 -72
- autocoder/common/code_auto_merge_editblock.py +13 -6
- autocoder/common/code_modification_ranker.py +1 -1
- autocoder/common/command_completer.py +3 -3
- autocoder/common/command_file_manager/manager.py +183 -47
- autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
- autocoder/common/command_templates.py +1 -1
- autocoder/common/conf_utils.py +2 -4
- autocoder/common/conversations/config.py +11 -3
- autocoder/common/conversations/get_conversation_manager.py +100 -2
- autocoder/common/conversations/llm_stats_models.py +264 -0
- autocoder/common/conversations/manager.py +112 -28
- autocoder/common/conversations/models.py +16 -2
- autocoder/common/conversations/storage/index_manager.py +134 -10
- autocoder/common/core_config/__init__.py +63 -0
- autocoder/common/core_config/agentic_mode_manager.py +109 -0
- autocoder/common/core_config/base_manager.py +123 -0
- autocoder/common/core_config/compatibility.py +151 -0
- autocoder/common/core_config/config_manager.py +156 -0
- autocoder/common/core_config/conversation_manager.py +31 -0
- autocoder/common/core_config/exclude_manager.py +72 -0
- autocoder/common/core_config/file_manager.py +177 -0
- autocoder/common/core_config/human_as_model_manager.py +129 -0
- autocoder/common/core_config/lib_manager.py +54 -0
- autocoder/common/core_config/main_manager.py +81 -0
- autocoder/common/core_config/mode_manager.py +126 -0
- autocoder/common/core_config/models.py +70 -0
- autocoder/common/core_config/test_memory_manager.py +1056 -0
- autocoder/common/env_manager.py +282 -0
- autocoder/common/env_manager_usage_example.py +211 -0
- autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
- autocoder/common/file_checkpoint/manager.py +264 -48
- autocoder/common/file_checkpoint/test_backup.py +1 -18
- autocoder/common/file_checkpoint/test_manager.py +270 -1
- autocoder/common/file_checkpoint/test_store.py +1 -17
- autocoder/common/file_handler/__init__.py +23 -0
- autocoder/common/file_handler/active_context_handler.py +159 -0
- autocoder/common/file_handler/add_files_handler.py +409 -0
- autocoder/common/file_handler/chat_handler.py +180 -0
- autocoder/common/file_handler/coding_handler.py +409 -0
- autocoder/common/file_handler/commit_handler.py +200 -0
- autocoder/common/file_handler/lib_handler.py +156 -0
- autocoder/common/file_handler/list_files_handler.py +111 -0
- autocoder/common/file_handler/mcp_handler.py +268 -0
- autocoder/common/file_handler/models_handler.py +493 -0
- autocoder/common/file_handler/remove_files_handler.py +172 -0
- autocoder/common/git_utils.py +44 -8
- autocoder/common/global_cancel.py +15 -6
- autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
- autocoder/common/international/__init__.py +31 -0
- autocoder/common/international/demo_international.py +92 -0
- autocoder/common/international/message_manager.py +157 -0
- autocoder/common/international/messages/__init__.py +56 -0
- autocoder/common/international/messages/async_command_messages.py +507 -0
- autocoder/common/international/messages/auto_coder_messages.py +2208 -0
- autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
- autocoder/common/international/messages/command_help_messages.py +986 -0
- autocoder/common/international/messages/conversation_command_messages.py +191 -0
- autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
- autocoder/common/international/messages/queue_command_messages.py +751 -0
- autocoder/common/international/messages/rules_command_messages.py +77 -0
- autocoder/common/international/messages/sdk_messages.py +1707 -0
- autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
- autocoder/common/international/messages/tool_display_messages.py +1212 -0
- autocoder/common/international/messages/workflow_exception_messages.py +473 -0
- autocoder/common/international/test_international.py +612 -0
- autocoder/common/linter_core/__init__.py +28 -0
- autocoder/common/linter_core/base_linter.py +61 -0
- autocoder/common/linter_core/config_loader.py +271 -0
- autocoder/common/linter_core/formatters/__init__.py +0 -0
- autocoder/common/linter_core/formatters/base_formatter.py +38 -0
- autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
- autocoder/common/linter_core/linter.py +166 -0
- autocoder/common/linter_core/linter_factory.py +216 -0
- autocoder/common/linter_core/linter_manager.py +333 -0
- autocoder/common/linter_core/linters/__init__.py +9 -0
- autocoder/common/linter_core/linters/java_linter.py +342 -0
- autocoder/common/linter_core/linters/python_linter.py +115 -0
- autocoder/common/linter_core/linters/typescript_linter.py +119 -0
- autocoder/common/linter_core/models/__init__.py +7 -0
- autocoder/common/linter_core/models/lint_result.py +91 -0
- autocoder/common/linter_core/models.py +33 -0
- autocoder/common/linter_core/tests/__init__.py +3 -0
- autocoder/common/linter_core/tests/test_config_loader.py +323 -0
- autocoder/common/linter_core/tests/test_config_loading.py +308 -0
- autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
- autocoder/common/linter_core/tests/test_formatters.py +147 -0
- autocoder/common/linter_core/tests/test_integration.py +317 -0
- autocoder/common/linter_core/tests/test_java_linter.py +496 -0
- autocoder/common/linter_core/tests/test_linters.py +265 -0
- autocoder/common/linter_core/tests/test_models.py +81 -0
- autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
- autocoder/common/linter_core/tests/verify_fixes.py +183 -0
- autocoder/common/llm_friendly_package/__init__.py +31 -0
- autocoder/common/llm_friendly_package/base_manager.py +102 -0
- autocoder/common/llm_friendly_package/docs_manager.py +121 -0
- autocoder/common/llm_friendly_package/library_manager.py +171 -0
- autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
- autocoder/common/llm_friendly_package/models.py +40 -0
- autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
- autocoder/common/llms/__init__.py +15 -0
- autocoder/common/llms/demo_error_handling.py +85 -0
- autocoder/common/llms/factory.py +142 -0
- autocoder/common/llms/manager.py +264 -0
- autocoder/common/llms/pricing.py +121 -0
- autocoder/common/llms/registry.py +316 -0
- autocoder/common/llms/schema.py +77 -0
- autocoder/common/llms/simple_demo.py +45 -0
- autocoder/common/llms/test_quick_model.py +116 -0
- autocoder/common/llms/test_remove_functionality.py +182 -0
- autocoder/common/llms/tests/__init__.py +1 -0
- autocoder/common/llms/tests/test_manager.py +330 -0
- autocoder/common/llms/tests/test_registry.py +364 -0
- autocoder/common/mcp_tools/__init__.py +62 -0
- autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
- autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
- autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
- autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
- autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
- autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
- autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
- autocoder/common/mcp_tools/verify_functionality.py +202 -0
- autocoder/common/model_speed_tester.py +32 -26
- autocoder/common/priority_directory_finder/__init__.py +142 -0
- autocoder/common/priority_directory_finder/examples.py +230 -0
- autocoder/common/priority_directory_finder/finder.py +283 -0
- autocoder/common/priority_directory_finder/models.py +236 -0
- autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
- autocoder/common/project_scanner/__init__.py +18 -0
- autocoder/common/project_scanner/compat.py +77 -0
- autocoder/common/project_scanner/scanner.py +436 -0
- autocoder/common/project_tracker/__init__.py +27 -0
- autocoder/common/project_tracker/api.py +228 -0
- autocoder/common/project_tracker/demo.py +272 -0
- autocoder/common/project_tracker/tracker.py +487 -0
- autocoder/common/project_tracker/types.py +53 -0
- autocoder/common/pruner/__init__.py +67 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
- autocoder/common/pruner/conversation_message_ids_api.py +386 -0
- autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
- autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
- autocoder/common/pruner/conversation_normalizer.py +347 -0
- autocoder/common/pruner/conversation_pruner.py +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
- autocoder/common/pruner/test_conversation_normalizer.py +502 -0
- autocoder/common/pruner/test_tool_content_detector.py +324 -0
- autocoder/common/pruner/tool_content_detector.py +227 -0
- autocoder/common/pruner/tools/__init__.py +18 -0
- autocoder/common/pruner/tools/query_message_ids.py +264 -0
- autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
- autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
- autocoder/common/pull_requests/__init__.py +9 -1
- autocoder/common/pull_requests/utils.py +122 -1
- autocoder/common/rag_manager/rag_manager.py +36 -40
- autocoder/common/rulefiles/__init__.py +53 -1
- autocoder/common/rulefiles/api.py +250 -0
- autocoder/common/rulefiles/core/__init__.py +14 -0
- autocoder/common/rulefiles/core/manager.py +241 -0
- autocoder/common/rulefiles/core/selector.py +805 -0
- autocoder/common/rulefiles/models/__init__.py +20 -0
- autocoder/common/rulefiles/models/index.py +16 -0
- autocoder/common/rulefiles/models/init_rule.py +18 -0
- autocoder/common/rulefiles/models/rule_file.py +18 -0
- autocoder/common/rulefiles/models/rule_relevance.py +14 -0
- autocoder/common/rulefiles/models/summary.py +16 -0
- autocoder/common/rulefiles/test_rulefiles.py +776 -0
- autocoder/common/rulefiles/utils/__init__.py +34 -0
- autocoder/common/rulefiles/utils/monitor.py +86 -0
- autocoder/common/rulefiles/utils/parser.py +230 -0
- autocoder/common/save_formatted_log.py +67 -10
- autocoder/common/search_replace.py +8 -1
- autocoder/common/search_replace_patch/__init__.py +24 -0
- autocoder/common/search_replace_patch/base.py +115 -0
- autocoder/common/search_replace_patch/manager.py +248 -0
- autocoder/common/search_replace_patch/patch_replacer.py +304 -0
- autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
- autocoder/common/search_replace_patch/string_replacer.py +181 -0
- autocoder/common/search_replace_patch/tests/__init__.py +3 -0
- autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
- autocoder/common/search_replace_patch/tests/test_base.py +188 -0
- autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
- autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
- autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
- autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
- autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
- autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
- autocoder/common/shell_commands/__init__.py +197 -0
- autocoder/common/shell_commands/background_process_notifier.py +346 -0
- autocoder/common/shell_commands/command_executor.py +1127 -0
- autocoder/common/shell_commands/error_recovery.py +541 -0
- autocoder/common/shell_commands/exceptions.py +120 -0
- autocoder/common/shell_commands/interactive_executor.py +476 -0
- autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
- autocoder/common/shell_commands/interactive_process.py +744 -0
- autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
- autocoder/common/shell_commands/monitoring.py +529 -0
- autocoder/common/shell_commands/process_cleanup.py +386 -0
- autocoder/common/shell_commands/process_manager.py +606 -0
- autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
- autocoder/common/shell_commands/tests/__init__.py +6 -0
- autocoder/common/shell_commands/tests/conftest.py +118 -0
- autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
- autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
- autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
- autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
- autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
- autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
- autocoder/common/shell_commands/tests/test_integration.py +664 -0
- autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
- autocoder/common/shell_commands/tests/test_performance.py +632 -0
- autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
- autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
- autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
- autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
- autocoder/common/shell_commands/timeout_config.py +315 -0
- autocoder/common/shell_commands/timeout_manager.py +352 -0
- autocoder/common/terminal_paste/__init__.py +14 -0
- autocoder/common/terminal_paste/demo.py +145 -0
- autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
- autocoder/common/terminal_paste/paste_handler.py +200 -0
- autocoder/common/terminal_paste/paste_manager.py +118 -0
- autocoder/common/terminal_paste/tests/__init__.py +1 -0
- autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
- autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
- autocoder/common/terminal_paste/utils.py +163 -0
- autocoder/common/test_autocoder_args.py +232 -0
- autocoder/common/test_env_manager.py +173 -0
- autocoder/common/test_env_manager_integration.py +159 -0
- autocoder/common/text_similarity/__init__.py +9 -0
- autocoder/common/text_similarity/demo.py +216 -0
- autocoder/common/text_similarity/examples.py +266 -0
- autocoder/common/text_similarity/test_text_similarity.py +306 -0
- autocoder/common/text_similarity/text_similarity.py +194 -0
- autocoder/common/text_similarity/utils.py +125 -0
- autocoder/common/todos/__init__.py +61 -0
- autocoder/common/todos/cache/__init__.py +16 -0
- autocoder/common/todos/cache/base_cache.py +89 -0
- autocoder/common/todos/cache/cache_manager.py +228 -0
- autocoder/common/todos/cache/memory_cache.py +225 -0
- autocoder/common/todos/config.py +155 -0
- autocoder/common/todos/exceptions.py +35 -0
- autocoder/common/todos/get_todo_manager.py +161 -0
- autocoder/common/todos/manager.py +537 -0
- autocoder/common/todos/models.py +239 -0
- autocoder/common/todos/storage/__init__.py +14 -0
- autocoder/common/todos/storage/base_storage.py +76 -0
- autocoder/common/todos/storage/file_storage.py +278 -0
- autocoder/common/tokens/counter.py +24 -2
- autocoder/common/tools_manager/__init__.py +17 -0
- autocoder/common/tools_manager/examples.py +162 -0
- autocoder/common/tools_manager/manager.py +385 -0
- autocoder/common/tools_manager/models.py +39 -0
- autocoder/common/tools_manager/test_tools_manager.py +303 -0
- autocoder/common/tools_manager/utils.py +191 -0
- autocoder/common/v2/agent/agentic_callbacks.py +270 -0
- autocoder/common/v2/agent/agentic_edit.py +2699 -1856
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
- autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
- autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
- autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
- autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
- autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
- autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +356 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
- autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
- autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
- autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
- autocoder/common/v2/agent/agentic_edit_types.py +343 -9
- autocoder/common/v2/agent/runner/__init__.py +3 -3
- autocoder/common/v2/agent/runner/base_runner.py +12 -26
- autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
- autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
- autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
- autocoder/common/v2/agent/runner/tool_display.py +557 -159
- autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
- autocoder/common/v2/agent/test_agentic_edit.py +194 -0
- autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
- autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
- autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
- autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
- autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
- autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
- autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
- autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
- autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
- autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
- autocoder/common/v2/code_auto_generate.py +136 -78
- autocoder/common/v2/code_auto_generate_diff.py +135 -79
- autocoder/common/v2/code_auto_generate_editblock.py +174 -99
- autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
- autocoder/common/v2/code_auto_merge.py +1 -1
- autocoder/common/v2/code_auto_merge_editblock.py +13 -1
- autocoder/common/v2/code_diff_manager.py +3 -3
- autocoder/common/v2/code_editblock_manager.py +4 -14
- autocoder/common/v2/code_manager.py +1 -1
- autocoder/common/v2/code_strict_diff_manager.py +2 -2
- autocoder/common/wrap_llm_hint/__init__.py +10 -0
- autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
- autocoder/common/wrap_llm_hint/utils.py +432 -0
- autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
- autocoder/completer/__init__.py +8 -0
- autocoder/completer/command_completer_v2.py +1094 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +400 -129
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- autocoder/{agent → index/filter}/agentic_filter.py +322 -333
- autocoder/index/filter/normal_filter.py +5 -11
- autocoder/index/filter/quick_filter.py +1 -1
- autocoder/index/index.py +36 -9
- autocoder/index/tests/__init__.py +1 -0
- autocoder/index/tests/run_tests.py +195 -0
- autocoder/index/tests/test_entry.py +303 -0
- autocoder/index/tests/test_index_manager.py +314 -0
- autocoder/index/tests/test_module_integration.py +300 -0
- autocoder/index/tests/test_symbols_utils.py +183 -0
- autocoder/inner/__init__.py +4 -0
- autocoder/inner/agentic.py +923 -0
- autocoder/inner/async_command_handler.py +992 -0
- autocoder/inner/conversation_command_handlers.py +623 -0
- autocoder/inner/merge_command_handler.py +213 -0
- autocoder/inner/queue_command_handler.py +684 -0
- autocoder/models.py +95 -266
- autocoder/plugins/git_helper_plugin.py +31 -29
- autocoder/plugins/token_helper_plugin.py +65 -46
- autocoder/pyproject/__init__.py +32 -29
- autocoder/rag/agentic_rag.py +215 -75
- autocoder/rag/cache/simple_cache.py +1 -2
- autocoder/rag/loaders/image_loader.py +1 -1
- autocoder/rag/long_context_rag.py +42 -26
- autocoder/rag/qa_conversation_strategy.py +1 -1
- autocoder/rag/terminal/__init__.py +17 -0
- autocoder/rag/terminal/args.py +581 -0
- autocoder/rag/terminal/bootstrap.py +61 -0
- autocoder/rag/terminal/command_handlers.py +653 -0
- autocoder/rag/terminal/formatters/__init__.py +20 -0
- autocoder/rag/terminal/formatters/base.py +70 -0
- autocoder/rag/terminal/formatters/json_format.py +66 -0
- autocoder/rag/terminal/formatters/stream_json.py +95 -0
- autocoder/rag/terminal/formatters/text.py +28 -0
- autocoder/rag/terminal/init.py +120 -0
- autocoder/rag/terminal/utils.py +106 -0
- autocoder/rag/test_agentic_rag.py +389 -0
- autocoder/rag/test_doc_filter.py +3 -3
- autocoder/rag/test_long_context_rag.py +1 -1
- autocoder/rag/test_token_limiter.py +517 -10
- autocoder/rag/token_counter.py +3 -0
- autocoder/rag/token_limiter.py +19 -15
- autocoder/rag/tools/__init__.py +26 -2
- autocoder/rag/tools/bochaai_example.py +343 -0
- autocoder/rag/tools/bochaai_sdk.py +541 -0
- autocoder/rag/tools/metaso_example.py +268 -0
- autocoder/rag/tools/metaso_sdk.py +417 -0
- autocoder/rag/tools/recall_tool.py +28 -7
- autocoder/rag/tools/run_integration_tests.py +204 -0
- autocoder/rag/tools/test_all_providers.py +318 -0
- autocoder/rag/tools/test_bochaai_integration.py +482 -0
- autocoder/rag/tools/test_final_integration.py +215 -0
- autocoder/rag/tools/test_metaso_integration.py +424 -0
- autocoder/rag/tools/test_metaso_real.py +171 -0
- autocoder/rag/tools/test_web_crawl_tool.py +639 -0
- autocoder/rag/tools/test_web_search_tool.py +509 -0
- autocoder/rag/tools/todo_read_tool.py +202 -0
- autocoder/rag/tools/todo_write_tool.py +412 -0
- autocoder/rag/tools/web_crawl_tool.py +634 -0
- autocoder/rag/tools/web_search_tool.py +558 -0
- autocoder/rag/tools/web_tools_example.py +119 -0
- autocoder/rag/types.py +16 -0
- autocoder/rag/variable_holder.py +4 -2
- autocoder/rags.py +86 -79
- autocoder/regexproject/__init__.py +23 -21
- autocoder/sdk/__init__.py +46 -190
- autocoder/sdk/api.py +370 -0
- autocoder/sdk/async_runner/__init__.py +26 -0
- autocoder/sdk/async_runner/async_executor.py +650 -0
- autocoder/sdk/async_runner/async_handler.py +356 -0
- autocoder/sdk/async_runner/markdown_processor.py +595 -0
- autocoder/sdk/async_runner/task_metadata.py +284 -0
- autocoder/sdk/async_runner/worktree_manager.py +438 -0
- autocoder/sdk/cli/__init__.py +2 -5
- autocoder/sdk/cli/formatters.py +28 -204
- autocoder/sdk/cli/handlers.py +77 -44
- autocoder/sdk/cli/main.py +154 -171
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -109
- autocoder/sdk/core/bridge.py +297 -115
- autocoder/sdk/exceptions.py +18 -12
- autocoder/sdk/formatters/__init__.py +19 -0
- autocoder/sdk/formatters/input.py +64 -0
- autocoder/sdk/formatters/output.py +247 -0
- autocoder/sdk/formatters/stream.py +54 -0
- autocoder/sdk/models/__init__.py +6 -5
- autocoder/sdk/models/options.py +55 -18
- autocoder/sdk/utils/formatters.py +27 -195
- autocoder/suffixproject/__init__.py +28 -25
- autocoder/terminal/__init__.py +14 -0
- autocoder/terminal/app.py +454 -0
- autocoder/terminal/args.py +32 -0
- autocoder/terminal/bootstrap.py +178 -0
- autocoder/terminal/command_processor.py +521 -0
- autocoder/terminal/command_registry.py +57 -0
- autocoder/terminal/help.py +97 -0
- autocoder/terminal/tasks/__init__.py +5 -0
- autocoder/terminal/tasks/background.py +77 -0
- autocoder/terminal/tasks/task_event.py +70 -0
- autocoder/terminal/ui/__init__.py +13 -0
- autocoder/terminal/ui/completer.py +268 -0
- autocoder/terminal/ui/keybindings.py +75 -0
- autocoder/terminal/ui/session.py +41 -0
- autocoder/terminal/ui/toolbar.py +64 -0
- autocoder/terminal/utils/__init__.py +13 -0
- autocoder/terminal/utils/errors.py +18 -0
- autocoder/terminal/utils/paths.py +19 -0
- autocoder/terminal/utils/shell.py +43 -0
- autocoder/terminal_v3/__init__.py +10 -0
- autocoder/terminal_v3/app.py +201 -0
- autocoder/terminal_v3/handlers/__init__.py +5 -0
- autocoder/terminal_v3/handlers/command_handler.py +131 -0
- autocoder/terminal_v3/models/__init__.py +6 -0
- autocoder/terminal_v3/models/conversation_buffer.py +214 -0
- autocoder/terminal_v3/models/message.py +50 -0
- autocoder/terminal_v3/models/tool_display.py +247 -0
- autocoder/terminal_v3/ui/__init__.py +7 -0
- autocoder/terminal_v3/ui/keybindings.py +56 -0
- autocoder/terminal_v3/ui/layout.py +141 -0
- autocoder/terminal_v3/ui/styles.py +43 -0
- autocoder/tsproject/__init__.py +23 -23
- autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
- autocoder/utils/llms.py +88 -80
- autocoder/utils/math_utils.py +101 -0
- autocoder/utils/model_provider_selector.py +16 -4
- autocoder/utils/operate_config_api.py +33 -5
- autocoder/utils/thread_utils.py +2 -2
- autocoder/version.py +4 -2
- autocoder/workflow_agents/__init__.py +84 -0
- autocoder/workflow_agents/agent.py +143 -0
- autocoder/workflow_agents/exceptions.py +573 -0
- autocoder/workflow_agents/executor.py +665 -0
- autocoder/workflow_agents/loader.py +749 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +173 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-1.0.0.dist-info/METADATA +0 -396
- auto_coder-1.0.0.dist-info/RECORD +0 -442
- auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
- autocoder/auto_coder_server.py +0 -672
- autocoder/benchmark.py +0 -138
- autocoder/common/ac_style_command_parser/example.py +0 -7
- autocoder/common/cleaner.py +0 -31
- autocoder/common/command_completer_v2.py +0 -615
- autocoder/common/context_pruner.py +0 -477
- autocoder/common/conversation_pruner.py +0 -132
- autocoder/common/directory_cache/__init__.py +0 -1
- autocoder/common/directory_cache/cache.py +0 -192
- autocoder/common/directory_cache/test_cache.py +0 -190
- autocoder/common/file_checkpoint/examples.py +0 -217
- autocoder/common/llm_friendly_package_example.py +0 -138
- autocoder/common/llm_friendly_package_test.py +0 -63
- autocoder/common/pull_requests/test_module.py +0 -1
- autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
- autocoder/common/text.py +0 -30
- autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
- autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
- autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
- autocoder/common/v2/agent/agentic_tool_display.py +0 -183
- autocoder/plugins/dynamic_completion_example.py +0 -148
- autocoder/plugins/sample_plugin.py +0 -160
- autocoder/sdk/cli/__main__.py +0 -26
- autocoder/sdk/cli/completion_wrapper.py +0 -38
- autocoder/sdk/cli/install_completion.py +0 -301
- autocoder/sdk/models/messages.py +0 -209
- autocoder/sdk/session/__init__.py +0 -32
- autocoder/sdk/session/session.py +0 -106
- autocoder/sdk/session/session_manager.py +0 -56
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Monitoring module for shell command execution.
|
|
3
|
+
|
|
4
|
+
This module provides comprehensive monitoring functionality including:
|
|
5
|
+
- Command execution logging
|
|
6
|
+
- Performance monitoring
|
|
7
|
+
- Metrics collection
|
|
8
|
+
- Error tracking
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
import threading
|
|
13
|
+
from typing import Dict, Optional, Any, List, Tuple
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from datetime import datetime
|
|
16
|
+
from loguru import logger
|
|
17
|
+
|
|
18
|
+
from .exceptions import CommandExecutionError, CommandTimeoutError
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class CommandExecutionMetrics:
|
|
23
|
+
"""
|
|
24
|
+
Metrics for command execution.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
command: The executed command
|
|
28
|
+
start_time: Execution start time
|
|
29
|
+
end_time: Execution end time
|
|
30
|
+
duration: Total execution duration in seconds
|
|
31
|
+
exit_code: Process exit code
|
|
32
|
+
timeout: Configured timeout (if any)
|
|
33
|
+
timed_out: Whether the command timed out
|
|
34
|
+
pid: Process ID
|
|
35
|
+
output_length: Length of command output
|
|
36
|
+
error_count: Number of errors encountered
|
|
37
|
+
recovery_attempts: Number of recovery attempts made
|
|
38
|
+
"""
|
|
39
|
+
command: str
|
|
40
|
+
start_time: datetime
|
|
41
|
+
end_time: Optional[datetime] = None
|
|
42
|
+
duration: Optional[float] = None
|
|
43
|
+
exit_code: Optional[int] = None
|
|
44
|
+
timeout: Optional[float] = None
|
|
45
|
+
timed_out: bool = False
|
|
46
|
+
pid: Optional[int] = None
|
|
47
|
+
output_length: int = 0
|
|
48
|
+
error_count: int = 0
|
|
49
|
+
recovery_attempts: int = 0
|
|
50
|
+
|
|
51
|
+
def finalize(self, end_time: Optional[datetime] = None) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Finalize metrics calculation.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
end_time: Optional end time, defaults to current time
|
|
57
|
+
"""
|
|
58
|
+
if end_time is None:
|
|
59
|
+
end_time = datetime.now()
|
|
60
|
+
|
|
61
|
+
self.end_time = end_time
|
|
62
|
+
self.duration = (end_time - self.start_time).total_seconds()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class CommandExecutionLogger:
|
|
66
|
+
"""
|
|
67
|
+
Logger for command execution events.
|
|
68
|
+
|
|
69
|
+
This class provides structured logging for command execution with
|
|
70
|
+
configurable verbosity levels and output formatting.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
def __init__(self, verbose: bool = False):
|
|
74
|
+
"""
|
|
75
|
+
Initialize command execution logger.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
verbose: Whether to enable verbose logging
|
|
79
|
+
"""
|
|
80
|
+
self.verbose = verbose
|
|
81
|
+
self.execution_history: List[CommandExecutionMetrics] = []
|
|
82
|
+
self._lock = threading.Lock()
|
|
83
|
+
|
|
84
|
+
logger.debug(f"CommandExecutionLogger initialized (verbose={verbose})")
|
|
85
|
+
|
|
86
|
+
def log_command_start(
|
|
87
|
+
self,
|
|
88
|
+
command: str,
|
|
89
|
+
timeout: Optional[float] = None,
|
|
90
|
+
pid: Optional[int] = None,
|
|
91
|
+
cwd: Optional[str] = None
|
|
92
|
+
) -> CommandExecutionMetrics:
|
|
93
|
+
"""
|
|
94
|
+
Log command execution start.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
command: The command being executed
|
|
98
|
+
timeout: Timeout configuration
|
|
99
|
+
pid: Process ID
|
|
100
|
+
cwd: Working directory
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
CommandExecutionMetrics instance for this execution
|
|
104
|
+
"""
|
|
105
|
+
metrics = CommandExecutionMetrics(
|
|
106
|
+
command=command,
|
|
107
|
+
start_time=datetime.now(),
|
|
108
|
+
timeout=timeout,
|
|
109
|
+
pid=pid
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
with self._lock:
|
|
113
|
+
self.execution_history.append(metrics)
|
|
114
|
+
|
|
115
|
+
if self.verbose:
|
|
116
|
+
logger.info(f"Starting command execution: {command}")
|
|
117
|
+
if timeout:
|
|
118
|
+
logger.info(f" Timeout: {timeout}s")
|
|
119
|
+
if pid:
|
|
120
|
+
logger.info(f" PID: {pid}")
|
|
121
|
+
if cwd:
|
|
122
|
+
logger.info(f" Working directory: {cwd}")
|
|
123
|
+
else:
|
|
124
|
+
logger.debug(f"Starting command: {command} (PID: {pid})")
|
|
125
|
+
|
|
126
|
+
return metrics
|
|
127
|
+
|
|
128
|
+
def log_command_complete(
|
|
129
|
+
self,
|
|
130
|
+
metrics: CommandExecutionMetrics,
|
|
131
|
+
exit_code: int,
|
|
132
|
+
output: str = "",
|
|
133
|
+
error: Optional[Exception] = None
|
|
134
|
+
) -> None:
|
|
135
|
+
"""
|
|
136
|
+
Log command execution completion.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
metrics: Execution metrics
|
|
140
|
+
exit_code: Process exit code
|
|
141
|
+
output: Command output
|
|
142
|
+
error: Any error that occurred
|
|
143
|
+
"""
|
|
144
|
+
metrics.exit_code = exit_code
|
|
145
|
+
metrics.output_length = len(output)
|
|
146
|
+
if error:
|
|
147
|
+
metrics.error_count += 1
|
|
148
|
+
# Check if it's a timeout error
|
|
149
|
+
if isinstance(error, CommandTimeoutError):
|
|
150
|
+
metrics.timed_out = True
|
|
151
|
+
|
|
152
|
+
metrics.finalize()
|
|
153
|
+
|
|
154
|
+
if self.verbose:
|
|
155
|
+
logger.info(f"Command completed: {metrics.command}")
|
|
156
|
+
logger.info(f" Exit code: {exit_code}")
|
|
157
|
+
logger.info(f" Duration: {metrics.duration:.2f}s")
|
|
158
|
+
logger.info(f" Output length: {metrics.output_length} characters")
|
|
159
|
+
if error:
|
|
160
|
+
logger.warning(f" Error: {error}")
|
|
161
|
+
else:
|
|
162
|
+
status = "SUCCESS" if exit_code == 0 else "FAILED"
|
|
163
|
+
logger.debug(f"Command {status}: {metrics.command} ({metrics.duration:.2f}s)")
|
|
164
|
+
|
|
165
|
+
# Log performance warnings
|
|
166
|
+
if metrics.duration and metrics.duration > 30.0:
|
|
167
|
+
logger.warning(f"Long-running command: {metrics.command} took {metrics.duration:.2f}s")
|
|
168
|
+
|
|
169
|
+
if metrics.timeout and metrics.duration and metrics.duration > metrics.timeout * 0.8:
|
|
170
|
+
logger.warning(f"Command approaching timeout: {metrics.command} ({metrics.duration:.2f}s/{metrics.timeout}s)")
|
|
171
|
+
|
|
172
|
+
def log_command_timeout(
|
|
173
|
+
self,
|
|
174
|
+
metrics: CommandExecutionMetrics,
|
|
175
|
+
timeout: float,
|
|
176
|
+
pid: int
|
|
177
|
+
) -> None:
|
|
178
|
+
"""
|
|
179
|
+
Log command timeout event.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
metrics: Execution metrics
|
|
183
|
+
timeout: Timeout value that was exceeded
|
|
184
|
+
pid: Process ID that timed out
|
|
185
|
+
"""
|
|
186
|
+
metrics.timed_out = True
|
|
187
|
+
metrics.finalize()
|
|
188
|
+
|
|
189
|
+
logger.error(f"Command timed out: {metrics.command}")
|
|
190
|
+
logger.error(f" Timeout: {timeout}s")
|
|
191
|
+
logger.error(f" PID: {pid}")
|
|
192
|
+
logger.error(f" Actual duration: {metrics.duration:.2f}s")
|
|
193
|
+
|
|
194
|
+
def log_process_cleanup(
|
|
195
|
+
self,
|
|
196
|
+
pid: int,
|
|
197
|
+
success: bool,
|
|
198
|
+
duration: float,
|
|
199
|
+
method: str = "unknown"
|
|
200
|
+
) -> None:
|
|
201
|
+
"""
|
|
202
|
+
Log process cleanup event.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
pid: Process ID that was cleaned up
|
|
206
|
+
success: Whether cleanup was successful
|
|
207
|
+
duration: Cleanup duration in seconds
|
|
208
|
+
method: Cleanup method used
|
|
209
|
+
"""
|
|
210
|
+
if success:
|
|
211
|
+
logger.debug(f"Process cleanup successful: PID {pid} ({method}, {duration:.2f}s)")
|
|
212
|
+
else:
|
|
213
|
+
logger.warning(f"Process cleanup failed: PID {pid} ({method}, {duration:.2f}s)")
|
|
214
|
+
|
|
215
|
+
def log_error_recovery(
|
|
216
|
+
self,
|
|
217
|
+
error: Exception,
|
|
218
|
+
recovery_attempt: int,
|
|
219
|
+
success: bool
|
|
220
|
+
) -> None:
|
|
221
|
+
"""
|
|
222
|
+
Log error recovery attempt.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
error: The error being recovered from
|
|
226
|
+
recovery_attempt: Recovery attempt number
|
|
227
|
+
success: Whether recovery was successful
|
|
228
|
+
"""
|
|
229
|
+
error_type = type(error).__name__
|
|
230
|
+
|
|
231
|
+
if success:
|
|
232
|
+
logger.info(f"Error recovery successful: {error_type} (attempt {recovery_attempt})")
|
|
233
|
+
else:
|
|
234
|
+
logger.warning(f"Error recovery failed: {error_type} (attempt {recovery_attempt})")
|
|
235
|
+
|
|
236
|
+
def get_execution_history(self) -> List[CommandExecutionMetrics]:
|
|
237
|
+
"""
|
|
238
|
+
Get command execution history.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
List of execution metrics
|
|
242
|
+
"""
|
|
243
|
+
with self._lock:
|
|
244
|
+
return self.execution_history.copy()
|
|
245
|
+
|
|
246
|
+
def get_summary_stats(self) -> Dict[str, Any]:
|
|
247
|
+
"""
|
|
248
|
+
Get summary statistics for command executions.
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
Dictionary with summary statistics
|
|
252
|
+
"""
|
|
253
|
+
with self._lock:
|
|
254
|
+
history = self.execution_history.copy()
|
|
255
|
+
|
|
256
|
+
if not history:
|
|
257
|
+
return {}
|
|
258
|
+
|
|
259
|
+
completed = [m for m in history if m.duration is not None]
|
|
260
|
+
successful = [m for m in completed if m.exit_code == 0]
|
|
261
|
+
failed = [m for m in completed if m.exit_code != 0 and not m.timed_out]
|
|
262
|
+
timed_out = [m for m in history if m.timed_out]
|
|
263
|
+
|
|
264
|
+
# Get durations that are not None for calculations
|
|
265
|
+
durations = [m.duration for m in completed if m.duration is not None]
|
|
266
|
+
total_duration = sum(durations)
|
|
267
|
+
avg_duration = total_duration / len(durations) if durations else 0
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
'total_commands': len(history),
|
|
271
|
+
'completed_commands': len(completed),
|
|
272
|
+
'successful_commands': len(successful),
|
|
273
|
+
'failed_commands': len(failed),
|
|
274
|
+
'timed_out_commands': len(timed_out),
|
|
275
|
+
'success_rate': len(successful) / len(completed) if completed else 0,
|
|
276
|
+
'timeout_rate': len(timed_out) / len(history) if history else 0,
|
|
277
|
+
'total_duration': total_duration,
|
|
278
|
+
'average_duration': avg_duration,
|
|
279
|
+
'max_duration': max(durations) if durations else 0,
|
|
280
|
+
'min_duration': min(durations) if durations else 0,
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class PerformanceMonitor:
|
|
285
|
+
"""
|
|
286
|
+
Performance monitor for command execution.
|
|
287
|
+
|
|
288
|
+
This class tracks performance metrics and provides analysis
|
|
289
|
+
of command execution patterns and performance trends.
|
|
290
|
+
"""
|
|
291
|
+
|
|
292
|
+
def __init__(self, max_history_size: int = 1000):
|
|
293
|
+
"""
|
|
294
|
+
Initialize performance monitor.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
max_history_size: Maximum number of metrics to keep in history
|
|
298
|
+
"""
|
|
299
|
+
self.max_history_size = max_history_size
|
|
300
|
+
self.metrics_history: List[CommandExecutionMetrics] = []
|
|
301
|
+
self.performance_alerts: List[Dict[str, Any]] = []
|
|
302
|
+
self._lock = threading.Lock()
|
|
303
|
+
|
|
304
|
+
logger.debug(f"PerformanceMonitor initialized (max_history={max_history_size})")
|
|
305
|
+
|
|
306
|
+
def record_execution(self, metrics: CommandExecutionMetrics) -> None:
|
|
307
|
+
"""
|
|
308
|
+
Record command execution metrics.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
metrics: Execution metrics to record
|
|
312
|
+
"""
|
|
313
|
+
with self._lock:
|
|
314
|
+
self.metrics_history.append(metrics)
|
|
315
|
+
|
|
316
|
+
# Trim history if too large
|
|
317
|
+
if len(self.metrics_history) > self.max_history_size:
|
|
318
|
+
self.metrics_history = self.metrics_history[-self.max_history_size:]
|
|
319
|
+
|
|
320
|
+
# Check for performance issues
|
|
321
|
+
self._check_performance_alerts(metrics)
|
|
322
|
+
|
|
323
|
+
def _check_performance_alerts(self, metrics: CommandExecutionMetrics) -> None:
|
|
324
|
+
"""
|
|
325
|
+
Check for performance issues and generate alerts.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
metrics: Execution metrics to check
|
|
329
|
+
"""
|
|
330
|
+
alerts = []
|
|
331
|
+
|
|
332
|
+
# Check for long execution times
|
|
333
|
+
if metrics.duration and metrics.duration > 60.0:
|
|
334
|
+
alerts.append({
|
|
335
|
+
'type': 'long_execution',
|
|
336
|
+
'message': f"Command took {metrics.duration:.2f}s to execute",
|
|
337
|
+
'command': metrics.command,
|
|
338
|
+
'duration': metrics.duration
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
# Check for timeout
|
|
342
|
+
if metrics.timed_out:
|
|
343
|
+
alerts.append({
|
|
344
|
+
'type': 'timeout',
|
|
345
|
+
'message': f"Command timed out after {metrics.timeout}s",
|
|
346
|
+
'command': metrics.command,
|
|
347
|
+
'timeout': metrics.timeout
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
# Check for high error rate
|
|
351
|
+
recent_metrics = self.get_recent_metrics(10)
|
|
352
|
+
if len(recent_metrics) >= 5:
|
|
353
|
+
error_rate = sum(1 for m in recent_metrics if m.error_count > 0) / len(recent_metrics)
|
|
354
|
+
if error_rate > 0.5:
|
|
355
|
+
alerts.append({
|
|
356
|
+
'type': 'high_error_rate',
|
|
357
|
+
'message': f"High error rate detected: {error_rate:.1%}",
|
|
358
|
+
'error_rate': error_rate
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
# Store alerts
|
|
362
|
+
if alerts:
|
|
363
|
+
with self._lock:
|
|
364
|
+
self.performance_alerts.extend(alerts)
|
|
365
|
+
# Keep only recent alerts
|
|
366
|
+
self.performance_alerts = self.performance_alerts[-100:]
|
|
367
|
+
|
|
368
|
+
for alert in alerts:
|
|
369
|
+
logger.warning(f"Performance alert: {alert['message']}")
|
|
370
|
+
|
|
371
|
+
def get_recent_metrics(self, count: int = 10) -> List[CommandExecutionMetrics]:
|
|
372
|
+
"""
|
|
373
|
+
Get recent command execution metrics.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
count: Number of recent metrics to return
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
List of recent metrics
|
|
380
|
+
"""
|
|
381
|
+
with self._lock:
|
|
382
|
+
return self.metrics_history[-count:]
|
|
383
|
+
|
|
384
|
+
def get_command_stats(self, command_pattern: str) -> Dict[str, Any]:
|
|
385
|
+
"""
|
|
386
|
+
Get statistics for commands matching a pattern.
|
|
387
|
+
|
|
388
|
+
Args:
|
|
389
|
+
command_pattern: Pattern to match commands against
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
Dictionary with command statistics
|
|
393
|
+
"""
|
|
394
|
+
with self._lock:
|
|
395
|
+
matching_metrics = [
|
|
396
|
+
m for m in self.metrics_history
|
|
397
|
+
if command_pattern in m.command
|
|
398
|
+
]
|
|
399
|
+
|
|
400
|
+
if not matching_metrics:
|
|
401
|
+
return {}
|
|
402
|
+
|
|
403
|
+
completed = [m for m in matching_metrics if m.duration is not None]
|
|
404
|
+
successful = [m for m in completed if m.exit_code == 0]
|
|
405
|
+
|
|
406
|
+
durations = [m.duration for m in completed if m.duration is not None]
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
'total_executions': len(matching_metrics),
|
|
410
|
+
'completed_executions': len(completed),
|
|
411
|
+
'successful_executions': len(successful),
|
|
412
|
+
'success_rate': len(successful) / len(completed) if completed else 0,
|
|
413
|
+
'average_duration': sum(durations) / len(durations) if durations else 0,
|
|
414
|
+
'max_duration': max(durations) if durations else 0,
|
|
415
|
+
'min_duration': min(durations) if durations else 0,
|
|
416
|
+
'total_duration': sum(durations),
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
def get_performance_summary(self) -> Dict[str, Any]:
|
|
420
|
+
"""
|
|
421
|
+
Get overall performance summary.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
Dictionary with performance summary
|
|
425
|
+
"""
|
|
426
|
+
with self._lock:
|
|
427
|
+
total_metrics = len(self.metrics_history)
|
|
428
|
+
alerts = len(self.performance_alerts)
|
|
429
|
+
|
|
430
|
+
if not self.metrics_history:
|
|
431
|
+
return {'total_commands': 0, 'alerts': 0}
|
|
432
|
+
|
|
433
|
+
recent_metrics = self.metrics_history[-50:] # Last 50 commands
|
|
434
|
+
|
|
435
|
+
completed = [m for m in recent_metrics if m.duration is not None]
|
|
436
|
+
successful = [m for m in completed if m.exit_code == 0]
|
|
437
|
+
timed_out = [m for m in recent_metrics if m.timed_out]
|
|
438
|
+
|
|
439
|
+
durations = [m.duration for m in completed if m.duration is not None]
|
|
440
|
+
avg_duration = sum(durations) / len(durations) if durations else 0
|
|
441
|
+
|
|
442
|
+
return {
|
|
443
|
+
'total_commands': total_metrics,
|
|
444
|
+
'recent_commands': len(recent_metrics),
|
|
445
|
+
'success_rate': len(successful) / len(completed) if completed else 0,
|
|
446
|
+
'timeout_rate': len(timed_out) / len(recent_metrics) if recent_metrics else 0,
|
|
447
|
+
'average_duration': avg_duration,
|
|
448
|
+
'performance_alerts': alerts,
|
|
449
|
+
'longest_command': max(durations) if durations else 0,
|
|
450
|
+
'shortest_command': min(durations) if durations else 0,
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
def get_alerts(self, count: int = 10) -> List[Dict[str, Any]]:
|
|
454
|
+
"""
|
|
455
|
+
Get recent performance alerts.
|
|
456
|
+
|
|
457
|
+
Args:
|
|
458
|
+
count: Number of alerts to return
|
|
459
|
+
|
|
460
|
+
Returns:
|
|
461
|
+
List of recent alerts
|
|
462
|
+
"""
|
|
463
|
+
with self._lock:
|
|
464
|
+
return self.performance_alerts[-count:]
|
|
465
|
+
|
|
466
|
+
def clear_alerts(self) -> None:
|
|
467
|
+
"""Clear all performance alerts."""
|
|
468
|
+
with self._lock:
|
|
469
|
+
self.performance_alerts.clear()
|
|
470
|
+
|
|
471
|
+
logger.debug("Performance alerts cleared")
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
# Global instances
|
|
475
|
+
_global_logger: Optional[CommandExecutionLogger] = None
|
|
476
|
+
_global_monitor: Optional[PerformanceMonitor] = None
|
|
477
|
+
_global_lock = threading.Lock()
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
def get_logger(verbose: bool = False) -> CommandExecutionLogger:
|
|
481
|
+
"""
|
|
482
|
+
Get global logger instance.
|
|
483
|
+
|
|
484
|
+
Args:
|
|
485
|
+
verbose: Whether to enable verbose logging
|
|
486
|
+
|
|
487
|
+
Returns:
|
|
488
|
+
Global logger instance
|
|
489
|
+
"""
|
|
490
|
+
global _global_logger
|
|
491
|
+
|
|
492
|
+
if _global_logger is None:
|
|
493
|
+
_global_logger = CommandExecutionLogger(verbose=verbose)
|
|
494
|
+
else:
|
|
495
|
+
# Update verbose flag if different
|
|
496
|
+
if _global_logger.verbose != verbose:
|
|
497
|
+
_global_logger.verbose = verbose
|
|
498
|
+
|
|
499
|
+
return _global_logger
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def get_global_monitor() -> PerformanceMonitor:
|
|
503
|
+
"""
|
|
504
|
+
Get or create global performance monitor.
|
|
505
|
+
|
|
506
|
+
Returns:
|
|
507
|
+
Global PerformanceMonitor instance
|
|
508
|
+
"""
|
|
509
|
+
global _global_monitor
|
|
510
|
+
|
|
511
|
+
if _global_monitor is None:
|
|
512
|
+
with _global_lock:
|
|
513
|
+
if _global_monitor is None:
|
|
514
|
+
_global_monitor = PerformanceMonitor()
|
|
515
|
+
|
|
516
|
+
return _global_monitor
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def reset_global_instances() -> None:
|
|
520
|
+
"""
|
|
521
|
+
Reset global logger and monitor instances.
|
|
522
|
+
|
|
523
|
+
This is mainly useful for testing.
|
|
524
|
+
"""
|
|
525
|
+
global _global_logger, _global_monitor
|
|
526
|
+
|
|
527
|
+
with _global_lock:
|
|
528
|
+
_global_logger = None
|
|
529
|
+
_global_monitor = None
|