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,386 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Process cleanup module for shell command execution.
|
|
3
|
+
|
|
4
|
+
This module provides comprehensive process cleanup functionality including:
|
|
5
|
+
- Cross-platform process tree cleanup
|
|
6
|
+
- Graceful and forced termination
|
|
7
|
+
- Zombie process prevention
|
|
8
|
+
- Process group management
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import signal
|
|
13
|
+
import platform
|
|
14
|
+
import time
|
|
15
|
+
from typing import List, Optional
|
|
16
|
+
from loguru import logger
|
|
17
|
+
|
|
18
|
+
from .exceptions import ProcessCleanupError, ProcessNotFoundError
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
import psutil
|
|
22
|
+
PSUTIL_AVAILABLE = True
|
|
23
|
+
except ImportError:
|
|
24
|
+
logger.warning("psutil not available, process cleanup will be limited")
|
|
25
|
+
PSUTIL_AVAILABLE = False
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def cleanup_process_tree(pid: int, timeout: float = 10.0, force_timeout: float = 5.0) -> bool:
|
|
29
|
+
"""
|
|
30
|
+
Clean up a process and all its children.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
pid: Process ID to clean up
|
|
34
|
+
timeout: Timeout for graceful termination (seconds)
|
|
35
|
+
force_timeout: Timeout for forced termination (seconds)
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
True if cleanup succeeded, False otherwise
|
|
39
|
+
"""
|
|
40
|
+
# Handle invalid PIDs gracefully
|
|
41
|
+
if pid <= 0:
|
|
42
|
+
logger.debug(f"Invalid PID {pid}, cleanup considered successful")
|
|
43
|
+
return True
|
|
44
|
+
|
|
45
|
+
if platform.system() == "Windows":
|
|
46
|
+
return _cleanup_process_tree_windows(pid, timeout, force_timeout)
|
|
47
|
+
else:
|
|
48
|
+
return _cleanup_process_tree_unix(pid, timeout, force_timeout)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _cleanup_process_tree_unix(pid: int, timeout: float, force_timeout: float) -> bool:
|
|
52
|
+
"""Clean up process tree on Unix systems."""
|
|
53
|
+
try:
|
|
54
|
+
# Check if process exists first
|
|
55
|
+
if not _process_exists(pid):
|
|
56
|
+
logger.debug(f"Process {pid} does not exist, cleanup considered successful")
|
|
57
|
+
return True
|
|
58
|
+
|
|
59
|
+
# Get process group ID
|
|
60
|
+
try:
|
|
61
|
+
pgid = os.getpgid(pid)
|
|
62
|
+
except OSError as e:
|
|
63
|
+
logger.debug(f"Cannot get process group for PID {pid}: {e}")
|
|
64
|
+
pgid = pid # Fallback to using the PID itself
|
|
65
|
+
|
|
66
|
+
# Get all child processes
|
|
67
|
+
children = get_process_children(pid)
|
|
68
|
+
logger.debug(f"Found {len(children)} child processes for PID {pid}")
|
|
69
|
+
|
|
70
|
+
# Try graceful termination first
|
|
71
|
+
if _terminate_gracefully_unix(pid, pgid, children, timeout):
|
|
72
|
+
logger.debug(f"Graceful termination successful for PID {pid}")
|
|
73
|
+
return True
|
|
74
|
+
|
|
75
|
+
logger.debug(f"Graceful termination failed, forcing termination for PID {pid}")
|
|
76
|
+
|
|
77
|
+
# Force termination if graceful failed
|
|
78
|
+
if _force_terminate_unix(pid, pgid, children, force_timeout):
|
|
79
|
+
logger.debug(f"Force termination successful for PID {pid}")
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
logger.warning(f"Force termination failed for PID {pid}")
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
except Exception as e:
|
|
86
|
+
logger.error(f"Error during process cleanup for PID {pid}: {e}")
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _terminate_gracefully_unix(pid: int, pgid: int, children: List, timeout: float) -> bool:
|
|
91
|
+
"""
|
|
92
|
+
Attempt graceful termination on Unix systems.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
pid: Process ID
|
|
96
|
+
pgid: Process group ID
|
|
97
|
+
children: List of child processes (if psutil available)
|
|
98
|
+
timeout: Timeout for graceful termination
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
True if successful
|
|
102
|
+
"""
|
|
103
|
+
# Check if process already gone
|
|
104
|
+
if not _process_exists(pid):
|
|
105
|
+
logger.debug(f"Process {pid} already terminated")
|
|
106
|
+
return True
|
|
107
|
+
|
|
108
|
+
# Send SIGTERM to process group
|
|
109
|
+
try:
|
|
110
|
+
os.killpg(pgid, signal.SIGTERM)
|
|
111
|
+
logger.debug(f"Sent SIGTERM to process group {pgid}")
|
|
112
|
+
except OSError as e:
|
|
113
|
+
logger.debug(f"Cannot send SIGTERM to process group {pgid}: {e}")
|
|
114
|
+
# Try sending to individual process
|
|
115
|
+
try:
|
|
116
|
+
os.kill(pid, signal.SIGTERM)
|
|
117
|
+
logger.debug(f"Sent SIGTERM to process {pid}")
|
|
118
|
+
except OSError as e2:
|
|
119
|
+
logger.debug(f"Cannot send SIGTERM to process {pid}: {e2}")
|
|
120
|
+
# If we can't send the signal, check if process is already gone
|
|
121
|
+
if not _process_exists(pid):
|
|
122
|
+
return True
|
|
123
|
+
|
|
124
|
+
# Wait for process termination
|
|
125
|
+
start_time = time.time()
|
|
126
|
+
while time.time() - start_time < timeout:
|
|
127
|
+
if not _process_exists(pid):
|
|
128
|
+
return True
|
|
129
|
+
|
|
130
|
+
# Check if using psutil, wait for children too
|
|
131
|
+
if PSUTIL_AVAILABLE and children:
|
|
132
|
+
all_gone = True
|
|
133
|
+
for child in children:
|
|
134
|
+
try:
|
|
135
|
+
if child.is_running():
|
|
136
|
+
all_gone = False
|
|
137
|
+
break
|
|
138
|
+
except psutil.NoSuchProcess:
|
|
139
|
+
pass
|
|
140
|
+
if all_gone:
|
|
141
|
+
return True
|
|
142
|
+
|
|
143
|
+
time.sleep(0.1)
|
|
144
|
+
|
|
145
|
+
return False
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _force_terminate_unix(pid: int, pgid: int, children: List, timeout: float) -> bool:
|
|
149
|
+
"""
|
|
150
|
+
Force termination on Unix systems.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
pid: Process ID
|
|
154
|
+
pgid: Process group ID
|
|
155
|
+
children: List of child processes
|
|
156
|
+
timeout: Timeout for forced termination
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
True if successful
|
|
160
|
+
"""
|
|
161
|
+
# Check if process already gone
|
|
162
|
+
if not _process_exists(pid):
|
|
163
|
+
logger.debug(f"Process {pid} already terminated")
|
|
164
|
+
return True
|
|
165
|
+
|
|
166
|
+
# Send SIGKILL to process group
|
|
167
|
+
try:
|
|
168
|
+
os.killpg(pgid, signal.SIGKILL)
|
|
169
|
+
logger.debug(f"Sent SIGKILL to process group {pgid}")
|
|
170
|
+
except OSError as e:
|
|
171
|
+
logger.debug(f"Cannot send SIGKILL to process group {pgid}: {e}")
|
|
172
|
+
# Try sending to individual process
|
|
173
|
+
try:
|
|
174
|
+
os.kill(pid, signal.SIGKILL)
|
|
175
|
+
logger.debug(f"Sent SIGKILL to process {pid}")
|
|
176
|
+
except OSError as e2:
|
|
177
|
+
logger.debug(f"Cannot send SIGKILL to process {pid}: {e2}")
|
|
178
|
+
# If we can't send the signal, check if process is already gone
|
|
179
|
+
if not _process_exists(pid):
|
|
180
|
+
return True
|
|
181
|
+
|
|
182
|
+
# Wait for final confirmation
|
|
183
|
+
start_time = time.time()
|
|
184
|
+
while time.time() - start_time < timeout:
|
|
185
|
+
if not _process_exists(pid):
|
|
186
|
+
return True
|
|
187
|
+
time.sleep(0.1)
|
|
188
|
+
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _cleanup_process_tree_windows(pid: int, timeout: float, force_timeout: float) -> bool:
|
|
193
|
+
"""
|
|
194
|
+
Windows-specific process tree cleanup.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
pid: Process ID to cleanup
|
|
198
|
+
timeout: Graceful termination timeout
|
|
199
|
+
force_timeout: Forced termination timeout
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
True if successful
|
|
203
|
+
"""
|
|
204
|
+
if not PSUTIL_AVAILABLE:
|
|
205
|
+
logger.error("psutil is required for Windows process cleanup")
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
try:
|
|
209
|
+
# Check if process exists
|
|
210
|
+
if not _process_exists(pid):
|
|
211
|
+
logger.debug(f"Process {pid} doesn't exist, cleanup not needed")
|
|
212
|
+
return True
|
|
213
|
+
|
|
214
|
+
# Get process and all children
|
|
215
|
+
try:
|
|
216
|
+
parent = psutil.Process(pid)
|
|
217
|
+
processes = [parent] + parent.children(recursive=True)
|
|
218
|
+
logger.debug(f"Found {len(processes)} processes to cleanup (including parent)")
|
|
219
|
+
except psutil.NoSuchProcess:
|
|
220
|
+
logger.debug(f"Process {pid} not found")
|
|
221
|
+
return True
|
|
222
|
+
|
|
223
|
+
# Step 1: Graceful termination
|
|
224
|
+
for proc in processes:
|
|
225
|
+
try:
|
|
226
|
+
proc.terminate()
|
|
227
|
+
logger.debug(f"Terminated process {proc.pid}")
|
|
228
|
+
except psutil.NoSuchProcess:
|
|
229
|
+
pass
|
|
230
|
+
except Exception as e:
|
|
231
|
+
logger.debug(f"Error terminating process {proc.pid}: {e}")
|
|
232
|
+
|
|
233
|
+
# Wait for graceful termination
|
|
234
|
+
try:
|
|
235
|
+
gone, still_alive = psutil.wait_procs(processes, timeout=timeout)
|
|
236
|
+
logger.debug(f"Graceful termination: {len(gone)} gone, {len(still_alive)} still alive")
|
|
237
|
+
except Exception as e:
|
|
238
|
+
logger.debug(f"Error waiting for processes: {e}")
|
|
239
|
+
still_alive = processes
|
|
240
|
+
|
|
241
|
+
# Step 2: Force termination if needed
|
|
242
|
+
if still_alive:
|
|
243
|
+
logger.debug(f"Force killing {len(still_alive)} remaining processes")
|
|
244
|
+
for proc in still_alive:
|
|
245
|
+
try:
|
|
246
|
+
proc.kill()
|
|
247
|
+
logger.debug(f"Force killed process {proc.pid}")
|
|
248
|
+
except psutil.NoSuchProcess:
|
|
249
|
+
pass
|
|
250
|
+
except Exception as e:
|
|
251
|
+
logger.debug(f"Error force killing process {proc.pid}: {e}")
|
|
252
|
+
|
|
253
|
+
# Final wait
|
|
254
|
+
try:
|
|
255
|
+
gone, still_alive = psutil.wait_procs(still_alive, timeout=force_timeout)
|
|
256
|
+
logger.debug(f"Force termination: {len(gone)} gone, {len(still_alive)} still alive")
|
|
257
|
+
except Exception as e:
|
|
258
|
+
logger.debug(f"Error in final wait: {e}")
|
|
259
|
+
|
|
260
|
+
# Check final result
|
|
261
|
+
return not _process_exists(pid)
|
|
262
|
+
|
|
263
|
+
except Exception as e:
|
|
264
|
+
logger.error(f"Error cleaning up Windows process tree for PID {pid}: {e}")
|
|
265
|
+
raise ProcessCleanupError(pid, str(e))
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _process_exists(pid: int) -> bool:
|
|
269
|
+
"""
|
|
270
|
+
Check if a process exists and is actually running.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
pid: Process ID to check
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
True if process exists and is running
|
|
277
|
+
"""
|
|
278
|
+
if PSUTIL_AVAILABLE:
|
|
279
|
+
try:
|
|
280
|
+
proc = psutil.Process(pid)
|
|
281
|
+
# Check if process is actually running (not zombie)
|
|
282
|
+
return proc.is_running() and proc.status() != psutil.STATUS_ZOMBIE
|
|
283
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
284
|
+
return False
|
|
285
|
+
else:
|
|
286
|
+
# Fallback for systems without psutil
|
|
287
|
+
try:
|
|
288
|
+
os.kill(pid, 0)
|
|
289
|
+
return True
|
|
290
|
+
except OSError:
|
|
291
|
+
return False
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def kill_process_group(pgid: int, sig: int = signal.SIGTERM) -> bool:
|
|
295
|
+
"""
|
|
296
|
+
Send signal to an entire process group.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
pgid: Process group ID
|
|
300
|
+
sig: Signal to send (default: SIGTERM)
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
True if successful
|
|
304
|
+
"""
|
|
305
|
+
try:
|
|
306
|
+
if platform.system() == "Windows":
|
|
307
|
+
logger.warning("Process group signaling not supported on Windows")
|
|
308
|
+
return False
|
|
309
|
+
|
|
310
|
+
os.killpg(pgid, sig)
|
|
311
|
+
logger.debug(f"Sent signal {sig} to process group {pgid}")
|
|
312
|
+
return True
|
|
313
|
+
|
|
314
|
+
except OSError as e:
|
|
315
|
+
logger.debug(f"Error sending signal {sig} to process group {pgid}: {e}")
|
|
316
|
+
return False
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def get_process_children(pid: int) -> List[int]:
|
|
320
|
+
"""
|
|
321
|
+
Get list of child process IDs.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
pid: Parent process ID
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
List of child process IDs
|
|
328
|
+
"""
|
|
329
|
+
if not PSUTIL_AVAILABLE:
|
|
330
|
+
logger.warning("psutil not available, cannot get process children")
|
|
331
|
+
return []
|
|
332
|
+
|
|
333
|
+
try:
|
|
334
|
+
parent = psutil.Process(pid)
|
|
335
|
+
children = parent.children(recursive=True)
|
|
336
|
+
return [child.pid for child in children]
|
|
337
|
+
|
|
338
|
+
except psutil.NoSuchProcess:
|
|
339
|
+
return []
|
|
340
|
+
except Exception as e:
|
|
341
|
+
logger.debug(f"Error getting children for process {pid}: {e}")
|
|
342
|
+
return []
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def is_process_running(pid: int) -> bool:
|
|
346
|
+
"""
|
|
347
|
+
Check if a process is currently running.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
pid: Process ID to check
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
True if process is running
|
|
354
|
+
"""
|
|
355
|
+
if not PSUTIL_AVAILABLE:
|
|
356
|
+
return _process_exists(pid)
|
|
357
|
+
|
|
358
|
+
try:
|
|
359
|
+
process = psutil.Process(pid)
|
|
360
|
+
return process.is_running()
|
|
361
|
+
except psutil.NoSuchProcess:
|
|
362
|
+
return False
|
|
363
|
+
except Exception:
|
|
364
|
+
# Fallback to basic existence check
|
|
365
|
+
return _process_exists(pid)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def wait_for_process_exit(pid: int, timeout: float = 10.0) -> bool:
|
|
369
|
+
"""
|
|
370
|
+
Wait for a process to exit.
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
pid: Process ID to wait for
|
|
374
|
+
timeout: Maximum time to wait in seconds
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
True if process exited within timeout
|
|
378
|
+
"""
|
|
379
|
+
start_time = time.time()
|
|
380
|
+
|
|
381
|
+
while time.time() - start_time < timeout:
|
|
382
|
+
if not _process_exists(pid):
|
|
383
|
+
return True
|
|
384
|
+
time.sleep(0.1)
|
|
385
|
+
|
|
386
|
+
return False
|