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
|
@@ -1,19 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MCP Tools Hub Module
|
|
3
|
+
|
|
4
|
+
This module provides the McpHub class for managing MCP server connections
|
|
5
|
+
and interactions. It handles server configuration, connection management,
|
|
6
|
+
and marketplace operations.
|
|
7
|
+
"""
|
|
8
|
+
|
|
1
9
|
import os
|
|
2
10
|
import json
|
|
3
11
|
import asyncio
|
|
4
|
-
import aiohttp
|
|
5
12
|
import importlib
|
|
6
13
|
import pkgutil
|
|
7
|
-
import re
|
|
8
|
-
import inspect
|
|
9
14
|
from datetime import datetime, timedelta
|
|
10
|
-
from typing import Dict, List, Optional, Any, Set,
|
|
15
|
+
from typing import Dict, List, Optional, Any, Set, Tuple
|
|
11
16
|
from pathlib import Path
|
|
12
17
|
from pydantic import BaseModel, Field
|
|
13
18
|
from loguru import logger
|
|
14
19
|
from contextlib import AsyncExitStack
|
|
15
|
-
|
|
16
|
-
from
|
|
20
|
+
|
|
21
|
+
from .types import (
|
|
22
|
+
McpTool, McpResource, McpResourceTemplate, McpServer,
|
|
23
|
+
MarketplaceMCPServerItem
|
|
24
|
+
)
|
|
17
25
|
|
|
18
26
|
try:
|
|
19
27
|
from mcp import ClientSession
|
|
@@ -27,49 +35,13 @@ except ImportError:
|
|
|
27
35
|
ClientSession = None
|
|
28
36
|
logger.error("mcp is not installed(which requires python>=3.11), please install it by `pip install mcp`")
|
|
29
37
|
|
|
30
|
-
class McpTool(BaseModel):
|
|
31
|
-
"""Represents an MCP tool configuration"""
|
|
32
|
-
|
|
33
|
-
name: str
|
|
34
|
-
description: Optional[str] = None
|
|
35
|
-
input_schema: dict = Field(default_factory=dict)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class McpResource(BaseModel):
|
|
39
|
-
"""Represents an MCP resource configuration"""
|
|
40
|
-
|
|
41
|
-
uri: str
|
|
42
|
-
name: str
|
|
43
|
-
description: Optional[str] = None
|
|
44
|
-
mime_type: Optional[str] = None
|
|
45
|
-
|
|
46
|
-
class McpResourceTemplate(BaseModel):
|
|
47
|
-
"""Represents an MCP resource template"""
|
|
48
|
-
|
|
49
|
-
uri_template: str
|
|
50
|
-
name: str
|
|
51
|
-
description: Optional[str] = None
|
|
52
|
-
mime_type: Optional[str] = None
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class McpServer(BaseModel):
|
|
56
|
-
"""Represents an MCP server configuration and status"""
|
|
57
|
-
|
|
58
|
-
name: str
|
|
59
|
-
config: str # JSON string of server config
|
|
60
|
-
status: str = "disconnected" # connected, disconnected, connecting
|
|
61
|
-
error: Optional[str] = None
|
|
62
|
-
tools: List[McpTool] = Field(default_factory=list)
|
|
63
|
-
resources: List[McpResource] = Field(default_factory=list)
|
|
64
|
-
resource_templates: List[McpResourceTemplate] = Field(default_factory=list)
|
|
65
|
-
|
|
66
38
|
|
|
67
39
|
class McpConnection:
|
|
68
40
|
"""Represents an active MCP server connection"""
|
|
69
41
|
|
|
70
|
-
def __init__(self, server: McpServer, session
|
|
42
|
+
def __init__(self, server: McpServer, session):
|
|
71
43
|
self.server = server
|
|
72
|
-
self.session = session
|
|
44
|
+
self.session = session
|
|
73
45
|
|
|
74
46
|
|
|
75
47
|
def _generate_server_configs() -> Tuple[Dict[str, Any], Dict[str, str]]:
|
|
@@ -127,7 +99,13 @@ class McpHub:
|
|
|
127
99
|
|
|
128
100
|
_instance = None
|
|
129
101
|
|
|
130
|
-
def __new__(cls, settings_path: Optional[str] = None):
|
|
102
|
+
def __new__(cls, settings_path: Optional[str] = None, marketplace_path: Optional[str] = None):
|
|
103
|
+
# For testing purposes, allow multiple instances with custom paths
|
|
104
|
+
if settings_path is not None or marketplace_path is not None:
|
|
105
|
+
instance = super(McpHub, cls).__new__(cls)
|
|
106
|
+
instance._initialized = False
|
|
107
|
+
return instance
|
|
108
|
+
|
|
131
109
|
if cls._instance is None:
|
|
132
110
|
cls._instance = super(McpHub, cls).__new__(cls)
|
|
133
111
|
cls._instance._initialized = False
|
|
@@ -178,7 +156,7 @@ class McpHub:
|
|
|
178
156
|
def _read_marketplace(self) -> Dict[str, List[Dict[str, Any]]]:
|
|
179
157
|
"""Read marketplace file"""
|
|
180
158
|
try:
|
|
181
|
-
with open(self.marketplace_path,"r", encoding="utf-8") as f:
|
|
159
|
+
with open(self.marketplace_path, "r", encoding="utf-8") as f:
|
|
182
160
|
return json.load(f)
|
|
183
161
|
except Exception as e:
|
|
184
162
|
logger.error(f"Failed to read marketplace: {e}")
|
|
@@ -216,7 +194,7 @@ class McpHub:
|
|
|
216
194
|
|
|
217
195
|
# Add the new item
|
|
218
196
|
data = self._read_marketplace()
|
|
219
|
-
data["mcpServers"].append(item.
|
|
197
|
+
data["mcpServers"].append(item.model_dump())
|
|
220
198
|
|
|
221
199
|
# Write back to file
|
|
222
200
|
with open(self.marketplace_path, "w", encoding="utf-8") as f:
|
|
@@ -341,12 +319,16 @@ class McpHub:
|
|
|
341
319
|
logger.error(f"Failed to apply marketplace item: {e}")
|
|
342
320
|
return False
|
|
343
321
|
|
|
344
|
-
async def add_server_config(self, name: str, config: Dict[str, Any]) ->
|
|
322
|
+
async def add_server_config(self, name: str, config: Dict[str, Any]) -> bool:
|
|
345
323
|
"""
|
|
346
324
|
Add or update MCP server configuration in settings file.
|
|
347
325
|
|
|
348
326
|
Args:
|
|
349
|
-
|
|
327
|
+
name: Name of the server
|
|
328
|
+
config: Server configuration dictionary
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
bool: True if successful, False otherwise
|
|
350
332
|
"""
|
|
351
333
|
settings = self._read_settings()
|
|
352
334
|
settings["mcpServers"][name] = config
|
|
@@ -410,12 +392,16 @@ class McpHub:
|
|
|
410
392
|
)
|
|
411
393
|
transport_config = config.get("transport", {
|
|
412
394
|
"type": "stdio",
|
|
413
|
-
"endpoint":""
|
|
395
|
+
"endpoint": ""
|
|
414
396
|
})
|
|
415
397
|
|
|
416
398
|
if transport_config["type"] not in ["stdio", "sse"]:
|
|
417
399
|
raise ValueError(f"Invalid transport type: {transport_config['type']}")
|
|
418
400
|
|
|
401
|
+
# Check if MCP is available
|
|
402
|
+
if stdio_client is None or sse_client is None or ClientSession is None:
|
|
403
|
+
raise RuntimeError("MCP is not installed or not available")
|
|
404
|
+
|
|
419
405
|
if transport_config["type"] == "stdio":
|
|
420
406
|
# Setup transport parameters
|
|
421
407
|
server_params = StdioServerParameters(
|
|
@@ -432,7 +418,6 @@ class McpHub:
|
|
|
432
418
|
url = transport_config["endpoint"]
|
|
433
419
|
transport = await exit_stack.enter_async_context(sse_client(url))
|
|
434
420
|
|
|
435
|
-
|
|
436
421
|
try:
|
|
437
422
|
stdio, write = transport
|
|
438
423
|
session = await exit_stack.enter_async_context(
|
|
@@ -455,11 +440,6 @@ class McpHub:
|
|
|
455
440
|
self.connections[name].server.error = error_msg
|
|
456
441
|
return server
|
|
457
442
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
443
|
async def delete_connection(self, name: str) -> None:
|
|
464
444
|
"""
|
|
465
445
|
Close and remove a server connection with proper cleanup
|
|
@@ -477,7 +457,6 @@ class McpHub:
|
|
|
477
457
|
del self.exit_stacks[name]
|
|
478
458
|
except Exception as e:
|
|
479
459
|
logger.error(f"Error cleaning up to {name}: {e}")
|
|
480
|
-
|
|
481
460
|
|
|
482
461
|
async def refresh_server_connection(self, name: str) -> None:
|
|
483
462
|
"""
|
|
@@ -577,14 +556,9 @@ class McpHub:
|
|
|
577
556
|
if not connection:
|
|
578
557
|
return []
|
|
579
558
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
# method="ping",
|
|
584
|
-
# )
|
|
585
|
-
# ),
|
|
586
|
-
# types.EmptyResult,
|
|
587
|
-
# )
|
|
559
|
+
if mcp_types is None:
|
|
560
|
+
logger.warning("MCP types not available")
|
|
561
|
+
return []
|
|
588
562
|
|
|
589
563
|
response = await connection.session.send_request(
|
|
590
564
|
mcp_types.ClientRequest(mcp_types.ListResourceTemplatesRequest(
|
|
@@ -617,7 +591,7 @@ class McpHub:
|
|
|
617
591
|
|
|
618
592
|
async def call_tool(
|
|
619
593
|
self, server_name: str, tool_name: str, tool_arguments: Optional[Dict] = None
|
|
620
|
-
)
|
|
594
|
+
):
|
|
621
595
|
"""
|
|
622
596
|
Call an MCP tool with arguments
|
|
623
597
|
"""
|
|
@@ -627,7 +601,7 @@ class McpHub:
|
|
|
627
601
|
|
|
628
602
|
return await connection.session.call_tool(tool_name, tool_arguments or {})
|
|
629
603
|
|
|
630
|
-
async def read_resource(self, server_name: str, uri: str)
|
|
604
|
+
async def read_resource(self, server_name: str, uri: str):
|
|
631
605
|
"""
|
|
632
606
|
Read an MCP resource
|
|
633
607
|
"""
|
|
@@ -649,4 +623,4 @@ class McpHub:
|
|
|
649
623
|
"""
|
|
650
624
|
Get all available server templates as JSON strings
|
|
651
625
|
"""
|
|
652
|
-
return MCP_SERVER_TEMPLATES
|
|
626
|
+
return MCP_SERVER_TEMPLATES
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MCP Tools Installer Module
|
|
3
|
+
|
|
4
|
+
This module provides the McpServerInstaller class for installing and
|
|
5
|
+
configuring MCP servers. It handles both built-in and external servers.
|
|
6
|
+
"""
|
|
7
|
+
|
|
1
8
|
import json
|
|
2
9
|
import sys
|
|
3
10
|
import os
|
|
4
11
|
import time
|
|
5
12
|
from typing import Dict, Any, Tuple, List
|
|
6
13
|
from loguru import logger
|
|
7
|
-
import asyncio
|
|
8
14
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
15
|
+
from .hub import McpHub, MCP_BUILD_IN_SERVERS
|
|
16
|
+
from .types import (
|
|
17
|
+
McpResponse, McpInstallRequest, InstallResult, ServerConfig,
|
|
18
|
+
McpExternalServer, MarketplaceMCPServerItem
|
|
19
|
+
)
|
|
11
20
|
from autocoder.chat_auto_coder_lang import get_message_with_format
|
|
12
21
|
|
|
13
22
|
|
|
@@ -130,7 +139,6 @@ class McpServerInstaller:
|
|
|
130
139
|
for s in external_servers:
|
|
131
140
|
if s.name == name:
|
|
132
141
|
if s.runtime == "python":
|
|
133
|
-
# self.install_python_package(name)
|
|
134
142
|
template_config = {
|
|
135
143
|
"command": "python",
|
|
136
144
|
"args": [
|
|
@@ -138,7 +146,6 @@ class McpServerInstaller:
|
|
|
138
146
|
],
|
|
139
147
|
}
|
|
140
148
|
elif s.runtime == "node":
|
|
141
|
-
# self.install_node_package(name)
|
|
142
149
|
template_config = {
|
|
143
150
|
"command": "npx",
|
|
144
151
|
"args": [
|
|
@@ -155,14 +162,6 @@ class McpServerInstaller:
|
|
|
155
162
|
if not config.get("args") and (name.startswith("@") or config.get("command") in ["npx", "npm"]):
|
|
156
163
|
config["args"] = ["-y", "-g", name]
|
|
157
164
|
|
|
158
|
-
## 如果有模板,则无需再次安装,处理模板的时候会自动安装
|
|
159
|
-
# if not template_config:
|
|
160
|
-
# # Install package if needed
|
|
161
|
-
# if name.startswith("@") or config.get("command") in ["npx", "npm"]:
|
|
162
|
-
# self.install_node_package(name)
|
|
163
|
-
# else:
|
|
164
|
-
# self.install_python_package(name)
|
|
165
|
-
|
|
166
165
|
return name, config
|
|
167
166
|
|
|
168
167
|
def parse_json_config(self, server_name_or_config: str) -> Tuple[str, Dict[str, Any]]:
|
|
@@ -175,16 +174,10 @@ class McpServerInstaller:
|
|
|
175
174
|
# 取第一个server 配置
|
|
176
175
|
config = list(raw_config.values())[0]
|
|
177
176
|
name = list(raw_config.keys())[0]
|
|
178
|
-
# if name.startswith("@") or config["command"] in ["npx", "npm"]:
|
|
179
|
-
# for item in config["args"]:
|
|
180
|
-
# if name in item:
|
|
181
|
-
# self.install_node_package(item)
|
|
182
|
-
# else:
|
|
183
|
-
# self.install_python_package(name)
|
|
184
177
|
|
|
185
178
|
return name, config
|
|
186
179
|
|
|
187
|
-
def process_market_install_item(self, market_item) -> Tuple[str, Dict[str, Any]]:
|
|
180
|
+
def process_market_install_item(self, market_item: MarketplaceMCPServerItem) -> Tuple[str, Dict[str, Any]]:
|
|
188
181
|
"""Process a MarketplaceMCPServerItem into name and config"""
|
|
189
182
|
name = market_item.name
|
|
190
183
|
config = {
|
|
@@ -192,14 +185,6 @@ class McpServerInstaller:
|
|
|
192
185
|
"args": market_item.args,
|
|
193
186
|
"env": market_item.env
|
|
194
187
|
}
|
|
195
|
-
|
|
196
|
-
# Install package if needed
|
|
197
|
-
# if name.startswith("@") or market_item.command in ["npx", "npm"]:
|
|
198
|
-
# for item in market_item.args:
|
|
199
|
-
# if name in item:
|
|
200
|
-
# self.install_node_package(item)
|
|
201
|
-
# elif market_item.command not in ["python", "node"]:
|
|
202
|
-
# self.install_python_package(name)
|
|
203
188
|
|
|
204
189
|
return name, config
|
|
205
190
|
|
|
@@ -215,6 +200,9 @@ class McpServerInstaller:
|
|
|
215
200
|
display_result = request.market_install_item.name
|
|
216
201
|
else:
|
|
217
202
|
server_name_or_config = request.server_name_or_config
|
|
203
|
+
if server_name_or_config is None:
|
|
204
|
+
raise ValueError("server_name_or_config is required")
|
|
205
|
+
|
|
218
206
|
display_result = server_name_or_config
|
|
219
207
|
|
|
220
208
|
# Try different parsing methods
|
|
@@ -1,64 +1,145 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MCP Tools Server Module
|
|
3
|
+
|
|
4
|
+
This module provides the McpServer class for handling MCP server operations
|
|
5
|
+
in a thread-safe manner. It manages requests and responses through async queues.
|
|
6
|
+
"""
|
|
7
|
+
|
|
1
8
|
import asyncio
|
|
2
9
|
from asyncio import Queue as AsyncQueue
|
|
3
10
|
import threading
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import
|
|
11
|
+
import signal
|
|
12
|
+
import atexit
|
|
13
|
+
from typing import Union
|
|
7
14
|
from loguru import logger
|
|
8
|
-
import json
|
|
9
15
|
|
|
10
|
-
from
|
|
11
|
-
from
|
|
16
|
+
from .hub import McpHub, MCP_BUILD_IN_SERVERS
|
|
17
|
+
from .executor import McpExecutor
|
|
18
|
+
from .installer import McpServerInstaller
|
|
19
|
+
from .types import (
|
|
20
|
+
McpRequest, McpInstallRequest, McpRemoveRequest, McpListRequest,
|
|
21
|
+
McpListRunningRequest, McpRefreshRequest, McpServerInfoRequest,
|
|
22
|
+
McpResponse, ServerInfo, InstallResult, RemoveResult, ListResult,
|
|
23
|
+
ListRunningResult, RefreshResult, QueryResult, ErrorResult,
|
|
24
|
+
StringResult, MarketplaceAddRequest, MarketplaceAddResult,
|
|
25
|
+
MarketplaceUpdateRequest, MarketplaceUpdateResult, MarketplaceMCPServerItem
|
|
26
|
+
)
|
|
12
27
|
from autocoder.utils.llms import get_single_llm
|
|
13
28
|
from autocoder.chat_auto_coder_lang import get_message_with_format
|
|
14
|
-
|
|
15
|
-
McpRequest, McpInstallRequest, McpRemoveRequest, McpListRequest,
|
|
16
|
-
McpListRunningRequest, McpRefreshRequest, McpServerInfoRequest,
|
|
17
|
-
McpResponse, ServerInfo, InstallResult, RemoveResult, ListResult,
|
|
18
|
-
ListRunningResult, RefreshResult, QueryResult, ErrorResult, ServerConfig,StringResult,
|
|
19
|
-
ExternalServerInfo, McpExternalServer, MarketplaceAddRequest, MarketplaceAddResult,
|
|
20
|
-
MarketplaceUpdateRequest, MarketplaceUpdateResult
|
|
21
|
-
)
|
|
22
|
-
from autocoder.common.mcp_server_install import McpServerInstaller
|
|
29
|
+
|
|
23
30
|
|
|
24
31
|
class McpServer:
|
|
32
|
+
"""
|
|
33
|
+
MCP Server handling class that manages MCP operations in a thread-safe manner.
|
|
34
|
+
|
|
35
|
+
This class provides an async interface for MCP operations while maintaining
|
|
36
|
+
thread safety through proper queue management.
|
|
37
|
+
"""
|
|
38
|
+
|
|
25
39
|
def __init__(self):
|
|
26
40
|
self._request_queue = AsyncQueue()
|
|
27
41
|
self._response_queue = AsyncQueue()
|
|
28
42
|
self._running = False
|
|
29
43
|
self._task = None
|
|
30
44
|
self._loop = None
|
|
45
|
+
self._thread = None
|
|
31
46
|
self._installer = McpServerInstaller()
|
|
47
|
+
self._shutdown_event = threading.Event()
|
|
32
48
|
|
|
33
49
|
def start(self):
|
|
50
|
+
"""Start the MCP server in a separate thread"""
|
|
34
51
|
if self._running:
|
|
35
52
|
return
|
|
36
53
|
|
|
37
54
|
self._running = True
|
|
55
|
+
self._shutdown_event.clear()
|
|
38
56
|
self._loop = asyncio.new_event_loop()
|
|
39
|
-
threading.Thread(target=self._run_event_loop, daemon=True)
|
|
57
|
+
self._thread = threading.Thread(target=self._run_event_loop, daemon=True)
|
|
58
|
+
self._thread.start()
|
|
40
59
|
|
|
41
60
|
def stop(self):
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
61
|
+
"""Stop the MCP server"""
|
|
62
|
+
if not self._running:
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
self._running = False
|
|
66
|
+
self._shutdown_event.set()
|
|
67
|
+
|
|
68
|
+
if self._loop and self._loop.is_running():
|
|
69
|
+
# Cancel the task gracefully
|
|
70
|
+
if self._task and not self._task.done():
|
|
71
|
+
self._loop.call_soon_threadsafe(self._task.cancel)
|
|
72
|
+
|
|
73
|
+
# Send None to break the request processing loop
|
|
74
|
+
try:
|
|
75
|
+
future = asyncio.run_coroutine_threadsafe(
|
|
76
|
+
self._request_queue.put(None), self._loop
|
|
77
|
+
)
|
|
78
|
+
future.result(timeout=1.0)
|
|
79
|
+
except Exception:
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
# Stop the event loop
|
|
83
|
+
self._loop.call_soon_threadsafe(self._loop.stop)
|
|
84
|
+
|
|
85
|
+
# Wait for thread to finish
|
|
86
|
+
if self._thread and self._thread.is_alive():
|
|
87
|
+
self._thread.join(timeout=2.0)
|
|
88
|
+
if self._thread.is_alive():
|
|
89
|
+
logger.warning("MCP server thread did not stop gracefully")
|
|
47
90
|
|
|
48
91
|
def _run_event_loop(self):
|
|
92
|
+
"""Run the event loop in the dedicated thread"""
|
|
93
|
+
if self._loop is None:
|
|
94
|
+
return
|
|
95
|
+
|
|
49
96
|
asyncio.set_event_loop(self._loop)
|
|
50
|
-
|
|
51
|
-
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
self._task = self._loop.create_task(self._process_request())
|
|
100
|
+
self._loop.run_forever()
|
|
101
|
+
except KeyboardInterrupt:
|
|
102
|
+
logger.info("KeyboardInterrupt received in MCP server event loop")
|
|
103
|
+
except Exception as e:
|
|
104
|
+
logger.error(f"Error in MCP server event loop: {e}")
|
|
105
|
+
finally:
|
|
106
|
+
# Clean up
|
|
107
|
+
if self._task and not self._task.done():
|
|
108
|
+
self._task.cancel()
|
|
109
|
+
try:
|
|
110
|
+
self._loop.run_until_complete(self._task)
|
|
111
|
+
except asyncio.CancelledError:
|
|
112
|
+
pass
|
|
113
|
+
|
|
114
|
+
# Close the loop
|
|
115
|
+
try:
|
|
116
|
+
self._loop.close()
|
|
117
|
+
except Exception as e:
|
|
118
|
+
logger.error(f"Error closing event loop: {e}")
|
|
52
119
|
|
|
53
120
|
async def _process_request(self):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
121
|
+
"""
|
|
122
|
+
Process incoming requests and generate responses
|
|
123
|
+
"""
|
|
124
|
+
hub = McpHub()
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
# May block if there are abnormal contents in mcp settings.json
|
|
128
|
+
await hub.initialize()
|
|
129
|
+
except Exception as e:
|
|
130
|
+
logger.error(f"Failed to initialize MCP hub: {e}")
|
|
131
|
+
return
|
|
58
132
|
|
|
59
133
|
while self._running:
|
|
60
|
-
try:
|
|
61
|
-
|
|
134
|
+
try:
|
|
135
|
+
# Use timeout to allow checking _running flag
|
|
136
|
+
try:
|
|
137
|
+
request = await asyncio.wait_for(
|
|
138
|
+
self._request_queue.get(), timeout=1.0
|
|
139
|
+
)
|
|
140
|
+
except asyncio.TimeoutError:
|
|
141
|
+
continue
|
|
142
|
+
|
|
62
143
|
if request is None:
|
|
63
144
|
break
|
|
64
145
|
|
|
@@ -89,14 +170,14 @@ class McpServer:
|
|
|
89
170
|
|
|
90
171
|
elif isinstance(request, McpListRequest):
|
|
91
172
|
try:
|
|
92
|
-
# Get built-in servers
|
|
173
|
+
# Get built-in servers
|
|
93
174
|
builtin_servers = []
|
|
94
175
|
for name, config in MCP_BUILD_IN_SERVERS.items():
|
|
95
176
|
marketplace_item = MarketplaceMCPServerItem(
|
|
96
177
|
name=name,
|
|
97
178
|
description=f"Built-in: {name}",
|
|
98
179
|
mcp_type="command",
|
|
99
|
-
command=config.get("command"
|
|
180
|
+
command=config.get("command") or "",
|
|
100
181
|
args=config.get("args", []),
|
|
101
182
|
env=config.get("env", {})
|
|
102
183
|
)
|
|
@@ -156,10 +237,15 @@ class McpServer:
|
|
|
156
237
|
|
|
157
238
|
elif isinstance(request, McpServerInfoRequest):
|
|
158
239
|
try:
|
|
159
|
-
llm = get_single_llm(request.model, product_mode=request.product_mode)
|
|
240
|
+
llm = get_single_llm(request.model, product_mode=request.product_mode or "lite")
|
|
241
|
+
if llm is None:
|
|
242
|
+
raise ValueError("Failed to get LLM instance")
|
|
160
243
|
mcp_executor = McpExecutor(hub, llm)
|
|
161
244
|
result = mcp_executor.get_connected_servers_info()
|
|
162
|
-
await self._response_queue.put(McpResponse(
|
|
245
|
+
await self._response_queue.put(McpResponse(
|
|
246
|
+
result=result,
|
|
247
|
+
raw_result=StringResult(result=result)
|
|
248
|
+
))
|
|
163
249
|
except Exception as e:
|
|
164
250
|
import traceback
|
|
165
251
|
traceback.print_exc()
|
|
@@ -172,8 +258,7 @@ class McpServer:
|
|
|
172
258
|
elif isinstance(request, McpListRunningRequest):
|
|
173
259
|
try:
|
|
174
260
|
servers = hub.get_servers()
|
|
175
|
-
running_servers = "\n".join(
|
|
176
|
-
[f"- {server.name}" for server in servers])
|
|
261
|
+
running_servers = "\n".join([f"- {server.name}" for server in servers])
|
|
177
262
|
result = running_servers if running_servers else ""
|
|
178
263
|
await self._response_queue.put(McpResponse(
|
|
179
264
|
result=result,
|
|
@@ -219,7 +304,7 @@ class McpServer:
|
|
|
219
304
|
name=request.name,
|
|
220
305
|
description=request.description,
|
|
221
306
|
mcp_type=request.mcp_type,
|
|
222
|
-
command=request.command,
|
|
307
|
+
command=request.command or "",
|
|
223
308
|
args=request.args or [],
|
|
224
309
|
env=request.env or {},
|
|
225
310
|
url=request.url or ""
|
|
@@ -264,7 +349,7 @@ class McpServer:
|
|
|
264
349
|
name=request.name,
|
|
265
350
|
description=request.description,
|
|
266
351
|
mcp_type=request.mcp_type,
|
|
267
|
-
command=request.command,
|
|
352
|
+
command=request.command or "",
|
|
268
353
|
args=request.args or [],
|
|
269
354
|
env=request.env or {},
|
|
270
355
|
url=request.url or ""
|
|
@@ -303,6 +388,7 @@ class McpServer:
|
|
|
303
388
|
))
|
|
304
389
|
|
|
305
390
|
else:
|
|
391
|
+
# Handle general MCP requests
|
|
306
392
|
if not request.query.strip():
|
|
307
393
|
await self._response_queue.put(McpResponse(
|
|
308
394
|
result="",
|
|
@@ -316,8 +402,7 @@ class McpServer:
|
|
|
316
402
|
|
|
317
403
|
llm = get_single_llm(request.model, product_mode=request.product_mode)
|
|
318
404
|
mcp_executor = McpExecutor(hub, llm)
|
|
319
|
-
conversations = [
|
|
320
|
-
{"role": "user", "content": request.query}]
|
|
405
|
+
conversations = [{"role": "user", "content": request.query}]
|
|
321
406
|
_, results = await mcp_executor.run(conversations)
|
|
322
407
|
|
|
323
408
|
if not results:
|
|
@@ -339,20 +424,53 @@ class McpServer:
|
|
|
339
424
|
results=results
|
|
340
425
|
)
|
|
341
426
|
))
|
|
427
|
+
except asyncio.CancelledError:
|
|
428
|
+
logger.info("MCP request processing was cancelled")
|
|
429
|
+
break
|
|
342
430
|
except Exception as e:
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
431
|
+
logger.error(f"Error in MCP request processing: {e}")
|
|
432
|
+
try:
|
|
433
|
+
await self._response_queue.put(McpResponse(
|
|
434
|
+
result="",
|
|
435
|
+
error=get_message_with_format("mcp_error_title") + ": " + str(e),
|
|
436
|
+
raw_result=ErrorResult(error=str(e))
|
|
437
|
+
))
|
|
438
|
+
except Exception:
|
|
439
|
+
pass
|
|
440
|
+
|
|
441
|
+
# Clean up hub connections
|
|
442
|
+
try:
|
|
443
|
+
await hub.shutdown()
|
|
444
|
+
except Exception as e:
|
|
445
|
+
logger.error(f"Error shutting down MCP hub: {e}")
|
|
348
446
|
|
|
349
|
-
def send_request(self, request: McpRequest) -> McpResponse:
|
|
447
|
+
def send_request(self, request: Union[McpRequest, McpServerInfoRequest]) -> McpResponse:
|
|
448
|
+
"""
|
|
449
|
+
Send a request to the MCP server and wait for response
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
request: The request to send
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
McpResponse: The response from the server
|
|
456
|
+
"""
|
|
457
|
+
if not self._running:
|
|
458
|
+
self.start()
|
|
459
|
+
|
|
350
460
|
async def _send():
|
|
351
461
|
await self._request_queue.put(request)
|
|
352
462
|
return await self._response_queue.get()
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
463
|
+
|
|
464
|
+
if self._loop is None:
|
|
465
|
+
return McpResponse(result="", error="Event loop not available")
|
|
466
|
+
|
|
467
|
+
try:
|
|
468
|
+
future = asyncio.run_coroutine_threadsafe(_send(), self._loop)
|
|
469
|
+
return future.result(timeout=30.0) # Add timeout to prevent hanging
|
|
470
|
+
except asyncio.TimeoutError:
|
|
471
|
+
return McpResponse(result="", error="Request timeout")
|
|
472
|
+
except Exception as e:
|
|
473
|
+
return McpResponse(result="", error=f"Request failed: {str(e)}")
|
|
356
474
|
|
|
357
475
|
|
|
358
476
|
# Global MCP server instance
|
|
@@ -360,10 +478,20 @@ _mcp_server = None
|
|
|
360
478
|
|
|
361
479
|
|
|
362
480
|
def get_mcp_server():
|
|
481
|
+
"""Get the global MCP server instance"""
|
|
363
482
|
global _mcp_server
|
|
364
483
|
if _mcp_server is None:
|
|
365
484
|
_mcp_server = McpServer()
|
|
366
485
|
_mcp_server.start()
|
|
486
|
+
# Register cleanup function
|
|
487
|
+
atexit.register(_cleanup_mcp_server)
|
|
367
488
|
return _mcp_server
|
|
368
489
|
|
|
369
490
|
|
|
491
|
+
def _cleanup_mcp_server():
|
|
492
|
+
"""Clean up the global MCP server instance"""
|
|
493
|
+
global _mcp_server
|
|
494
|
+
if _mcp_server is not None:
|
|
495
|
+
logger.info("Cleaning up MCP server...")
|
|
496
|
+
_mcp_server.stop()
|
|
497
|
+
_mcp_server = None
|