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,192 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
import os, fnmatch, asyncio
|
|
3
|
-
from watchfiles import Change
|
|
4
|
-
from autocoder.common.ignorefiles.ignore_file_utils import should_ignore
|
|
5
|
-
from autocoder.common.file_monitor.monitor import get_file_monitor
|
|
6
|
-
import logging
|
|
7
|
-
import functools
|
|
8
|
-
|
|
9
|
-
logger = logging.getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
class DirectoryCache:
|
|
12
|
-
_instance: "DirectoryCache|None" = None
|
|
13
|
-
|
|
14
|
-
def __init__(self, root: str):
|
|
15
|
-
self.root = os.path.abspath(root)
|
|
16
|
-
self.files_set: set[str] = set()
|
|
17
|
-
self.lock = asyncio.Lock()
|
|
18
|
-
self._main_loop = asyncio.get_event_loop() # 保存主事件循环引用
|
|
19
|
-
logger.info(f"Initializing DirectoryCache for root: {self.root}")
|
|
20
|
-
|
|
21
|
-
# ---------- 单例获取 ----------
|
|
22
|
-
@classmethod
|
|
23
|
-
def get_instance(cls, root: str | None = None) -> "DirectoryCache":
|
|
24
|
-
if cls._instance is None:
|
|
25
|
-
if root is None:
|
|
26
|
-
raise ValueError("root is required when initializing DirectoryCache for the first time")
|
|
27
|
-
logger.info("Creating new DirectoryCache instance.")
|
|
28
|
-
cls._instance = cls(root)
|
|
29
|
-
cls._instance._build() # 同步首扫
|
|
30
|
-
cls._instance._register_monitor()
|
|
31
|
-
elif root is not None and os.path.abspath(root) != cls._instance.root:
|
|
32
|
-
# 如果请求的 root 与已存在的实例 root 不同,可以选择抛出错误或重新初始化
|
|
33
|
-
logger.warning(f"Requested root {os.path.abspath(root)} differs from existing instance root {cls._instance.root}. Re-initializing cache.")
|
|
34
|
-
cls._instance = cls(root)
|
|
35
|
-
cls._instance._build()
|
|
36
|
-
cls._instance._register_monitor()
|
|
37
|
-
|
|
38
|
-
return cls._instance
|
|
39
|
-
|
|
40
|
-
# ---------- 构建 ----------
|
|
41
|
-
def _build(self) -> None:
|
|
42
|
-
logger.info(f"Building initial file cache for {self.root}...")
|
|
43
|
-
count = 0
|
|
44
|
-
for r, ds, fs in os.walk(self.root, followlinks=True):
|
|
45
|
-
# 过滤掉需要忽略的目录
|
|
46
|
-
ds[:] = [d for d in ds if not should_ignore(os.path.join(r, d))]
|
|
47
|
-
for f in fs:
|
|
48
|
-
fp = os.path.join(r, f)
|
|
49
|
-
abs_fp = os.path.abspath(fp)
|
|
50
|
-
if not should_ignore(abs_fp):
|
|
51
|
-
self.files_set.add(abs_fp)
|
|
52
|
-
count += 1
|
|
53
|
-
logger.info(f"Initial cache build complete. Found {count} files.")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# ---------- 监控回调 ----------
|
|
57
|
-
def _register_monitor(self) -> None:
|
|
58
|
-
try:
|
|
59
|
-
logger.info(f"Registering file monitor for {self.root}")
|
|
60
|
-
mon = get_file_monitor(self.root)
|
|
61
|
-
# 使用 functools.partial 包装异步回调
|
|
62
|
-
async_callback_wrapper = functools.partial(self._on_change_wrapper)
|
|
63
|
-
mon.register("**/*", async_callback_wrapper) # 监听所有文件变化
|
|
64
|
-
if not mon.is_running():
|
|
65
|
-
logger.info("Starting file monitor...")
|
|
66
|
-
mon.start()
|
|
67
|
-
logger.info("File monitor registered and running.")
|
|
68
|
-
except Exception as e:
|
|
69
|
-
logger.error(f"Failed to register or start file monitor: {e}", exc_info=True)
|
|
70
|
-
|
|
71
|
-
# Wrapper to run the async callback in the event loop
|
|
72
|
-
def _on_change_wrapper(self, change: Change, path: str):
|
|
73
|
-
try:
|
|
74
|
-
# 使用run_coroutine_threadsafe在主事件循环中运行协程
|
|
75
|
-
# 注意:主事件循环必须在其他地方运行,如主线程中
|
|
76
|
-
asyncio.run_coroutine_threadsafe(self._on_change(change, path), self._main_loop)
|
|
77
|
-
except Exception as e:
|
|
78
|
-
logger.error(f"Error executing _on_change_wrapper: {e}", exc_info=True)
|
|
79
|
-
# 如果run_coroutine_threadsafe失败,可以考虑一个同步的备用处理方法
|
|
80
|
-
try:
|
|
81
|
-
# 同步备份处理
|
|
82
|
-
ap = os.path.abspath(path)
|
|
83
|
-
if should_ignore(ap):
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
if change is Change.added:
|
|
87
|
-
self.files_set.add(ap)
|
|
88
|
-
elif change is Change.deleted:
|
|
89
|
-
self.files_set.discard(ap)
|
|
90
|
-
# Change.modified不需要更新集合
|
|
91
|
-
except Exception as backup_error:
|
|
92
|
-
logger.error(f"Backup handler also failed: {backup_error}", exc_info=True)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
async def _on_change(self, change: Change, path: str) -> None:
|
|
96
|
-
ap = os.path.abspath(path)
|
|
97
|
-
# Check ignore status again, as gitignore might change
|
|
98
|
-
if should_ignore(ap):
|
|
99
|
-
# If a previously tracked file becomes ignored, remove it
|
|
100
|
-
async with self.lock:
|
|
101
|
-
if ap in self.files_set:
|
|
102
|
-
logger.debug(f"File became ignored, removing from cache: {ap}")
|
|
103
|
-
self.files_set.discard(ap)
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
async with self.lock:
|
|
107
|
-
if change is Change.added:
|
|
108
|
-
logger.debug(f"File added, adding to cache: {ap}")
|
|
109
|
-
self.files_set.add(ap)
|
|
110
|
-
elif change is Change.deleted:
|
|
111
|
-
logger.debug(f"File deleted, removing from cache: {ap}")
|
|
112
|
-
self.files_set.discard(ap)
|
|
113
|
-
elif change is Change.modified:
|
|
114
|
-
# Modification doesn't change existence, but we might want to log or handle metadata updates if needed
|
|
115
|
-
logger.debug(f"File modified: {ap} (ignored in cache set)")
|
|
116
|
-
pass # No change needed for the set itself
|
|
117
|
-
|
|
118
|
-
# ---------- 查询 ----------
|
|
119
|
-
async def query(self, patterns: list[str]) -> list[str]:
|
|
120
|
-
logger.debug(f"Querying cache with patterns: {patterns}")
|
|
121
|
-
async with self.lock:
|
|
122
|
-
# Make a copy to avoid issues if the set is modified during iteration (though lock prevents this here)
|
|
123
|
-
current_files = list(self.files_set)
|
|
124
|
-
|
|
125
|
-
if not patterns or patterns == [""] or patterns == ["*"]:
|
|
126
|
-
logger.debug(f"Returning all {len(current_files)} cached files.")
|
|
127
|
-
return current_files
|
|
128
|
-
|
|
129
|
-
out: set[str] = set()
|
|
130
|
-
|
|
131
|
-
for p in patterns:
|
|
132
|
-
pattern_abs = os.path.abspath(os.path.join(self.root, p)) if not os.path.isabs(p) else p
|
|
133
|
-
is_glob = "*" in p or "?" in p or "[" in p # More robust glob check
|
|
134
|
-
|
|
135
|
-
try:
|
|
136
|
-
if is_glob:
|
|
137
|
-
# fnmatch expects relative paths for matching within a root usually,
|
|
138
|
-
# but here we match against absolute paths in files_set.
|
|
139
|
-
# We need a pattern that works with absolute paths.
|
|
140
|
-
# If pattern 'p' is like '*.py', we need to match '/path/to/root/**/*.py'
|
|
141
|
-
# Let's adjust the pattern logic or filtering logic.
|
|
142
|
-
|
|
143
|
-
# Option 1: Match relative paths within the root
|
|
144
|
-
# Convert absolute paths in files_set to relative for matching
|
|
145
|
-
# relative_files = [os.path.relpath(f, self.root) for f in current_files]
|
|
146
|
-
# matched_relative = fnmatch.filter(relative_files, p)
|
|
147
|
-
# out.update(os.path.join(self.root, rel_f) for rel_f in matched_relative)
|
|
148
|
-
|
|
149
|
-
# Option 2: Match absolute paths directly (might need careful pattern construction)
|
|
150
|
-
# If p is relative, make it absolute based on root for matching
|
|
151
|
-
# Example: p = "src/*.py" -> effective_pattern = "/path/to/root/src/*.py"
|
|
152
|
-
# This requires fnmatch to handle absolute paths correctly or custom logic.
|
|
153
|
-
|
|
154
|
-
# Option 3: Simplified wildcard matching on absolute paths
|
|
155
|
-
# Treat '*' as a general wildcard anywhere in the path.
|
|
156
|
-
# fnmatch.filter might work if the pattern is constructed like `*pattern*`
|
|
157
|
-
# Let's stick to the user's original logic first, assuming it worked for their case
|
|
158
|
-
# The original `*{p}*` suggests substring matching with wildcards? Let's refine.
|
|
159
|
-
|
|
160
|
-
# Refined Glob Matching:
|
|
161
|
-
# If p contains wildcards, assume it's a glob pattern relative to root.
|
|
162
|
-
# Convert files_set paths to relative for matching.
|
|
163
|
-
for f_abs in current_files:
|
|
164
|
-
f_rel = os.path.relpath(f_abs, self.root)
|
|
165
|
-
if fnmatch.fnmatch(f_rel, p) or fnmatch.fnmatch(os.path.basename(f_abs), p):
|
|
166
|
-
out.add(f_abs)
|
|
167
|
-
|
|
168
|
-
else:
|
|
169
|
-
# Exact or substring matching for non-glob patterns
|
|
170
|
-
# Match against filename or full path segment
|
|
171
|
-
p_lower = p.lower()
|
|
172
|
-
for f_abs in current_files:
|
|
173
|
-
if p_lower in os.path.basename(f_abs).lower() or p_lower in f_abs.lower():
|
|
174
|
-
out.add(f_abs)
|
|
175
|
-
|
|
176
|
-
except Exception as e:
|
|
177
|
-
logger.error(f"Error during pattern matching for '{p}': {e}", exc_info=True)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
result = sorted(list(out)) # Sort for consistent output
|
|
181
|
-
logger.debug(f"Query returned {len(result)} files.")
|
|
182
|
-
return result
|
|
183
|
-
|
|
184
|
-
# Helper function (optional, could be integrated into get_instance)
|
|
185
|
-
def initialize_cache(root_path: str):
|
|
186
|
-
"""Initializes the DirectoryCache singleton."""
|
|
187
|
-
try:
|
|
188
|
-
DirectoryCache.get_instance(root_path)
|
|
189
|
-
logger.info("DirectoryCache initialized successfully.")
|
|
190
|
-
except Exception as e:
|
|
191
|
-
logger.error(f"Failed to initialize DirectoryCache: {e}", exc_info=True)
|
|
192
|
-
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
import os
|
|
3
|
-
import tempfile
|
|
4
|
-
import shutil
|
|
5
|
-
import asyncio
|
|
6
|
-
from unittest.mock import patch, MagicMock
|
|
7
|
-
|
|
8
|
-
# 导入被测模块
|
|
9
|
-
from autocoder.common.directory_cache.cache import DirectoryCache
|
|
10
|
-
|
|
11
|
-
# 测试环境辅助函数
|
|
12
|
-
def create_test_environment(base_dir, structure):
|
|
13
|
-
"""创建测试所需的文件/目录结构"""
|
|
14
|
-
for path, content in structure.items():
|
|
15
|
-
full_path = os.path.join(base_dir, path)
|
|
16
|
-
os.makedirs(os.path.dirname(full_path), exist_ok=True)
|
|
17
|
-
with open(full_path, 'w', encoding='utf-8') as f:
|
|
18
|
-
f.write(content)
|
|
19
|
-
|
|
20
|
-
# Pytest Fixture: 临时目录
|
|
21
|
-
@pytest.fixture(scope="function")
|
|
22
|
-
def temp_test_dir():
|
|
23
|
-
"""提供一个临时的、测试后自动清理的目录"""
|
|
24
|
-
temp_dir = tempfile.mkdtemp()
|
|
25
|
-
print(f"创建测试临时目录: {temp_dir}")
|
|
26
|
-
yield temp_dir
|
|
27
|
-
print(f"清理测试临时目录: {temp_dir}")
|
|
28
|
-
shutil.rmtree(temp_dir)
|
|
29
|
-
|
|
30
|
-
# Pytest Fixture: 重置单例
|
|
31
|
-
@pytest.fixture(autouse=True)
|
|
32
|
-
def reset_singleton():
|
|
33
|
-
"""每次测试前重置DirectoryCache单例"""
|
|
34
|
-
DirectoryCache._instance = None
|
|
35
|
-
yield
|
|
36
|
-
DirectoryCache._instance = None
|
|
37
|
-
|
|
38
|
-
# Pytest Fixture: 文件监视器模拟
|
|
39
|
-
@pytest.fixture
|
|
40
|
-
def mock_file_monitor():
|
|
41
|
-
"""模拟文件监视器"""
|
|
42
|
-
mock_monitor = MagicMock()
|
|
43
|
-
mock_monitor.register = MagicMock()
|
|
44
|
-
mock_monitor.is_running = MagicMock(return_value=False)
|
|
45
|
-
mock_monitor.start = MagicMock()
|
|
46
|
-
|
|
47
|
-
with patch('autocoder.common.directory_cache.cache.get_file_monitor', return_value=mock_monitor):
|
|
48
|
-
yield mock_monitor
|
|
49
|
-
|
|
50
|
-
# --- 测试用例 ---
|
|
51
|
-
|
|
52
|
-
@pytest.mark.asyncio
|
|
53
|
-
async def test_initialization(temp_test_dir, mock_file_monitor):
|
|
54
|
-
"""测试DirectoryCache的初始化和单例模式"""
|
|
55
|
-
# 创建测试文件结构
|
|
56
|
-
create_test_environment(temp_test_dir, {
|
|
57
|
-
"file1.txt": "测试内容1",
|
|
58
|
-
"subdir/file2.txt": "测试内容2",
|
|
59
|
-
".gitignore": "*.ignored"
|
|
60
|
-
})
|
|
61
|
-
create_test_environment(temp_test_dir, {
|
|
62
|
-
"file3.ignored": "这个文件应该被忽略"
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
# 获取实例
|
|
66
|
-
cache = DirectoryCache.get_instance(temp_test_dir)
|
|
67
|
-
|
|
68
|
-
# 验证单例模式
|
|
69
|
-
assert DirectoryCache.get_instance() is cache
|
|
70
|
-
assert cache.root == os.path.abspath(temp_test_dir)
|
|
71
|
-
|
|
72
|
-
# 验证文件缓存构建
|
|
73
|
-
assert len(cache.files_set) == 3 # file1.txt, subdir/file2.txt, .gitignore
|
|
74
|
-
assert os.path.join(temp_test_dir, "file1.txt") in [os.path.normpath(f) for f in cache.files_set]
|
|
75
|
-
assert os.path.join(temp_test_dir, "subdir/file2.txt") in [os.path.normpath(f) for f in cache.files_set]
|
|
76
|
-
|
|
77
|
-
# 验证监视器注册
|
|
78
|
-
mock_file_monitor.register.assert_called_once()
|
|
79
|
-
mock_file_monitor.start.assert_called_once()
|
|
80
|
-
|
|
81
|
-
@pytest.mark.asyncio
|
|
82
|
-
async def test_query_all_files(temp_test_dir, mock_file_monitor):
|
|
83
|
-
"""测试查询所有文件"""
|
|
84
|
-
# 创建测试文件结构
|
|
85
|
-
create_test_environment(temp_test_dir, {
|
|
86
|
-
"file1.py": "def test(): pass",
|
|
87
|
-
"file2.txt": "text content",
|
|
88
|
-
"subdir/file3.py": "class Test: pass"
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
# 获取实例并查询所有文件
|
|
92
|
-
cache = DirectoryCache.get_instance(temp_test_dir)
|
|
93
|
-
result = await cache.query(["*"])
|
|
94
|
-
|
|
95
|
-
# 验证结果
|
|
96
|
-
assert len(result) == 3
|
|
97
|
-
assert sorted([os.path.basename(f) for f in result]) == ["file1.py", "file2.txt", "file3.py"]
|
|
98
|
-
|
|
99
|
-
@pytest.mark.asyncio
|
|
100
|
-
async def test_query_with_pattern(temp_test_dir, mock_file_monitor):
|
|
101
|
-
"""测试使用模式查询文件"""
|
|
102
|
-
# 创建测试文件结构
|
|
103
|
-
create_test_environment(temp_test_dir, {
|
|
104
|
-
"file1.py": "def test(): pass",
|
|
105
|
-
"file2.txt": "text content",
|
|
106
|
-
"subdir/file3.py": "class Test: pass",
|
|
107
|
-
"another.doc": "document"
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
# 获取实例
|
|
111
|
-
cache = DirectoryCache.get_instance(temp_test_dir)
|
|
112
|
-
|
|
113
|
-
# 测试不同的查询模式
|
|
114
|
-
py_files = await cache.query(["*.py"])
|
|
115
|
-
assert len(py_files) == 2
|
|
116
|
-
assert all(f.endswith('.py') for f in py_files)
|
|
117
|
-
|
|
118
|
-
txt_files = await cache.query(["*.txt"])
|
|
119
|
-
assert len(txt_files) == 1
|
|
120
|
-
assert txt_files[0].endswith('file2.txt')
|
|
121
|
-
|
|
122
|
-
# 测试多模式查询
|
|
123
|
-
mixed_files = await cache.query(["*.py", "*.txt"])
|
|
124
|
-
assert len(mixed_files) == 3
|
|
125
|
-
assert len([f for f in mixed_files if f.endswith('.py')]) == 2
|
|
126
|
-
assert len([f for f in mixed_files if f.endswith('.txt')]) == 1
|
|
127
|
-
|
|
128
|
-
@pytest.mark.asyncio
|
|
129
|
-
async def test_file_change_events(temp_test_dir, mock_file_monitor):
|
|
130
|
-
"""测试文件变更事件处理"""
|
|
131
|
-
from watchfiles import Change
|
|
132
|
-
|
|
133
|
-
# 创建测试文件结构
|
|
134
|
-
create_test_environment(temp_test_dir, {
|
|
135
|
-
"file1.txt": "初始内容"
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
# 获取实例
|
|
139
|
-
cache = DirectoryCache.get_instance(temp_test_dir)
|
|
140
|
-
|
|
141
|
-
# 初始状态
|
|
142
|
-
file_path = os.path.join(temp_test_dir, "file1.txt")
|
|
143
|
-
abs_file_path = os.path.abspath(file_path)
|
|
144
|
-
assert abs_file_path in cache.files_set
|
|
145
|
-
|
|
146
|
-
# 测试删除事件
|
|
147
|
-
await cache._on_change(Change.deleted, abs_file_path)
|
|
148
|
-
assert abs_file_path not in cache.files_set
|
|
149
|
-
|
|
150
|
-
# 测试添加事件
|
|
151
|
-
await cache._on_change(Change.added, abs_file_path)
|
|
152
|
-
assert abs_file_path in cache.files_set
|
|
153
|
-
|
|
154
|
-
# 测试修改事件 (不应改变集合)
|
|
155
|
-
initial_set_size = len(cache.files_set)
|
|
156
|
-
await cache._on_change(Change.modified, abs_file_path)
|
|
157
|
-
assert len(cache.files_set) == initial_set_size
|
|
158
|
-
assert abs_file_path in cache.files_set
|
|
159
|
-
|
|
160
|
-
# 测试新文件
|
|
161
|
-
new_file_path = os.path.join(temp_test_dir, "newfile.txt")
|
|
162
|
-
abs_new_file_path = os.path.abspath(new_file_path)
|
|
163
|
-
await cache._on_change(Change.added, abs_new_file_path)
|
|
164
|
-
assert abs_new_file_path in cache.files_set
|
|
165
|
-
|
|
166
|
-
@pytest.mark.asyncio
|
|
167
|
-
async def test_reinitialization_with_different_root(temp_test_dir, mock_file_monitor):
|
|
168
|
-
"""测试使用不同根目录重新初始化缓存"""
|
|
169
|
-
# 创建第一个测试目录
|
|
170
|
-
first_dir = os.path.join(temp_test_dir, "first")
|
|
171
|
-
os.makedirs(first_dir)
|
|
172
|
-
create_test_environment(first_dir, {"test.txt": "first directory"})
|
|
173
|
-
|
|
174
|
-
# 初始化缓存
|
|
175
|
-
cache1 = DirectoryCache.get_instance(first_dir)
|
|
176
|
-
assert cache1.root == os.path.abspath(first_dir)
|
|
177
|
-
|
|
178
|
-
# 创建第二个测试目录
|
|
179
|
-
second_dir = os.path.join(temp_test_dir, "second")
|
|
180
|
-
os.makedirs(second_dir)
|
|
181
|
-
create_test_environment(second_dir, {"other.txt": "second directory"})
|
|
182
|
-
|
|
183
|
-
# 使用新目录重新初始化
|
|
184
|
-
cache2 = DirectoryCache.get_instance(second_dir)
|
|
185
|
-
assert cache2.root == os.path.abspath(second_dir)
|
|
186
|
-
|
|
187
|
-
# 验证文件集合已更新
|
|
188
|
-
all_files = await cache2.query(["*"])
|
|
189
|
-
assert len(all_files) == 1
|
|
190
|
-
assert all_files[0].endswith('other.txt')
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
文件变更管理模块的使用示例
|
|
3
|
-
|
|
4
|
-
展示如何使用文件变更管理模块进行文件变更的应用和撤销。
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import os
|
|
8
|
-
import sys
|
|
9
|
-
import json
|
|
10
|
-
from typing import Dict, Any
|
|
11
|
-
|
|
12
|
-
from autocoder.common.file_checkpoint.models import FileChange
|
|
13
|
-
from autocoder.common.file_checkpoint.manager import FileChangeManager
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def example_apply_changes(project_dir: str):
|
|
17
|
-
"""
|
|
18
|
-
示例:应用文件变更
|
|
19
|
-
|
|
20
|
-
Args:
|
|
21
|
-
project_dir: 项目目录
|
|
22
|
-
"""
|
|
23
|
-
print(f"示例:应用文件变更到项目 {project_dir}")
|
|
24
|
-
|
|
25
|
-
# 创建文件变更管理器
|
|
26
|
-
manager = FileChangeManager(project_dir)
|
|
27
|
-
|
|
28
|
-
# 准备文件变更
|
|
29
|
-
changes = {
|
|
30
|
-
"example.txt": FileChange(
|
|
31
|
-
file_path="example.txt",
|
|
32
|
-
content="这是一个示例文件\n用于演示文件变更管理模块的功能\n",
|
|
33
|
-
is_new=True
|
|
34
|
-
),
|
|
35
|
-
"README.md": FileChange(
|
|
36
|
-
file_path="README.md",
|
|
37
|
-
content="# 示例项目\n\n这是一个用于演示文件变更管理模块的示例项目。\n",
|
|
38
|
-
is_new=True
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
# 应用变更
|
|
43
|
-
result = manager.apply_changes(changes)
|
|
44
|
-
|
|
45
|
-
# 输出结果
|
|
46
|
-
if result.success:
|
|
47
|
-
print(f"成功应用了 {len(result.change_ids)} 个文件变更")
|
|
48
|
-
for change_id in result.change_ids:
|
|
49
|
-
print(f" - 变更ID: {change_id}")
|
|
50
|
-
else:
|
|
51
|
-
print("应用变更失败")
|
|
52
|
-
for file_path, error in result.errors.items():
|
|
53
|
-
print(f" - {file_path}: {error}")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def example_preview_changes(project_dir: str):
|
|
57
|
-
"""
|
|
58
|
-
示例:预览文件变更
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
project_dir: 项目目录
|
|
62
|
-
"""
|
|
63
|
-
print(f"示例:预览文件变更")
|
|
64
|
-
|
|
65
|
-
# 创建文件变更管理器
|
|
66
|
-
manager = FileChangeManager(project_dir)
|
|
67
|
-
|
|
68
|
-
# 准备文件变更
|
|
69
|
-
changes = {
|
|
70
|
-
"example.txt": FileChange(
|
|
71
|
-
file_path="example.txt",
|
|
72
|
-
content="这是一个修改后的示例文件\n用于演示文件变更管理模块的功能\n新增的一行\n",
|
|
73
|
-
is_new=False
|
|
74
|
-
)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
# 预览变更
|
|
78
|
-
diff_results = manager.preview_changes(changes)
|
|
79
|
-
|
|
80
|
-
# 输出差异
|
|
81
|
-
for file_path, diff_result in diff_results.items():
|
|
82
|
-
print(f"\n文件: {file_path}")
|
|
83
|
-
print(diff_result.get_diff_summary())
|
|
84
|
-
if diff_result.old_content is not None and not diff_result.is_new and not diff_result.is_deletion:
|
|
85
|
-
diff_text = manager.get_diff_text(diff_result.old_content, diff_result.new_content)
|
|
86
|
-
print("\n差异:")
|
|
87
|
-
print(diff_text)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def example_undo_changes(project_dir: str):
|
|
91
|
-
"""
|
|
92
|
-
示例:撤销文件变更
|
|
93
|
-
|
|
94
|
-
Args:
|
|
95
|
-
project_dir: 项目目录
|
|
96
|
-
"""
|
|
97
|
-
print(f"示例:撤销文件变更")
|
|
98
|
-
|
|
99
|
-
# 创建文件变更管理器
|
|
100
|
-
manager = FileChangeManager(project_dir)
|
|
101
|
-
|
|
102
|
-
# 撤销最近的变更
|
|
103
|
-
result = manager.undo_last_change()
|
|
104
|
-
|
|
105
|
-
# 输出结果
|
|
106
|
-
if result.success:
|
|
107
|
-
print(f"成功撤销了变更,恢复了 {len(result.restored_files)} 个文件")
|
|
108
|
-
for file_path in result.restored_files:
|
|
109
|
-
print(f" - {file_path}")
|
|
110
|
-
else:
|
|
111
|
-
print("撤销变更失败")
|
|
112
|
-
for file_path, error in result.errors.items():
|
|
113
|
-
print(f" - {file_path}: {error}")
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def example_get_history(project_dir: str):
|
|
117
|
-
"""
|
|
118
|
-
示例:获取变更历史
|
|
119
|
-
|
|
120
|
-
Args:
|
|
121
|
-
project_dir: 项目目录
|
|
122
|
-
"""
|
|
123
|
-
print(f"示例:获取变更历史")
|
|
124
|
-
|
|
125
|
-
# 创建文件变更管理器
|
|
126
|
-
manager = FileChangeManager(project_dir)
|
|
127
|
-
|
|
128
|
-
# 获取变更历史
|
|
129
|
-
changes = manager.get_change_history(limit=5)
|
|
130
|
-
|
|
131
|
-
# 输出历史记录
|
|
132
|
-
print(f"最近 {len(changes)} 条变更记录:")
|
|
133
|
-
for change in changes:
|
|
134
|
-
timestamp = change.timestamp
|
|
135
|
-
file_path = change.file_path
|
|
136
|
-
change_type = "新建" if change.is_new else "删除" if change.is_deletion else "修改"
|
|
137
|
-
print(f" - [{timestamp}] {change_type} {file_path} (ID: {change.change_id})")
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
def example_integration_with_agentic_edit():
|
|
141
|
-
"""
|
|
142
|
-
示例:与 AgenticEdit 集成
|
|
143
|
-
|
|
144
|
-
展示如何将文件变更管理模块集成到 AgenticEdit 中
|
|
145
|
-
"""
|
|
146
|
-
print("示例:与 AgenticEdit 集成")
|
|
147
|
-
|
|
148
|
-
# 这是一个伪代码示例,展示如何修改 AgenticEdit.apply_changes 方法
|
|
149
|
-
code = """
|
|
150
|
-
def apply_changes(self):
|
|
151
|
-
\"\"\"
|
|
152
|
-
Apply all tracked file changes to the original project directory.
|
|
153
|
-
\"\"\"
|
|
154
|
-
from autocoder.common.file_checkpoint.models import FileChange
|
|
155
|
-
from autocoder.common.file_checkpoint.manager import FileChangeManager
|
|
156
|
-
|
|
157
|
-
# 创建文件变更管理器
|
|
158
|
-
manager = FileChangeManager(self.args.source_dir)
|
|
159
|
-
|
|
160
|
-
# 将影子系统的变更转换为 FileChange 对象
|
|
161
|
-
changes = {}
|
|
162
|
-
for file_path, change in self.get_all_file_changes().items():
|
|
163
|
-
changes[file_path] = FileChange(
|
|
164
|
-
file_path=file_path,
|
|
165
|
-
content=change.content,
|
|
166
|
-
is_new=not os.path.exists(file_path)
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
# 应用变更
|
|
170
|
-
result = manager.apply_changes(changes)
|
|
171
|
-
|
|
172
|
-
# 处理结果
|
|
173
|
-
if result.success:
|
|
174
|
-
# 继续执行原有的 Git 提交等逻辑
|
|
175
|
-
if not self.args.skip_commit:
|
|
176
|
-
try:
|
|
177
|
-
# ... 原有的 Git 提交代码 ...
|
|
178
|
-
except Exception as e:
|
|
179
|
-
# ... 原有的错误处理 ...
|
|
180
|
-
else:
|
|
181
|
-
# 处理应用变更失败的情况
|
|
182
|
-
error_messages = "\\n".join([f"{path}: {error}" for path, error in result.errors.items()])
|
|
183
|
-
self.printer.print_str_in_terminal(
|
|
184
|
-
f"Failed to apply changes:\\n{error_messages}",
|
|
185
|
-
style="red"
|
|
186
|
-
)
|
|
187
|
-
"""
|
|
188
|
-
|
|
189
|
-
print(code)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def main():
|
|
193
|
-
"""主函数"""
|
|
194
|
-
if len(sys.argv) < 2:
|
|
195
|
-
print("用法: python examples.py <项目目录>")
|
|
196
|
-
return
|
|
197
|
-
|
|
198
|
-
project_dir = sys.argv[1]
|
|
199
|
-
|
|
200
|
-
# 运行示例
|
|
201
|
-
example_apply_changes(project_dir)
|
|
202
|
-
print("\n" + "-" * 50 + "\n")
|
|
203
|
-
|
|
204
|
-
example_preview_changes(project_dir)
|
|
205
|
-
print("\n" + "-" * 50 + "\n")
|
|
206
|
-
|
|
207
|
-
example_get_history(project_dir)
|
|
208
|
-
print("\n" + "-" * 50 + "\n")
|
|
209
|
-
|
|
210
|
-
example_undo_changes(project_dir)
|
|
211
|
-
print("\n" + "-" * 50 + "\n")
|
|
212
|
-
|
|
213
|
-
example_integration_with_agentic_edit()
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if __name__ == "__main__":
|
|
217
|
-
main()
|