auto-coder 1.0.0__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- auto_coder-2.0.0.dist-info/LICENSE +158 -0
- auto_coder-2.0.0.dist-info/METADATA +558 -0
- auto_coder-2.0.0.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
- autocoder/__init__.py +31 -0
- autocoder/agent/auto_filegroup.py +32 -13
- autocoder/agent/auto_learn_from_commit.py +9 -1
- autocoder/agent/base_agentic/__init__.py +3 -0
- autocoder/agent/base_agentic/agent_hub.py +1 -1
- autocoder/agent/base_agentic/base_agent.py +235 -136
- autocoder/agent/base_agentic/default_tools.py +119 -118
- autocoder/agent/base_agentic/test_base_agent.py +1 -1
- autocoder/agent/base_agentic/tool_registry.py +32 -20
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
- autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
- autocoder/agent/base_agentic/types.py +42 -0
- autocoder/agent/entry_command_agent/chat.py +73 -59
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +970 -2345
- autocoder/auto_coder_terminal.py +26 -0
- autocoder/auto_coder_terminal_v3.py +190 -0
- autocoder/chat/conf_command.py +224 -124
- autocoder/chat/models_command.py +361 -299
- autocoder/chat/rules_command.py +79 -31
- autocoder/chat_auto_coder.py +988 -398
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +25 -8
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +44 -44
- autocoder/common/__init__.py +150 -128
- autocoder/common/ac_style_command_parser/__init__.py +39 -2
- autocoder/common/ac_style_command_parser/config.py +422 -0
- autocoder/common/ac_style_command_parser/parser.py +292 -78
- autocoder/common/ac_style_command_parser/test_parser.py +241 -16
- autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
- autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
- autocoder/common/action_yml_file_manager.py +25 -13
- autocoder/common/agent_events/__init__.py +52 -0
- autocoder/common/agent_events/agent_event_emitter.py +193 -0
- autocoder/common/agent_events/event_factory.py +177 -0
- autocoder/common/agent_events/examples.py +307 -0
- autocoder/common/agent_events/types.py +113 -0
- autocoder/common/agent_events/utils.py +68 -0
- autocoder/common/agent_hooks/__init__.py +44 -0
- autocoder/common/agent_hooks/examples.py +582 -0
- autocoder/common/agent_hooks/hook_executor.py +217 -0
- autocoder/common/agent_hooks/hook_manager.py +288 -0
- autocoder/common/agent_hooks/types.py +133 -0
- autocoder/common/agent_hooks/utils.py +99 -0
- autocoder/common/agent_query_queue/queue_executor.py +324 -0
- autocoder/common/agent_query_queue/queue_manager.py +325 -0
- autocoder/common/agents/__init__.py +11 -0
- autocoder/common/agents/agent_manager.py +323 -0
- autocoder/common/agents/agent_parser.py +189 -0
- autocoder/common/agents/example_usage.py +344 -0
- autocoder/common/agents/integration_example.py +330 -0
- autocoder/common/agents/test_agent_parser.py +545 -0
- autocoder/common/async_utils.py +101 -0
- autocoder/common/auto_coder_lang.py +23 -972
- autocoder/common/autocoderargs_parser/__init__.py +14 -0
- autocoder/common/autocoderargs_parser/parser.py +184 -0
- autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
- autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
- autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
- autocoder/common/autocoderargs_parser/token_parser.py +290 -0
- autocoder/common/buildin_tokenizer.py +2 -4
- autocoder/common/code_auto_generate.py +149 -74
- autocoder/common/code_auto_generate_diff.py +163 -70
- autocoder/common/code_auto_generate_editblock.py +179 -89
- autocoder/common/code_auto_generate_strict_diff.py +167 -72
- autocoder/common/code_auto_merge_editblock.py +13 -6
- autocoder/common/code_modification_ranker.py +1 -1
- autocoder/common/command_completer.py +3 -3
- autocoder/common/command_file_manager/manager.py +183 -47
- autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
- autocoder/common/command_templates.py +1 -1
- autocoder/common/conf_utils.py +2 -4
- autocoder/common/conversations/config.py +11 -3
- autocoder/common/conversations/get_conversation_manager.py +100 -2
- autocoder/common/conversations/llm_stats_models.py +264 -0
- autocoder/common/conversations/manager.py +112 -28
- autocoder/common/conversations/models.py +16 -2
- autocoder/common/conversations/storage/index_manager.py +134 -10
- autocoder/common/core_config/__init__.py +63 -0
- autocoder/common/core_config/agentic_mode_manager.py +109 -0
- autocoder/common/core_config/base_manager.py +123 -0
- autocoder/common/core_config/compatibility.py +151 -0
- autocoder/common/core_config/config_manager.py +156 -0
- autocoder/common/core_config/conversation_manager.py +31 -0
- autocoder/common/core_config/exclude_manager.py +72 -0
- autocoder/common/core_config/file_manager.py +177 -0
- autocoder/common/core_config/human_as_model_manager.py +129 -0
- autocoder/common/core_config/lib_manager.py +54 -0
- autocoder/common/core_config/main_manager.py +81 -0
- autocoder/common/core_config/mode_manager.py +126 -0
- autocoder/common/core_config/models.py +70 -0
- autocoder/common/core_config/test_memory_manager.py +1056 -0
- autocoder/common/env_manager.py +282 -0
- autocoder/common/env_manager_usage_example.py +211 -0
- autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
- autocoder/common/file_checkpoint/manager.py +264 -48
- autocoder/common/file_checkpoint/test_backup.py +1 -18
- autocoder/common/file_checkpoint/test_manager.py +270 -1
- autocoder/common/file_checkpoint/test_store.py +1 -17
- autocoder/common/file_handler/__init__.py +23 -0
- autocoder/common/file_handler/active_context_handler.py +159 -0
- autocoder/common/file_handler/add_files_handler.py +409 -0
- autocoder/common/file_handler/chat_handler.py +180 -0
- autocoder/common/file_handler/coding_handler.py +401 -0
- autocoder/common/file_handler/commit_handler.py +200 -0
- autocoder/common/file_handler/lib_handler.py +156 -0
- autocoder/common/file_handler/list_files_handler.py +111 -0
- autocoder/common/file_handler/mcp_handler.py +268 -0
- autocoder/common/file_handler/models_handler.py +493 -0
- autocoder/common/file_handler/remove_files_handler.py +172 -0
- autocoder/common/git_utils.py +44 -8
- autocoder/common/global_cancel.py +15 -6
- autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
- autocoder/common/international/__init__.py +31 -0
- autocoder/common/international/demo_international.py +92 -0
- autocoder/common/international/message_manager.py +157 -0
- autocoder/common/international/messages/__init__.py +56 -0
- autocoder/common/international/messages/async_command_messages.py +507 -0
- autocoder/common/international/messages/auto_coder_messages.py +2208 -0
- autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
- autocoder/common/international/messages/command_help_messages.py +986 -0
- autocoder/common/international/messages/conversation_command_messages.py +191 -0
- autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
- autocoder/common/international/messages/queue_command_messages.py +751 -0
- autocoder/common/international/messages/rules_command_messages.py +77 -0
- autocoder/common/international/messages/sdk_messages.py +1707 -0
- autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
- autocoder/common/international/messages/tool_display_messages.py +1212 -0
- autocoder/common/international/messages/workflow_exception_messages.py +473 -0
- autocoder/common/international/test_international.py +612 -0
- autocoder/common/linter_core/__init__.py +28 -0
- autocoder/common/linter_core/base_linter.py +61 -0
- autocoder/common/linter_core/config_loader.py +271 -0
- autocoder/common/linter_core/formatters/__init__.py +0 -0
- autocoder/common/linter_core/formatters/base_formatter.py +38 -0
- autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
- autocoder/common/linter_core/linter.py +166 -0
- autocoder/common/linter_core/linter_factory.py +216 -0
- autocoder/common/linter_core/linter_manager.py +333 -0
- autocoder/common/linter_core/linters/__init__.py +9 -0
- autocoder/common/linter_core/linters/java_linter.py +342 -0
- autocoder/common/linter_core/linters/python_linter.py +115 -0
- autocoder/common/linter_core/linters/typescript_linter.py +119 -0
- autocoder/common/linter_core/models/__init__.py +7 -0
- autocoder/common/linter_core/models/lint_result.py +91 -0
- autocoder/common/linter_core/models.py +33 -0
- autocoder/common/linter_core/tests/__init__.py +3 -0
- autocoder/common/linter_core/tests/test_config_loader.py +323 -0
- autocoder/common/linter_core/tests/test_config_loading.py +308 -0
- autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
- autocoder/common/linter_core/tests/test_formatters.py +147 -0
- autocoder/common/linter_core/tests/test_integration.py +317 -0
- autocoder/common/linter_core/tests/test_java_linter.py +496 -0
- autocoder/common/linter_core/tests/test_linters.py +265 -0
- autocoder/common/linter_core/tests/test_models.py +81 -0
- autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
- autocoder/common/linter_core/tests/verify_fixes.py +183 -0
- autocoder/common/llm_friendly_package/__init__.py +31 -0
- autocoder/common/llm_friendly_package/base_manager.py +102 -0
- autocoder/common/llm_friendly_package/docs_manager.py +121 -0
- autocoder/common/llm_friendly_package/library_manager.py +171 -0
- autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
- autocoder/common/llm_friendly_package/models.py +40 -0
- autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
- autocoder/common/llms/__init__.py +15 -0
- autocoder/common/llms/demo_error_handling.py +85 -0
- autocoder/common/llms/factory.py +142 -0
- autocoder/common/llms/manager.py +264 -0
- autocoder/common/llms/pricing.py +121 -0
- autocoder/common/llms/registry.py +288 -0
- autocoder/common/llms/schema.py +77 -0
- autocoder/common/llms/simple_demo.py +45 -0
- autocoder/common/llms/test_quick_model.py +116 -0
- autocoder/common/llms/test_remove_functionality.py +182 -0
- autocoder/common/llms/tests/__init__.py +1 -0
- autocoder/common/llms/tests/test_manager.py +330 -0
- autocoder/common/llms/tests/test_registry.py +364 -0
- autocoder/common/mcp_tools/__init__.py +62 -0
- autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
- autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
- autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
- autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
- autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
- autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
- autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
- autocoder/common/mcp_tools/verify_functionality.py +202 -0
- autocoder/common/model_speed_tester.py +32 -26
- autocoder/common/priority_directory_finder/__init__.py +142 -0
- autocoder/common/priority_directory_finder/examples.py +230 -0
- autocoder/common/priority_directory_finder/finder.py +283 -0
- autocoder/common/priority_directory_finder/models.py +236 -0
- autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
- autocoder/common/project_scanner/__init__.py +18 -0
- autocoder/common/project_scanner/compat.py +77 -0
- autocoder/common/project_scanner/scanner.py +436 -0
- autocoder/common/project_tracker/__init__.py +27 -0
- autocoder/common/project_tracker/api.py +228 -0
- autocoder/common/project_tracker/demo.py +272 -0
- autocoder/common/project_tracker/tracker.py +487 -0
- autocoder/common/project_tracker/types.py +53 -0
- autocoder/common/pruner/__init__.py +67 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
- autocoder/common/pruner/conversation_message_ids_api.py +386 -0
- autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
- autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
- autocoder/common/pruner/conversation_normalizer.py +347 -0
- autocoder/common/pruner/conversation_pruner.py +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
- autocoder/common/pruner/test_conversation_normalizer.py +502 -0
- autocoder/common/pruner/test_tool_content_detector.py +324 -0
- autocoder/common/pruner/tool_content_detector.py +227 -0
- autocoder/common/pruner/tools/__init__.py +18 -0
- autocoder/common/pruner/tools/query_message_ids.py +264 -0
- autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
- autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
- autocoder/common/pull_requests/__init__.py +9 -1
- autocoder/common/pull_requests/utils.py +122 -1
- autocoder/common/rag_manager/rag_manager.py +36 -40
- autocoder/common/rulefiles/__init__.py +53 -1
- autocoder/common/rulefiles/api.py +250 -0
- autocoder/common/rulefiles/core/__init__.py +14 -0
- autocoder/common/rulefiles/core/manager.py +241 -0
- autocoder/common/rulefiles/core/selector.py +805 -0
- autocoder/common/rulefiles/models/__init__.py +20 -0
- autocoder/common/rulefiles/models/index.py +16 -0
- autocoder/common/rulefiles/models/init_rule.py +18 -0
- autocoder/common/rulefiles/models/rule_file.py +18 -0
- autocoder/common/rulefiles/models/rule_relevance.py +14 -0
- autocoder/common/rulefiles/models/summary.py +16 -0
- autocoder/common/rulefiles/test_rulefiles.py +776 -0
- autocoder/common/rulefiles/utils/__init__.py +34 -0
- autocoder/common/rulefiles/utils/monitor.py +86 -0
- autocoder/common/rulefiles/utils/parser.py +230 -0
- autocoder/common/save_formatted_log.py +67 -10
- autocoder/common/search_replace.py +8 -1
- autocoder/common/search_replace_patch/__init__.py +24 -0
- autocoder/common/search_replace_patch/base.py +115 -0
- autocoder/common/search_replace_patch/manager.py +248 -0
- autocoder/common/search_replace_patch/patch_replacer.py +304 -0
- autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
- autocoder/common/search_replace_patch/string_replacer.py +181 -0
- autocoder/common/search_replace_patch/tests/__init__.py +3 -0
- autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
- autocoder/common/search_replace_patch/tests/test_base.py +188 -0
- autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
- autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
- autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
- autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
- autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
- autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
- autocoder/common/shell_commands/__init__.py +197 -0
- autocoder/common/shell_commands/background_process_notifier.py +346 -0
- autocoder/common/shell_commands/command_executor.py +1127 -0
- autocoder/common/shell_commands/error_recovery.py +541 -0
- autocoder/common/shell_commands/exceptions.py +120 -0
- autocoder/common/shell_commands/interactive_executor.py +476 -0
- autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
- autocoder/common/shell_commands/interactive_process.py +744 -0
- autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
- autocoder/common/shell_commands/monitoring.py +529 -0
- autocoder/common/shell_commands/process_cleanup.py +386 -0
- autocoder/common/shell_commands/process_manager.py +606 -0
- autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
- autocoder/common/shell_commands/tests/__init__.py +6 -0
- autocoder/common/shell_commands/tests/conftest.py +118 -0
- autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
- autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
- autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
- autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
- autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
- autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
- autocoder/common/shell_commands/tests/test_integration.py +664 -0
- autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
- autocoder/common/shell_commands/tests/test_performance.py +632 -0
- autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
- autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
- autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
- autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
- autocoder/common/shell_commands/timeout_config.py +315 -0
- autocoder/common/shell_commands/timeout_manager.py +352 -0
- autocoder/common/terminal_paste/__init__.py +14 -0
- autocoder/common/terminal_paste/demo.py +145 -0
- autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
- autocoder/common/terminal_paste/paste_handler.py +200 -0
- autocoder/common/terminal_paste/paste_manager.py +118 -0
- autocoder/common/terminal_paste/tests/__init__.py +1 -0
- autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
- autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
- autocoder/common/terminal_paste/utils.py +163 -0
- autocoder/common/test_autocoder_args.py +232 -0
- autocoder/common/test_env_manager.py +173 -0
- autocoder/common/test_env_manager_integration.py +159 -0
- autocoder/common/text_similarity/__init__.py +9 -0
- autocoder/common/text_similarity/demo.py +216 -0
- autocoder/common/text_similarity/examples.py +266 -0
- autocoder/common/text_similarity/test_text_similarity.py +306 -0
- autocoder/common/text_similarity/text_similarity.py +194 -0
- autocoder/common/text_similarity/utils.py +125 -0
- autocoder/common/todos/__init__.py +61 -0
- autocoder/common/todos/cache/__init__.py +16 -0
- autocoder/common/todos/cache/base_cache.py +89 -0
- autocoder/common/todos/cache/cache_manager.py +228 -0
- autocoder/common/todos/cache/memory_cache.py +225 -0
- autocoder/common/todos/config.py +155 -0
- autocoder/common/todos/exceptions.py +35 -0
- autocoder/common/todos/get_todo_manager.py +161 -0
- autocoder/common/todos/manager.py +537 -0
- autocoder/common/todos/models.py +239 -0
- autocoder/common/todos/storage/__init__.py +14 -0
- autocoder/common/todos/storage/base_storage.py +76 -0
- autocoder/common/todos/storage/file_storage.py +278 -0
- autocoder/common/tokens/counter.py +24 -2
- autocoder/common/tools_manager/__init__.py +17 -0
- autocoder/common/tools_manager/examples.py +162 -0
- autocoder/common/tools_manager/manager.py +385 -0
- autocoder/common/tools_manager/models.py +39 -0
- autocoder/common/tools_manager/test_tools_manager.py +303 -0
- autocoder/common/tools_manager/utils.py +191 -0
- autocoder/common/v2/agent/agentic_callbacks.py +270 -0
- autocoder/common/v2/agent/agentic_edit.py +2699 -1856
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
- autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
- autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
- autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
- autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
- autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
- autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
- autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
- autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
- autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
- autocoder/common/v2/agent/agentic_edit_types.py +343 -9
- autocoder/common/v2/agent/runner/__init__.py +3 -3
- autocoder/common/v2/agent/runner/base_runner.py +12 -26
- autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
- autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
- autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
- autocoder/common/v2/agent/runner/tool_display.py +557 -159
- autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
- autocoder/common/v2/agent/test_agentic_edit.py +194 -0
- autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
- autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
- autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
- autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
- autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
- autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
- autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
- autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
- autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
- autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
- autocoder/common/v2/code_auto_generate.py +136 -78
- autocoder/common/v2/code_auto_generate_diff.py +135 -79
- autocoder/common/v2/code_auto_generate_editblock.py +174 -99
- autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
- autocoder/common/v2/code_auto_merge.py +1 -1
- autocoder/common/v2/code_auto_merge_editblock.py +13 -1
- autocoder/common/v2/code_diff_manager.py +3 -3
- autocoder/common/v2/code_editblock_manager.py +4 -14
- autocoder/common/v2/code_manager.py +1 -1
- autocoder/common/v2/code_strict_diff_manager.py +2 -2
- autocoder/common/wrap_llm_hint/__init__.py +10 -0
- autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
- autocoder/common/wrap_llm_hint/utils.py +432 -0
- autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
- autocoder/completer/__init__.py +8 -0
- autocoder/completer/command_completer_v2.py +1051 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +165 -7
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +116 -124
- autocoder/{agent → index/filter}/agentic_filter.py +322 -333
- autocoder/index/filter/normal_filter.py +5 -11
- autocoder/index/filter/quick_filter.py +1 -1
- autocoder/index/index.py +36 -9
- autocoder/index/tests/__init__.py +1 -0
- autocoder/index/tests/run_tests.py +195 -0
- autocoder/index/tests/test_entry.py +303 -0
- autocoder/index/tests/test_index_manager.py +314 -0
- autocoder/index/tests/test_module_integration.py +300 -0
- autocoder/index/tests/test_symbols_utils.py +183 -0
- autocoder/inner/__init__.py +4 -0
- autocoder/inner/agentic.py +932 -0
- autocoder/inner/async_command_handler.py +992 -0
- autocoder/inner/conversation_command_handlers.py +623 -0
- autocoder/inner/merge_command_handler.py +213 -0
- autocoder/inner/queue_command_handler.py +684 -0
- autocoder/models.py +95 -266
- autocoder/plugins/git_helper_plugin.py +31 -29
- autocoder/plugins/token_helper_plugin.py +65 -46
- autocoder/pyproject/__init__.py +32 -29
- autocoder/rag/agentic_rag.py +215 -75
- autocoder/rag/cache/simple_cache.py +1 -2
- autocoder/rag/loaders/image_loader.py +1 -1
- autocoder/rag/long_context_rag.py +42 -26
- autocoder/rag/qa_conversation_strategy.py +1 -1
- autocoder/rag/terminal/__init__.py +17 -0
- autocoder/rag/terminal/args.py +581 -0
- autocoder/rag/terminal/bootstrap.py +61 -0
- autocoder/rag/terminal/command_handlers.py +653 -0
- autocoder/rag/terminal/formatters/__init__.py +20 -0
- autocoder/rag/terminal/formatters/base.py +70 -0
- autocoder/rag/terminal/formatters/json_format.py +66 -0
- autocoder/rag/terminal/formatters/stream_json.py +95 -0
- autocoder/rag/terminal/formatters/text.py +28 -0
- autocoder/rag/terminal/init.py +120 -0
- autocoder/rag/terminal/utils.py +106 -0
- autocoder/rag/test_agentic_rag.py +389 -0
- autocoder/rag/test_doc_filter.py +3 -3
- autocoder/rag/test_long_context_rag.py +1 -1
- autocoder/rag/test_token_limiter.py +517 -10
- autocoder/rag/token_counter.py +3 -0
- autocoder/rag/token_limiter.py +19 -15
- autocoder/rag/tools/__init__.py +26 -2
- autocoder/rag/tools/bochaai_example.py +343 -0
- autocoder/rag/tools/bochaai_sdk.py +541 -0
- autocoder/rag/tools/metaso_example.py +268 -0
- autocoder/rag/tools/metaso_sdk.py +417 -0
- autocoder/rag/tools/recall_tool.py +28 -7
- autocoder/rag/tools/run_integration_tests.py +204 -0
- autocoder/rag/tools/test_all_providers.py +318 -0
- autocoder/rag/tools/test_bochaai_integration.py +482 -0
- autocoder/rag/tools/test_final_integration.py +215 -0
- autocoder/rag/tools/test_metaso_integration.py +424 -0
- autocoder/rag/tools/test_metaso_real.py +171 -0
- autocoder/rag/tools/test_web_crawl_tool.py +639 -0
- autocoder/rag/tools/test_web_search_tool.py +509 -0
- autocoder/rag/tools/todo_read_tool.py +202 -0
- autocoder/rag/tools/todo_write_tool.py +412 -0
- autocoder/rag/tools/web_crawl_tool.py +634 -0
- autocoder/rag/tools/web_search_tool.py +558 -0
- autocoder/rag/tools/web_tools_example.py +119 -0
- autocoder/rag/types.py +16 -0
- autocoder/rag/variable_holder.py +4 -2
- autocoder/rags.py +86 -79
- autocoder/regexproject/__init__.py +23 -21
- autocoder/sdk/__init__.py +46 -190
- autocoder/sdk/api.py +370 -0
- autocoder/sdk/async_runner/__init__.py +26 -0
- autocoder/sdk/async_runner/async_executor.py +650 -0
- autocoder/sdk/async_runner/async_handler.py +356 -0
- autocoder/sdk/async_runner/markdown_processor.py +595 -0
- autocoder/sdk/async_runner/task_metadata.py +284 -0
- autocoder/sdk/async_runner/worktree_manager.py +438 -0
- autocoder/sdk/cli/__init__.py +2 -5
- autocoder/sdk/cli/formatters.py +28 -204
- autocoder/sdk/cli/handlers.py +77 -44
- autocoder/sdk/cli/main.py +154 -171
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -109
- autocoder/sdk/core/bridge.py +297 -115
- autocoder/sdk/exceptions.py +18 -12
- autocoder/sdk/formatters/__init__.py +19 -0
- autocoder/sdk/formatters/input.py +64 -0
- autocoder/sdk/formatters/output.py +247 -0
- autocoder/sdk/formatters/stream.py +54 -0
- autocoder/sdk/models/__init__.py +6 -5
- autocoder/sdk/models/options.py +55 -18
- autocoder/sdk/utils/formatters.py +27 -195
- autocoder/suffixproject/__init__.py +28 -25
- autocoder/terminal/__init__.py +14 -0
- autocoder/terminal/app.py +454 -0
- autocoder/terminal/args.py +32 -0
- autocoder/terminal/bootstrap.py +178 -0
- autocoder/terminal/command_processor.py +521 -0
- autocoder/terminal/command_registry.py +57 -0
- autocoder/terminal/help.py +97 -0
- autocoder/terminal/tasks/__init__.py +5 -0
- autocoder/terminal/tasks/background.py +77 -0
- autocoder/terminal/tasks/task_event.py +70 -0
- autocoder/terminal/ui/__init__.py +13 -0
- autocoder/terminal/ui/completer.py +268 -0
- autocoder/terminal/ui/keybindings.py +75 -0
- autocoder/terminal/ui/session.py +41 -0
- autocoder/terminal/ui/toolbar.py +64 -0
- autocoder/terminal/utils/__init__.py +13 -0
- autocoder/terminal/utils/errors.py +18 -0
- autocoder/terminal/utils/paths.py +19 -0
- autocoder/terminal/utils/shell.py +43 -0
- autocoder/terminal_v3/__init__.py +10 -0
- autocoder/terminal_v3/app.py +201 -0
- autocoder/terminal_v3/handlers/__init__.py +5 -0
- autocoder/terminal_v3/handlers/command_handler.py +131 -0
- autocoder/terminal_v3/models/__init__.py +6 -0
- autocoder/terminal_v3/models/conversation_buffer.py +214 -0
- autocoder/terminal_v3/models/message.py +50 -0
- autocoder/terminal_v3/models/tool_display.py +247 -0
- autocoder/terminal_v3/ui/__init__.py +7 -0
- autocoder/terminal_v3/ui/keybindings.py +56 -0
- autocoder/terminal_v3/ui/layout.py +141 -0
- autocoder/terminal_v3/ui/styles.py +43 -0
- autocoder/tsproject/__init__.py +23 -23
- autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
- autocoder/utils/llms.py +88 -80
- autocoder/utils/math_utils.py +101 -0
- autocoder/utils/model_provider_selector.py +16 -4
- autocoder/utils/operate_config_api.py +33 -5
- autocoder/utils/thread_utils.py +2 -2
- autocoder/version.py +4 -2
- autocoder/workflow_agents/__init__.py +84 -0
- autocoder/workflow_agents/agent.py +143 -0
- autocoder/workflow_agents/exceptions.py +573 -0
- autocoder/workflow_agents/executor.py +489 -0
- autocoder/workflow_agents/loader.py +737 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +172 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-1.0.0.dist-info/METADATA +0 -396
- auto_coder-1.0.0.dist-info/RECORD +0 -442
- auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
- autocoder/auto_coder_server.py +0 -672
- autocoder/benchmark.py +0 -138
- autocoder/common/ac_style_command_parser/example.py +0 -7
- autocoder/common/cleaner.py +0 -31
- autocoder/common/command_completer_v2.py +0 -615
- autocoder/common/context_pruner.py +0 -477
- autocoder/common/conversation_pruner.py +0 -132
- autocoder/common/directory_cache/__init__.py +0 -1
- autocoder/common/directory_cache/cache.py +0 -192
- autocoder/common/directory_cache/test_cache.py +0 -190
- autocoder/common/file_checkpoint/examples.py +0 -217
- autocoder/common/llm_friendly_package_example.py +0 -138
- autocoder/common/llm_friendly_package_test.py +0 -63
- autocoder/common/pull_requests/test_module.py +0 -1
- autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
- autocoder/common/text.py +0 -30
- autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
- autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
- autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
- autocoder/common/v2/agent/agentic_tool_display.py +0 -183
- autocoder/plugins/dynamic_completion_example.py +0 -148
- autocoder/plugins/sample_plugin.py +0 -160
- autocoder/sdk/cli/__main__.py +0 -26
- autocoder/sdk/cli/completion_wrapper.py +0 -38
- autocoder/sdk/cli/install_completion.py +0 -301
- autocoder/sdk/models/messages.py +0 -209
- autocoder/sdk/session/__init__.py +0 -32
- autocoder/sdk/session/session.py +0 -106
- autocoder/sdk/session/session_manager.py +0 -56
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Linter-enabled tool resolver that extends BaseToolResolver with linting capabilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, List
|
|
6
|
+
from autocoder.common.v2.agent.agentic_edit_types import BaseTool, ToolResult
|
|
7
|
+
from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
|
|
8
|
+
from autocoder.common.v2.agent.agentic_edit_tools.linter_config_models import LinterConfig
|
|
9
|
+
from autocoder.common import AutoCoderArgs
|
|
10
|
+
from autocoder.common.linter_core.config_loader import load_linter_config
|
|
11
|
+
import typing
|
|
12
|
+
import os
|
|
13
|
+
import json
|
|
14
|
+
from loguru import logger
|
|
15
|
+
|
|
16
|
+
if typing.TYPE_CHECKING:
|
|
17
|
+
from autocoder.common.v2.agent.agentic_edit import AgenticEdit
|
|
18
|
+
from autocoder.common.linter_core.linter_manager import LinterManager
|
|
19
|
+
from autocoder.common.v2.agent.agentic_edit_tools.lint_report import LintReport
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class LinterEnabledToolResolver(BaseToolResolver):
|
|
23
|
+
"""
|
|
24
|
+
Tool resolver with integrated linter support.
|
|
25
|
+
|
|
26
|
+
This class extends BaseToolResolver to provide linting capabilities
|
|
27
|
+
for tools that modify files.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, agent: Optional['AgenticEdit'], tool: BaseTool, args: AutoCoderArgs):
|
|
31
|
+
"""
|
|
32
|
+
Initializes the resolver with linter support.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
agent: The AutoCoder agent instance.
|
|
36
|
+
tool: The Pydantic model instance representing the tool call.
|
|
37
|
+
args: Additional arguments needed for execution (e.g., source_dir).
|
|
38
|
+
"""
|
|
39
|
+
super().__init__(agent, tool, args)
|
|
40
|
+
|
|
41
|
+
# Initialize linter
|
|
42
|
+
self.linter_manager: Optional['LinterManager'] = None
|
|
43
|
+
self.linter_config: Optional[LinterConfig] = None
|
|
44
|
+
self._init_linter()
|
|
45
|
+
|
|
46
|
+
def _init_linter(self):
|
|
47
|
+
"""初始化 Linter 管理器"""
|
|
48
|
+
try:
|
|
49
|
+
# Load and validate linter configuration using the centralized loader
|
|
50
|
+
source_dir = getattr(self.args, 'source_dir', None)
|
|
51
|
+
linter_config_path = getattr(self.args, 'linter_config_path', None)
|
|
52
|
+
|
|
53
|
+
raw_config = load_linter_config(
|
|
54
|
+
config_path=linter_config_path,
|
|
55
|
+
source_dir=source_dir
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
self.linter_config = LinterConfig.from_dict(raw_config)
|
|
59
|
+
|
|
60
|
+
# Check if linter is enabled
|
|
61
|
+
if not self.linter_config.enabled:
|
|
62
|
+
logger.debug("Linter is disabled in configuration")
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
# Import and initialize LinterManager
|
|
66
|
+
from autocoder.common.linter_core.linter_manager import LinterManager
|
|
67
|
+
|
|
68
|
+
# Convert to manager-compatible config
|
|
69
|
+
manager_config = self.linter_config.to_manager_config()
|
|
70
|
+
|
|
71
|
+
self.linter_manager = LinterManager(manager_config, source_dir=source_dir)
|
|
72
|
+
logger.info("Linter manager initialized successfully with validated configuration")
|
|
73
|
+
|
|
74
|
+
except ImportError as e:
|
|
75
|
+
logger.warning(f"Linter module not available: {e}")
|
|
76
|
+
except ValueError as e:
|
|
77
|
+
logger.error(f"Invalid linter configuration: {e}")
|
|
78
|
+
# Use default disabled config on validation error
|
|
79
|
+
self.linter_config = LinterConfig(enabled=False)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logger.error(f"Failed to initialize linter: {e}")
|
|
82
|
+
# Use default disabled config on error
|
|
83
|
+
self.linter_config = LinterConfig(enabled=False)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def should_lint(self, file_path: str) -> bool:
|
|
87
|
+
"""判断文件是否需要 lint 检查"""
|
|
88
|
+
if not self.linter_manager or not self.linter_config:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
# Use the Pydantic model's method
|
|
92
|
+
should_lint = self.linter_config.should_lint_file(file_path)
|
|
93
|
+
|
|
94
|
+
if not should_lint:
|
|
95
|
+
logger.debug(f"File {file_path} excluded from linting")
|
|
96
|
+
|
|
97
|
+
return should_lint
|
|
98
|
+
|
|
99
|
+
def lint_files(self, file_paths: List[str]) -> Optional['LintReport']:
|
|
100
|
+
"""对文件运行 linter 检查"""
|
|
101
|
+
if not self.linter_manager:
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
from autocoder.common.v2.agent.agentic_edit_tools.lint_report import LintReport
|
|
106
|
+
|
|
107
|
+
# Convert relative paths to absolute paths
|
|
108
|
+
abs_file_paths = []
|
|
109
|
+
source_dir = self.args.source_dir or "."
|
|
110
|
+
for file_path in file_paths:
|
|
111
|
+
if not os.path.isabs(file_path):
|
|
112
|
+
abs_path = os.path.abspath(os.path.join(source_dir, file_path))
|
|
113
|
+
else:
|
|
114
|
+
abs_path = file_path
|
|
115
|
+
abs_file_paths.append(abs_path)
|
|
116
|
+
|
|
117
|
+
# Run linter
|
|
118
|
+
results = self.linter_manager.lint_files(abs_file_paths, parallel=False)
|
|
119
|
+
|
|
120
|
+
# Create report
|
|
121
|
+
report = LintReport.from_linter_results(results, self.linter_manager)
|
|
122
|
+
|
|
123
|
+
return report
|
|
124
|
+
|
|
125
|
+
except Exception as e:
|
|
126
|
+
logger.error(f"Error running linter: {e}")
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
def handle_lint_results(self, original_result: ToolResult, lint_report: Optional['LintReport']) -> ToolResult:
|
|
130
|
+
"""处理 lint 结果并更新 ToolResult"""
|
|
131
|
+
if not lint_report or not self.linter_config:
|
|
132
|
+
return original_result
|
|
133
|
+
|
|
134
|
+
# Get configuration from Pydantic model
|
|
135
|
+
mode = self.linter_config.mode
|
|
136
|
+
report_format = self.linter_config.report.format
|
|
137
|
+
include_in_result = self.linter_config.report.include_in_result
|
|
138
|
+
|
|
139
|
+
# Generate report text based on format
|
|
140
|
+
if report_format == 'detailed':
|
|
141
|
+
report_text = lint_report.to_markdown()
|
|
142
|
+
elif report_format == 'json':
|
|
143
|
+
report_text = json.dumps(lint_report.to_json(), indent=2)
|
|
144
|
+
else: # simple
|
|
145
|
+
report_text = lint_report.to_simple_text()
|
|
146
|
+
|
|
147
|
+
# Handle based on mode
|
|
148
|
+
if mode == 'blocking' and lint_report.has_issues():
|
|
149
|
+
# Blocking mode - fail the operation
|
|
150
|
+
return ToolResult(
|
|
151
|
+
success=False,
|
|
152
|
+
message=f"Operation blocked due to lint issues:\n{report_text}",
|
|
153
|
+
content={'lint_report': lint_report.to_json()} if include_in_result else None
|
|
154
|
+
)
|
|
155
|
+
elif mode == 'silent':
|
|
156
|
+
# Silent mode - don't modify the result
|
|
157
|
+
if include_in_result and original_result.content:
|
|
158
|
+
if isinstance(original_result.content, dict):
|
|
159
|
+
original_result.content['lint_report'] = lint_report.to_json()
|
|
160
|
+
return original_result
|
|
161
|
+
else: # warning mode (default)
|
|
162
|
+
# Warning mode - append lint results to message
|
|
163
|
+
if lint_report.has_issues():
|
|
164
|
+
new_message = f"{original_result.message}\n\n{report_text}"
|
|
165
|
+
else:
|
|
166
|
+
new_message = f"{original_result.message}\n✅ Lint check passed - No issues found"
|
|
167
|
+
|
|
168
|
+
# Create new result with updated message and content
|
|
169
|
+
new_content = original_result.content or {}
|
|
170
|
+
if include_in_result:
|
|
171
|
+
if isinstance(new_content, dict):
|
|
172
|
+
new_content['lint_report'] = lint_report.to_json()
|
|
173
|
+
else:
|
|
174
|
+
new_content = {'lint_report': lint_report.to_json()}
|
|
175
|
+
|
|
176
|
+
return ToolResult(
|
|
177
|
+
success=original_result.success,
|
|
178
|
+
message=new_message,
|
|
179
|
+
content=new_content if new_content else None
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
def resolve(self) -> ToolResult:
|
|
183
|
+
"""
|
|
184
|
+
Must be implemented by subclasses.
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
A ToolResult object indicating success or failure and a message.
|
|
188
|
+
"""
|
|
189
|
+
raise NotImplementedError("Subclasses must implement the resolve method")
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import Dict, Any, Optional, List, Set, Union
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
3
5
|
from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
|
|
4
6
|
from autocoder.common.v2.agent.agentic_edit_types import ListFilesTool, ToolResult # Import ToolResult from types
|
|
5
7
|
from loguru import logger
|
|
@@ -12,97 +14,148 @@ if typing.TYPE_CHECKING:
|
|
|
12
14
|
from autocoder.common.v2.agent.agentic_edit import AgenticEdit
|
|
13
15
|
|
|
14
16
|
|
|
17
|
+
class ListErrorInfo(BaseModel):
|
|
18
|
+
"""Information about errors encountered during list operations."""
|
|
19
|
+
file_path: str = Field(..., description="Path to the file/directory that caused the error")
|
|
20
|
+
error_type: str = Field(..., description="Type of error (e.g., 'PermissionError', 'FileNotFoundError')")
|
|
21
|
+
error_message: str = Field(..., description="Detailed error message")
|
|
22
|
+
|
|
23
|
+
class Config:
|
|
24
|
+
"""Pydantic configuration."""
|
|
25
|
+
frozen = True
|
|
26
|
+
extra = "forbid"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ListResultContent(BaseModel):
|
|
30
|
+
"""Content structure for list operation results."""
|
|
31
|
+
files: List[str] = Field(..., description="List of files and directories found")
|
|
32
|
+
errors: List[ListErrorInfo] = Field(..., description="List of errors encountered during listing")
|
|
33
|
+
|
|
34
|
+
class Config:
|
|
35
|
+
"""Pydantic configuration."""
|
|
36
|
+
frozen = True
|
|
37
|
+
extra = "forbid"
|
|
38
|
+
|
|
39
|
+
|
|
15
40
|
class ListFilesToolResolver(BaseToolResolver):
|
|
16
41
|
def __init__(self, agent: Optional['AgenticEdit'], tool: ListFilesTool, args: AutoCoderArgs):
|
|
17
42
|
super().__init__(agent, tool, args)
|
|
18
43
|
self.tool: ListFilesTool = tool # For type hinting
|
|
19
|
-
self.shadow_manager = self.agent.shadow_manager
|
|
20
44
|
|
|
21
|
-
def list_files_in_dir(self, base_dir: str, recursive: bool, source_dir: str, is_outside_source: bool) -> Set[str]:
|
|
22
|
-
"""Helper function to list files in a directory
|
|
45
|
+
def list_files_in_dir(self, base_dir: str, recursive: bool, source_dir: str, is_outside_source: bool) -> tuple[Set[str], List[ListErrorInfo]]:
|
|
46
|
+
"""Helper function to list files in a directory with error collection.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Tuple of (file set, error information list)
|
|
50
|
+
"""
|
|
23
51
|
result = set()
|
|
52
|
+
errors = []
|
|
53
|
+
|
|
24
54
|
try:
|
|
25
55
|
if recursive:
|
|
26
56
|
for root, dirs, files in os.walk(base_dir):
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
57
|
+
try:
|
|
58
|
+
# Modify dirs in-place to skip ignored dirs early
|
|
59
|
+
accessible_dirs = []
|
|
60
|
+
for d in dirs:
|
|
61
|
+
dir_path = os.path.join(root, d)
|
|
62
|
+
if should_ignore(dir_path):
|
|
63
|
+
continue
|
|
64
|
+
try:
|
|
65
|
+
# Test if we can access the directory
|
|
66
|
+
os.listdir(dir_path)
|
|
67
|
+
accessible_dirs.append(d)
|
|
68
|
+
except (PermissionError, OSError) as e:
|
|
69
|
+
error_info = ListErrorInfo(
|
|
70
|
+
file_path=dir_path,
|
|
71
|
+
error_type=type(e).__name__,
|
|
72
|
+
error_message=f"Cannot access directory: {str(e)}"
|
|
73
|
+
)
|
|
74
|
+
errors.append(error_info)
|
|
75
|
+
logger.warning(f"Cannot access directory {dir_path}: {e}")
|
|
76
|
+
dirs[:] = accessible_dirs
|
|
77
|
+
|
|
78
|
+
# Process files in current directory
|
|
79
|
+
for name in files:
|
|
80
|
+
full_path = os.path.join(root, name)
|
|
81
|
+
if should_ignore(full_path):
|
|
82
|
+
continue
|
|
83
|
+
try:
|
|
84
|
+
# Test if we can access the file
|
|
85
|
+
os.stat(full_path)
|
|
86
|
+
display_path = os.path.relpath(full_path, source_dir) if not is_outside_source else full_path
|
|
87
|
+
result.add(display_path)
|
|
88
|
+
except (PermissionError, OSError) as e:
|
|
89
|
+
error_info = ListErrorInfo(
|
|
90
|
+
file_path=full_path,
|
|
91
|
+
error_type=type(e).__name__,
|
|
92
|
+
error_message=f"Cannot access file: {str(e)}"
|
|
93
|
+
)
|
|
94
|
+
errors.append(error_info)
|
|
95
|
+
logger.warning(f"Cannot access file {full_path}: {e}")
|
|
96
|
+
|
|
97
|
+
# Add accessible directories to result
|
|
98
|
+
for d in dirs:
|
|
99
|
+
full_path = os.path.join(root, d)
|
|
100
|
+
display_path = os.path.relpath(full_path, source_dir) if not is_outside_source else full_path
|
|
101
|
+
result.add(display_path + "/")
|
|
102
|
+
|
|
103
|
+
except (PermissionError, OSError) as e:
|
|
104
|
+
error_info = ListErrorInfo(
|
|
105
|
+
file_path=root,
|
|
106
|
+
error_type=type(e).__name__,
|
|
107
|
+
error_message=f"Cannot access directory during walk: {str(e)}"
|
|
108
|
+
)
|
|
109
|
+
errors.append(error_info)
|
|
110
|
+
logger.warning(f"Cannot access directory {root} during walk: {e}")
|
|
111
|
+
break # Stop walking this branch
|
|
112
|
+
else:
|
|
113
|
+
try:
|
|
114
|
+
items = os.listdir(base_dir)
|
|
115
|
+
for item in items:
|
|
116
|
+
full_path = os.path.join(base_dir, item)
|
|
31
117
|
if should_ignore(full_path):
|
|
32
118
|
continue
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
119
|
+
try:
|
|
120
|
+
display_path = os.path.relpath(full_path, source_dir) if not is_outside_source else full_path
|
|
121
|
+
if os.path.isdir(full_path):
|
|
122
|
+
result.add(display_path + "/")
|
|
123
|
+
else:
|
|
124
|
+
result.add(display_path)
|
|
125
|
+
except (PermissionError, OSError) as e:
|
|
126
|
+
error_info = ListErrorInfo(
|
|
127
|
+
file_path=full_path,
|
|
128
|
+
error_type=type(e).__name__,
|
|
129
|
+
error_message=f"Cannot access item: {str(e)}"
|
|
130
|
+
)
|
|
131
|
+
errors.append(error_info)
|
|
132
|
+
logger.warning(f"Cannot access item {full_path}: {e}")
|
|
133
|
+
except (PermissionError, OSError) as e:
|
|
134
|
+
error_info = ListErrorInfo(
|
|
135
|
+
file_path=base_dir,
|
|
136
|
+
error_type=type(e).__name__,
|
|
137
|
+
error_message=f"Cannot list directory: {str(e)}"
|
|
138
|
+
)
|
|
139
|
+
errors.append(error_info)
|
|
140
|
+
logger.warning(f"Cannot list directory {base_dir}: {e}")
|
|
49
141
|
except Exception as e:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"""List files using shadow manager for path translation"""
|
|
55
|
-
# Security check: Allow listing outside source_dir IF the original path is outside?
|
|
56
|
-
is_outside_source = not absolute_list_path.startswith(absolute_source_dir)
|
|
57
|
-
if is_outside_source:
|
|
58
|
-
logger.warning(f"Listing path is outside the project source directory: {list_path_str}")
|
|
59
|
-
|
|
60
|
-
# Check if shadow directory exists for this path
|
|
61
|
-
shadow_exists = False
|
|
62
|
-
shadow_dir_path = None
|
|
63
|
-
if self.shadow_manager:
|
|
64
|
-
try:
|
|
65
|
-
shadow_dir_path = self.shadow_manager.to_shadow_path(absolute_list_path)
|
|
66
|
-
if os.path.exists(shadow_dir_path) and os.path.isdir(shadow_dir_path):
|
|
67
|
-
shadow_exists = True
|
|
68
|
-
except Exception as e:
|
|
69
|
-
logger.warning(f"Error checking shadow path for {absolute_list_path}: {e}")
|
|
70
|
-
|
|
71
|
-
# Validate that at least one of the directories exists
|
|
72
|
-
if not os.path.exists(absolute_list_path) and not shadow_exists:
|
|
73
|
-
return ToolResult(success=False, message=f"Error: Path not found: {list_path_str}")
|
|
74
|
-
if os.path.exists(absolute_list_path) and not os.path.isdir(absolute_list_path):
|
|
75
|
-
return ToolResult(success=False, message=f"Error: Path is not a directory: {list_path_str}")
|
|
76
|
-
if shadow_exists and not os.path.isdir(shadow_dir_path):
|
|
77
|
-
return ToolResult(success=False, message=f"Error: Shadow path is not a directory: {shadow_dir_path}")
|
|
78
|
-
|
|
79
|
-
# Collect files from shadow and/or source directory
|
|
80
|
-
shadow_files_set = set()
|
|
81
|
-
if shadow_exists:
|
|
82
|
-
shadow_files_set = self.list_files_in_dir(shadow_dir_path, recursive, source_dir, is_outside_source)
|
|
83
|
-
|
|
84
|
-
source_files_set = set()
|
|
85
|
-
if os.path.exists(absolute_list_path) and os.path.isdir(absolute_list_path):
|
|
86
|
-
source_files_set = self.list_files_in_dir(absolute_list_path, recursive, source_dir, is_outside_source)
|
|
87
|
-
|
|
88
|
-
# Merge results, prioritizing shadow files if exist
|
|
89
|
-
if shadow_exists:
|
|
90
|
-
merged_files = shadow_files_set.union(
|
|
91
|
-
{f for f in source_files_set if f not in shadow_files_set}
|
|
142
|
+
error_info = ListErrorInfo(
|
|
143
|
+
file_path=base_dir,
|
|
144
|
+
error_type=type(e).__name__,
|
|
145
|
+
error_message=f"Unexpected error: {str(e)}"
|
|
92
146
|
)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
logger.info(message)
|
|
99
|
-
return sorted(merged_files)
|
|
100
|
-
except Exception as e:
|
|
101
|
-
logger.error(f"Error listing files in '{list_path_str}': {str(e)}")
|
|
102
|
-
return ToolResult(success=False, message=f"An unexpected error occurred while listing files: {str(e)}")
|
|
147
|
+
errors.append(error_info)
|
|
148
|
+
logger.warning(f"Unexpected error listing files in {base_dir}: {e}")
|
|
149
|
+
|
|
150
|
+
return result, errors
|
|
151
|
+
|
|
103
152
|
|
|
104
|
-
def list_files_normal(self, list_path_str: str, recursive: bool, source_dir: str, absolute_source_dir: str, absolute_list_path: str) -> Union[ToolResult, List[str]]:
|
|
105
|
-
"""List files directly without using shadow manager
|
|
153
|
+
def list_files_normal(self, list_path_str: str, recursive: bool, source_dir: str, absolute_source_dir: str, absolute_list_path: str) -> Union[ToolResult, tuple[List[str], List[ListErrorInfo]]]:
|
|
154
|
+
"""List files directly without using shadow manager with error collection.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
ToolResult on error, or tuple of (file list, error information) on success
|
|
158
|
+
"""
|
|
106
159
|
# Security check: Allow listing outside source_dir IF the original path is outside?
|
|
107
160
|
is_outside_source = not absolute_list_path.startswith(absolute_source_dir)
|
|
108
161
|
if is_outside_source:
|
|
@@ -115,14 +168,13 @@ class ListFilesToolResolver(BaseToolResolver):
|
|
|
115
168
|
return ToolResult(success=False, message=f"Error: Path is not a directory: {list_path_str}")
|
|
116
169
|
|
|
117
170
|
# Collect files from the directory
|
|
118
|
-
files_set = self.list_files_in_dir(absolute_list_path, recursive, source_dir, is_outside_source)
|
|
171
|
+
files_set, errors = self.list_files_in_dir(absolute_list_path, recursive, source_dir, is_outside_source)
|
|
119
172
|
|
|
120
173
|
try:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return sorted(files_set)
|
|
174
|
+
sorted_files = sorted(files_set)
|
|
175
|
+
return sorted_files, errors
|
|
124
176
|
except Exception as e:
|
|
125
|
-
logger.error(f"Error
|
|
177
|
+
logger.error(f"Error sorting files in '{list_path_str}': {str(e)}")
|
|
126
178
|
return ToolResult(success=False, message=f"An unexpected error occurred while listing files: {str(e)}")
|
|
127
179
|
|
|
128
180
|
def resolve(self) -> ToolResult:
|
|
@@ -133,23 +185,39 @@ class ListFilesToolResolver(BaseToolResolver):
|
|
|
133
185
|
absolute_source_dir = os.path.abspath(source_dir)
|
|
134
186
|
absolute_list_path = os.path.abspath(os.path.join(source_dir, list_path_str))
|
|
135
187
|
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
# Handle the case where the implementation returns a sorted list instead of a ToolResult
|
|
143
|
-
if isinstance(result, list):
|
|
144
|
-
total_items = len(result)
|
|
145
|
-
# Limit results to 200 if needed
|
|
146
|
-
if total_items > 200:
|
|
147
|
-
truncated_result = result[:200]
|
|
148
|
-
message = f"Successfully listed contents of '{list_path_str}' (Recursive: {recursive}). Found {total_items} items, showing only the first 200."
|
|
149
|
-
logger.info(message)
|
|
150
|
-
return ToolResult(success=True, message=message, content=truncated_result)
|
|
151
|
-
else:
|
|
152
|
-
message = f"Successfully listed contents of '{list_path_str}' (Recursive: {recursive}). Found {total_items} items."
|
|
153
|
-
return ToolResult(success=True, message=message, content=result)
|
|
154
|
-
else:
|
|
188
|
+
# Use the normal implementation since shadow_manager is no longer available
|
|
189
|
+
result = self.list_files_normal(list_path_str, recursive, source_dir, absolute_source_dir, absolute_list_path)
|
|
190
|
+
|
|
191
|
+
# Handle the case where the implementation returns a ToolResult (error case)
|
|
192
|
+
if isinstance(result, ToolResult):
|
|
155
193
|
return result
|
|
194
|
+
|
|
195
|
+
# Handle successful results (tuple of files and errors)
|
|
196
|
+
files_list, errors = result
|
|
197
|
+
total_items = len(files_list)
|
|
198
|
+
total_errors = len(errors)
|
|
199
|
+
|
|
200
|
+
# Prepare error summary for message
|
|
201
|
+
error_summary = ""
|
|
202
|
+
if total_errors > 0:
|
|
203
|
+
error_types = {}
|
|
204
|
+
for error in errors:
|
|
205
|
+
error_types[error.error_type] = error_types.get(error.error_type, 0) + 1
|
|
206
|
+
error_summary = f" Encountered {total_errors} errors: " + ", ".join([f"{count} {error_type}" for error_type, count in error_types.items()])
|
|
207
|
+
|
|
208
|
+
# Prepare content with both results and errors using Pydantic model
|
|
209
|
+
truncated_files = files_list[:200] if total_items > 200 else files_list
|
|
210
|
+
content_model = ListResultContent(
|
|
211
|
+
files=truncated_files,
|
|
212
|
+
errors=errors
|
|
213
|
+
)
|
|
214
|
+
content = content_model.model_dump()
|
|
215
|
+
|
|
216
|
+
# Limit results to 200 if needed
|
|
217
|
+
if total_items > 200:
|
|
218
|
+
message = f"Successfully listed contents of '{list_path_str}' (Recursive: {recursive}). Found {total_items} items, showing only the first 200.{error_summary}"
|
|
219
|
+
logger.info(message)
|
|
220
|
+
return ToolResult(success=True, message=message, content=content)
|
|
221
|
+
else:
|
|
222
|
+
message = f"Successfully listed contents of '{list_path_str}' (Recursive: {recursive}). Found {total_items} items.{error_summary}"
|
|
223
|
+
return ToolResult(success=True, message=message, content=content)
|