auto-coder 0.1.400__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- auto_coder-2.0.0.dist-info/LICENSE +158 -0
- auto_coder-2.0.0.dist-info/METADATA +558 -0
- auto_coder-2.0.0.dist-info/RECORD +795 -0
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
- autocoder/__init__.py +31 -0
- autocoder/agent/auto_filegroup.py +32 -13
- autocoder/agent/auto_learn_from_commit.py +9 -1
- autocoder/agent/base_agentic/__init__.py +3 -0
- autocoder/agent/base_agentic/agent_hub.py +1 -1
- autocoder/agent/base_agentic/base_agent.py +235 -136
- autocoder/agent/base_agentic/default_tools.py +119 -118
- autocoder/agent/base_agentic/test_base_agent.py +1 -1
- autocoder/agent/base_agentic/tool_registry.py +32 -20
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +25 -4
- autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
- autocoder/agent/base_agentic/types.py +42 -0
- autocoder/agent/entry_command_agent/chat.py +73 -59
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +1029 -2310
- autocoder/auto_coder_terminal.py +26 -0
- autocoder/auto_coder_terminal_v3.py +190 -0
- autocoder/chat/conf_command.py +224 -124
- autocoder/chat/models_command.py +361 -299
- autocoder/chat/rules_command.py +79 -31
- autocoder/chat_auto_coder.py +1021 -372
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +26 -9
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +44 -44
- autocoder/common/__init__.py +150 -128
- autocoder/common/ac_style_command_parser/__init__.py +39 -2
- autocoder/common/ac_style_command_parser/config.py +422 -0
- autocoder/common/ac_style_command_parser/parser.py +292 -78
- autocoder/common/ac_style_command_parser/test_parser.py +241 -16
- autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
- autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
- autocoder/common/action_yml_file_manager.py +25 -13
- autocoder/common/agent_events/__init__.py +52 -0
- autocoder/common/agent_events/agent_event_emitter.py +193 -0
- autocoder/common/agent_events/event_factory.py +177 -0
- autocoder/common/agent_events/examples.py +307 -0
- autocoder/common/agent_events/types.py +113 -0
- autocoder/common/agent_events/utils.py +68 -0
- autocoder/common/agent_hooks/__init__.py +44 -0
- autocoder/common/agent_hooks/examples.py +582 -0
- autocoder/common/agent_hooks/hook_executor.py +217 -0
- autocoder/common/agent_hooks/hook_manager.py +288 -0
- autocoder/common/agent_hooks/types.py +133 -0
- autocoder/common/agent_hooks/utils.py +99 -0
- autocoder/common/agent_query_queue/queue_executor.py +324 -0
- autocoder/common/agent_query_queue/queue_manager.py +325 -0
- autocoder/common/agents/__init__.py +11 -0
- autocoder/common/agents/agent_manager.py +323 -0
- autocoder/common/agents/agent_parser.py +189 -0
- autocoder/common/agents/example_usage.py +344 -0
- autocoder/common/agents/integration_example.py +330 -0
- autocoder/common/agents/test_agent_parser.py +545 -0
- autocoder/common/async_utils.py +101 -0
- autocoder/common/auto_coder_lang.py +23 -972
- autocoder/common/autocoderargs_parser/__init__.py +14 -0
- autocoder/common/autocoderargs_parser/parser.py +184 -0
- autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
- autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
- autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
- autocoder/common/autocoderargs_parser/token_parser.py +290 -0
- autocoder/common/buildin_tokenizer.py +2 -4
- autocoder/common/code_auto_generate.py +149 -74
- autocoder/common/code_auto_generate_diff.py +163 -70
- autocoder/common/code_auto_generate_editblock.py +179 -89
- autocoder/common/code_auto_generate_strict_diff.py +167 -72
- autocoder/common/code_auto_merge_editblock.py +13 -6
- autocoder/common/code_modification_ranker.py +1 -1
- autocoder/common/command_completer.py +3 -3
- autocoder/common/command_file_manager/manager.py +183 -47
- autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
- autocoder/common/command_templates.py +1 -1
- autocoder/common/conf_utils.py +2 -4
- autocoder/common/conversations/config.py +11 -3
- autocoder/common/conversations/get_conversation_manager.py +100 -2
- autocoder/common/conversations/llm_stats_models.py +264 -0
- autocoder/common/conversations/manager.py +112 -28
- autocoder/common/conversations/models.py +16 -2
- autocoder/common/conversations/storage/index_manager.py +134 -10
- autocoder/common/core_config/__init__.py +63 -0
- autocoder/common/core_config/agentic_mode_manager.py +109 -0
- autocoder/common/core_config/base_manager.py +123 -0
- autocoder/common/core_config/compatibility.py +151 -0
- autocoder/common/core_config/config_manager.py +156 -0
- autocoder/common/core_config/conversation_manager.py +31 -0
- autocoder/common/core_config/exclude_manager.py +72 -0
- autocoder/common/core_config/file_manager.py +177 -0
- autocoder/common/core_config/human_as_model_manager.py +129 -0
- autocoder/common/core_config/lib_manager.py +54 -0
- autocoder/common/core_config/main_manager.py +81 -0
- autocoder/common/core_config/mode_manager.py +126 -0
- autocoder/common/core_config/models.py +70 -0
- autocoder/common/core_config/test_memory_manager.py +1056 -0
- autocoder/common/env_manager.py +282 -0
- autocoder/common/env_manager_usage_example.py +211 -0
- autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
- autocoder/common/file_checkpoint/manager.py +264 -48
- autocoder/common/file_checkpoint/test_backup.py +1 -18
- autocoder/common/file_checkpoint/test_manager.py +270 -1
- autocoder/common/file_checkpoint/test_store.py +1 -17
- autocoder/common/file_handler/__init__.py +23 -0
- autocoder/common/file_handler/active_context_handler.py +159 -0
- autocoder/common/file_handler/add_files_handler.py +409 -0
- autocoder/common/file_handler/chat_handler.py +180 -0
- autocoder/common/file_handler/coding_handler.py +401 -0
- autocoder/common/file_handler/commit_handler.py +200 -0
- autocoder/common/file_handler/lib_handler.py +156 -0
- autocoder/common/file_handler/list_files_handler.py +111 -0
- autocoder/common/file_handler/mcp_handler.py +268 -0
- autocoder/common/file_handler/models_handler.py +493 -0
- autocoder/common/file_handler/remove_files_handler.py +172 -0
- autocoder/common/file_monitor/test_file_monitor.py +307 -0
- autocoder/common/git_utils.py +51 -10
- autocoder/common/global_cancel.py +15 -6
- autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
- autocoder/common/international/__init__.py +31 -0
- autocoder/common/international/demo_international.py +92 -0
- autocoder/common/international/message_manager.py +157 -0
- autocoder/common/international/messages/__init__.py +56 -0
- autocoder/common/international/messages/async_command_messages.py +507 -0
- autocoder/common/international/messages/auto_coder_messages.py +2208 -0
- autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
- autocoder/common/international/messages/command_help_messages.py +986 -0
- autocoder/common/international/messages/conversation_command_messages.py +191 -0
- autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
- autocoder/common/international/messages/queue_command_messages.py +751 -0
- autocoder/common/international/messages/rules_command_messages.py +77 -0
- autocoder/common/international/messages/sdk_messages.py +1707 -0
- autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
- autocoder/common/international/messages/tool_display_messages.py +1212 -0
- autocoder/common/international/messages/workflow_exception_messages.py +473 -0
- autocoder/common/international/test_international.py +612 -0
- autocoder/common/linter_core/__init__.py +28 -0
- autocoder/common/linter_core/base_linter.py +61 -0
- autocoder/common/linter_core/config_loader.py +271 -0
- autocoder/common/linter_core/formatters/__init__.py +0 -0
- autocoder/common/linter_core/formatters/base_formatter.py +38 -0
- autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
- autocoder/common/linter_core/linter.py +166 -0
- autocoder/common/linter_core/linter_factory.py +216 -0
- autocoder/common/linter_core/linter_manager.py +333 -0
- autocoder/common/linter_core/linters/__init__.py +9 -0
- autocoder/common/linter_core/linters/java_linter.py +342 -0
- autocoder/common/linter_core/linters/python_linter.py +115 -0
- autocoder/common/linter_core/linters/typescript_linter.py +119 -0
- autocoder/common/linter_core/models/__init__.py +7 -0
- autocoder/common/linter_core/models/lint_result.py +91 -0
- autocoder/common/linter_core/models.py +33 -0
- autocoder/common/linter_core/tests/__init__.py +3 -0
- autocoder/common/linter_core/tests/test_config_loader.py +323 -0
- autocoder/common/linter_core/tests/test_config_loading.py +308 -0
- autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
- autocoder/common/linter_core/tests/test_formatters.py +147 -0
- autocoder/common/linter_core/tests/test_integration.py +317 -0
- autocoder/common/linter_core/tests/test_java_linter.py +496 -0
- autocoder/common/linter_core/tests/test_linters.py +265 -0
- autocoder/common/linter_core/tests/test_models.py +81 -0
- autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
- autocoder/common/linter_core/tests/verify_fixes.py +183 -0
- autocoder/common/llm_friendly_package/__init__.py +31 -0
- autocoder/common/llm_friendly_package/base_manager.py +102 -0
- autocoder/common/llm_friendly_package/docs_manager.py +121 -0
- autocoder/common/llm_friendly_package/library_manager.py +171 -0
- autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
- autocoder/common/llm_friendly_package/models.py +40 -0
- autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
- autocoder/common/llms/__init__.py +15 -0
- autocoder/common/llms/demo_error_handling.py +85 -0
- autocoder/common/llms/factory.py +142 -0
- autocoder/common/llms/manager.py +264 -0
- autocoder/common/llms/pricing.py +121 -0
- autocoder/common/llms/registry.py +288 -0
- autocoder/common/llms/schema.py +77 -0
- autocoder/common/llms/simple_demo.py +45 -0
- autocoder/common/llms/test_quick_model.py +116 -0
- autocoder/common/llms/test_remove_functionality.py +182 -0
- autocoder/common/llms/tests/__init__.py +1 -0
- autocoder/common/llms/tests/test_manager.py +330 -0
- autocoder/common/llms/tests/test_registry.py +364 -0
- autocoder/common/mcp_tools/__init__.py +62 -0
- autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
- autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
- autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
- autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
- autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
- autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
- autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
- autocoder/common/mcp_tools/verify_functionality.py +202 -0
- autocoder/common/model_speed_tester.py +32 -26
- autocoder/common/priority_directory_finder/__init__.py +142 -0
- autocoder/common/priority_directory_finder/examples.py +230 -0
- autocoder/common/priority_directory_finder/finder.py +283 -0
- autocoder/common/priority_directory_finder/models.py +236 -0
- autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
- autocoder/common/project_scanner/__init__.py +18 -0
- autocoder/common/project_scanner/compat.py +77 -0
- autocoder/common/project_scanner/scanner.py +436 -0
- autocoder/common/project_tracker/__init__.py +27 -0
- autocoder/common/project_tracker/api.py +228 -0
- autocoder/common/project_tracker/demo.py +272 -0
- autocoder/common/project_tracker/tracker.py +487 -0
- autocoder/common/project_tracker/types.py +53 -0
- autocoder/common/pruner/__init__.py +67 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +746 -0
- autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
- autocoder/common/pruner/conversation_message_ids_api.py +386 -0
- autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
- autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
- autocoder/common/pruner/conversation_normalizer.py +347 -0
- autocoder/common/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
- autocoder/common/pruner/test_context_pruner.py +546 -0
- autocoder/common/pruner/test_conversation_normalizer.py +502 -0
- autocoder/common/pruner/test_tool_content_detector.py +324 -0
- autocoder/common/pruner/tool_content_detector.py +227 -0
- autocoder/common/pruner/tools/__init__.py +18 -0
- autocoder/common/pruner/tools/query_message_ids.py +264 -0
- autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
- autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
- autocoder/common/pull_requests/__init__.py +9 -1
- autocoder/common/pull_requests/utils.py +122 -1
- autocoder/common/rag_manager/rag_manager.py +36 -40
- autocoder/common/rulefiles/__init__.py +53 -1
- autocoder/common/rulefiles/api.py +250 -0
- autocoder/common/rulefiles/core/__init__.py +14 -0
- autocoder/common/rulefiles/core/manager.py +241 -0
- autocoder/common/rulefiles/core/selector.py +805 -0
- autocoder/common/rulefiles/models/__init__.py +20 -0
- autocoder/common/rulefiles/models/index.py +16 -0
- autocoder/common/rulefiles/models/init_rule.py +18 -0
- autocoder/common/rulefiles/models/rule_file.py +18 -0
- autocoder/common/rulefiles/models/rule_relevance.py +14 -0
- autocoder/common/rulefiles/models/summary.py +16 -0
- autocoder/common/rulefiles/test_rulefiles.py +776 -0
- autocoder/common/rulefiles/utils/__init__.py +34 -0
- autocoder/common/rulefiles/utils/monitor.py +86 -0
- autocoder/common/rulefiles/utils/parser.py +230 -0
- autocoder/common/save_formatted_log.py +67 -10
- autocoder/common/search_replace.py +8 -1
- autocoder/common/search_replace_patch/__init__.py +24 -0
- autocoder/common/search_replace_patch/base.py +115 -0
- autocoder/common/search_replace_patch/manager.py +248 -0
- autocoder/common/search_replace_patch/patch_replacer.py +304 -0
- autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
- autocoder/common/search_replace_patch/string_replacer.py +181 -0
- autocoder/common/search_replace_patch/tests/__init__.py +3 -0
- autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
- autocoder/common/search_replace_patch/tests/test_base.py +188 -0
- autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
- autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
- autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
- autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
- autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
- autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
- autocoder/common/shell_commands/__init__.py +197 -0
- autocoder/common/shell_commands/background_process_notifier.py +346 -0
- autocoder/common/shell_commands/command_executor.py +1127 -0
- autocoder/common/shell_commands/error_recovery.py +541 -0
- autocoder/common/shell_commands/exceptions.py +120 -0
- autocoder/common/shell_commands/interactive_executor.py +476 -0
- autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
- autocoder/common/shell_commands/interactive_process.py +744 -0
- autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
- autocoder/common/shell_commands/monitoring.py +529 -0
- autocoder/common/shell_commands/process_cleanup.py +386 -0
- autocoder/common/shell_commands/process_manager.py +606 -0
- autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
- autocoder/common/shell_commands/tests/__init__.py +6 -0
- autocoder/common/shell_commands/tests/conftest.py +118 -0
- autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
- autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
- autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
- autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
- autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
- autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
- autocoder/common/shell_commands/tests/test_integration.py +664 -0
- autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
- autocoder/common/shell_commands/tests/test_performance.py +632 -0
- autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
- autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
- autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
- autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
- autocoder/common/shell_commands/timeout_config.py +315 -0
- autocoder/common/shell_commands/timeout_manager.py +352 -0
- autocoder/common/terminal_paste/__init__.py +14 -0
- autocoder/common/terminal_paste/demo.py +145 -0
- autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
- autocoder/common/terminal_paste/paste_handler.py +200 -0
- autocoder/common/terminal_paste/paste_manager.py +118 -0
- autocoder/common/terminal_paste/tests/__init__.py +1 -0
- autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
- autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
- autocoder/common/terminal_paste/utils.py +163 -0
- autocoder/common/test_autocoder_args.py +232 -0
- autocoder/common/test_env_manager.py +173 -0
- autocoder/common/test_env_manager_integration.py +159 -0
- autocoder/common/text_similarity/__init__.py +9 -0
- autocoder/common/text_similarity/demo.py +216 -0
- autocoder/common/text_similarity/examples.py +266 -0
- autocoder/common/text_similarity/test_text_similarity.py +306 -0
- autocoder/common/text_similarity/text_similarity.py +194 -0
- autocoder/common/text_similarity/utils.py +125 -0
- autocoder/common/todos/__init__.py +61 -0
- autocoder/common/todos/cache/__init__.py +16 -0
- autocoder/common/todos/cache/base_cache.py +89 -0
- autocoder/common/todos/cache/cache_manager.py +228 -0
- autocoder/common/todos/cache/memory_cache.py +225 -0
- autocoder/common/todos/config.py +155 -0
- autocoder/common/todos/exceptions.py +35 -0
- autocoder/common/todos/get_todo_manager.py +161 -0
- autocoder/common/todos/manager.py +537 -0
- autocoder/common/todos/models.py +239 -0
- autocoder/common/todos/storage/__init__.py +14 -0
- autocoder/common/todos/storage/base_storage.py +76 -0
- autocoder/common/todos/storage/file_storage.py +278 -0
- autocoder/common/tokens/__init__.py +15 -0
- autocoder/common/tokens/counter.py +44 -2
- autocoder/common/tools_manager/__init__.py +17 -0
- autocoder/common/tools_manager/examples.py +162 -0
- autocoder/common/tools_manager/manager.py +385 -0
- autocoder/common/tools_manager/models.py +39 -0
- autocoder/common/tools_manager/test_tools_manager.py +303 -0
- autocoder/common/tools_manager/utils.py +191 -0
- autocoder/common/v2/agent/agentic_callbacks.py +270 -0
- autocoder/common/v2/agent/agentic_edit.py +2729 -2052
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
- autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
- autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
- autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +565 -30
- autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
- autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
- autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
- autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +244 -51
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
- autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +409 -140
- autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +209 -194
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
- autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
- autocoder/common/v2/agent/agentic_edit_types.py +386 -10
- autocoder/common/v2/agent/runner/__init__.py +31 -0
- autocoder/common/v2/agent/runner/base_runner.py +92 -0
- autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
- autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
- autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
- autocoder/common/v2/agent/runner/tool_display.py +589 -0
- autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
- autocoder/common/v2/agent/test_agentic_edit.py +194 -0
- autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
- autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
- autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
- autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
- autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
- autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
- autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
- autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
- autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
- autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
- autocoder/common/v2/code_auto_generate.py +136 -78
- autocoder/common/v2/code_auto_generate_diff.py +135 -79
- autocoder/common/v2/code_auto_generate_editblock.py +174 -99
- autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
- autocoder/common/v2/code_auto_merge.py +1 -1
- autocoder/common/v2/code_auto_merge_editblock.py +13 -1
- autocoder/common/v2/code_diff_manager.py +3 -3
- autocoder/common/v2/code_editblock_manager.py +4 -14
- autocoder/common/v2/code_manager.py +1 -1
- autocoder/common/v2/code_strict_diff_manager.py +2 -2
- autocoder/common/wrap_llm_hint/__init__.py +10 -0
- autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
- autocoder/common/wrap_llm_hint/utils.py +432 -0
- autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
- autocoder/completer/__init__.py +8 -0
- autocoder/completer/command_completer_v2.py +1051 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +165 -7
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- autocoder/{agent → index/filter}/agentic_filter.py +323 -334
- autocoder/index/filter/normal_filter.py +5 -11
- autocoder/index/filter/quick_filter.py +1 -1
- autocoder/index/index.py +36 -9
- autocoder/index/tests/__init__.py +1 -0
- autocoder/index/tests/run_tests.py +195 -0
- autocoder/index/tests/test_entry.py +303 -0
- autocoder/index/tests/test_index_manager.py +314 -0
- autocoder/index/tests/test_module_integration.py +300 -0
- autocoder/index/tests/test_symbols_utils.py +183 -0
- autocoder/inner/__init__.py +4 -0
- autocoder/inner/agentic.py +932 -0
- autocoder/inner/async_command_handler.py +992 -0
- autocoder/inner/conversation_command_handlers.py +623 -0
- autocoder/inner/merge_command_handler.py +213 -0
- autocoder/inner/queue_command_handler.py +684 -0
- autocoder/models.py +95 -266
- autocoder/plugins/git_helper_plugin.py +31 -29
- autocoder/plugins/token_helper_plugin.py +156 -37
- autocoder/pyproject/__init__.py +32 -29
- autocoder/rag/agentic_rag.py +215 -75
- autocoder/rag/cache/simple_cache.py +1 -2
- autocoder/rag/loaders/image_loader.py +1 -1
- autocoder/rag/long_context_rag.py +42 -26
- autocoder/rag/qa_conversation_strategy.py +1 -1
- autocoder/rag/terminal/__init__.py +17 -0
- autocoder/rag/terminal/args.py +581 -0
- autocoder/rag/terminal/bootstrap.py +61 -0
- autocoder/rag/terminal/command_handlers.py +653 -0
- autocoder/rag/terminal/formatters/__init__.py +20 -0
- autocoder/rag/terminal/formatters/base.py +70 -0
- autocoder/rag/terminal/formatters/json_format.py +66 -0
- autocoder/rag/terminal/formatters/stream_json.py +95 -0
- autocoder/rag/terminal/formatters/text.py +28 -0
- autocoder/rag/terminal/init.py +120 -0
- autocoder/rag/terminal/utils.py +106 -0
- autocoder/rag/test_agentic_rag.py +389 -0
- autocoder/rag/test_doc_filter.py +3 -3
- autocoder/rag/test_long_context_rag.py +1 -1
- autocoder/rag/test_token_limiter.py +517 -10
- autocoder/rag/token_counter.py +3 -0
- autocoder/rag/token_limiter.py +19 -15
- autocoder/rag/tools/__init__.py +26 -2
- autocoder/rag/tools/bochaai_example.py +343 -0
- autocoder/rag/tools/bochaai_sdk.py +541 -0
- autocoder/rag/tools/metaso_example.py +268 -0
- autocoder/rag/tools/metaso_sdk.py +417 -0
- autocoder/rag/tools/recall_tool.py +28 -7
- autocoder/rag/tools/run_integration_tests.py +204 -0
- autocoder/rag/tools/test_all_providers.py +318 -0
- autocoder/rag/tools/test_bochaai_integration.py +482 -0
- autocoder/rag/tools/test_final_integration.py +215 -0
- autocoder/rag/tools/test_metaso_integration.py +424 -0
- autocoder/rag/tools/test_metaso_real.py +171 -0
- autocoder/rag/tools/test_web_crawl_tool.py +639 -0
- autocoder/rag/tools/test_web_search_tool.py +509 -0
- autocoder/rag/tools/todo_read_tool.py +202 -0
- autocoder/rag/tools/todo_write_tool.py +412 -0
- autocoder/rag/tools/web_crawl_tool.py +634 -0
- autocoder/rag/tools/web_search_tool.py +558 -0
- autocoder/rag/tools/web_tools_example.py +119 -0
- autocoder/rag/types.py +16 -0
- autocoder/rag/variable_holder.py +4 -2
- autocoder/rags.py +86 -79
- autocoder/regexproject/__init__.py +23 -21
- autocoder/run_context.py +9 -0
- autocoder/sdk/__init__.py +50 -161
- autocoder/sdk/api.py +370 -0
- autocoder/sdk/async_runner/__init__.py +26 -0
- autocoder/sdk/async_runner/async_executor.py +650 -0
- autocoder/sdk/async_runner/async_handler.py +356 -0
- autocoder/sdk/async_runner/markdown_processor.py +595 -0
- autocoder/sdk/async_runner/task_metadata.py +284 -0
- autocoder/sdk/async_runner/worktree_manager.py +438 -0
- autocoder/sdk/cli/__init__.py +2 -5
- autocoder/sdk/cli/formatters.py +28 -204
- autocoder/sdk/cli/handlers.py +77 -44
- autocoder/sdk/cli/main.py +158 -170
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -267
- autocoder/sdk/core/bridge.py +298 -118
- autocoder/sdk/exceptions.py +18 -12
- autocoder/sdk/formatters/__init__.py +19 -0
- autocoder/sdk/formatters/input.py +64 -0
- autocoder/sdk/formatters/output.py +247 -0
- autocoder/sdk/formatters/stream.py +54 -0
- autocoder/sdk/models/__init__.py +6 -5
- autocoder/sdk/models/options.py +55 -18
- autocoder/sdk/utils/formatters.py +27 -195
- autocoder/suffixproject/__init__.py +28 -25
- autocoder/terminal/__init__.py +14 -0
- autocoder/terminal/app.py +454 -0
- autocoder/terminal/args.py +32 -0
- autocoder/terminal/bootstrap.py +178 -0
- autocoder/terminal/command_processor.py +521 -0
- autocoder/terminal/command_registry.py +57 -0
- autocoder/terminal/help.py +97 -0
- autocoder/terminal/tasks/__init__.py +5 -0
- autocoder/terminal/tasks/background.py +77 -0
- autocoder/terminal/tasks/task_event.py +70 -0
- autocoder/terminal/ui/__init__.py +13 -0
- autocoder/terminal/ui/completer.py +268 -0
- autocoder/terminal/ui/keybindings.py +75 -0
- autocoder/terminal/ui/session.py +41 -0
- autocoder/terminal/ui/toolbar.py +64 -0
- autocoder/terminal/utils/__init__.py +13 -0
- autocoder/terminal/utils/errors.py +18 -0
- autocoder/terminal/utils/paths.py +19 -0
- autocoder/terminal/utils/shell.py +43 -0
- autocoder/terminal_v3/__init__.py +10 -0
- autocoder/terminal_v3/app.py +201 -0
- autocoder/terminal_v3/handlers/__init__.py +5 -0
- autocoder/terminal_v3/handlers/command_handler.py +131 -0
- autocoder/terminal_v3/models/__init__.py +6 -0
- autocoder/terminal_v3/models/conversation_buffer.py +214 -0
- autocoder/terminal_v3/models/message.py +50 -0
- autocoder/terminal_v3/models/tool_display.py +247 -0
- autocoder/terminal_v3/ui/__init__.py +7 -0
- autocoder/terminal_v3/ui/keybindings.py +56 -0
- autocoder/terminal_v3/ui/layout.py +141 -0
- autocoder/terminal_v3/ui/styles.py +43 -0
- autocoder/tsproject/__init__.py +23 -23
- autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
- autocoder/utils/llms.py +88 -80
- autocoder/utils/math_utils.py +101 -0
- autocoder/utils/model_provider_selector.py +16 -4
- autocoder/utils/operate_config_api.py +33 -5
- autocoder/utils/thread_utils.py +2 -2
- autocoder/version.py +4 -2
- autocoder/workflow_agents/__init__.py +84 -0
- autocoder/workflow_agents/agent.py +143 -0
- autocoder/workflow_agents/exceptions.py +573 -0
- autocoder/workflow_agents/executor.py +489 -0
- autocoder/workflow_agents/loader.py +737 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +172 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-0.1.400.dist-info/METADATA +0 -396
- auto_coder-0.1.400.dist-info/RECORD +0 -425
- auto_coder-0.1.400.dist-info/licenses/LICENSE +0 -201
- autocoder/auto_coder_server.py +0 -672
- autocoder/benchmark.py +0 -138
- autocoder/common/ac_style_command_parser/example.py +0 -7
- autocoder/common/cleaner.py +0 -31
- autocoder/common/command_completer_v2.py +0 -615
- autocoder/common/directory_cache/__init__.py +0 -1
- autocoder/common/directory_cache/cache.py +0 -192
- autocoder/common/directory_cache/test_cache.py +0 -190
- autocoder/common/file_checkpoint/examples.py +0 -217
- autocoder/common/llm_friendly_package_example.py +0 -138
- autocoder/common/llm_friendly_package_test.py +0 -63
- autocoder/common/pull_requests/test_module.py +0 -1
- autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
- autocoder/common/text.py +0 -30
- autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
- autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
- autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
- autocoder/common/v2/agent/agentic_tool_display.py +0 -183
- autocoder/plugins/dynamic_completion_example.py +0 -148
- autocoder/plugins/sample_plugin.py +0 -160
- autocoder/sdk/cli/__main__.py +0 -26
- autocoder/sdk/cli/completion_wrapper.py +0 -38
- autocoder/sdk/cli/install_completion.py +0 -301
- autocoder/sdk/models/messages.py +0 -209
- autocoder/sdk/session/__init__.py +0 -32
- autocoder/sdk/session/session.py +0 -106
- autocoder/sdk/session/session_manager.py +0 -56
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Interactive command executor for shell command execution.
|
|
3
|
+
|
|
4
|
+
This module provides interactive command execution functionality including:
|
|
5
|
+
- Integration with existing CommandExecutor
|
|
6
|
+
- Timeout and monitoring support
|
|
7
|
+
- Cross-platform compatibility
|
|
8
|
+
- Signal handling and process management
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import signal
|
|
13
|
+
import threading
|
|
14
|
+
import time
|
|
15
|
+
import logging
|
|
16
|
+
from typing import Optional, Dict, Any, Union, List, Callable
|
|
17
|
+
|
|
18
|
+
# Set up logger safely
|
|
19
|
+
try:
|
|
20
|
+
from loguru import logger as module_logger
|
|
21
|
+
except ImportError:
|
|
22
|
+
# Fallback to standard logging if loguru is not available
|
|
23
|
+
module_logger = logging.getLogger(__name__)
|
|
24
|
+
if not module_logger.handlers:
|
|
25
|
+
handler = logging.StreamHandler()
|
|
26
|
+
handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
|
27
|
+
module_logger.addHandler(handler)
|
|
28
|
+
module_logger.setLevel(logging.DEBUG)
|
|
29
|
+
|
|
30
|
+
from .command_executor import CommandExecutor
|
|
31
|
+
from .interactive_process import InteractiveProcess
|
|
32
|
+
from .timeout_config import TimeoutConfig
|
|
33
|
+
from .monitoring import CommandExecutionLogger, PerformanceMonitor
|
|
34
|
+
from .error_recovery import ErrorRecoveryManager
|
|
35
|
+
from .exceptions import CommandExecutionError, CommandTimeoutError
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class InteractiveSession:
|
|
39
|
+
"""
|
|
40
|
+
Interactive session manager for handling multiple interactive processes.
|
|
41
|
+
|
|
42
|
+
This class manages the lifecycle of interactive sessions, including
|
|
43
|
+
process monitoring, timeout handling, and cleanup.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
process: InteractiveProcess,
|
|
49
|
+
session_id: str,
|
|
50
|
+
timeout: Optional[float] = None,
|
|
51
|
+
logger: Optional[CommandExecutionLogger] = None,
|
|
52
|
+
monitor: Optional[PerformanceMonitor] = None
|
|
53
|
+
):
|
|
54
|
+
"""
|
|
55
|
+
Initialize interactive session.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
process: Interactive process instance
|
|
59
|
+
session_id: Unique session identifier
|
|
60
|
+
timeout: Session timeout in seconds
|
|
61
|
+
logger: Command execution logger
|
|
62
|
+
monitor: Performance monitor
|
|
63
|
+
"""
|
|
64
|
+
self.process = process
|
|
65
|
+
self.session_id = session_id
|
|
66
|
+
self.timeout = timeout
|
|
67
|
+
self.logger = logger
|
|
68
|
+
self.monitor = monitor
|
|
69
|
+
|
|
70
|
+
# Session state
|
|
71
|
+
self.start_time = time.time()
|
|
72
|
+
self.last_activity = time.time()
|
|
73
|
+
self.timeout_timer: Optional[threading.Timer] = None
|
|
74
|
+
self.cleanup_callbacks: List[Callable] = []
|
|
75
|
+
|
|
76
|
+
# Start timeout if specified
|
|
77
|
+
if self.timeout:
|
|
78
|
+
self._start_timeout()
|
|
79
|
+
|
|
80
|
+
def _start_timeout(self) -> None:
|
|
81
|
+
"""Start session timeout timer."""
|
|
82
|
+
if self.timeout_timer:
|
|
83
|
+
self.timeout_timer.cancel()
|
|
84
|
+
|
|
85
|
+
def timeout_handler():
|
|
86
|
+
module_logger.warning(f"Interactive session {self.session_id} timed out after {self.timeout}s")
|
|
87
|
+
self.terminate()
|
|
88
|
+
|
|
89
|
+
self.timeout_timer = threading.Timer(self.timeout or 0, timeout_handler)
|
|
90
|
+
self.timeout_timer.daemon = True
|
|
91
|
+
self.timeout_timer.start()
|
|
92
|
+
|
|
93
|
+
def update_activity(self) -> None:
|
|
94
|
+
"""Update last activity timestamp and reset timeout."""
|
|
95
|
+
self.last_activity = time.time()
|
|
96
|
+
|
|
97
|
+
if self.timeout:
|
|
98
|
+
self._start_timeout()
|
|
99
|
+
|
|
100
|
+
def add_cleanup_callback(self, callback: Callable) -> None:
|
|
101
|
+
"""Add cleanup callback to be called when session ends."""
|
|
102
|
+
self.cleanup_callbacks.append(callback)
|
|
103
|
+
|
|
104
|
+
def terminate(self) -> bool:
|
|
105
|
+
"""Terminate the interactive session."""
|
|
106
|
+
try:
|
|
107
|
+
# Cancel timeout
|
|
108
|
+
if self.timeout_timer:
|
|
109
|
+
self.timeout_timer.cancel()
|
|
110
|
+
self.timeout_timer = None
|
|
111
|
+
|
|
112
|
+
# Terminate process
|
|
113
|
+
success = self.process.terminate()
|
|
114
|
+
|
|
115
|
+
# Call cleanup callbacks
|
|
116
|
+
for callback in self.cleanup_callbacks:
|
|
117
|
+
try:
|
|
118
|
+
callback(self)
|
|
119
|
+
except Exception as e:
|
|
120
|
+
module_logger.error(f"Error in cleanup callback: {e}")
|
|
121
|
+
|
|
122
|
+
# Log session stats
|
|
123
|
+
if self.logger:
|
|
124
|
+
stats = self.process.get_stats()
|
|
125
|
+
module_logger.info(f"Interactive session {self.session_id} ended: {stats}")
|
|
126
|
+
|
|
127
|
+
return success
|
|
128
|
+
|
|
129
|
+
except Exception as e:
|
|
130
|
+
module_logger.error(f"Error terminating session {self.session_id}: {e}")
|
|
131
|
+
return False
|
|
132
|
+
|
|
133
|
+
def get_session_stats(self) -> Dict[str, Any]:
|
|
134
|
+
"""Get session statistics."""
|
|
135
|
+
return {
|
|
136
|
+
'session_id': self.session_id,
|
|
137
|
+
'start_time': self.start_time,
|
|
138
|
+
'last_activity': self.last_activity,
|
|
139
|
+
'duration': time.time() - self.start_time,
|
|
140
|
+
'process_stats': self.process.get_stats(),
|
|
141
|
+
'timeout': self.timeout
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
def __del__(self) -> None:
|
|
145
|
+
"""Destructor - cleanup session."""
|
|
146
|
+
try:
|
|
147
|
+
if self.process.is_alive():
|
|
148
|
+
self.terminate()
|
|
149
|
+
except Exception:
|
|
150
|
+
pass
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class InteractiveCommandExecutor:
|
|
154
|
+
"""
|
|
155
|
+
Interactive command executor with full integration to shell_commands system.
|
|
156
|
+
|
|
157
|
+
This class extends the capabilities of CommandExecutor to support
|
|
158
|
+
interactive command execution while maintaining compatibility with
|
|
159
|
+
existing timeout, monitoring, and error recovery systems.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
def __init__(
|
|
163
|
+
self,
|
|
164
|
+
config: Optional[TimeoutConfig] = None,
|
|
165
|
+
logger: Optional[CommandExecutionLogger] = None,
|
|
166
|
+
monitor: Optional[PerformanceMonitor] = None,
|
|
167
|
+
error_recovery: Optional[ErrorRecoveryManager] = None,
|
|
168
|
+
verbose: bool = False
|
|
169
|
+
):
|
|
170
|
+
"""
|
|
171
|
+
Initialize interactive command executor.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
config: Timeout configuration
|
|
175
|
+
logger: Command execution logger
|
|
176
|
+
monitor: Performance monitor
|
|
177
|
+
error_recovery: Error recovery manager
|
|
178
|
+
verbose: Whether to enable verbose logging
|
|
179
|
+
"""
|
|
180
|
+
# Initialize base executor for shared functionality
|
|
181
|
+
self.base_executor = CommandExecutor(
|
|
182
|
+
config=config,
|
|
183
|
+
logger=logger,
|
|
184
|
+
monitor=monitor,
|
|
185
|
+
error_recovery=error_recovery,
|
|
186
|
+
verbose=verbose
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# Interactive-specific state
|
|
190
|
+
self.active_sessions: Dict[str, InteractiveSession] = {}
|
|
191
|
+
self.session_counter = 0
|
|
192
|
+
self._lock = threading.Lock()
|
|
193
|
+
|
|
194
|
+
module_logger.debug("InteractiveCommandExecutor initialized")
|
|
195
|
+
|
|
196
|
+
def execute_interactive(
|
|
197
|
+
self,
|
|
198
|
+
command: Union[str, List[str]],
|
|
199
|
+
cwd: Optional[str] = None,
|
|
200
|
+
env: Optional[Dict[str, str]] = None,
|
|
201
|
+
timeout: Optional[float] = None,
|
|
202
|
+
use_pty: Optional[bool] = None,
|
|
203
|
+
shell: bool = True,
|
|
204
|
+
encoding: str = 'utf-8',
|
|
205
|
+
session_id: Optional[str] = None,
|
|
206
|
+
**kwargs
|
|
207
|
+
) -> InteractiveSession:
|
|
208
|
+
"""
|
|
209
|
+
Execute a command interactively.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
command: Command to execute
|
|
213
|
+
cwd: Working directory
|
|
214
|
+
env: Environment variables
|
|
215
|
+
timeout: Session timeout (None for no timeout)
|
|
216
|
+
use_pty: Whether to use PTY (auto-detect if None)
|
|
217
|
+
shell: Whether to use shell
|
|
218
|
+
encoding: Text encoding
|
|
219
|
+
session_id: Custom session ID (auto-generated if None)
|
|
220
|
+
**kwargs: Additional arguments
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
InteractiveSession instance
|
|
224
|
+
|
|
225
|
+
Raises:
|
|
226
|
+
CommandExecutionError: If command execution fails
|
|
227
|
+
"""
|
|
228
|
+
# Generate session ID if not provided
|
|
229
|
+
if session_id is None:
|
|
230
|
+
with self._lock:
|
|
231
|
+
self.session_counter += 1
|
|
232
|
+
session_id = f"session_{self.session_counter}_{int(time.time())}"
|
|
233
|
+
|
|
234
|
+
# Determine timeout
|
|
235
|
+
if timeout is None:
|
|
236
|
+
# For interactive commands, use interactive_timeout from config
|
|
237
|
+
if hasattr(self.base_executor.config, 'interactive_timeout'):
|
|
238
|
+
timeout = self.base_executor.config.interactive_timeout
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
# Create interactive process
|
|
242
|
+
process = InteractiveProcess(
|
|
243
|
+
command=command,
|
|
244
|
+
cwd=cwd,
|
|
245
|
+
env=env,
|
|
246
|
+
use_pty=use_pty,
|
|
247
|
+
shell=shell,
|
|
248
|
+
encoding=encoding,
|
|
249
|
+
**kwargs
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# Start the process
|
|
253
|
+
process.start()
|
|
254
|
+
|
|
255
|
+
# Create session
|
|
256
|
+
session = InteractiveSession(
|
|
257
|
+
process=process,
|
|
258
|
+
session_id=session_id,
|
|
259
|
+
timeout=timeout,
|
|
260
|
+
logger=self.base_executor.logger,
|
|
261
|
+
monitor=self.base_executor.monitor
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Register session
|
|
265
|
+
with self._lock:
|
|
266
|
+
self.active_sessions[session_id] = session
|
|
267
|
+
|
|
268
|
+
# Add cleanup callback to remove from active sessions
|
|
269
|
+
session.add_cleanup_callback(self._session_cleanup_callback)
|
|
270
|
+
|
|
271
|
+
module_logger.info(f"Started interactive session {session_id} for command: {command}")
|
|
272
|
+
|
|
273
|
+
return session
|
|
274
|
+
|
|
275
|
+
except Exception as e:
|
|
276
|
+
module_logger.error(f"Failed to start interactive session: {e}")
|
|
277
|
+
raise CommandExecutionError(f"Failed to execute interactive command: {e}")
|
|
278
|
+
|
|
279
|
+
def _session_cleanup_callback(self, session: InteractiveSession) -> None:
|
|
280
|
+
"""Cleanup callback for session termination."""
|
|
281
|
+
with self._lock:
|
|
282
|
+
self.active_sessions.pop(session.session_id, None)
|
|
283
|
+
|
|
284
|
+
module_logger.debug(f"Cleaned up session {session.session_id}")
|
|
285
|
+
|
|
286
|
+
def get_session(self, session_id: str) -> Optional[InteractiveSession]:
|
|
287
|
+
"""Get active session by ID."""
|
|
288
|
+
with self._lock:
|
|
289
|
+
return self.active_sessions.get(session_id)
|
|
290
|
+
|
|
291
|
+
def list_sessions(self) -> List[Dict[str, Any]]:
|
|
292
|
+
"""List all active sessions."""
|
|
293
|
+
with self._lock:
|
|
294
|
+
return [session.get_session_stats() for session in self.active_sessions.values()]
|
|
295
|
+
|
|
296
|
+
def terminate_session(self, session_id: str) -> bool:
|
|
297
|
+
"""Terminate a specific session."""
|
|
298
|
+
session = self.get_session(session_id)
|
|
299
|
+
if session:
|
|
300
|
+
return session.terminate()
|
|
301
|
+
return False
|
|
302
|
+
|
|
303
|
+
def terminate_all_sessions(self) -> Dict[str, bool]:
|
|
304
|
+
"""Terminate all active sessions."""
|
|
305
|
+
results = {}
|
|
306
|
+
|
|
307
|
+
with self._lock:
|
|
308
|
+
sessions = list(self.active_sessions.values())
|
|
309
|
+
|
|
310
|
+
for session in sessions:
|
|
311
|
+
try:
|
|
312
|
+
results[session.session_id] = session.terminate()
|
|
313
|
+
except Exception as e:
|
|
314
|
+
module_logger.error(f"Error terminating session {session.session_id}: {e}")
|
|
315
|
+
results[session.session_id] = False
|
|
316
|
+
|
|
317
|
+
return results
|
|
318
|
+
|
|
319
|
+
def send_signal_to_session(self, session_id: str, sig: int) -> bool:
|
|
320
|
+
"""Send signal to a specific session."""
|
|
321
|
+
session = self.get_session(session_id)
|
|
322
|
+
if session and session.process.is_alive():
|
|
323
|
+
try:
|
|
324
|
+
session.process.send_signal(sig)
|
|
325
|
+
session.update_activity()
|
|
326
|
+
return True
|
|
327
|
+
except Exception as e:
|
|
328
|
+
module_logger.error(f"Error sending signal to session {session_id}: {e}")
|
|
329
|
+
return False
|
|
330
|
+
return False
|
|
331
|
+
|
|
332
|
+
def send_interrupt_to_session(self, session_id: str) -> bool:
|
|
333
|
+
"""Send interrupt signal (Ctrl+C) to a specific session."""
|
|
334
|
+
return self.send_signal_to_session(session_id, signal.SIGINT)
|
|
335
|
+
|
|
336
|
+
def write_to_session(self, session_id: str, data: str) -> bool:
|
|
337
|
+
"""Write data to a specific session."""
|
|
338
|
+
session = self.get_session(session_id)
|
|
339
|
+
if session and session.process.is_alive():
|
|
340
|
+
try:
|
|
341
|
+
session.process.write(data)
|
|
342
|
+
session.update_activity()
|
|
343
|
+
return True
|
|
344
|
+
except Exception as e:
|
|
345
|
+
module_logger.error(f"Error writing to session {session_id}: {e}")
|
|
346
|
+
return False
|
|
347
|
+
return False
|
|
348
|
+
|
|
349
|
+
def read_from_session(
|
|
350
|
+
self,
|
|
351
|
+
session_id: str,
|
|
352
|
+
timeout: Optional[float] = None
|
|
353
|
+
) -> Optional[str]:
|
|
354
|
+
"""Read output from a specific session."""
|
|
355
|
+
session = self.get_session(session_id)
|
|
356
|
+
if session:
|
|
357
|
+
try:
|
|
358
|
+
data = session.process.read_output(timeout=timeout)
|
|
359
|
+
if data:
|
|
360
|
+
session.update_activity()
|
|
361
|
+
return data
|
|
362
|
+
except Exception as e:
|
|
363
|
+
module_logger.error(f"Error reading from session {session_id}: {e}")
|
|
364
|
+
return None
|
|
365
|
+
return None
|
|
366
|
+
|
|
367
|
+
def get_executor_stats(self) -> Dict[str, Any]:
|
|
368
|
+
"""Get executor statistics."""
|
|
369
|
+
with self._lock:
|
|
370
|
+
active_count = len(self.active_sessions)
|
|
371
|
+
sessions_stats = [s.get_session_stats() for s in self.active_sessions.values()]
|
|
372
|
+
|
|
373
|
+
return {
|
|
374
|
+
'active_sessions': active_count,
|
|
375
|
+
'total_sessions_created': self.session_counter,
|
|
376
|
+
'base_executor_stats': self.base_executor.get_status(),
|
|
377
|
+
'sessions': sessions_stats
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
def cleanup(self) -> None:
|
|
381
|
+
"""Clean up all resources."""
|
|
382
|
+
module_logger.debug("Cleaning up InteractiveCommandExecutor")
|
|
383
|
+
|
|
384
|
+
# Terminate all sessions
|
|
385
|
+
self.terminate_all_sessions()
|
|
386
|
+
|
|
387
|
+
# Clean up base executor
|
|
388
|
+
self.base_executor.cleanup()
|
|
389
|
+
|
|
390
|
+
module_logger.debug("InteractiveCommandExecutor cleanup completed")
|
|
391
|
+
|
|
392
|
+
def __del__(self) -> None:
|
|
393
|
+
"""Destructor - cleanup when executor is destroyed."""
|
|
394
|
+
try:
|
|
395
|
+
self.cleanup()
|
|
396
|
+
except Exception:
|
|
397
|
+
pass
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
# Convenience functions for simple usage
|
|
401
|
+
def execute_interactive(
|
|
402
|
+
command: Union[str, List[str]],
|
|
403
|
+
cwd: Optional[str] = None,
|
|
404
|
+
env: Optional[Dict[str, str]] = None,
|
|
405
|
+
timeout: Optional[float] = None,
|
|
406
|
+
use_pty: Optional[bool] = None,
|
|
407
|
+
verbose: bool = False,
|
|
408
|
+
**kwargs
|
|
409
|
+
) -> InteractiveSession:
|
|
410
|
+
"""
|
|
411
|
+
Convenience function to execute a command interactively.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
command: Command to execute
|
|
415
|
+
cwd: Working directory
|
|
416
|
+
env: Environment variables
|
|
417
|
+
timeout: Session timeout
|
|
418
|
+
use_pty: Whether to use PTY
|
|
419
|
+
verbose: Whether to enable verbose logging
|
|
420
|
+
**kwargs: Additional arguments
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
InteractiveSession instance
|
|
424
|
+
"""
|
|
425
|
+
executor = InteractiveCommandExecutor(verbose=verbose)
|
|
426
|
+
|
|
427
|
+
try:
|
|
428
|
+
return executor.execute_interactive(
|
|
429
|
+
command=command,
|
|
430
|
+
cwd=cwd,
|
|
431
|
+
env=env,
|
|
432
|
+
timeout=timeout,
|
|
433
|
+
use_pty=use_pty,
|
|
434
|
+
**kwargs
|
|
435
|
+
)
|
|
436
|
+
except Exception:
|
|
437
|
+
executor.cleanup()
|
|
438
|
+
raise
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def create_interactive_shell(
|
|
442
|
+
shell_command: Optional[str] = None,
|
|
443
|
+
cwd: Optional[str] = None,
|
|
444
|
+
env: Optional[Dict[str, str]] = None,
|
|
445
|
+
timeout: Optional[float] = None,
|
|
446
|
+
**kwargs
|
|
447
|
+
) -> InteractiveSession:
|
|
448
|
+
"""
|
|
449
|
+
Create an interactive shell session.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
shell_command: Shell command to execute (auto-detect if None)
|
|
453
|
+
cwd: Working directory
|
|
454
|
+
env: Environment variables
|
|
455
|
+
timeout: Session timeout
|
|
456
|
+
**kwargs: Additional arguments
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
InteractiveSession instance
|
|
460
|
+
"""
|
|
461
|
+
if shell_command is None:
|
|
462
|
+
# Auto-detect shell
|
|
463
|
+
import platform
|
|
464
|
+
if platform.system() == "Windows":
|
|
465
|
+
shell_command = "cmd"
|
|
466
|
+
else:
|
|
467
|
+
shell_command = os.environ.get("SHELL", "/bin/bash")
|
|
468
|
+
|
|
469
|
+
return execute_interactive(
|
|
470
|
+
command=shell_command,
|
|
471
|
+
cwd=cwd,
|
|
472
|
+
env=env,
|
|
473
|
+
timeout=timeout,
|
|
474
|
+
use_pty=True, # Prefer PTY for shell
|
|
475
|
+
**kwargs
|
|
476
|
+
)
|