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,172 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Tool Caller Integration Test
|
|
4
|
+
|
|
5
|
+
验证 ToolCaller 与 AgenticEdit 的集成是否正常工作。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
# 添加项目根目录到 Python 路径
|
|
12
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../../../../..'))
|
|
13
|
+
|
|
14
|
+
from unittest.mock import Mock
|
|
15
|
+
from autocoder.common import AutoCoderArgs
|
|
16
|
+
from autocoder.common.v2.agent.agentic_edit_types import ExecuteCommandTool, ToolResult
|
|
17
|
+
from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
|
|
18
|
+
from autocoder.common.v2.agent.tool_caller import ToolCaller
|
|
19
|
+
from autocoder.common.v2.agent.tool_caller.plugins.examples import LoggingPlugin, SecurityFilterPlugin
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestToolResolver(BaseToolResolver):
|
|
23
|
+
"""测试用的工具解析器"""
|
|
24
|
+
|
|
25
|
+
def resolve(self) -> ToolResult:
|
|
26
|
+
if isinstance(self.tool, ExecuteCommandTool):
|
|
27
|
+
return ToolResult(
|
|
28
|
+
success=True,
|
|
29
|
+
message=f"Test: Command '{self.tool.command}' executed",
|
|
30
|
+
content={"output": f"Mock output for: {self.tool.command}"}
|
|
31
|
+
)
|
|
32
|
+
else:
|
|
33
|
+
return ToolResult(
|
|
34
|
+
success=False,
|
|
35
|
+
message=f"Test: Unsupported tool type {type(self.tool).__name__}"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_tool_caller_basic():
|
|
40
|
+
"""测试 ToolCaller 基本功能"""
|
|
41
|
+
print("Testing ToolCaller basic functionality...")
|
|
42
|
+
|
|
43
|
+
# 创建工具解析器映射
|
|
44
|
+
tool_resolver_map = {
|
|
45
|
+
ExecuteCommandTool: TestToolResolver
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# 创建 ToolCaller
|
|
49
|
+
args = AutoCoderArgs(source_dir=".")
|
|
50
|
+
tool_caller = ToolCaller(
|
|
51
|
+
tool_resolver_map=tool_resolver_map,
|
|
52
|
+
args=args,
|
|
53
|
+
enable_plugins=True
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# 测试工具调用
|
|
57
|
+
tool = ExecuteCommandTool(command="echo 'test'", requires_approval=False)
|
|
58
|
+
result = tool_caller.call_tool(tool)
|
|
59
|
+
|
|
60
|
+
assert result.success, f"Tool call failed: {result.message}"
|
|
61
|
+
print("✓ Basic tool calling works")
|
|
62
|
+
|
|
63
|
+
return tool_caller
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_plugin_system(tool_caller):
|
|
67
|
+
"""测试插件系统"""
|
|
68
|
+
print("Testing plugin system...")
|
|
69
|
+
|
|
70
|
+
# 注册插件
|
|
71
|
+
logging_plugin = LoggingPlugin(enabled=True)
|
|
72
|
+
security_plugin = SecurityFilterPlugin(enabled=True)
|
|
73
|
+
|
|
74
|
+
assert tool_caller.register_plugin(logging_plugin), "Failed to register logging plugin"
|
|
75
|
+
assert tool_caller.register_plugin(security_plugin), "Failed to register security plugin"
|
|
76
|
+
print("✓ Plugin registration works")
|
|
77
|
+
|
|
78
|
+
# 检查插件状态
|
|
79
|
+
status = tool_caller.get_plugin_status()
|
|
80
|
+
assert status["total_plugins"] == 2, f"Expected 2 plugins, got {status['total_plugins']}"
|
|
81
|
+
assert status["enabled_plugins"] == 2, f"Expected 2 enabled plugins, got {status['enabled_plugins']}"
|
|
82
|
+
print("✓ Plugin status reporting works")
|
|
83
|
+
|
|
84
|
+
# 测试插件功能
|
|
85
|
+
safe_tool = ExecuteCommandTool(command="echo 'safe'", requires_approval=False)
|
|
86
|
+
result = tool_caller.call_tool(safe_tool)
|
|
87
|
+
assert result.success, "Safe tool call failed"
|
|
88
|
+
print("✓ Safe tool call with plugins works")
|
|
89
|
+
|
|
90
|
+
# 测试安全过滤
|
|
91
|
+
dangerous_tool = ExecuteCommandTool(command="rm -rf /", requires_approval=False)
|
|
92
|
+
result = tool_caller.call_tool(dangerous_tool)
|
|
93
|
+
assert result.success, "Dangerous tool should be blocked but return success"
|
|
94
|
+
print("✓ Security filtering works")
|
|
95
|
+
|
|
96
|
+
# 检查统计
|
|
97
|
+
log_stats = logging_plugin.get_statistics()
|
|
98
|
+
assert log_stats["total_logged_calls"] > 0, "No calls logged"
|
|
99
|
+
print("✓ Logging plugin statistics work")
|
|
100
|
+
|
|
101
|
+
filter_stats = security_plugin.get_filter_statistics()
|
|
102
|
+
assert filter_stats["blocked_count"] > 0, "No dangerous commands blocked"
|
|
103
|
+
print("✓ Security filter statistics work")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_integration_with_mock_agent():
|
|
107
|
+
"""测试与模拟代理的集成"""
|
|
108
|
+
print("Testing integration with mock agent...")
|
|
109
|
+
|
|
110
|
+
# 创建模拟代理
|
|
111
|
+
mock_agent = Mock()
|
|
112
|
+
|
|
113
|
+
# 创建工具解析器映射
|
|
114
|
+
tool_resolver_map = {
|
|
115
|
+
ExecuteCommandTool: TestToolResolver
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# 创建 ToolCaller
|
|
119
|
+
args = AutoCoderArgs(source_dir=".")
|
|
120
|
+
tool_caller = ToolCaller(
|
|
121
|
+
tool_resolver_map=tool_resolver_map,
|
|
122
|
+
agent=mock_agent,
|
|
123
|
+
args=args,
|
|
124
|
+
enable_plugins=True
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# 测试工具调用
|
|
128
|
+
tool = ExecuteCommandTool(command="echo 'integration test'", requires_approval=False)
|
|
129
|
+
result = tool_caller.call_tool(tool)
|
|
130
|
+
|
|
131
|
+
assert result.success, f"Integration test failed: {result.message}"
|
|
132
|
+
print("✓ Integration with mock agent works")
|
|
133
|
+
|
|
134
|
+
# 测试统计信息
|
|
135
|
+
stats = tool_caller.get_stats()
|
|
136
|
+
assert stats["total_calls"] > 0, "No calls recorded"
|
|
137
|
+
assert stats["success_rate"] == 1.0, f"Expected 100% success rate, got {stats['success_rate']}"
|
|
138
|
+
print("✓ Statistics collection works")
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def main():
|
|
142
|
+
"""主测试函数"""
|
|
143
|
+
print("=" * 60)
|
|
144
|
+
print("Tool Caller Integration Test")
|
|
145
|
+
print("=" * 60)
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
# 基本功能测试
|
|
149
|
+
tool_caller = test_tool_caller_basic()
|
|
150
|
+
|
|
151
|
+
# 插件系统测试
|
|
152
|
+
test_plugin_system(tool_caller)
|
|
153
|
+
|
|
154
|
+
# 集成测试
|
|
155
|
+
test_integration_with_mock_agent()
|
|
156
|
+
|
|
157
|
+
print("\n" + "=" * 60)
|
|
158
|
+
print("✓ All integration tests passed!")
|
|
159
|
+
print("=" * 60)
|
|
160
|
+
|
|
161
|
+
return True
|
|
162
|
+
|
|
163
|
+
except Exception as e:
|
|
164
|
+
print(f"\n✗ Integration test failed: {e}")
|
|
165
|
+
import traceback
|
|
166
|
+
traceback.print_exc()
|
|
167
|
+
return False
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if __name__ == "__main__":
|
|
171
|
+
success = main()
|
|
172
|
+
sys.exit(0 if success else 1)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tool Call Plugins
|
|
3
|
+
|
|
4
|
+
工具调用插件系统,提供插件接口和基础实现。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .plugin_interface import ToolCallPlugin, PluginPriority
|
|
8
|
+
from .base_plugin import BaseToolCallPlugin
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"ToolCallPlugin",
|
|
12
|
+
"BaseToolCallPlugin",
|
|
13
|
+
"PluginPriority"
|
|
14
|
+
]
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base Tool Call Plugin
|
|
3
|
+
|
|
4
|
+
提供工具调用插件的基础实现。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict, Optional, TYPE_CHECKING
|
|
8
|
+
from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult
|
|
9
|
+
from .plugin_interface import ToolCallPlugin, PluginPriority
|
|
10
|
+
from loguru import logger
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from autocoder.common.v2.agent.agentic_edit import AgenticEdit
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseToolCallPlugin(ToolCallPlugin):
|
|
17
|
+
"""
|
|
18
|
+
工具调用插件基础实现类
|
|
19
|
+
|
|
20
|
+
提供常见功能的默认实现,插件开发者可以继承此类。
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, enabled: bool = True):
|
|
24
|
+
"""
|
|
25
|
+
初始化插件
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
enabled: 插件是否启用
|
|
29
|
+
"""
|
|
30
|
+
self._enabled = enabled
|
|
31
|
+
self._config = {}
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def enabled(self) -> bool:
|
|
35
|
+
"""插件是否启用"""
|
|
36
|
+
return self._enabled
|
|
37
|
+
|
|
38
|
+
def set_enabled(self, enabled: bool) -> None:
|
|
39
|
+
"""设置插件启用状态"""
|
|
40
|
+
self._enabled = enabled
|
|
41
|
+
|
|
42
|
+
def set_config(self, config: Dict[str, Any]) -> None:
|
|
43
|
+
"""设置插件配置"""
|
|
44
|
+
self._config = config
|
|
45
|
+
|
|
46
|
+
def get_config(self, key: str, default: Any = None) -> Any:
|
|
47
|
+
"""获取配置项"""
|
|
48
|
+
return self._config.get(key, default)
|
|
49
|
+
|
|
50
|
+
def log_info(self, message: str) -> None:
|
|
51
|
+
"""记录信息日志"""
|
|
52
|
+
logger.info(f"[{self.name}] {message}")
|
|
53
|
+
|
|
54
|
+
def log_warning(self, message: str) -> None:
|
|
55
|
+
"""记录警告日志"""
|
|
56
|
+
logger.warning(f"[{self.name}] {message}")
|
|
57
|
+
|
|
58
|
+
def log_error(self, message: str) -> None:
|
|
59
|
+
"""记录错误日志"""
|
|
60
|
+
logger.error(f"[{self.name}] {message}")
|
|
61
|
+
|
|
62
|
+
def create_context(self, **kwargs) -> Dict[str, Any]:
|
|
63
|
+
"""创建上下文信息"""
|
|
64
|
+
context = {
|
|
65
|
+
"plugin_name": self.name,
|
|
66
|
+
"plugin_priority": self.priority.value,
|
|
67
|
+
"timestamp": __import__("time").time()
|
|
68
|
+
}
|
|
69
|
+
context.update(kwargs)
|
|
70
|
+
return context
|
|
71
|
+
|
|
72
|
+
def should_process_tool(self, tool: BaseTool, agent: Optional['AgenticEdit']) -> bool:
|
|
73
|
+
"""
|
|
74
|
+
判断是否应该处理这个工具
|
|
75
|
+
|
|
76
|
+
默认实现:只有当插件启用时才处理
|
|
77
|
+
"""
|
|
78
|
+
return self.enabled
|
|
79
|
+
|
|
80
|
+
def before_tool_execution(
|
|
81
|
+
self,
|
|
82
|
+
tool: BaseTool,
|
|
83
|
+
agent: Optional['AgenticEdit'],
|
|
84
|
+
context: Optional[Dict[str, Any]] = None
|
|
85
|
+
) -> BaseTool:
|
|
86
|
+
"""
|
|
87
|
+
工具执行前的处理
|
|
88
|
+
|
|
89
|
+
默认实现:记录日志并返回原始工具
|
|
90
|
+
"""
|
|
91
|
+
if self.enabled:
|
|
92
|
+
self.log_info(f"Before execution of {type(tool).__name__}")
|
|
93
|
+
return tool
|
|
94
|
+
|
|
95
|
+
def after_tool_execution(
|
|
96
|
+
self,
|
|
97
|
+
tool: BaseTool,
|
|
98
|
+
tool_result: ToolResult,
|
|
99
|
+
agent: Optional['AgenticEdit'],
|
|
100
|
+
context: Optional[Dict[str, Any]] = None
|
|
101
|
+
) -> ToolResult:
|
|
102
|
+
"""
|
|
103
|
+
工具执行后的处理
|
|
104
|
+
|
|
105
|
+
默认实现:记录日志并返回原始结果
|
|
106
|
+
"""
|
|
107
|
+
if self.enabled:
|
|
108
|
+
success_str = "successfully" if tool_result.success else "with error"
|
|
109
|
+
self.log_info(f"After execution of {type(tool).__name__} {success_str}")
|
|
110
|
+
return tool_result
|
|
111
|
+
|
|
112
|
+
def on_tool_error(
|
|
113
|
+
self,
|
|
114
|
+
tool: BaseTool,
|
|
115
|
+
error: Exception,
|
|
116
|
+
agent: Optional['AgenticEdit'],
|
|
117
|
+
context: Optional[Dict[str, Any]] = None
|
|
118
|
+
) -> Optional[ToolResult]:
|
|
119
|
+
"""
|
|
120
|
+
工具执行出错时的处理
|
|
121
|
+
|
|
122
|
+
默认实现:记录错误日志,不提供替代结果
|
|
123
|
+
"""
|
|
124
|
+
if self.enabled:
|
|
125
|
+
self.log_error(f"Error in {type(tool).__name__}: {str(error)}")
|
|
126
|
+
return None
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Logging Plugin Example
|
|
3
|
+
|
|
4
|
+
记录工具调用日志的示例插件。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from typing import Optional, Dict, Any, TYPE_CHECKING
|
|
9
|
+
from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult
|
|
10
|
+
from ..base_plugin import BaseToolCallPlugin
|
|
11
|
+
from ..plugin_interface import PluginPriority
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from autocoder.common.v2.agent.agentic_edit import AgenticEdit
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class LoggingPlugin(BaseToolCallPlugin):
|
|
18
|
+
"""
|
|
19
|
+
日志记录插件
|
|
20
|
+
|
|
21
|
+
记录所有工具调用的详细信息,包括参数、执行时间和结果。
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, enabled: bool = True, detailed_logging: bool = False):
|
|
25
|
+
"""
|
|
26
|
+
初始化日志插件
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
enabled: 插件是否启用
|
|
30
|
+
detailed_logging: 是否记录详细日志(包括工具参数和结果内容)
|
|
31
|
+
"""
|
|
32
|
+
super().__init__(enabled)
|
|
33
|
+
self.detailed_logging = detailed_logging
|
|
34
|
+
self.call_history = []
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def name(self) -> str:
|
|
38
|
+
return "logging"
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def priority(self) -> PluginPriority:
|
|
42
|
+
return PluginPriority.LOW # 记录日志通常优先级较低
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def description(self) -> str:
|
|
46
|
+
return "Records detailed logs of all tool calls and executions"
|
|
47
|
+
|
|
48
|
+
def before_tool_execution(
|
|
49
|
+
self,
|
|
50
|
+
tool: BaseTool,
|
|
51
|
+
agent: Optional['AgenticEdit'],
|
|
52
|
+
context: Optional[Dict[str, Any]] = None
|
|
53
|
+
) -> BaseTool:
|
|
54
|
+
"""记录工具执行前的信息"""
|
|
55
|
+
if not self.enabled:
|
|
56
|
+
return tool
|
|
57
|
+
|
|
58
|
+
call_info = {
|
|
59
|
+
"tool_name": type(tool).__name__,
|
|
60
|
+
"timestamp": context.get("timestamp") if context else None,
|
|
61
|
+
"call_id": context.get("call_id") if context else None,
|
|
62
|
+
"phase": "before_execution"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if self.detailed_logging:
|
|
66
|
+
call_info["tool_params"] = tool.model_dump() if hasattr(tool, 'model_dump') else str(tool)
|
|
67
|
+
|
|
68
|
+
self.call_history.append(call_info)
|
|
69
|
+
self.log_info(f"Starting execution of {type(tool).__name__}")
|
|
70
|
+
|
|
71
|
+
if self.detailed_logging:
|
|
72
|
+
self.log_info(f"Tool parameters: {json.dumps(call_info.get('tool_params', {}), indent=2)}")
|
|
73
|
+
|
|
74
|
+
return tool
|
|
75
|
+
|
|
76
|
+
def after_tool_execution(
|
|
77
|
+
self,
|
|
78
|
+
tool: BaseTool,
|
|
79
|
+
tool_result: ToolResult,
|
|
80
|
+
agent: Optional['AgenticEdit'],
|
|
81
|
+
context: Optional[Dict[str, Any]] = None
|
|
82
|
+
) -> ToolResult:
|
|
83
|
+
"""记录工具执行后的信息"""
|
|
84
|
+
if not self.enabled:
|
|
85
|
+
return tool_result
|
|
86
|
+
|
|
87
|
+
call_info = {
|
|
88
|
+
"tool_name": type(tool).__name__,
|
|
89
|
+
"timestamp": context.get("timestamp") if context else None,
|
|
90
|
+
"call_id": context.get("call_id") if context else None,
|
|
91
|
+
"phase": "after_execution",
|
|
92
|
+
"success": tool_result.success,
|
|
93
|
+
"message": tool_result.message
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if self.detailed_logging and tool_result.content:
|
|
97
|
+
# 只记录前500个字符,避免日志过长
|
|
98
|
+
content_str = str(tool_result.content)
|
|
99
|
+
if len(content_str) > 500:
|
|
100
|
+
content_str = content_str[:500] + "..."
|
|
101
|
+
call_info["result_content"] = content_str
|
|
102
|
+
|
|
103
|
+
self.call_history.append(call_info)
|
|
104
|
+
|
|
105
|
+
status = "successfully" if tool_result.success else "with error"
|
|
106
|
+
self.log_info(f"Completed execution of {type(tool).__name__} {status}")
|
|
107
|
+
|
|
108
|
+
if not tool_result.success:
|
|
109
|
+
self.log_warning(f"Tool execution failed: {tool_result.message}")
|
|
110
|
+
|
|
111
|
+
if self.detailed_logging:
|
|
112
|
+
self.log_info(f"Result: {json.dumps(call_info, indent=2, default=str)}")
|
|
113
|
+
|
|
114
|
+
return tool_result
|
|
115
|
+
|
|
116
|
+
def on_tool_error(
|
|
117
|
+
self,
|
|
118
|
+
tool: BaseTool,
|
|
119
|
+
error: Exception,
|
|
120
|
+
agent: Optional['AgenticEdit'],
|
|
121
|
+
context: Optional[Dict[str, Any]] = None
|
|
122
|
+
) -> Optional[ToolResult]:
|
|
123
|
+
"""记录工具执行错误"""
|
|
124
|
+
if not self.enabled:
|
|
125
|
+
return None
|
|
126
|
+
|
|
127
|
+
call_info = {
|
|
128
|
+
"tool_name": type(tool).__name__,
|
|
129
|
+
"timestamp": context.get("timestamp") if context else None,
|
|
130
|
+
"call_id": context.get("call_id") if context else None,
|
|
131
|
+
"phase": "error",
|
|
132
|
+
"error_type": type(error).__name__,
|
|
133
|
+
"error_message": str(error)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
self.call_history.append(call_info)
|
|
137
|
+
self.log_error(f"Tool {type(tool).__name__} failed with {type(error).__name__}: {str(error)}")
|
|
138
|
+
|
|
139
|
+
# 不提供恢复结果,只记录错误
|
|
140
|
+
return None
|
|
141
|
+
|
|
142
|
+
def get_call_history(self) -> list:
|
|
143
|
+
"""获取调用历史"""
|
|
144
|
+
return self.call_history.copy()
|
|
145
|
+
|
|
146
|
+
def clear_history(self) -> None:
|
|
147
|
+
"""清空调用历史"""
|
|
148
|
+
self.call_history.clear()
|
|
149
|
+
self.log_info("Call history cleared")
|
|
150
|
+
|
|
151
|
+
def get_statistics(self) -> Dict[str, Any]:
|
|
152
|
+
"""获取统计信息"""
|
|
153
|
+
total_calls = len([call for call in self.call_history if call["phase"] == "after_execution"])
|
|
154
|
+
successful_calls = len([call for call in self.call_history
|
|
155
|
+
if call["phase"] == "after_execution" and call.get("success", False)])
|
|
156
|
+
error_calls = len([call for call in self.call_history if call["phase"] == "error"])
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
"total_logged_calls": total_calls,
|
|
160
|
+
"successful_calls": successful_calls,
|
|
161
|
+
"error_calls": error_calls,
|
|
162
|
+
"success_rate": successful_calls / total_calls if total_calls > 0 else 0.0,
|
|
163
|
+
"detailed_logging": self.detailed_logging
|
|
164
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Security Filter Plugin Example
|
|
3
|
+
|
|
4
|
+
安全过滤插件,用于拦截和过滤敏感信息。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from copy import deepcopy
|
|
9
|
+
from typing import Optional, Dict, Any, List, TYPE_CHECKING
|
|
10
|
+
from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult, ExecuteCommandTool
|
|
11
|
+
from ..base_plugin import BaseToolCallPlugin
|
|
12
|
+
from ..plugin_interface import PluginPriority
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from autocoder.common.v2.agent.agentic_edit import AgenticEdit
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SecurityFilterPlugin(BaseToolCallPlugin):
|
|
19
|
+
"""
|
|
20
|
+
安全过滤插件
|
|
21
|
+
|
|
22
|
+
过滤敏感信息,如密码、API密钥等,防止在工具执行过程中泄露。
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, enabled: bool = True):
|
|
26
|
+
"""
|
|
27
|
+
初始化安全过滤插件
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
enabled: 插件是否启用
|
|
31
|
+
"""
|
|
32
|
+
super().__init__(enabled)
|
|
33
|
+
|
|
34
|
+
# 敏感信息正则模式
|
|
35
|
+
self.sensitive_patterns = [
|
|
36
|
+
(r'password\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'password=***'),
|
|
37
|
+
(r'passwd\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'passwd=***'),
|
|
38
|
+
(r'api_key\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'api_key=***'),
|
|
39
|
+
(r'secret\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'secret=***'),
|
|
40
|
+
(r'token\s*[=:]\s*["\']?([^"\'\s]+)["\']?', 'token=***'),
|
|
41
|
+
(r'--password\s+([^\s]+)', '--password ***'),
|
|
42
|
+
(r'-p\s+([^\s]+)', '-p ***'),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
# 危险命令模式
|
|
46
|
+
self.dangerous_commands = [
|
|
47
|
+
r'rm\s+-rf\s+/',
|
|
48
|
+
r'sudo\s+rm\s+-rf',
|
|
49
|
+
r'format\s+c:',
|
|
50
|
+
r'del\s+/q\s+/s\s+c:\\',
|
|
51
|
+
r'shutdown\s+(-s|-r|-h)',
|
|
52
|
+
r'halt',
|
|
53
|
+
r'reboot',
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
self.filtered_count = 0
|
|
57
|
+
self.blocked_count = 0
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def name(self) -> str:
|
|
61
|
+
return "security_filter"
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def priority(self) -> PluginPriority:
|
|
65
|
+
return PluginPriority.HIGHEST # 安全过滤应该最先执行
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def description(self) -> str:
|
|
69
|
+
return "Filters sensitive information and blocks dangerous commands"
|
|
70
|
+
|
|
71
|
+
def should_process_tool(self, tool: BaseTool, agent: Optional['AgenticEdit']) -> bool:
|
|
72
|
+
"""只处理执行命令工具和其他可能包含敏感信息的工具"""
|
|
73
|
+
return self.enabled and isinstance(tool, (ExecuteCommandTool,))
|
|
74
|
+
|
|
75
|
+
def before_tool_execution(
|
|
76
|
+
self,
|
|
77
|
+
tool: BaseTool,
|
|
78
|
+
agent: Optional['AgenticEdit'],
|
|
79
|
+
context: Optional[Dict[str, Any]] = None
|
|
80
|
+
) -> BaseTool:
|
|
81
|
+
"""在工具执行前过滤敏感信息"""
|
|
82
|
+
if not self.should_process_tool(tool, agent):
|
|
83
|
+
return tool
|
|
84
|
+
|
|
85
|
+
# 创建工具的副本以避免修改原始工具
|
|
86
|
+
filtered_tool = deepcopy(tool)
|
|
87
|
+
|
|
88
|
+
if isinstance(filtered_tool, ExecuteCommandTool):
|
|
89
|
+
original_command = filtered_tool.command
|
|
90
|
+
|
|
91
|
+
# 检查危险命令
|
|
92
|
+
if self._is_dangerous_command(original_command):
|
|
93
|
+
self.blocked_count += 1
|
|
94
|
+
self.log_warning(f"Blocked dangerous command: {original_command}")
|
|
95
|
+
# 创建一个安全的替代命令
|
|
96
|
+
filtered_tool.command = "echo 'BLOCKED: Potentially dangerous command detected'"
|
|
97
|
+
return filtered_tool
|
|
98
|
+
|
|
99
|
+
# 过滤敏感信息
|
|
100
|
+
filtered_command = self._filter_sensitive_info(original_command)
|
|
101
|
+
if filtered_command != original_command:
|
|
102
|
+
self.filtered_count += 1
|
|
103
|
+
self.log_info(f"Filtered sensitive information from command")
|
|
104
|
+
filtered_tool.command = filtered_command
|
|
105
|
+
|
|
106
|
+
return filtered_tool
|
|
107
|
+
|
|
108
|
+
def after_tool_execution(
|
|
109
|
+
self,
|
|
110
|
+
tool: BaseTool,
|
|
111
|
+
tool_result: ToolResult,
|
|
112
|
+
agent: Optional['AgenticEdit'],
|
|
113
|
+
context: Optional[Dict[str, Any]] = None
|
|
114
|
+
) -> ToolResult:
|
|
115
|
+
"""在工具执行后过滤结果中的敏感信息"""
|
|
116
|
+
if not self.should_process_tool(tool, agent):
|
|
117
|
+
return tool_result
|
|
118
|
+
|
|
119
|
+
# 创建结果的副本
|
|
120
|
+
filtered_result = ToolResult(
|
|
121
|
+
success=tool_result.success,
|
|
122
|
+
message=self._filter_sensitive_info(tool_result.message),
|
|
123
|
+
content=self._filter_result_content(tool_result.content)
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
return filtered_result
|
|
127
|
+
|
|
128
|
+
def _is_dangerous_command(self, command: str) -> bool:
|
|
129
|
+
"""检查是否为危险命令"""
|
|
130
|
+
command_lower = command.lower().strip()
|
|
131
|
+
|
|
132
|
+
for pattern in self.dangerous_commands:
|
|
133
|
+
if re.search(pattern, command_lower, re.IGNORECASE):
|
|
134
|
+
return True
|
|
135
|
+
|
|
136
|
+
return False
|
|
137
|
+
|
|
138
|
+
def _filter_sensitive_info(self, text: str) -> str:
|
|
139
|
+
"""过滤文本中的敏感信息"""
|
|
140
|
+
if not text:
|
|
141
|
+
return text
|
|
142
|
+
|
|
143
|
+
filtered_text = text
|
|
144
|
+
|
|
145
|
+
for pattern, replacement in self.sensitive_patterns:
|
|
146
|
+
filtered_text = re.sub(pattern, replacement, filtered_text, flags=re.IGNORECASE)
|
|
147
|
+
|
|
148
|
+
return filtered_text
|
|
149
|
+
|
|
150
|
+
def _filter_result_content(self, content: Any) -> Any:
|
|
151
|
+
"""过滤结果内容中的敏感信息"""
|
|
152
|
+
if content is None:
|
|
153
|
+
return content
|
|
154
|
+
|
|
155
|
+
if isinstance(content, str):
|
|
156
|
+
return self._filter_sensitive_info(content)
|
|
157
|
+
|
|
158
|
+
elif isinstance(content, dict):
|
|
159
|
+
filtered_content = {}
|
|
160
|
+
for key, value in content.items():
|
|
161
|
+
if isinstance(value, str):
|
|
162
|
+
filtered_content[key] = self._filter_sensitive_info(value)
|
|
163
|
+
else:
|
|
164
|
+
filtered_content[key] = value
|
|
165
|
+
return filtered_content
|
|
166
|
+
|
|
167
|
+
elif isinstance(content, list):
|
|
168
|
+
return [
|
|
169
|
+
self._filter_sensitive_info(item) if isinstance(item, str) else item
|
|
170
|
+
for item in content
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
return content
|
|
174
|
+
|
|
175
|
+
def add_sensitive_pattern(self, pattern: str, replacement: str) -> None:
|
|
176
|
+
"""添加新的敏感信息模式"""
|
|
177
|
+
self.sensitive_patterns.append((pattern, replacement))
|
|
178
|
+
self.log_info(f"Added new sensitive pattern: {pattern}")
|
|
179
|
+
|
|
180
|
+
def add_dangerous_command(self, pattern: str) -> None:
|
|
181
|
+
"""添加新的危险命令模式"""
|
|
182
|
+
self.dangerous_commands.append(pattern)
|
|
183
|
+
self.log_info(f"Added new dangerous command pattern: {pattern}")
|
|
184
|
+
|
|
185
|
+
def get_filter_statistics(self) -> Dict[str, Any]:
|
|
186
|
+
"""获取过滤统计信息"""
|
|
187
|
+
return {
|
|
188
|
+
"filtered_count": self.filtered_count,
|
|
189
|
+
"blocked_count": self.blocked_count,
|
|
190
|
+
"sensitive_patterns_count": len(self.sensitive_patterns),
|
|
191
|
+
"dangerous_patterns_count": len(self.dangerous_commands)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
def reset_statistics(self) -> None:
|
|
195
|
+
"""重置统计信息"""
|
|
196
|
+
self.filtered_count = 0
|
|
197
|
+
self.blocked_count = 0
|
|
198
|
+
self.log_info("Filter statistics reset")
|