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,932 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import uuid
|
|
3
|
+
import yaml
|
|
4
|
+
import json
|
|
5
|
+
import byzerllm
|
|
6
|
+
from typing import List, Dict, Any, Optional, Tuple, Union, Generator
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.panel import Panel
|
|
9
|
+
from rich.markdown import Markdown
|
|
10
|
+
from copy import deepcopy
|
|
11
|
+
from loguru import logger as global_logger
|
|
12
|
+
from byzerllm.utils.str2model import to_model
|
|
13
|
+
from autocoder.index.filter.agentic_filter import AgenticFilterResponse
|
|
14
|
+
|
|
15
|
+
from autocoder.common import AutoCoderArgs
|
|
16
|
+
from autocoder.common.autocoderargs_parser import AutoCoderArgsParser
|
|
17
|
+
from autocoder.common.v2.agent.agentic_edit import AgenticEditRequest
|
|
18
|
+
from autocoder.common.v2.agent.agentic_edit_types import (
|
|
19
|
+
AgenticEditConversationConfig,
|
|
20
|
+
ConversationAction,
|
|
21
|
+
)
|
|
22
|
+
from autocoder.common.conversations.get_conversation_manager import (
|
|
23
|
+
get_conversation_manager,
|
|
24
|
+
)
|
|
25
|
+
from autocoder.common.v2.agent.runner import (
|
|
26
|
+
TerminalRunner,
|
|
27
|
+
FileBasedEventRunner,
|
|
28
|
+
)
|
|
29
|
+
from autocoder.utils.llms import get_single_llm
|
|
30
|
+
from autocoder.common.ac_style_command_parser import parse_query
|
|
31
|
+
from autocoder.common.core_config import get_memory_manager
|
|
32
|
+
from autocoder.utils import get_last_yaml_file
|
|
33
|
+
from autocoder.auto_coder import main as auto_coder_main
|
|
34
|
+
from byzerllm.utils.nontext import Image
|
|
35
|
+
from autocoder.chat_auto_coder_lang import get_message as get_i18n_message
|
|
36
|
+
|
|
37
|
+
from autocoder.inner.async_command_handler import AsyncCommandHandler
|
|
38
|
+
from autocoder.inner.queue_command_handler import QueueCommandHandler
|
|
39
|
+
from autocoder.inner.merge_command_handler import MergeCommandHandler
|
|
40
|
+
from autocoder.inner.conversation_command_handlers import (
|
|
41
|
+
ConversationNewCommandHandler,
|
|
42
|
+
ConversationResumeCommandHandler,
|
|
43
|
+
ConversationListCommandHandler,
|
|
44
|
+
ConversationRenameCommandHandler,
|
|
45
|
+
ConversationCommandCommandHandler,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class RunAgentic:
|
|
50
|
+
"""处理 /auto 指令的核心类"""
|
|
51
|
+
|
|
52
|
+
def __init__(self):
|
|
53
|
+
"""初始化 RunAgentic 类"""
|
|
54
|
+
self._console = Console()
|
|
55
|
+
self._conversation_config = AgenticEditConversationConfig(
|
|
56
|
+
action=ConversationAction.CONTINUE
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def run(
|
|
60
|
+
self,
|
|
61
|
+
query: str,
|
|
62
|
+
cancel_token: Optional[str] = None,
|
|
63
|
+
conversation_history: Optional[List[Dict[str, Any]]] = None,
|
|
64
|
+
) -> Optional[str]:
|
|
65
|
+
"""
|
|
66
|
+
处理/auto指令
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
query: 用户查询
|
|
70
|
+
cancel_token: 取消令牌
|
|
71
|
+
conversation_history: 对话历史
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
conversation_id: 对话ID
|
|
75
|
+
"""
|
|
76
|
+
# 1. 检查是否是 /help 命令
|
|
77
|
+
if self._handle_help_command(query):
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
# 2. 初始化上下文
|
|
81
|
+
args, llm = self._initialize_context(query)
|
|
82
|
+
if llm is None:
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
# 3. 解析命令信息
|
|
86
|
+
command_infos = parse_query(query)
|
|
87
|
+
|
|
88
|
+
# 3. 处理命令链
|
|
89
|
+
should_terminate, conversation_config = self._process_command_chain(
|
|
90
|
+
query, args, command_infos, llm, cancel_token
|
|
91
|
+
)
|
|
92
|
+
if should_terminate:
|
|
93
|
+
# 如果命令已处理,返回相应的值
|
|
94
|
+
if conversation_config is None:
|
|
95
|
+
return None # async/queue/merge 命令已处理
|
|
96
|
+
else:
|
|
97
|
+
return conversation_config.conversation_id # conversation 命令已处理
|
|
98
|
+
|
|
99
|
+
# 4. 设置任务查询
|
|
100
|
+
task_query = conversation_config.query if conversation_config.query else query
|
|
101
|
+
if not conversation_config.query:
|
|
102
|
+
conversation_config.query = task_query
|
|
103
|
+
|
|
104
|
+
# 5. 确保对话ID存在
|
|
105
|
+
self._ensure_conversation_id(conversation_config)
|
|
106
|
+
|
|
107
|
+
# 6. 执行任务
|
|
108
|
+
self._execute_runner(llm, args, conversation_config, task_query, cancel_token)
|
|
109
|
+
|
|
110
|
+
# 7. 刷新文件列表
|
|
111
|
+
self._refresh_completer()
|
|
112
|
+
|
|
113
|
+
return conversation_config.conversation_id
|
|
114
|
+
|
|
115
|
+
@byzerllm.prompt()
|
|
116
|
+
def _filter_query_reminder(self) -> str:
|
|
117
|
+
"""
|
|
118
|
+
---
|
|
119
|
+
[[REMINDER: You are in context discovery mode. Analyze the request above to identify relevant files, but DO NOT implement the request. Focus on thorough file discovery and understanding the codebase context.
|
|
120
|
+
|
|
121
|
+
You must output a JSON string with the following format in attempt_completion tool:
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"files": [
|
|
125
|
+
{"path": "/path/to/file1.py", "operation": "MODIFY"},
|
|
126
|
+
{"path": "/path/to/file2.md", "operation": "REFERENCE"},
|
|
127
|
+
{"path": "/path/to/new_file.txt", "operation": "ADD"},
|
|
128
|
+
{"path": "/path/to/old_file.log", "operation": "REMOVE"}
|
|
129
|
+
],
|
|
130
|
+
"reasoning": "Detailed explanation of your analysis process: what you searched for, what patterns you found, how you identified these files as relevant, and why each file would be involved in the context of the user's request."
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
Never stop unless you think you have found the enough files to satisfy the user's request.
|
|
134
|
+
]]
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
@byzerllm.prompt()
|
|
138
|
+
def _filter_plan(self) -> str:
|
|
139
|
+
"""
|
|
140
|
+
You are a context discovery assistant. Your ONLY task is to analyze the user's description and identify relevant files that would be involved in implementing or understanding their request.
|
|
141
|
+
|
|
142
|
+
IMPORTANT: You should NOT implement the user's request. Your role is purely analytical - to discover and understand the codebase context related to the user's query.
|
|
143
|
+
|
|
144
|
+
Even if the user says "modify XXX" or "implement YYY", you should:
|
|
145
|
+
1. Understand what files would be involved in such changes
|
|
146
|
+
2. Identify related components, dependencies, and configuration files
|
|
147
|
+
3. Find existing similar implementations for reference
|
|
148
|
+
4. Locate test files and documentation that would be relevant
|
|
149
|
+
|
|
150
|
+
Your analysis should be thorough but focused on FILE DISCOVERY, not task execution.
|
|
151
|
+
|
|
152
|
+
You must output a JSON string in the attempt_completion tool with this exact format:
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"files": [
|
|
156
|
+
{"path": "/path/to/file1.py", "operation": "MODIFY"},
|
|
157
|
+
{"path": "/path/to/file2.md", "operation": "REFERENCE"},
|
|
158
|
+
{"path": "/path/to/new_file.txt", "operation": "ADD"},
|
|
159
|
+
{"path": "/path/to/old_file.log", "operation": "REMOVE"}
|
|
160
|
+
],
|
|
161
|
+
"reasoning": "Detailed explanation of your analysis process: what you searched for, what patterns you found, how you identified these files as relevant, and why each file would be involved in the context of the user's request."
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Operation types:
|
|
166
|
+
- MODIFY: Files that would need changes
|
|
167
|
+
- REFERENCE: Files to understand for context (dependencies, similar implementations, interfaces)
|
|
168
|
+
- ADD: New files that would need to be created
|
|
169
|
+
- REMOVE: Files that might need to be deleted or replaced
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
def filter(
|
|
173
|
+
self, query: str, cancel_token: Optional[str] = None
|
|
174
|
+
) -> Optional[AgenticFilterResponse]:
|
|
175
|
+
"""
|
|
176
|
+
处理/auto指令的过滤模式(用于发现相关文件)
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
query: 用户查询
|
|
180
|
+
cancel_token: 取消令牌
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
AgenticFilterResponse: 过滤结果
|
|
184
|
+
"""
|
|
185
|
+
# 1. 初始化配置和LLM
|
|
186
|
+
args = self._get_final_config()
|
|
187
|
+
execute_file, _ = self._generate_new_yaml(query)
|
|
188
|
+
args.file = execute_file
|
|
189
|
+
|
|
190
|
+
llm = self._get_llm(args)
|
|
191
|
+
if llm is None:
|
|
192
|
+
return
|
|
193
|
+
|
|
194
|
+
# 2. 创建对话配置
|
|
195
|
+
conversation_config = self._ensure_conversation_id(self._conversation_config)
|
|
196
|
+
conversation_config.query = query
|
|
197
|
+
|
|
198
|
+
# 3. 处理特殊对话操作
|
|
199
|
+
if self._handle_conversation_actions(conversation_config):
|
|
200
|
+
return conversation_config.conversation_id
|
|
201
|
+
|
|
202
|
+
# 4. 创建新对话
|
|
203
|
+
conversation_manager = get_conversation_manager()
|
|
204
|
+
conversation_id = conversation_manager.create_conversation(
|
|
205
|
+
name=query or "New Conversation",
|
|
206
|
+
description=query or "New Conversation",
|
|
207
|
+
)
|
|
208
|
+
conversation_manager.set_current_conversation(conversation_id)
|
|
209
|
+
conversation_config.conversation_id = conversation_id
|
|
210
|
+
|
|
211
|
+
# 5. 配置过滤模式参数
|
|
212
|
+
args_copy = deepcopy(args)
|
|
213
|
+
args_copy.agentic_mode = "plan"
|
|
214
|
+
args_copy.code_model = args.index_filter_model or args.model
|
|
215
|
+
|
|
216
|
+
# 6. 执行文件发现
|
|
217
|
+
runner = TerminalRunner(
|
|
218
|
+
llm=llm,
|
|
219
|
+
args=args_copy,
|
|
220
|
+
conversation_config=conversation_config,
|
|
221
|
+
cancel_token=cancel_token,
|
|
222
|
+
system_prompt=self._filter_plan.prompt(),
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# 执行并重试逻辑(最多重试3次)
|
|
226
|
+
max_retries = args_copy.agentic_filter_retries
|
|
227
|
+
last_exception = None
|
|
228
|
+
|
|
229
|
+
for attempt in range(max_retries):
|
|
230
|
+
try:
|
|
231
|
+
if attempt == 0:
|
|
232
|
+
# 第一次执行
|
|
233
|
+
result = runner.run(
|
|
234
|
+
AgenticEditRequest(
|
|
235
|
+
user_input=query
|
|
236
|
+
+ "\n"
|
|
237
|
+
+ self._filter_query_reminder.prompt(),
|
|
238
|
+
)
|
|
239
|
+
)
|
|
240
|
+
else:
|
|
241
|
+
# 重试执行,将异常信息传递给模型
|
|
242
|
+
exception_message = f"<异常>\n{str(last_exception)}\n\n根据异常修正错误,重新使用 attempt_completion 进行输出"
|
|
243
|
+
global_logger.warning(
|
|
244
|
+
f"Filter method retry attempt {attempt + 1}/{max_retries}, error: {last_exception}"
|
|
245
|
+
)
|
|
246
|
+
result = runner.run(
|
|
247
|
+
AgenticEditRequest(
|
|
248
|
+
user_input=exception_message,
|
|
249
|
+
)
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# 尝试转换为模型
|
|
253
|
+
return to_model(result, AgenticFilterResponse)
|
|
254
|
+
|
|
255
|
+
except Exception as e:
|
|
256
|
+
last_exception = e
|
|
257
|
+
global_logger.error(
|
|
258
|
+
f"Filter method failed on attempt {attempt + 1}/{max_retries}: {e}"
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
# 如果是最后一次尝试,抛出异常
|
|
262
|
+
if attempt == max_retries - 1:
|
|
263
|
+
global_logger.error(
|
|
264
|
+
f"Filter method failed after {max_retries} attempts"
|
|
265
|
+
)
|
|
266
|
+
raise
|
|
267
|
+
|
|
268
|
+
# 理论上不会到达这里,但为了类型安全
|
|
269
|
+
raise RuntimeError("Filter method failed unexpectedly")
|
|
270
|
+
|
|
271
|
+
def run_with_events(
|
|
272
|
+
self,
|
|
273
|
+
query: str,
|
|
274
|
+
pre_commit: bool = False,
|
|
275
|
+
post_commit: bool = False,
|
|
276
|
+
pr: bool = False,
|
|
277
|
+
extra_args: Dict[str, Any] = {},
|
|
278
|
+
cancel_token: Optional[str] = None,
|
|
279
|
+
conversation_history: Optional[List[Dict[str, Any]]] = None,
|
|
280
|
+
system_prompt: Optional[str] = None,
|
|
281
|
+
conversation_action: ConversationAction = ConversationAction.NEW,
|
|
282
|
+
conversation_id: Optional[str] = None,
|
|
283
|
+
is_sub_agent: bool = False,
|
|
284
|
+
) -> Generator[Any, None, None]:
|
|
285
|
+
"""
|
|
286
|
+
处理/auto指令(事件流模式)
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
query: 用户查询
|
|
290
|
+
pre_commit: 是否预提交
|
|
291
|
+
post_commit: 是否后提交
|
|
292
|
+
pr: 是否创建PR
|
|
293
|
+
extra_args: 额外参数
|
|
294
|
+
cancel_token: 取消令牌
|
|
295
|
+
conversation_history: 对话历史
|
|
296
|
+
system_prompt: 系统提示
|
|
297
|
+
conversation_action: 对话动作
|
|
298
|
+
conversation_id: 对话ID
|
|
299
|
+
is_sub_agent: 是否为子代理
|
|
300
|
+
|
|
301
|
+
Yields:
|
|
302
|
+
event: 执行事件
|
|
303
|
+
"""
|
|
304
|
+
# 1. 初始化配置和LLM
|
|
305
|
+
args = self._get_final_config()
|
|
306
|
+
|
|
307
|
+
# 覆盖默认配置,但不做持久化
|
|
308
|
+
args.agentic_max_rounds = extra_args.get("max_turns", args.agentic_max_rounds)
|
|
309
|
+
args.model = extra_args.get("model", args.model)
|
|
310
|
+
args.code_model = args.model
|
|
311
|
+
args.include_rules = extra_args.get("include_rules", False)
|
|
312
|
+
|
|
313
|
+
global_logger.info(args)
|
|
314
|
+
|
|
315
|
+
execute_file, _ = self._generate_new_yaml(query)
|
|
316
|
+
args.file = execute_file
|
|
317
|
+
|
|
318
|
+
llm = self._get_llm(args)
|
|
319
|
+
if llm is None:
|
|
320
|
+
return
|
|
321
|
+
|
|
322
|
+
# 2. 创建对话配置
|
|
323
|
+
conversation_config = AgenticEditConversationConfig(
|
|
324
|
+
action=conversation_action,
|
|
325
|
+
conversation_id=conversation_id,
|
|
326
|
+
is_sub_agent=is_sub_agent,
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# 3. 设置提交和PR选项
|
|
330
|
+
if pre_commit:
|
|
331
|
+
conversation_config.commit = True
|
|
332
|
+
if post_commit:
|
|
333
|
+
conversation_config.commit = True
|
|
334
|
+
|
|
335
|
+
conversation_config.query = query
|
|
336
|
+
conversation_config.pull_request = pr
|
|
337
|
+
|
|
338
|
+
# 4. 处理对话管理
|
|
339
|
+
self._setup_conversation_for_events(conversation_config, is_sub_agent)
|
|
340
|
+
|
|
341
|
+
# 5. 注册取消令牌
|
|
342
|
+
if cancel_token:
|
|
343
|
+
from autocoder.common.global_cancel import global_cancel
|
|
344
|
+
|
|
345
|
+
global_cancel.register_token(cancel_token)
|
|
346
|
+
|
|
347
|
+
try:
|
|
348
|
+
# 6. 执行事件流
|
|
349
|
+
from autocoder.common.v2.agent.runner import SdkRunner
|
|
350
|
+
|
|
351
|
+
runner = SdkRunner(
|
|
352
|
+
llm=llm,
|
|
353
|
+
args=args,
|
|
354
|
+
conversation_config=conversation_config,
|
|
355
|
+
system_prompt=system_prompt,
|
|
356
|
+
cancel_token=cancel_token,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
events = runner.run(AgenticEditRequest(user_input=query))
|
|
360
|
+
|
|
361
|
+
for event in events:
|
|
362
|
+
yield event
|
|
363
|
+
|
|
364
|
+
finally:
|
|
365
|
+
# 7. 清理
|
|
366
|
+
self._refresh_completer()
|
|
367
|
+
if cancel_token:
|
|
368
|
+
from autocoder.common.global_cancel import global_cancel
|
|
369
|
+
|
|
370
|
+
global_cancel.reset_token(cancel_token)
|
|
371
|
+
|
|
372
|
+
# ==================== 内部辅助方法 ====================
|
|
373
|
+
|
|
374
|
+
def _handle_help_command(self, query: str) -> bool:
|
|
375
|
+
"""
|
|
376
|
+
处理 /help 命令
|
|
377
|
+
|
|
378
|
+
Args:
|
|
379
|
+
query: 用户查询
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
bool: 如果是 /help 命令返回 True,否则返回 False
|
|
383
|
+
"""
|
|
384
|
+
# 去除前后空格并检查是否是 /help 命令
|
|
385
|
+
query_stripped = query.strip()
|
|
386
|
+
if query_stripped == "/help" or query_stripped == "":
|
|
387
|
+
help_text = get_i18n_message("auto_help_text")
|
|
388
|
+
print(help_text)
|
|
389
|
+
return True
|
|
390
|
+
return False
|
|
391
|
+
|
|
392
|
+
def _show_llm_error(self, error: Exception) -> None:
|
|
393
|
+
"""显示LLM配置错误"""
|
|
394
|
+
self._console.print(
|
|
395
|
+
Panel(
|
|
396
|
+
f"[red]LLM Configuration Error:[/red]\n\n{str(error)}",
|
|
397
|
+
title="[red]Error[/red]",
|
|
398
|
+
border_style="red",
|
|
399
|
+
padding=(1, 2),
|
|
400
|
+
)
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
def _get_llm(self, args: AutoCoderArgs) -> Optional[Any]:
|
|
404
|
+
"""获取LLM实例"""
|
|
405
|
+
try:
|
|
406
|
+
return get_single_llm(
|
|
407
|
+
args.code_model or args.model, product_mode=args.product_mode
|
|
408
|
+
)
|
|
409
|
+
except ValueError as e:
|
|
410
|
+
self._show_llm_error(e)
|
|
411
|
+
return None
|
|
412
|
+
|
|
413
|
+
def _initialize_context(
|
|
414
|
+
self, query: str
|
|
415
|
+
) -> Tuple[Optional[AutoCoderArgs], Optional[Any]]:
|
|
416
|
+
"""
|
|
417
|
+
初始化运行上下文
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
query: 用户查询
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
tuple: (args, llm) 如果成功,否则 (None, None)
|
|
424
|
+
"""
|
|
425
|
+
args = self._get_final_config()
|
|
426
|
+
|
|
427
|
+
execute_file, _ = self._generate_new_yaml(query)
|
|
428
|
+
args.file = execute_file
|
|
429
|
+
|
|
430
|
+
llm = self._get_llm(args)
|
|
431
|
+
if llm is None:
|
|
432
|
+
return None, None
|
|
433
|
+
return args, llm
|
|
434
|
+
|
|
435
|
+
def _process_command_chain(
|
|
436
|
+
self, query: str, args: AutoCoderArgs, command_infos: Any, llm: Any = None, cancel_token: Optional[str] = None
|
|
437
|
+
) -> Tuple[bool, Optional[AgenticEditConversationConfig]]:
|
|
438
|
+
"""
|
|
439
|
+
处理命令链,使用责任链模式
|
|
440
|
+
|
|
441
|
+
Args:
|
|
442
|
+
query: 用户查询
|
|
443
|
+
args: 配置参数
|
|
444
|
+
command_infos: 命令信息
|
|
445
|
+
llm: LLM实例
|
|
446
|
+
cancel_token: 取消令牌
|
|
447
|
+
|
|
448
|
+
Returns:
|
|
449
|
+
tuple: (should_terminate, conversation_config)
|
|
450
|
+
- should_terminate=True, conversation_config=None: async/queue/merge已处理,返回None
|
|
451
|
+
- should_terminate=True, conversation_config=obj: conversation handler已处理,返回conversation_id
|
|
452
|
+
- should_terminate=False, conversation_config=obj: 继续执行后续逻辑
|
|
453
|
+
"""
|
|
454
|
+
# 初始化对话配置
|
|
455
|
+
conversation_config = AgenticEditConversationConfig(
|
|
456
|
+
action=ConversationAction.CONTINUE
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
# 处理 async 指令
|
|
460
|
+
async_handler = AsyncCommandHandler()
|
|
461
|
+
async_result = async_handler.handle_async_command(query, args)
|
|
462
|
+
if async_result is None:
|
|
463
|
+
return True, None
|
|
464
|
+
|
|
465
|
+
# 处理 queue 指令
|
|
466
|
+
queue_handler = QueueCommandHandler()
|
|
467
|
+
queue_result = queue_handler.handle_queue_command(query, args)
|
|
468
|
+
if queue_result is None:
|
|
469
|
+
return True, None
|
|
470
|
+
|
|
471
|
+
# 处理 merge 指令(需要 llm 和 conversation_config)
|
|
472
|
+
if llm is not None:
|
|
473
|
+
# 确保对话ID存在
|
|
474
|
+
self._ensure_conversation_id(conversation_config)
|
|
475
|
+
merge_handler = MergeCommandHandler()
|
|
476
|
+
merge_result = merge_handler.handle_merge_command(
|
|
477
|
+
query, args, llm, conversation_config, cancel_token
|
|
478
|
+
)
|
|
479
|
+
if merge_result is None:
|
|
480
|
+
return True, None
|
|
481
|
+
|
|
482
|
+
# 处理 conversation handlers
|
|
483
|
+
conversation_new_handler = ConversationNewCommandHandler()
|
|
484
|
+
new_handler_result = conversation_new_handler.handle_new_command(
|
|
485
|
+
query, conversation_config
|
|
486
|
+
)
|
|
487
|
+
if new_handler_result is None:
|
|
488
|
+
return True, conversation_config
|
|
489
|
+
|
|
490
|
+
conversation_resume_handler = ConversationResumeCommandHandler()
|
|
491
|
+
resume_handler_result = conversation_resume_handler.handle_resume_command(
|
|
492
|
+
query, conversation_config
|
|
493
|
+
)
|
|
494
|
+
if resume_handler_result is None:
|
|
495
|
+
return True, conversation_config
|
|
496
|
+
|
|
497
|
+
conversation_list_handler = ConversationListCommandHandler()
|
|
498
|
+
list_handler_result = conversation_list_handler.handle_list_command(
|
|
499
|
+
query, conversation_config
|
|
500
|
+
)
|
|
501
|
+
if list_handler_result is None:
|
|
502
|
+
return True, conversation_config
|
|
503
|
+
|
|
504
|
+
conversation_rename_handler = ConversationRenameCommandHandler()
|
|
505
|
+
rename_handler_result = conversation_rename_handler.handle_rename_command(
|
|
506
|
+
query, conversation_config
|
|
507
|
+
)
|
|
508
|
+
if rename_handler_result is None:
|
|
509
|
+
return True, conversation_config
|
|
510
|
+
|
|
511
|
+
# 处理 command 指令
|
|
512
|
+
|
|
513
|
+
command_handler = ConversationCommandCommandHandler()
|
|
514
|
+
command_result = command_handler.handle_command_command(
|
|
515
|
+
query, conversation_config, command_infos
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
if command_result is None:
|
|
519
|
+
return True, conversation_config
|
|
520
|
+
|
|
521
|
+
return False, conversation_config
|
|
522
|
+
|
|
523
|
+
def _ensure_conversation_id(
|
|
524
|
+
self, conversation_config: AgenticEditConversationConfig
|
|
525
|
+
) -> AgenticEditConversationConfig:
|
|
526
|
+
"""
|
|
527
|
+
确保对话ID存在
|
|
528
|
+
|
|
529
|
+
Args:
|
|
530
|
+
conversation_config: 对话配置
|
|
531
|
+
|
|
532
|
+
Returns:
|
|
533
|
+
str: 对话ID
|
|
534
|
+
"""
|
|
535
|
+
if conversation_config.action == ConversationAction.CONTINUE:
|
|
536
|
+
conversation_manager = get_conversation_manager()
|
|
537
|
+
conversation_id = conversation_manager.get_current_conversation_id()
|
|
538
|
+
if not conversation_id:
|
|
539
|
+
conversation_id = conversation_manager.create_conversation(
|
|
540
|
+
name=conversation_config.query or "New Conversation",
|
|
541
|
+
description=conversation_config.query or "New Conversation",
|
|
542
|
+
)
|
|
543
|
+
conversation_config.conversation_id = conversation_id
|
|
544
|
+
|
|
545
|
+
if (
|
|
546
|
+
conversation_config.action == ConversationAction.RESUME
|
|
547
|
+
and not conversation_config.conversation_id
|
|
548
|
+
):
|
|
549
|
+
conversation_manager = get_conversation_manager()
|
|
550
|
+
conversation_id = conversation_manager.get_current_conversation_id()
|
|
551
|
+
if not conversation_id:
|
|
552
|
+
conversation_id = conversation_manager.create_conversation(
|
|
553
|
+
name=conversation_config.query or "New Conversation",
|
|
554
|
+
description=conversation_config.query or "New Conversation",
|
|
555
|
+
)
|
|
556
|
+
conversation_config.conversation_id = conversation_id
|
|
557
|
+
|
|
558
|
+
if conversation_config.action == ConversationAction.NEW:
|
|
559
|
+
conversation_manager = get_conversation_manager()
|
|
560
|
+
conversation_id = conversation_manager.create_conversation(
|
|
561
|
+
name=conversation_config.query or "New Conversation",
|
|
562
|
+
description=conversation_config.query or "New Conversation",
|
|
563
|
+
)
|
|
564
|
+
conversation_manager.set_current_conversation(conversation_id)
|
|
565
|
+
conversation_config.conversation_id = conversation_id
|
|
566
|
+
|
|
567
|
+
self._conversation_config = conversation_config
|
|
568
|
+
return self._conversation_config
|
|
569
|
+
|
|
570
|
+
def _execute_runner(
|
|
571
|
+
self,
|
|
572
|
+
llm: Any,
|
|
573
|
+
args: AutoCoderArgs,
|
|
574
|
+
conversation_config: AgenticEditConversationConfig,
|
|
575
|
+
task_query: str,
|
|
576
|
+
cancel_token: Optional[str],
|
|
577
|
+
) -> None:
|
|
578
|
+
"""
|
|
579
|
+
根据运行模式执行相应的runner
|
|
580
|
+
|
|
581
|
+
Args:
|
|
582
|
+
llm: LLM实例
|
|
583
|
+
args: 配置参数
|
|
584
|
+
conversation_config: 对话配置
|
|
585
|
+
task_query: 任务查询
|
|
586
|
+
cancel_token: 取消令牌
|
|
587
|
+
"""
|
|
588
|
+
from autocoder.run_context import get_run_context, RunMode
|
|
589
|
+
|
|
590
|
+
runner_class = {
|
|
591
|
+
RunMode.WEB: FileBasedEventRunner,
|
|
592
|
+
RunMode.TERMINAL: TerminalRunner,
|
|
593
|
+
}.get(get_run_context().mode)
|
|
594
|
+
|
|
595
|
+
if runner_class:
|
|
596
|
+
runner = runner_class(
|
|
597
|
+
llm=llm,
|
|
598
|
+
args=args,
|
|
599
|
+
conversation_config=conversation_config,
|
|
600
|
+
cancel_token=cancel_token,
|
|
601
|
+
)
|
|
602
|
+
runner.run(AgenticEditRequest(user_input=task_query))
|
|
603
|
+
|
|
604
|
+
def _setup_conversation_for_events(
|
|
605
|
+
self, conversation_config: AgenticEditConversationConfig, is_sub_agent: bool
|
|
606
|
+
) -> None:
|
|
607
|
+
"""
|
|
608
|
+
为事件流模式设置对话管理
|
|
609
|
+
|
|
610
|
+
Args:
|
|
611
|
+
conversation_config: 对话配置
|
|
612
|
+
is_sub_agent: 是否为子代理
|
|
613
|
+
"""
|
|
614
|
+
conversation_manager = get_conversation_manager()
|
|
615
|
+
|
|
616
|
+
# 处理 NEW 动作
|
|
617
|
+
if conversation_config.action == ConversationAction.NEW:
|
|
618
|
+
conversation_id = conversation_manager.create_conversation(
|
|
619
|
+
name=conversation_config.query or "New Conversation",
|
|
620
|
+
description=conversation_config.query or "New Conversation",
|
|
621
|
+
)
|
|
622
|
+
if not is_sub_agent:
|
|
623
|
+
conversation_manager.set_current_conversation(conversation_id)
|
|
624
|
+
conversation_config.conversation_id = conversation_id
|
|
625
|
+
|
|
626
|
+
# 处理 RESUME 动作(有 conversation_id)
|
|
627
|
+
elif (
|
|
628
|
+
conversation_config.action == ConversationAction.RESUME
|
|
629
|
+
and conversation_config.conversation_id
|
|
630
|
+
):
|
|
631
|
+
if not is_sub_agent:
|
|
632
|
+
conversation_manager.set_current_conversation(
|
|
633
|
+
conversation_config.conversation_id
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
# 处理 RESUME 动作(无 conversation_id,使用当前对话)
|
|
637
|
+
elif (
|
|
638
|
+
conversation_config.action == ConversationAction.RESUME
|
|
639
|
+
and not conversation_config.conversation_id
|
|
640
|
+
and conversation_manager.get_current_conversation_id()
|
|
641
|
+
):
|
|
642
|
+
conversation_config.conversation_id = (
|
|
643
|
+
conversation_manager.get_current_conversation_id()
|
|
644
|
+
)
|
|
645
|
+
if not is_sub_agent:
|
|
646
|
+
conversation_manager.set_current_conversation(
|
|
647
|
+
conversation_config.conversation_id
|
|
648
|
+
)
|
|
649
|
+
|
|
650
|
+
# 处理 CONTINUE 动作
|
|
651
|
+
elif conversation_config.action == ConversationAction.CONTINUE:
|
|
652
|
+
conversation_config.conversation_id = (
|
|
653
|
+
conversation_manager.get_current_conversation_id()
|
|
654
|
+
)
|
|
655
|
+
if not is_sub_agent:
|
|
656
|
+
if conversation_config.conversation_id:
|
|
657
|
+
conversation_manager.set_current_conversation(
|
|
658
|
+
conversation_config.conversation_id
|
|
659
|
+
)
|
|
660
|
+
else:
|
|
661
|
+
conversation_id = conversation_manager.create_conversation(
|
|
662
|
+
name=conversation_config.query or "New Conversation",
|
|
663
|
+
description=conversation_config.query or "New Conversation",
|
|
664
|
+
)
|
|
665
|
+
conversation_manager.set_current_conversation(conversation_id)
|
|
666
|
+
conversation_config.conversation_id = conversation_id
|
|
667
|
+
|
|
668
|
+
# 确保有 conversation_id
|
|
669
|
+
if not conversation_config.conversation_id:
|
|
670
|
+
conversation_id = conversation_manager.create_conversation(
|
|
671
|
+
name=conversation_config.query or "New Conversation",
|
|
672
|
+
description=conversation_config.query or "New Conversation",
|
|
673
|
+
)
|
|
674
|
+
if not is_sub_agent:
|
|
675
|
+
conversation_manager.set_current_conversation(conversation_id)
|
|
676
|
+
conversation_config.conversation_id = conversation_id
|
|
677
|
+
|
|
678
|
+
def _get_memory(self) -> Dict[str, Any]:
|
|
679
|
+
"""获取内存配置"""
|
|
680
|
+
memory_manager = get_memory_manager()
|
|
681
|
+
return memory_manager.get_memory_dict()
|
|
682
|
+
|
|
683
|
+
def _get_final_config(self) -> AutoCoderArgs:
|
|
684
|
+
"""获取最终配置"""
|
|
685
|
+
from autocoder.common.core_config import get_memory_manager
|
|
686
|
+
|
|
687
|
+
memory_manager = get_memory_manager()
|
|
688
|
+
conf = memory_manager.get_all_config()
|
|
689
|
+
yaml_config = {
|
|
690
|
+
"include_file": ["./base/base.yml"],
|
|
691
|
+
"auto_merge": conf.get("auto_merge", "editblock"),
|
|
692
|
+
"human_as_model": conf.get("human_as_model", "false") == "true",
|
|
693
|
+
"skip_build_index": conf.get("skip_build_index", "true") == "true",
|
|
694
|
+
"skip_confirm": conf.get("skip_confirm", "true") == "true",
|
|
695
|
+
"silence": conf.get("silence", "true") == "true",
|
|
696
|
+
"include_project_structure": conf.get("include_project_structure", "false")
|
|
697
|
+
== "true",
|
|
698
|
+
"exclude_files": memory_manager.get_exclude_files(),
|
|
699
|
+
}
|
|
700
|
+
for key, value in conf.items():
|
|
701
|
+
converted_value = self._convert_config_value(key, value)
|
|
702
|
+
if converted_value is not None:
|
|
703
|
+
yaml_config[key] = converted_value
|
|
704
|
+
|
|
705
|
+
temp_yaml = os.path.join("actions", f"{uuid.uuid4()}.yml")
|
|
706
|
+
try:
|
|
707
|
+
with open(temp_yaml, "w", encoding="utf-8") as f:
|
|
708
|
+
f.write(self._convert_yaml_config_to_str(yaml_config=yaml_config))
|
|
709
|
+
args = self._convert_yaml_to_config(temp_yaml)
|
|
710
|
+
finally:
|
|
711
|
+
if os.path.exists(temp_yaml):
|
|
712
|
+
os.remove(temp_yaml)
|
|
713
|
+
return args
|
|
714
|
+
|
|
715
|
+
def _convert_config_value(self, key: str, value: Any) -> Any:
|
|
716
|
+
"""转换配置值"""
|
|
717
|
+
# 定义需要使用 token 解析的字段
|
|
718
|
+
token_fields = {
|
|
719
|
+
"conversation_prune_safe_zone_tokens",
|
|
720
|
+
"context_prune_safe_zone_tokens",
|
|
721
|
+
"context_prune_sliding_window_size",
|
|
722
|
+
"context_prune_sliding_window_overlap",
|
|
723
|
+
"rag_params_max_tokens",
|
|
724
|
+
"rag_context_window_limit",
|
|
725
|
+
"rag_duckdb_vector_dim",
|
|
726
|
+
"rag_duckdb_query_top_k",
|
|
727
|
+
"rag_emb_dim",
|
|
728
|
+
"rag_emb_text_size",
|
|
729
|
+
"hybrid_index_max_output_tokens",
|
|
730
|
+
"data_cells_max_num",
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
field_info = AutoCoderArgs.model_fields.get(key)
|
|
734
|
+
if field_info:
|
|
735
|
+
# 对于需要 token 解析的字段,使用 AutoCoderArgsParser
|
|
736
|
+
if key in token_fields:
|
|
737
|
+
try:
|
|
738
|
+
parser = AutoCoderArgsParser()
|
|
739
|
+
return parser.parse_token_field(key, value)
|
|
740
|
+
except Exception as e:
|
|
741
|
+
print(
|
|
742
|
+
f"Warning: Failed to parse token field '{key}' with value '{value}': {e}"
|
|
743
|
+
)
|
|
744
|
+
# 如果解析失败,fallback 到原有逻辑
|
|
745
|
+
pass
|
|
746
|
+
|
|
747
|
+
# 原有的类型转换逻辑
|
|
748
|
+
if isinstance(value, str) and value.lower() in ["true", "false"]:
|
|
749
|
+
return value.lower() == "true"
|
|
750
|
+
elif "float" in str(field_info.annotation):
|
|
751
|
+
return float(value)
|
|
752
|
+
elif "int" in str(field_info.annotation):
|
|
753
|
+
return int(value)
|
|
754
|
+
else:
|
|
755
|
+
return value
|
|
756
|
+
else:
|
|
757
|
+
print(f"Invalid configuration key: {key}")
|
|
758
|
+
return None
|
|
759
|
+
|
|
760
|
+
def _convert_yaml_config_to_str(self, yaml_config: Dict[str, Any]) -> str:
|
|
761
|
+
"""将YAML配置转换为字符串"""
|
|
762
|
+
yaml_content = yaml.safe_dump(
|
|
763
|
+
yaml_config,
|
|
764
|
+
allow_unicode=True,
|
|
765
|
+
default_flow_style=False,
|
|
766
|
+
default_style=None,
|
|
767
|
+
)
|
|
768
|
+
return yaml_content
|
|
769
|
+
|
|
770
|
+
def _convert_yaml_to_config(self, yaml_file: str) -> AutoCoderArgs:
|
|
771
|
+
"""将YAML文件转换为配置对象"""
|
|
772
|
+
from autocoder.auto_coder import AutoCoderArgs, load_include_files, Template
|
|
773
|
+
|
|
774
|
+
args = AutoCoderArgs()
|
|
775
|
+
with open(yaml_file, "r", encoding="utf-8") as f:
|
|
776
|
+
config = yaml.safe_load(f)
|
|
777
|
+
config = load_include_files(config, yaml_file)
|
|
778
|
+
for key, value in config.items():
|
|
779
|
+
if key != "file": # 排除 --file 参数本身
|
|
780
|
+
# key: ENV {{VARIABLE_NAME}}
|
|
781
|
+
if isinstance(value, str) and value.startswith("ENV"):
|
|
782
|
+
template = Template(value.removeprefix("ENV").strip())
|
|
783
|
+
value = template.render(os.environ)
|
|
784
|
+
setattr(args, key, value)
|
|
785
|
+
return args
|
|
786
|
+
|
|
787
|
+
def _generate_new_yaml(self, query: str) -> Tuple[str, AutoCoderArgs]:
|
|
788
|
+
"""生成新的YAML配置文件"""
|
|
789
|
+
memory = self._get_memory()
|
|
790
|
+
conf = memory.get("conf", {})
|
|
791
|
+
current_files = memory.get("current_files", {}).get("files", [])
|
|
792
|
+
auto_coder_main(["next", "chat_action"])
|
|
793
|
+
latest_yaml_file = get_last_yaml_file("actions")
|
|
794
|
+
if latest_yaml_file:
|
|
795
|
+
yaml_config = {
|
|
796
|
+
"include_file": ["./base/base.yml"],
|
|
797
|
+
"auto_merge": conf.get("auto_merge", "editblock"),
|
|
798
|
+
"human_as_model": conf.get("human_as_model", "false") == "true",
|
|
799
|
+
"skip_build_index": conf.get("skip_build_index", "true") == "true",
|
|
800
|
+
"skip_confirm": conf.get("skip_confirm", "true") == "true",
|
|
801
|
+
"silence": conf.get("silence", "true") == "true",
|
|
802
|
+
"include_project_structure": conf.get(
|
|
803
|
+
"include_project_structure", "false"
|
|
804
|
+
)
|
|
805
|
+
== "true",
|
|
806
|
+
"exclude_files": memory.get("exclude_files", []),
|
|
807
|
+
}
|
|
808
|
+
yaml_config["context"] = ""
|
|
809
|
+
for key, value in conf.items():
|
|
810
|
+
converted_value = self._convert_config_value(key, value)
|
|
811
|
+
if converted_value is not None:
|
|
812
|
+
yaml_config[key] = converted_value
|
|
813
|
+
|
|
814
|
+
yaml_config["urls"] = current_files + self._get_llm_friendly_package_docs(
|
|
815
|
+
return_paths=True
|
|
816
|
+
)
|
|
817
|
+
# handle image
|
|
818
|
+
v = Image.convert_image_paths_from(query)
|
|
819
|
+
yaml_config["query"] = v
|
|
820
|
+
|
|
821
|
+
yaml_content = self._convert_yaml_config_to_str(yaml_config=yaml_config)
|
|
822
|
+
|
|
823
|
+
execute_file = os.path.join("actions", latest_yaml_file)
|
|
824
|
+
with open(os.path.join(execute_file), "w", encoding="utf-8") as f:
|
|
825
|
+
f.write(yaml_content)
|
|
826
|
+
return execute_file, self._convert_yaml_to_config(execute_file)
|
|
827
|
+
|
|
828
|
+
def _get_llm_friendly_package_docs(
|
|
829
|
+
self, package_name: Optional[str] = None, return_paths: bool = False
|
|
830
|
+
) -> List[str]:
|
|
831
|
+
"""获取LLM友好的包文档"""
|
|
832
|
+
from autocoder.common.llm_friendly_package import get_package_manager
|
|
833
|
+
|
|
834
|
+
package_manager = get_package_manager()
|
|
835
|
+
return package_manager.get_docs(package_name, return_paths)
|
|
836
|
+
|
|
837
|
+
def _handle_conversation_actions(
|
|
838
|
+
self, conversation_config: AgenticEditConversationConfig
|
|
839
|
+
) -> bool:
|
|
840
|
+
"""
|
|
841
|
+
处理对话列表和创建新对话的操作
|
|
842
|
+
|
|
843
|
+
Args:
|
|
844
|
+
conversation_config: 对话配置对象
|
|
845
|
+
|
|
846
|
+
Returns:
|
|
847
|
+
bool: 如果处理了特殊操作(LIST或NEW without input)返回True,否则返回False
|
|
848
|
+
"""
|
|
849
|
+
if not conversation_config:
|
|
850
|
+
return False
|
|
851
|
+
|
|
852
|
+
console = Console()
|
|
853
|
+
|
|
854
|
+
# 处理LIST操作
|
|
855
|
+
if conversation_config.action == ConversationAction.LIST:
|
|
856
|
+
conversation_manager = get_conversation_manager()
|
|
857
|
+
conversations = conversation_manager.list_conversations()
|
|
858
|
+
# 只保留 conversation_id 和 name 字段
|
|
859
|
+
filtered_conversations = []
|
|
860
|
+
for conv in conversations:
|
|
861
|
+
filtered_conv = {
|
|
862
|
+
"conversation_id": conv.get("conversation_id"),
|
|
863
|
+
"name": conv.get("name"),
|
|
864
|
+
}
|
|
865
|
+
filtered_conversations.append(filtered_conv)
|
|
866
|
+
|
|
867
|
+
# 格式化 JSON 输出,使用 JSON 格式渲染而不是 Markdown
|
|
868
|
+
json_str = json.dumps(filtered_conversations, ensure_ascii=False, indent=4)
|
|
869
|
+
console.print(
|
|
870
|
+
Panel(
|
|
871
|
+
json_str,
|
|
872
|
+
title="🏁 Task Completion",
|
|
873
|
+
border_style="green",
|
|
874
|
+
title_align="left",
|
|
875
|
+
)
|
|
876
|
+
)
|
|
877
|
+
return True
|
|
878
|
+
|
|
879
|
+
# 处理NEW操作且没有用户输入
|
|
880
|
+
if (
|
|
881
|
+
conversation_config.action == ConversationAction.NEW
|
|
882
|
+
and not conversation_config.query.strip()
|
|
883
|
+
):
|
|
884
|
+
conversation_manager = get_conversation_manager()
|
|
885
|
+
conversation_id = conversation_manager.create_conversation(
|
|
886
|
+
name=conversation_config.query or "New Conversation",
|
|
887
|
+
description=conversation_config.query or "New Conversation",
|
|
888
|
+
)
|
|
889
|
+
conversation_manager.set_current_conversation(conversation_id)
|
|
890
|
+
conversation_message = f"New conversation created: {conversation_manager.get_current_conversation_id()}"
|
|
891
|
+
|
|
892
|
+
# 使用safe console print的简单版本
|
|
893
|
+
try:
|
|
894
|
+
console.print(
|
|
895
|
+
Panel(
|
|
896
|
+
Markdown(conversation_message),
|
|
897
|
+
title="🏁 Task Completion",
|
|
898
|
+
border_style="green",
|
|
899
|
+
title_align="left",
|
|
900
|
+
)
|
|
901
|
+
)
|
|
902
|
+
except Exception:
|
|
903
|
+
# fallback to plain text
|
|
904
|
+
safe_content = conversation_message.replace("[", "\\[").replace(
|
|
905
|
+
"]", "\\]"
|
|
906
|
+
)
|
|
907
|
+
console.print(
|
|
908
|
+
Panel(
|
|
909
|
+
safe_content,
|
|
910
|
+
title="🏁 Task Completion",
|
|
911
|
+
border_style="green",
|
|
912
|
+
title_align="left",
|
|
913
|
+
)
|
|
914
|
+
)
|
|
915
|
+
return True
|
|
916
|
+
|
|
917
|
+
return False
|
|
918
|
+
|
|
919
|
+
def _refresh_completer(self) -> None:
|
|
920
|
+
"""刷新命令补全器"""
|
|
921
|
+
try:
|
|
922
|
+
# 延迟导入,避免循环依赖
|
|
923
|
+
|
|
924
|
+
# 获取全局 completer 实例
|
|
925
|
+
# 注意:这里需要访问 auto_coder_runner 模块的全局变量
|
|
926
|
+
# 由于我们不能修改 auto_coder_runner.py,所以这里直接导入
|
|
927
|
+
import autocoder.auto_coder_runner as runner_module
|
|
928
|
+
|
|
929
|
+
if hasattr(runner_module, "completer"):
|
|
930
|
+
runner_module.completer.refresh_files()
|
|
931
|
+
except Exception as e:
|
|
932
|
+
global_logger.warning(f"Failed to refresh completer: {e}")
|