auto-coder 0.1.400__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- auto_coder-2.0.0.dist-info/LICENSE +158 -0
- auto_coder-2.0.0.dist-info/METADATA +558 -0
- auto_coder-2.0.0.dist-info/RECORD +795 -0
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
- autocoder/__init__.py +31 -0
- autocoder/agent/auto_filegroup.py +32 -13
- autocoder/agent/auto_learn_from_commit.py +9 -1
- autocoder/agent/base_agentic/__init__.py +3 -0
- autocoder/agent/base_agentic/agent_hub.py +1 -1
- autocoder/agent/base_agentic/base_agent.py +235 -136
- autocoder/agent/base_agentic/default_tools.py +119 -118
- autocoder/agent/base_agentic/test_base_agent.py +1 -1
- autocoder/agent/base_agentic/tool_registry.py +32 -20
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +25 -4
- autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
- autocoder/agent/base_agentic/types.py +42 -0
- autocoder/agent/entry_command_agent/chat.py +73 -59
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +1029 -2310
- autocoder/auto_coder_terminal.py +26 -0
- autocoder/auto_coder_terminal_v3.py +190 -0
- autocoder/chat/conf_command.py +224 -124
- autocoder/chat/models_command.py +361 -299
- autocoder/chat/rules_command.py +79 -31
- autocoder/chat_auto_coder.py +1021 -372
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +26 -9
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +44 -44
- autocoder/common/__init__.py +150 -128
- autocoder/common/ac_style_command_parser/__init__.py +39 -2
- autocoder/common/ac_style_command_parser/config.py +422 -0
- autocoder/common/ac_style_command_parser/parser.py +292 -78
- autocoder/common/ac_style_command_parser/test_parser.py +241 -16
- autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
- autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
- autocoder/common/action_yml_file_manager.py +25 -13
- autocoder/common/agent_events/__init__.py +52 -0
- autocoder/common/agent_events/agent_event_emitter.py +193 -0
- autocoder/common/agent_events/event_factory.py +177 -0
- autocoder/common/agent_events/examples.py +307 -0
- autocoder/common/agent_events/types.py +113 -0
- autocoder/common/agent_events/utils.py +68 -0
- autocoder/common/agent_hooks/__init__.py +44 -0
- autocoder/common/agent_hooks/examples.py +582 -0
- autocoder/common/agent_hooks/hook_executor.py +217 -0
- autocoder/common/agent_hooks/hook_manager.py +288 -0
- autocoder/common/agent_hooks/types.py +133 -0
- autocoder/common/agent_hooks/utils.py +99 -0
- autocoder/common/agent_query_queue/queue_executor.py +324 -0
- autocoder/common/agent_query_queue/queue_manager.py +325 -0
- autocoder/common/agents/__init__.py +11 -0
- autocoder/common/agents/agent_manager.py +323 -0
- autocoder/common/agents/agent_parser.py +189 -0
- autocoder/common/agents/example_usage.py +344 -0
- autocoder/common/agents/integration_example.py +330 -0
- autocoder/common/agents/test_agent_parser.py +545 -0
- autocoder/common/async_utils.py +101 -0
- autocoder/common/auto_coder_lang.py +23 -972
- autocoder/common/autocoderargs_parser/__init__.py +14 -0
- autocoder/common/autocoderargs_parser/parser.py +184 -0
- autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
- autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
- autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
- autocoder/common/autocoderargs_parser/token_parser.py +290 -0
- autocoder/common/buildin_tokenizer.py +2 -4
- autocoder/common/code_auto_generate.py +149 -74
- autocoder/common/code_auto_generate_diff.py +163 -70
- autocoder/common/code_auto_generate_editblock.py +179 -89
- autocoder/common/code_auto_generate_strict_diff.py +167 -72
- autocoder/common/code_auto_merge_editblock.py +13 -6
- autocoder/common/code_modification_ranker.py +1 -1
- autocoder/common/command_completer.py +3 -3
- autocoder/common/command_file_manager/manager.py +183 -47
- autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
- autocoder/common/command_templates.py +1 -1
- autocoder/common/conf_utils.py +2 -4
- autocoder/common/conversations/config.py +11 -3
- autocoder/common/conversations/get_conversation_manager.py +100 -2
- autocoder/common/conversations/llm_stats_models.py +264 -0
- autocoder/common/conversations/manager.py +112 -28
- autocoder/common/conversations/models.py +16 -2
- autocoder/common/conversations/storage/index_manager.py +134 -10
- autocoder/common/core_config/__init__.py +63 -0
- autocoder/common/core_config/agentic_mode_manager.py +109 -0
- autocoder/common/core_config/base_manager.py +123 -0
- autocoder/common/core_config/compatibility.py +151 -0
- autocoder/common/core_config/config_manager.py +156 -0
- autocoder/common/core_config/conversation_manager.py +31 -0
- autocoder/common/core_config/exclude_manager.py +72 -0
- autocoder/common/core_config/file_manager.py +177 -0
- autocoder/common/core_config/human_as_model_manager.py +129 -0
- autocoder/common/core_config/lib_manager.py +54 -0
- autocoder/common/core_config/main_manager.py +81 -0
- autocoder/common/core_config/mode_manager.py +126 -0
- autocoder/common/core_config/models.py +70 -0
- autocoder/common/core_config/test_memory_manager.py +1056 -0
- autocoder/common/env_manager.py +282 -0
- autocoder/common/env_manager_usage_example.py +211 -0
- autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
- autocoder/common/file_checkpoint/manager.py +264 -48
- autocoder/common/file_checkpoint/test_backup.py +1 -18
- autocoder/common/file_checkpoint/test_manager.py +270 -1
- autocoder/common/file_checkpoint/test_store.py +1 -17
- autocoder/common/file_handler/__init__.py +23 -0
- autocoder/common/file_handler/active_context_handler.py +159 -0
- autocoder/common/file_handler/add_files_handler.py +409 -0
- autocoder/common/file_handler/chat_handler.py +180 -0
- autocoder/common/file_handler/coding_handler.py +401 -0
- autocoder/common/file_handler/commit_handler.py +200 -0
- autocoder/common/file_handler/lib_handler.py +156 -0
- autocoder/common/file_handler/list_files_handler.py +111 -0
- autocoder/common/file_handler/mcp_handler.py +268 -0
- autocoder/common/file_handler/models_handler.py +493 -0
- autocoder/common/file_handler/remove_files_handler.py +172 -0
- autocoder/common/file_monitor/test_file_monitor.py +307 -0
- autocoder/common/git_utils.py +51 -10
- autocoder/common/global_cancel.py +15 -6
- autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
- autocoder/common/international/__init__.py +31 -0
- autocoder/common/international/demo_international.py +92 -0
- autocoder/common/international/message_manager.py +157 -0
- autocoder/common/international/messages/__init__.py +56 -0
- autocoder/common/international/messages/async_command_messages.py +507 -0
- autocoder/common/international/messages/auto_coder_messages.py +2208 -0
- autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
- autocoder/common/international/messages/command_help_messages.py +986 -0
- autocoder/common/international/messages/conversation_command_messages.py +191 -0
- autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
- autocoder/common/international/messages/queue_command_messages.py +751 -0
- autocoder/common/international/messages/rules_command_messages.py +77 -0
- autocoder/common/international/messages/sdk_messages.py +1707 -0
- autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
- autocoder/common/international/messages/tool_display_messages.py +1212 -0
- autocoder/common/international/messages/workflow_exception_messages.py +473 -0
- autocoder/common/international/test_international.py +612 -0
- autocoder/common/linter_core/__init__.py +28 -0
- autocoder/common/linter_core/base_linter.py +61 -0
- autocoder/common/linter_core/config_loader.py +271 -0
- autocoder/common/linter_core/formatters/__init__.py +0 -0
- autocoder/common/linter_core/formatters/base_formatter.py +38 -0
- autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
- autocoder/common/linter_core/linter.py +166 -0
- autocoder/common/linter_core/linter_factory.py +216 -0
- autocoder/common/linter_core/linter_manager.py +333 -0
- autocoder/common/linter_core/linters/__init__.py +9 -0
- autocoder/common/linter_core/linters/java_linter.py +342 -0
- autocoder/common/linter_core/linters/python_linter.py +115 -0
- autocoder/common/linter_core/linters/typescript_linter.py +119 -0
- autocoder/common/linter_core/models/__init__.py +7 -0
- autocoder/common/linter_core/models/lint_result.py +91 -0
- autocoder/common/linter_core/models.py +33 -0
- autocoder/common/linter_core/tests/__init__.py +3 -0
- autocoder/common/linter_core/tests/test_config_loader.py +323 -0
- autocoder/common/linter_core/tests/test_config_loading.py +308 -0
- autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
- autocoder/common/linter_core/tests/test_formatters.py +147 -0
- autocoder/common/linter_core/tests/test_integration.py +317 -0
- autocoder/common/linter_core/tests/test_java_linter.py +496 -0
- autocoder/common/linter_core/tests/test_linters.py +265 -0
- autocoder/common/linter_core/tests/test_models.py +81 -0
- autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
- autocoder/common/linter_core/tests/verify_fixes.py +183 -0
- autocoder/common/llm_friendly_package/__init__.py +31 -0
- autocoder/common/llm_friendly_package/base_manager.py +102 -0
- autocoder/common/llm_friendly_package/docs_manager.py +121 -0
- autocoder/common/llm_friendly_package/library_manager.py +171 -0
- autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
- autocoder/common/llm_friendly_package/models.py +40 -0
- autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
- autocoder/common/llms/__init__.py +15 -0
- autocoder/common/llms/demo_error_handling.py +85 -0
- autocoder/common/llms/factory.py +142 -0
- autocoder/common/llms/manager.py +264 -0
- autocoder/common/llms/pricing.py +121 -0
- autocoder/common/llms/registry.py +288 -0
- autocoder/common/llms/schema.py +77 -0
- autocoder/common/llms/simple_demo.py +45 -0
- autocoder/common/llms/test_quick_model.py +116 -0
- autocoder/common/llms/test_remove_functionality.py +182 -0
- autocoder/common/llms/tests/__init__.py +1 -0
- autocoder/common/llms/tests/test_manager.py +330 -0
- autocoder/common/llms/tests/test_registry.py +364 -0
- autocoder/common/mcp_tools/__init__.py +62 -0
- autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
- autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
- autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
- autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
- autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
- autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
- autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
- autocoder/common/mcp_tools/verify_functionality.py +202 -0
- autocoder/common/model_speed_tester.py +32 -26
- autocoder/common/priority_directory_finder/__init__.py +142 -0
- autocoder/common/priority_directory_finder/examples.py +230 -0
- autocoder/common/priority_directory_finder/finder.py +283 -0
- autocoder/common/priority_directory_finder/models.py +236 -0
- autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
- autocoder/common/project_scanner/__init__.py +18 -0
- autocoder/common/project_scanner/compat.py +77 -0
- autocoder/common/project_scanner/scanner.py +436 -0
- autocoder/common/project_tracker/__init__.py +27 -0
- autocoder/common/project_tracker/api.py +228 -0
- autocoder/common/project_tracker/demo.py +272 -0
- autocoder/common/project_tracker/tracker.py +487 -0
- autocoder/common/project_tracker/types.py +53 -0
- autocoder/common/pruner/__init__.py +67 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +746 -0
- autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
- autocoder/common/pruner/conversation_message_ids_api.py +386 -0
- autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
- autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
- autocoder/common/pruner/conversation_normalizer.py +347 -0
- autocoder/common/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
- autocoder/common/pruner/test_context_pruner.py +546 -0
- autocoder/common/pruner/test_conversation_normalizer.py +502 -0
- autocoder/common/pruner/test_tool_content_detector.py +324 -0
- autocoder/common/pruner/tool_content_detector.py +227 -0
- autocoder/common/pruner/tools/__init__.py +18 -0
- autocoder/common/pruner/tools/query_message_ids.py +264 -0
- autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
- autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
- autocoder/common/pull_requests/__init__.py +9 -1
- autocoder/common/pull_requests/utils.py +122 -1
- autocoder/common/rag_manager/rag_manager.py +36 -40
- autocoder/common/rulefiles/__init__.py +53 -1
- autocoder/common/rulefiles/api.py +250 -0
- autocoder/common/rulefiles/core/__init__.py +14 -0
- autocoder/common/rulefiles/core/manager.py +241 -0
- autocoder/common/rulefiles/core/selector.py +805 -0
- autocoder/common/rulefiles/models/__init__.py +20 -0
- autocoder/common/rulefiles/models/index.py +16 -0
- autocoder/common/rulefiles/models/init_rule.py +18 -0
- autocoder/common/rulefiles/models/rule_file.py +18 -0
- autocoder/common/rulefiles/models/rule_relevance.py +14 -0
- autocoder/common/rulefiles/models/summary.py +16 -0
- autocoder/common/rulefiles/test_rulefiles.py +776 -0
- autocoder/common/rulefiles/utils/__init__.py +34 -0
- autocoder/common/rulefiles/utils/monitor.py +86 -0
- autocoder/common/rulefiles/utils/parser.py +230 -0
- autocoder/common/save_formatted_log.py +67 -10
- autocoder/common/search_replace.py +8 -1
- autocoder/common/search_replace_patch/__init__.py +24 -0
- autocoder/common/search_replace_patch/base.py +115 -0
- autocoder/common/search_replace_patch/manager.py +248 -0
- autocoder/common/search_replace_patch/patch_replacer.py +304 -0
- autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
- autocoder/common/search_replace_patch/string_replacer.py +181 -0
- autocoder/common/search_replace_patch/tests/__init__.py +3 -0
- autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
- autocoder/common/search_replace_patch/tests/test_base.py +188 -0
- autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
- autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
- autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
- autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
- autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
- autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
- autocoder/common/shell_commands/__init__.py +197 -0
- autocoder/common/shell_commands/background_process_notifier.py +346 -0
- autocoder/common/shell_commands/command_executor.py +1127 -0
- autocoder/common/shell_commands/error_recovery.py +541 -0
- autocoder/common/shell_commands/exceptions.py +120 -0
- autocoder/common/shell_commands/interactive_executor.py +476 -0
- autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
- autocoder/common/shell_commands/interactive_process.py +744 -0
- autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
- autocoder/common/shell_commands/monitoring.py +529 -0
- autocoder/common/shell_commands/process_cleanup.py +386 -0
- autocoder/common/shell_commands/process_manager.py +606 -0
- autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
- autocoder/common/shell_commands/tests/__init__.py +6 -0
- autocoder/common/shell_commands/tests/conftest.py +118 -0
- autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
- autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
- autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
- autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
- autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
- autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
- autocoder/common/shell_commands/tests/test_integration.py +664 -0
- autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
- autocoder/common/shell_commands/tests/test_performance.py +632 -0
- autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
- autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
- autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
- autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
- autocoder/common/shell_commands/timeout_config.py +315 -0
- autocoder/common/shell_commands/timeout_manager.py +352 -0
- autocoder/common/terminal_paste/__init__.py +14 -0
- autocoder/common/terminal_paste/demo.py +145 -0
- autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
- autocoder/common/terminal_paste/paste_handler.py +200 -0
- autocoder/common/terminal_paste/paste_manager.py +118 -0
- autocoder/common/terminal_paste/tests/__init__.py +1 -0
- autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
- autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
- autocoder/common/terminal_paste/utils.py +163 -0
- autocoder/common/test_autocoder_args.py +232 -0
- autocoder/common/test_env_manager.py +173 -0
- autocoder/common/test_env_manager_integration.py +159 -0
- autocoder/common/text_similarity/__init__.py +9 -0
- autocoder/common/text_similarity/demo.py +216 -0
- autocoder/common/text_similarity/examples.py +266 -0
- autocoder/common/text_similarity/test_text_similarity.py +306 -0
- autocoder/common/text_similarity/text_similarity.py +194 -0
- autocoder/common/text_similarity/utils.py +125 -0
- autocoder/common/todos/__init__.py +61 -0
- autocoder/common/todos/cache/__init__.py +16 -0
- autocoder/common/todos/cache/base_cache.py +89 -0
- autocoder/common/todos/cache/cache_manager.py +228 -0
- autocoder/common/todos/cache/memory_cache.py +225 -0
- autocoder/common/todos/config.py +155 -0
- autocoder/common/todos/exceptions.py +35 -0
- autocoder/common/todos/get_todo_manager.py +161 -0
- autocoder/common/todos/manager.py +537 -0
- autocoder/common/todos/models.py +239 -0
- autocoder/common/todos/storage/__init__.py +14 -0
- autocoder/common/todos/storage/base_storage.py +76 -0
- autocoder/common/todos/storage/file_storage.py +278 -0
- autocoder/common/tokens/__init__.py +15 -0
- autocoder/common/tokens/counter.py +44 -2
- autocoder/common/tools_manager/__init__.py +17 -0
- autocoder/common/tools_manager/examples.py +162 -0
- autocoder/common/tools_manager/manager.py +385 -0
- autocoder/common/tools_manager/models.py +39 -0
- autocoder/common/tools_manager/test_tools_manager.py +303 -0
- autocoder/common/tools_manager/utils.py +191 -0
- autocoder/common/v2/agent/agentic_callbacks.py +270 -0
- autocoder/common/v2/agent/agentic_edit.py +2729 -2052
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
- autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
- autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
- autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +565 -30
- autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
- autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
- autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
- autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +244 -51
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
- autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +409 -140
- autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +209 -194
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
- autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
- autocoder/common/v2/agent/agentic_edit_types.py +386 -10
- autocoder/common/v2/agent/runner/__init__.py +31 -0
- autocoder/common/v2/agent/runner/base_runner.py +92 -0
- autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
- autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
- autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
- autocoder/common/v2/agent/runner/tool_display.py +589 -0
- autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
- autocoder/common/v2/agent/test_agentic_edit.py +194 -0
- autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
- autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
- autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
- autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
- autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
- autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
- autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
- autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
- autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
- autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
- autocoder/common/v2/code_auto_generate.py +136 -78
- autocoder/common/v2/code_auto_generate_diff.py +135 -79
- autocoder/common/v2/code_auto_generate_editblock.py +174 -99
- autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
- autocoder/common/v2/code_auto_merge.py +1 -1
- autocoder/common/v2/code_auto_merge_editblock.py +13 -1
- autocoder/common/v2/code_diff_manager.py +3 -3
- autocoder/common/v2/code_editblock_manager.py +4 -14
- autocoder/common/v2/code_manager.py +1 -1
- autocoder/common/v2/code_strict_diff_manager.py +2 -2
- autocoder/common/wrap_llm_hint/__init__.py +10 -0
- autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
- autocoder/common/wrap_llm_hint/utils.py +432 -0
- autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
- autocoder/completer/__init__.py +8 -0
- autocoder/completer/command_completer_v2.py +1051 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +165 -7
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- autocoder/{agent → index/filter}/agentic_filter.py +323 -334
- autocoder/index/filter/normal_filter.py +5 -11
- autocoder/index/filter/quick_filter.py +1 -1
- autocoder/index/index.py +36 -9
- autocoder/index/tests/__init__.py +1 -0
- autocoder/index/tests/run_tests.py +195 -0
- autocoder/index/tests/test_entry.py +303 -0
- autocoder/index/tests/test_index_manager.py +314 -0
- autocoder/index/tests/test_module_integration.py +300 -0
- autocoder/index/tests/test_symbols_utils.py +183 -0
- autocoder/inner/__init__.py +4 -0
- autocoder/inner/agentic.py +932 -0
- autocoder/inner/async_command_handler.py +992 -0
- autocoder/inner/conversation_command_handlers.py +623 -0
- autocoder/inner/merge_command_handler.py +213 -0
- autocoder/inner/queue_command_handler.py +684 -0
- autocoder/models.py +95 -266
- autocoder/plugins/git_helper_plugin.py +31 -29
- autocoder/plugins/token_helper_plugin.py +156 -37
- autocoder/pyproject/__init__.py +32 -29
- autocoder/rag/agentic_rag.py +215 -75
- autocoder/rag/cache/simple_cache.py +1 -2
- autocoder/rag/loaders/image_loader.py +1 -1
- autocoder/rag/long_context_rag.py +42 -26
- autocoder/rag/qa_conversation_strategy.py +1 -1
- autocoder/rag/terminal/__init__.py +17 -0
- autocoder/rag/terminal/args.py +581 -0
- autocoder/rag/terminal/bootstrap.py +61 -0
- autocoder/rag/terminal/command_handlers.py +653 -0
- autocoder/rag/terminal/formatters/__init__.py +20 -0
- autocoder/rag/terminal/formatters/base.py +70 -0
- autocoder/rag/terminal/formatters/json_format.py +66 -0
- autocoder/rag/terminal/formatters/stream_json.py +95 -0
- autocoder/rag/terminal/formatters/text.py +28 -0
- autocoder/rag/terminal/init.py +120 -0
- autocoder/rag/terminal/utils.py +106 -0
- autocoder/rag/test_agentic_rag.py +389 -0
- autocoder/rag/test_doc_filter.py +3 -3
- autocoder/rag/test_long_context_rag.py +1 -1
- autocoder/rag/test_token_limiter.py +517 -10
- autocoder/rag/token_counter.py +3 -0
- autocoder/rag/token_limiter.py +19 -15
- autocoder/rag/tools/__init__.py +26 -2
- autocoder/rag/tools/bochaai_example.py +343 -0
- autocoder/rag/tools/bochaai_sdk.py +541 -0
- autocoder/rag/tools/metaso_example.py +268 -0
- autocoder/rag/tools/metaso_sdk.py +417 -0
- autocoder/rag/tools/recall_tool.py +28 -7
- autocoder/rag/tools/run_integration_tests.py +204 -0
- autocoder/rag/tools/test_all_providers.py +318 -0
- autocoder/rag/tools/test_bochaai_integration.py +482 -0
- autocoder/rag/tools/test_final_integration.py +215 -0
- autocoder/rag/tools/test_metaso_integration.py +424 -0
- autocoder/rag/tools/test_metaso_real.py +171 -0
- autocoder/rag/tools/test_web_crawl_tool.py +639 -0
- autocoder/rag/tools/test_web_search_tool.py +509 -0
- autocoder/rag/tools/todo_read_tool.py +202 -0
- autocoder/rag/tools/todo_write_tool.py +412 -0
- autocoder/rag/tools/web_crawl_tool.py +634 -0
- autocoder/rag/tools/web_search_tool.py +558 -0
- autocoder/rag/tools/web_tools_example.py +119 -0
- autocoder/rag/types.py +16 -0
- autocoder/rag/variable_holder.py +4 -2
- autocoder/rags.py +86 -79
- autocoder/regexproject/__init__.py +23 -21
- autocoder/run_context.py +9 -0
- autocoder/sdk/__init__.py +50 -161
- autocoder/sdk/api.py +370 -0
- autocoder/sdk/async_runner/__init__.py +26 -0
- autocoder/sdk/async_runner/async_executor.py +650 -0
- autocoder/sdk/async_runner/async_handler.py +356 -0
- autocoder/sdk/async_runner/markdown_processor.py +595 -0
- autocoder/sdk/async_runner/task_metadata.py +284 -0
- autocoder/sdk/async_runner/worktree_manager.py +438 -0
- autocoder/sdk/cli/__init__.py +2 -5
- autocoder/sdk/cli/formatters.py +28 -204
- autocoder/sdk/cli/handlers.py +77 -44
- autocoder/sdk/cli/main.py +158 -170
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -267
- autocoder/sdk/core/bridge.py +298 -118
- autocoder/sdk/exceptions.py +18 -12
- autocoder/sdk/formatters/__init__.py +19 -0
- autocoder/sdk/formatters/input.py +64 -0
- autocoder/sdk/formatters/output.py +247 -0
- autocoder/sdk/formatters/stream.py +54 -0
- autocoder/sdk/models/__init__.py +6 -5
- autocoder/sdk/models/options.py +55 -18
- autocoder/sdk/utils/formatters.py +27 -195
- autocoder/suffixproject/__init__.py +28 -25
- autocoder/terminal/__init__.py +14 -0
- autocoder/terminal/app.py +454 -0
- autocoder/terminal/args.py +32 -0
- autocoder/terminal/bootstrap.py +178 -0
- autocoder/terminal/command_processor.py +521 -0
- autocoder/terminal/command_registry.py +57 -0
- autocoder/terminal/help.py +97 -0
- autocoder/terminal/tasks/__init__.py +5 -0
- autocoder/terminal/tasks/background.py +77 -0
- autocoder/terminal/tasks/task_event.py +70 -0
- autocoder/terminal/ui/__init__.py +13 -0
- autocoder/terminal/ui/completer.py +268 -0
- autocoder/terminal/ui/keybindings.py +75 -0
- autocoder/terminal/ui/session.py +41 -0
- autocoder/terminal/ui/toolbar.py +64 -0
- autocoder/terminal/utils/__init__.py +13 -0
- autocoder/terminal/utils/errors.py +18 -0
- autocoder/terminal/utils/paths.py +19 -0
- autocoder/terminal/utils/shell.py +43 -0
- autocoder/terminal_v3/__init__.py +10 -0
- autocoder/terminal_v3/app.py +201 -0
- autocoder/terminal_v3/handlers/__init__.py +5 -0
- autocoder/terminal_v3/handlers/command_handler.py +131 -0
- autocoder/terminal_v3/models/__init__.py +6 -0
- autocoder/terminal_v3/models/conversation_buffer.py +214 -0
- autocoder/terminal_v3/models/message.py +50 -0
- autocoder/terminal_v3/models/tool_display.py +247 -0
- autocoder/terminal_v3/ui/__init__.py +7 -0
- autocoder/terminal_v3/ui/keybindings.py +56 -0
- autocoder/terminal_v3/ui/layout.py +141 -0
- autocoder/terminal_v3/ui/styles.py +43 -0
- autocoder/tsproject/__init__.py +23 -23
- autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
- autocoder/utils/llms.py +88 -80
- autocoder/utils/math_utils.py +101 -0
- autocoder/utils/model_provider_selector.py +16 -4
- autocoder/utils/operate_config_api.py +33 -5
- autocoder/utils/thread_utils.py +2 -2
- autocoder/version.py +4 -2
- autocoder/workflow_agents/__init__.py +84 -0
- autocoder/workflow_agents/agent.py +143 -0
- autocoder/workflow_agents/exceptions.py +573 -0
- autocoder/workflow_agents/executor.py +489 -0
- autocoder/workflow_agents/loader.py +737 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +172 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-0.1.400.dist-info/METADATA +0 -396
- auto_coder-0.1.400.dist-info/RECORD +0 -425
- auto_coder-0.1.400.dist-info/licenses/LICENSE +0 -201
- autocoder/auto_coder_server.py +0 -672
- autocoder/benchmark.py +0 -138
- autocoder/common/ac_style_command_parser/example.py +0 -7
- autocoder/common/cleaner.py +0 -31
- autocoder/common/command_completer_v2.py +0 -615
- autocoder/common/directory_cache/__init__.py +0 -1
- autocoder/common/directory_cache/cache.py +0 -192
- autocoder/common/directory_cache/test_cache.py +0 -190
- autocoder/common/file_checkpoint/examples.py +0 -217
- autocoder/common/llm_friendly_package_example.py +0 -138
- autocoder/common/llm_friendly_package_test.py +0 -63
- autocoder/common/pull_requests/test_module.py +0 -1
- autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
- autocoder/common/text.py +0 -30
- autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
- autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
- autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
- autocoder/common/v2/agent/agentic_tool_display.py +0 -183
- autocoder/plugins/dynamic_completion_example.py +0 -148
- autocoder/plugins/sample_plugin.py +0 -160
- autocoder/sdk/cli/__main__.py +0 -26
- autocoder/sdk/cli/completion_wrapper.py +0 -38
- autocoder/sdk/cli/install_completion.py +0 -301
- autocoder/sdk/models/messages.py +0 -209
- autocoder/sdk/session/__init__.py +0 -32
- autocoder/sdk/session/session.py +0 -106
- autocoder/sdk/session/session_manager.py +0 -56
- {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -14,7 +14,6 @@ import byzerllm
|
|
|
14
14
|
from pydantic import BaseModel
|
|
15
15
|
|
|
16
16
|
from autocoder.common import AutoCoderArgs, git_utils, SourceCodeList, SourceCode
|
|
17
|
-
from autocoder.common.global_cancel import global_cancel
|
|
18
17
|
from autocoder.rag.variable_holder import VariableHolder
|
|
19
18
|
from autocoder.utils import llms as llms_utils
|
|
20
19
|
from autocoder.common.global_cancel import global_cancel
|
|
@@ -22,13 +21,9 @@ from autocoder.common import detect_env
|
|
|
22
21
|
from autocoder.common import shells
|
|
23
22
|
from autocoder.common.printer import Printer
|
|
24
23
|
from autocoder.utils.auto_project_type import ProjectTypeAnalyzer
|
|
25
|
-
from autocoder.common.
|
|
24
|
+
from autocoder.common.mcp_tools.server import get_mcp_server, McpServerInfoRequest
|
|
26
25
|
from autocoder.common.file_monitor.monitor import FileMonitor
|
|
27
|
-
from autocoder.common.rulefiles
|
|
28
|
-
from autocoder.auto_coder_runner import load_tokenizer
|
|
29
|
-
from autocoder.linters.shadow_linter import ShadowLinter
|
|
30
|
-
from autocoder.compilers.shadow_compiler import ShadowCompiler
|
|
31
|
-
from autocoder.shadows.shadow_manager import ShadowManager
|
|
26
|
+
from autocoder.common.rulefiles import get_required_and_index_rules, get_rules
|
|
32
27
|
from autocoder.events.event_manager_singleton import get_event_manager
|
|
33
28
|
from autocoder.events.event_types import Event, EventType, EventMetadata
|
|
34
29
|
from autocoder.events import event_content as EventContentCreator
|
|
@@ -43,7 +38,8 @@ from .types import (
|
|
|
43
38
|
BaseTool, ToolResult, AgentRequest, FileChangeEntry,
|
|
44
39
|
LLMOutputEvent, LLMThinkingEvent, ToolCallEvent, ToolResultEvent,
|
|
45
40
|
CompletionEvent, ErrorEvent, TokenUsageEvent, AttemptCompletionTool,
|
|
46
|
-
PlanModeRespondTool,Message,ReplyDecision, PlanModeRespondEvent
|
|
41
|
+
PlanModeRespondTool, Message, ReplyDecision, PlanModeRespondEvent, RetryEvent,
|
|
42
|
+
AgenticEditConversationConfig, ConversationAction
|
|
47
43
|
)
|
|
48
44
|
from .tool_registry import ToolRegistry
|
|
49
45
|
from .tools.base_tool_resolver import BaseToolResolver
|
|
@@ -54,6 +50,19 @@ from .agentic_tool_display import get_tool_display_message
|
|
|
54
50
|
from autocoder.common.utils_code_auto_generate import stream_chat_with_continue
|
|
55
51
|
from autocoder.common.save_formatted_log import save_formatted_log
|
|
56
52
|
from . import agentic_lang
|
|
53
|
+
from autocoder.common.autocoderargs_parser import AutoCoderArgsParser
|
|
54
|
+
import importlib.resources as resources
|
|
55
|
+
|
|
56
|
+
def load_tokenizer():
|
|
57
|
+
from autocoder.rag.variable_holder import VariableHolder
|
|
58
|
+
from tokenizers import Tokenizer
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
tokenizer_path = str(resources.files("autocoder") / "data" / "tokenizer.json")
|
|
62
|
+
VariableHolder.TOKENIZER_PATH = tokenizer_path
|
|
63
|
+
VariableHolder.TOKENIZER_MODEL = Tokenizer.from_file(tokenizer_path)
|
|
64
|
+
except FileNotFoundError:
|
|
65
|
+
tokenizer_path = None
|
|
57
66
|
|
|
58
67
|
class BaseAgent(ABC):
|
|
59
68
|
"""
|
|
@@ -68,16 +77,29 @@ class BaseAgent(ABC):
|
|
|
68
77
|
files: SourceCodeList,
|
|
69
78
|
args: AutoCoderArgs,
|
|
70
79
|
conversation_history: Optional[List[Dict[str, Any]]] = None,
|
|
71
|
-
default_tools_list: Optional[List[str]] = None
|
|
80
|
+
default_tools_list: Optional[List[str]] = None,
|
|
81
|
+
custom_system_prompt: Optional[str] = None,
|
|
82
|
+
conversation_config: Optional['AgenticEditConversationConfig'] = None,
|
|
83
|
+
cancel_token: Optional[str] = None
|
|
72
84
|
):
|
|
85
|
+
# 并行执行相关初始化
|
|
86
|
+
self._parallel_executor = None
|
|
87
|
+
if getattr(args, 'enable_parallel_tools', False):
|
|
88
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
89
|
+
self._parallel_executor = ThreadPoolExecutor(max_workers=4)
|
|
73
90
|
"""
|
|
74
91
|
初始化代理
|
|
75
92
|
|
|
76
93
|
Args:
|
|
94
|
+
name: 代理名称
|
|
77
95
|
llm: 语言模型客户端
|
|
78
96
|
files: 源码文件列表
|
|
79
97
|
args: 配置参数
|
|
80
98
|
conversation_history: 对话历史记录
|
|
99
|
+
default_tools_list: 默认工具列表
|
|
100
|
+
custom_system_prompt: 自定义系统提示
|
|
101
|
+
conversation_config: 对话配置
|
|
102
|
+
cancel_token: 取消令牌
|
|
81
103
|
"""
|
|
82
104
|
# 1. 初始化FileMonitor(必须最先进行)
|
|
83
105
|
try:
|
|
@@ -102,7 +124,17 @@ class BaseAgent(ABC):
|
|
|
102
124
|
self.args = args
|
|
103
125
|
self.files = files
|
|
104
126
|
self.printer = Printer()
|
|
105
|
-
|
|
127
|
+
# 对话历史存储优化:限制最大长度,实现LRU缓存
|
|
128
|
+
self.max_conversation_history = getattr(args, 'max_conversation_history', 20)
|
|
129
|
+
self.conversation_history = conversation_history[-self.max_conversation_history:] if conversation_history else []
|
|
130
|
+
self.conversation_config = conversation_config
|
|
131
|
+
self.cancel_token = cancel_token
|
|
132
|
+
|
|
133
|
+
# 内存监控
|
|
134
|
+
self._memory_warning_issued = False
|
|
135
|
+
|
|
136
|
+
# Initialize AutoCoderArgs parser for flexible parameter parsing
|
|
137
|
+
self.args_parser = AutoCoderArgsParser()
|
|
106
138
|
|
|
107
139
|
|
|
108
140
|
# 5. 初始化其他组件
|
|
@@ -149,14 +181,25 @@ class BaseAgent(ABC):
|
|
|
149
181
|
self.joined_groups: Dict[str, Group] = {}
|
|
150
182
|
self.private_chats: Dict[str, List[Message]] = {}
|
|
151
183
|
self.agentic_conversations: List[Dict[str,Any]] = []
|
|
152
|
-
self.custom_system_prompt = "You are a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices."
|
|
184
|
+
self.custom_system_prompt = custom_system_prompt or "You are a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices."
|
|
153
185
|
self.refuse_reply_reason = ""
|
|
154
186
|
self._group_lock = threading.RLock() # 保护 joined_groups
|
|
155
187
|
self._chat_lock = threading.RLock() # 保护 private_chats
|
|
156
188
|
# 自动注册到AgentHub
|
|
157
189
|
AgentHub.register_agent(self)
|
|
158
190
|
register_default_tools(params=self._render_context(), default_tools_list=default_tools_list)
|
|
191
|
+
|
|
192
|
+
def _get_parsed_safe_zone_tokens(self) -> int:
|
|
193
|
+
"""
|
|
194
|
+
解析 conversation_prune_safe_zone_tokens 参数,支持多种格式
|
|
159
195
|
|
|
196
|
+
Returns:
|
|
197
|
+
解析后的 token 数量
|
|
198
|
+
"""
|
|
199
|
+
return self.args_parser.parse_conversation_prune_safe_zone_tokens(
|
|
200
|
+
self.args.conversation_prune_safe_zone_tokens,
|
|
201
|
+
self.args.code_model
|
|
202
|
+
)
|
|
160
203
|
|
|
161
204
|
def who_am_i(self, role: str) -> 'BaseAgent':
|
|
162
205
|
self.custom_system_prompt = role
|
|
@@ -393,41 +436,35 @@ class BaseAgent(ABC):
|
|
|
393
436
|
"""
|
|
394
437
|
return self.file_changes
|
|
395
438
|
|
|
396
|
-
def
|
|
439
|
+
def get_all_file_changes(self) -> Dict[str, FileChangeEntry]:
|
|
397
440
|
"""
|
|
398
|
-
|
|
441
|
+
获取当前记录的所有文件变更信息。
|
|
399
442
|
|
|
400
443
|
Returns:
|
|
401
|
-
|
|
444
|
+
字典,key 为文件路径,value 为变更详情
|
|
402
445
|
"""
|
|
403
|
-
|
|
404
|
-
shadow_root = self.shadow_manager.shadows_dir
|
|
405
|
-
for root, dirs, files in os.walk(shadow_root):
|
|
406
|
-
for fname in files:
|
|
407
|
-
shadow_file_path = os.path.join(root, fname)
|
|
408
|
-
try:
|
|
409
|
-
project_file_path = self.shadow_manager.from_shadow_path(
|
|
410
|
-
shadow_file_path)
|
|
411
|
-
rel_path = os.path.relpath(
|
|
412
|
-
project_file_path, self.args.source_dir)
|
|
413
|
-
changed_files.append(rel_path)
|
|
414
|
-
except Exception:
|
|
415
|
-
# 非映射关系,忽略
|
|
416
|
-
continue
|
|
417
|
-
return changed_files
|
|
446
|
+
return self.file_changes
|
|
418
447
|
|
|
419
448
|
|
|
449
|
+
# 缓存工具标签查找结果
|
|
450
|
+
_tool_tag_cache = {}
|
|
451
|
+
|
|
420
452
|
def _reconstruct_tool_xml(self, tool: BaseTool) -> str:
|
|
421
453
|
"""
|
|
422
454
|
Reconstructs the XML representation of a tool call from its Pydantic model.
|
|
423
455
|
"""
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
456
|
+
tool_type = type(tool)
|
|
457
|
+
# 首先检查缓存
|
|
458
|
+
tool_tag = self._tool_tag_cache.get(tool_type)
|
|
459
|
+
if tool_tag is None:
|
|
460
|
+
tool_tag = next(
|
|
461
|
+
(tag for tag, model in ToolRegistry.get_tag_model_map().items() if tool_type is model), None)
|
|
462
|
+
if tool_tag:
|
|
463
|
+
self._tool_tag_cache[tool_type] = tool_tag
|
|
464
|
+
else:
|
|
465
|
+
logger.error(
|
|
466
|
+
f"Cannot find tag name for tool type {tool_type.__name__}")
|
|
467
|
+
return f"<error>Could not find tag for tool {tool_type.__name__}</error>"
|
|
431
468
|
|
|
432
469
|
xml_parts = [f"<{tool_tag}>"]
|
|
433
470
|
for field_name, field_value in tool.model_dump(exclude_none=True).items():
|
|
@@ -524,7 +561,7 @@ class BaseAgent(ABC):
|
|
|
524
561
|
# Tool Use Guidelines
|
|
525
562
|
|
|
526
563
|
1. In <thinking> tags, assess what information you already have and what information you need to proceed with the task.
|
|
527
|
-
2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like
|
|
564
|
+
2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like `ls` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task.
|
|
528
565
|
3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
|
|
529
566
|
4. Formulate your tool use using the XML format specified for each tool.
|
|
530
567
|
5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include:
|
|
@@ -595,9 +632,9 @@ class BaseAgent(ABC):
|
|
|
595
632
|
RULES
|
|
596
633
|
|
|
597
634
|
- Your current working directory is: {{current_project}}
|
|
598
|
-
- You cannot
|
|
635
|
+
- You cannot `cd` into a different directory to complete a task. You are stuck operating from '{{ current_project }}', so be sure to pass in the correct 'path' parameter when using tools that require a path.
|
|
599
636
|
- Do not use the ~ character or $HOME to refer to the home directory.
|
|
600
|
-
- Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '{{ current_project }}', and if so prepend with
|
|
637
|
+
- Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '{{ current_project }}', and if so prepend with `cd`'ing into that directory && then executing the command (as one command since you are stuck operating from '{{current_project}}'). For example, if you needed to run `npm install` in a project outside of '{{current_project}}', you would need to prepend with a `cd` i.e. pseudocode for this would be `cd (path to project) && (command, in this case npm install)`.
|
|
601
638
|
- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches.
|
|
602
639
|
- The write_to_file and replace_in_file tools are ONLY to be used for creating and updating research plans, search strategies, or summarizing findings. They are NOT to be used for modifying system files or any operational code.
|
|
603
640
|
- When making research plans, always consider the context and objectives clearly outlined by the user.
|
|
@@ -625,15 +662,11 @@ class BaseAgent(ABC):
|
|
|
625
662
|
RULES OR DOCUMENTS PROVIDED BY USER
|
|
626
663
|
|
|
627
664
|
The following rules are provided by the user, and you must follow them strictly.
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
{% for key, value in extra_docs.items() %}
|
|
631
|
-
<user_rule_or_document_file>
|
|
665
|
+
|
|
666
|
+
{% for key, value in extra_docs.items() %}
|
|
632
667
|
##File: {{ key }}
|
|
633
|
-
{{ value }}
|
|
634
|
-
|
|
635
|
-
{% endfor %}
|
|
636
|
-
</user_rule_or_document_files>
|
|
668
|
+
{{ value }}
|
|
669
|
+
{% endfor %}
|
|
637
670
|
|
|
638
671
|
Make sure you always start your task by using the read_file tool to get the relevant RULE files listed in index.md based on the user's specific requirements.
|
|
639
672
|
{% endif %}
|
|
@@ -719,7 +752,7 @@ class BaseAgent(ABC):
|
|
|
719
752
|
"env_info": env_info,
|
|
720
753
|
"shell_type": shell_type,
|
|
721
754
|
"shell_encoding": shells.get_terminal_encoding(),
|
|
722
|
-
"conversation_safe_zone_tokens": self.
|
|
755
|
+
"conversation_safe_zone_tokens": self._get_parsed_safe_zone_tokens(),
|
|
723
756
|
"os_distribution": shells.get_os_distribution(),
|
|
724
757
|
"current_user": shells.get_current_username(),
|
|
725
758
|
"current_project": os.path.abspath(self.args.source_dir),
|
|
@@ -754,6 +787,17 @@ class BaseAgent(ABC):
|
|
|
754
787
|
conversations = [
|
|
755
788
|
{"role": "system", "content": system_prompt},
|
|
756
789
|
]
|
|
790
|
+
|
|
791
|
+
# 恢复对话历史
|
|
792
|
+
if self.conversation_history:
|
|
793
|
+
logger.info(f"Restoring conversation history with {len(self.conversation_history)} messages")
|
|
794
|
+
for message in self.conversation_history:
|
|
795
|
+
# 确保消息格式正确(包含 role 和 content 字段)
|
|
796
|
+
if isinstance(message, dict) and 'role' in message and 'content' in message:
|
|
797
|
+
conversations.append({
|
|
798
|
+
"role": message['role'],
|
|
799
|
+
"content": message['content']
|
|
800
|
+
})
|
|
757
801
|
|
|
758
802
|
conversations.append({
|
|
759
803
|
"role": "user", "content": request.user_input
|
|
@@ -770,10 +814,13 @@ class BaseAgent(ABC):
|
|
|
770
814
|
should_yield_completion_event = False
|
|
771
815
|
completion_event = None
|
|
772
816
|
|
|
773
|
-
|
|
817
|
+
# 更明确的循环条件,添加最大轮次检查
|
|
818
|
+
max_iterations = getattr(self.args, 'agentic_max_rounds', 20)
|
|
819
|
+
while iteration_count <= max_iterations:
|
|
774
820
|
iteration_count += 1
|
|
775
|
-
|
|
776
|
-
global_cancel.check_and_raise(token=self.args.
|
|
821
|
+
tool_executed = False
|
|
822
|
+
global_cancel.check_and_raise(token=self.cancel_token or self.args.cancel_token)
|
|
823
|
+
|
|
777
824
|
last_message = conversations[-1]
|
|
778
825
|
if last_message["role"] == "assistant":
|
|
779
826
|
logger.info(f"Last message is assistant, skipping LLM interaction cycle")
|
|
@@ -785,12 +832,18 @@ class BaseAgent(ABC):
|
|
|
785
832
|
), completion_xml="")
|
|
786
833
|
else:
|
|
787
834
|
yield completion_event
|
|
788
|
-
break
|
|
789
|
-
logger.info(
|
|
790
|
-
f"Starting LLM interaction cycle. History size: {len(conversations)}")
|
|
835
|
+
break
|
|
791
836
|
|
|
792
|
-
assistant_buffer = ""
|
|
793
|
-
|
|
837
|
+
assistant_buffer = ""
|
|
838
|
+
|
|
839
|
+
# Check if we need to handle max rounds
|
|
840
|
+
if hasattr(self.args, 'agentic_max_rounds') and iteration_count > self.args.agentic_max_rounds:
|
|
841
|
+
logger.info(f"Agentic max rounds reached: {self.args.agentic_max_rounds}")
|
|
842
|
+
yield CompletionEvent(completion=AttemptCompletionTool(
|
|
843
|
+
result="Agentic max rounds reached, please try again later",
|
|
844
|
+
command=""
|
|
845
|
+
), completion_xml="")
|
|
846
|
+
break
|
|
794
847
|
|
|
795
848
|
## 实际请求大模型
|
|
796
849
|
llm_response_gen = stream_chat_with_continue(
|
|
@@ -800,37 +853,36 @@ class BaseAgent(ABC):
|
|
|
800
853
|
args=self.args
|
|
801
854
|
)
|
|
802
855
|
|
|
803
|
-
logger.info("Starting to parse LLM response stream")
|
|
804
856
|
parsed_events = self.stream_and_parse_llm_response(
|
|
805
857
|
llm_response_gen)
|
|
806
858
|
|
|
807
859
|
event_count = 0
|
|
808
860
|
mark_event_should_finish = False
|
|
809
861
|
for event in parsed_events:
|
|
862
|
+
global_cancel.check_and_raise(token=self.cancel_token or self.args.cancel_token)
|
|
810
863
|
event_count += 1
|
|
811
|
-
logger.info(f"Processing event #{event_count}: {type(event).__name__}")
|
|
812
|
-
global_cancel.check_and_raise(token=self.args.event_file)
|
|
813
864
|
|
|
814
865
|
if mark_event_should_finish:
|
|
815
866
|
if isinstance(event, TokenUsageEvent):
|
|
816
|
-
logger.info("Yielding token usage event")
|
|
817
867
|
yield event
|
|
818
868
|
continue
|
|
819
869
|
|
|
820
870
|
if isinstance(event, (LLMOutputEvent, LLMThinkingEvent)):
|
|
821
|
-
assistant_buffer += event.text
|
|
822
|
-
|
|
823
|
-
yield event # Yield text/thinking immediately for display
|
|
871
|
+
assistant_buffer += event.text
|
|
872
|
+
yield event # Yield text/thinking immediately for display
|
|
824
873
|
|
|
825
874
|
elif isinstance(event, ToolCallEvent):
|
|
875
|
+
|
|
876
|
+
## Check for background tasks notifications (basic implementation)
|
|
877
|
+
## This is a simplified version compared to agentic_edit.py
|
|
878
|
+
## Subclasses can override this for more sophisticated handling
|
|
879
|
+
|
|
826
880
|
tool_executed = True
|
|
827
881
|
tool_obj = event.tool
|
|
828
882
|
tool_name = type(tool_obj).__name__
|
|
829
883
|
logger.info(f"Tool call detected: {tool_name}")
|
|
830
884
|
tool_xml = event.tool_xml # Already reconstructed by parser
|
|
831
885
|
|
|
832
|
-
# Append assistant's thoughts and the tool call to history
|
|
833
|
-
logger.info(f"Adding assistant message with tool call to conversation history")
|
|
834
886
|
conversations.append({
|
|
835
887
|
"role": "assistant",
|
|
836
888
|
"content": assistant_buffer + tool_xml
|
|
@@ -838,29 +890,22 @@ class BaseAgent(ABC):
|
|
|
838
890
|
assistant_buffer = "" # Reset buffer after tool call
|
|
839
891
|
|
|
840
892
|
yield event # Yield the ToolCallEvent for display
|
|
841
|
-
logger.info("Yielded ToolCallEvent")
|
|
842
893
|
|
|
843
894
|
# Handle AttemptCompletion separately as it ends the loop
|
|
844
|
-
if isinstance(tool_obj, AttemptCompletionTool):
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
logger.info(
|
|
850
|
-
"Agentic analyze loop finished due to AttemptCompletion.")
|
|
851
|
-
save_formatted_log(self.args.source_dir, json.dumps(conversations, ensure_ascii=False), "agentic_conversation")
|
|
895
|
+
if isinstance(tool_obj, AttemptCompletionTool):
|
|
896
|
+
completion_event = CompletionEvent(
|
|
897
|
+
completion=tool_obj, completion_xml=tool_xml)
|
|
898
|
+
save_formatted_log(self.args.source_dir, json.dumps(
|
|
899
|
+
conversations, ensure_ascii=False), "agentic_conversation")
|
|
852
900
|
mark_event_should_finish = True
|
|
853
901
|
should_yield_completion_event = True
|
|
854
902
|
continue
|
|
855
903
|
|
|
856
|
-
if isinstance(tool_obj, PlanModeRespondTool):
|
|
857
|
-
logger.info(
|
|
858
|
-
"PlanModeRespondTool received. Finalizing session.")
|
|
859
|
-
logger.info(f"Plan mode response: {tool_obj.response[:50]}...")
|
|
904
|
+
if isinstance(tool_obj, PlanModeRespondTool):
|
|
860
905
|
yield PlanModeRespondEvent(completion=tool_obj, completion_xml=tool_xml)
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
906
|
+
save_formatted_log(self.args.source_dir, json.dumps(
|
|
907
|
+
conversations, ensure_ascii=False), "agentic_conversation")
|
|
908
|
+
mark_event_should_finish = True
|
|
864
909
|
continue
|
|
865
910
|
|
|
866
911
|
# Resolve the tool
|
|
@@ -872,7 +917,7 @@ class BaseAgent(ABC):
|
|
|
872
917
|
success=False, message="Error: Tool resolver not implemented.", content=None)
|
|
873
918
|
result_event = ToolResultEvent(tool_name=type(
|
|
874
919
|
tool_obj).__name__, result=tool_result)
|
|
875
|
-
|
|
920
|
+
tool_executed_xml = f"<tool_result tool_name='{type(tool_obj).__name__}' success='false'><message>Error: Tool resolver not implemented.</message><content></content></tool_result>"
|
|
876
921
|
else:
|
|
877
922
|
try:
|
|
878
923
|
logger.info(f"Creating resolver for tool: {tool_name}")
|
|
@@ -886,15 +931,13 @@ class BaseAgent(ABC):
|
|
|
886
931
|
result_event = ToolResultEvent(tool_name=type(
|
|
887
932
|
tool_obj).__name__, result=tool_result)
|
|
888
933
|
|
|
889
|
-
# Prepare XML for conversation history
|
|
890
|
-
logger.info("Preparing XML for conversation history")
|
|
891
934
|
escaped_message = xml.sax.saxutils.escape(
|
|
892
935
|
tool_result.message)
|
|
893
936
|
content_str = str(
|
|
894
937
|
tool_result.content) if tool_result.content is not None else ""
|
|
895
938
|
escaped_content = xml.sax.saxutils.escape(
|
|
896
939
|
content_str)
|
|
897
|
-
|
|
940
|
+
tool_executed_xml = (
|
|
898
941
|
f"<tool_result tool_name='{type(tool_obj).__name__}' success='{str(tool_result.success).lower()}'>"
|
|
899
942
|
f"<message>{escaped_message}</message>"
|
|
900
943
|
f"<content>{escaped_content}</content>"
|
|
@@ -910,25 +953,23 @@ class BaseAgent(ABC):
|
|
|
910
953
|
tool_obj).__name__, result=tool_result)
|
|
911
954
|
escaped_error = xml.sax.saxutils.escape(
|
|
912
955
|
error_message)
|
|
913
|
-
|
|
956
|
+
tool_executed_xml = f"<tool_result tool_name='{type(tool_obj).__name__}' success='false'><message>{escaped_error}</message><content></content></tool_result>"
|
|
914
957
|
|
|
915
|
-
yield result_event # Yield the ToolResultEvent for display
|
|
916
|
-
logger.info("Yielded ToolResultEvent")
|
|
958
|
+
yield result_event # Yield the ToolResultEvent for display
|
|
917
959
|
|
|
918
|
-
#
|
|
919
|
-
logger.info("Adding tool result to conversation history")
|
|
960
|
+
# 添加工具结果到对话历史
|
|
920
961
|
conversations.append({
|
|
921
962
|
"role": "user", # Simulating the user providing the tool result
|
|
922
|
-
"content":
|
|
963
|
+
"content": tool_executed_xml
|
|
923
964
|
})
|
|
924
|
-
|
|
925
|
-
f"Added tool result to conversations for tool {type(tool_obj).__name__}")
|
|
926
|
-
logger.info(f"Breaking LLM cycle after executing tool: {tool_name}")
|
|
927
|
-
|
|
965
|
+
|
|
928
966
|
# 一次交互只能有一次工具,剩下的其实就没有用了,但是如果不让流式处理完,我们就无法获取服务端
|
|
929
967
|
# 返回的token消耗和计费,所以通过此标记来完成进入空转,直到流式走完,获取到最后的token消耗和计费
|
|
930
|
-
mark_event_should_finish = True
|
|
931
|
-
|
|
968
|
+
mark_event_should_finish = True
|
|
969
|
+
|
|
970
|
+
elif isinstance(event, RetryEvent):
|
|
971
|
+
logger.info(f"Retry event occurred: {event.message}")
|
|
972
|
+
yield event
|
|
932
973
|
|
|
933
974
|
elif isinstance(event, ErrorEvent):
|
|
934
975
|
logger.error(f"Error event occurred: {event.message}")
|
|
@@ -936,37 +977,38 @@ class BaseAgent(ABC):
|
|
|
936
977
|
# Optionally stop the process on parsing errors
|
|
937
978
|
# logger.error("Stopping analyze loop due to parsing error.")
|
|
938
979
|
# return
|
|
939
|
-
elif isinstance(event, TokenUsageEvent):
|
|
940
|
-
|
|
941
|
-
yield event
|
|
980
|
+
elif isinstance(event, TokenUsageEvent):
|
|
981
|
+
yield event
|
|
942
982
|
|
|
943
983
|
if not tool_executed:
|
|
944
984
|
# No tool executed in this LLM response cycle
|
|
945
|
-
logger.info("LLM response finished without executing a tool.")
|
|
985
|
+
logger.info("LLM response finished without executing a tool.")
|
|
946
986
|
# Append any remaining assistant buffer to history if it wasn't followed by a tool
|
|
947
987
|
if assistant_buffer:
|
|
948
|
-
|
|
988
|
+
|
|
949
989
|
last_message = conversations[-1]
|
|
950
990
|
if last_message["role"] != "assistant":
|
|
951
991
|
logger.info("Adding new assistant message")
|
|
952
992
|
conversations.append(
|
|
953
993
|
{"role": "assistant", "content": assistant_buffer})
|
|
994
|
+
|
|
954
995
|
elif last_message["role"] == "assistant":
|
|
955
996
|
logger.info("Appending to existing assistant message")
|
|
956
997
|
last_message["content"] += assistant_buffer
|
|
957
|
-
|
|
998
|
+
|
|
958
999
|
# 添加系统提示,要求LLM必须使用工具或明确结束,而不是直接退出
|
|
959
|
-
logger.info(
|
|
1000
|
+
logger.info(
|
|
1001
|
+
"Adding system reminder to use tools or attempt completion")
|
|
1002
|
+
|
|
960
1003
|
conversations.append({
|
|
961
1004
|
"role": "user",
|
|
962
1005
|
"content": "NOTE: You must use an appropriate tool (such as read_file, write_to_file, execute_command, etc.) or explicitly complete the task (using attempt_completion). Do not provide text responses without taking concrete actions. Please select a suitable tool to continue based on the user's task."
|
|
963
1006
|
})
|
|
964
|
-
|
|
965
|
-
logger.info("Continuing the LLM interaction loop without breaking")
|
|
1007
|
+
|
|
966
1008
|
continue
|
|
967
1009
|
|
|
968
|
-
logger.info(f"
|
|
969
|
-
save_formatted_log(self.args.source_dir, json.dumps(conversations, ensure_ascii=False), "agentic_conversation")
|
|
1010
|
+
logger.info(f"AgenticEdit analyze loop finished after {iteration_count} iterations.")
|
|
1011
|
+
save_formatted_log(self.args.source_dir, json.dumps(conversations, ensure_ascii=False), "agentic_conversation")
|
|
970
1012
|
|
|
971
1013
|
def stream_and_parse_llm_response(
|
|
972
1014
|
self, generator: Generator[Tuple[str, Any], None, None]
|
|
@@ -986,10 +1028,17 @@ class BaseAgent(ABC):
|
|
|
986
1028
|
in_tool_block = False
|
|
987
1029
|
in_thinking_block = False
|
|
988
1030
|
current_tool_tag = None
|
|
989
|
-
|
|
990
|
-
|
|
1031
|
+
|
|
1032
|
+
# 预编译正则表达式以提高性能
|
|
1033
|
+
tool_start_pattern = re.compile(r"<([a-zA-Z0-9_]+)>")
|
|
1034
|
+
_tool_end_pattern = re.compile(r"</([a-zA-Z0-9_]+)>")
|
|
991
1035
|
thinking_start_tag = "<thinking>"
|
|
992
1036
|
thinking_end_tag = "</thinking>"
|
|
1037
|
+
_param_pattern = re.compile(r"<([a-zA-Z0-9_]+)>(.*?)</\1>", re.DOTALL)
|
|
1038
|
+
|
|
1039
|
+
# 性能监控
|
|
1040
|
+
start_time = time.time()
|
|
1041
|
+
event_count = 0
|
|
993
1042
|
|
|
994
1043
|
def parse_tool_xml(tool_xml: str, tool_tag: str) -> Optional[BaseTool]:
|
|
995
1044
|
"""Minimal parser for tool XML string."""
|
|
@@ -1049,7 +1098,7 @@ class BaseAgent(ABC):
|
|
|
1049
1098
|
|
|
1050
1099
|
last_metadata = None
|
|
1051
1100
|
for content_chunk, metadata in generator:
|
|
1052
|
-
global_cancel.check_and_raise(token=self.args.
|
|
1101
|
+
global_cancel.check_and_raise(token=self.cancel_token or self.args.cancel_token)
|
|
1053
1102
|
if not content_chunk:
|
|
1054
1103
|
last_metadata = metadata
|
|
1055
1104
|
continue
|
|
@@ -1095,9 +1144,9 @@ class BaseAgent(ABC):
|
|
|
1095
1144
|
else:
|
|
1096
1145
|
yield ToolCallEvent(tool=tool_obj, tool_xml=reconstructed_xml)
|
|
1097
1146
|
else:
|
|
1098
|
-
yield ErrorEvent(message=f"Failed to parse tool: <{current_tool_tag}>")
|
|
1147
|
+
# yield ErrorEvent(message=f"Failed to parse tool: <{current_tool_tag}>")
|
|
1099
1148
|
# Optionally yield the raw XML as plain text?
|
|
1100
|
-
|
|
1149
|
+
yield LLMOutputEvent(text=f"Failed to parse tool: <{current_tool_tag}> {tool_xml}")
|
|
1101
1150
|
|
|
1102
1151
|
buffer = buffer[tool_block_end_index:]
|
|
1103
1152
|
in_tool_block = False
|
|
@@ -1170,19 +1219,25 @@ class BaseAgent(ABC):
|
|
|
1170
1219
|
# After generator exhausted, yield any remaining content
|
|
1171
1220
|
if in_thinking_block:
|
|
1172
1221
|
# Unterminated thinking block
|
|
1173
|
-
yield
|
|
1222
|
+
yield RetryEvent(message="Stream ended with unterminated <thinking> block.")
|
|
1174
1223
|
if buffer:
|
|
1175
1224
|
# Yield remaining as thinking
|
|
1176
1225
|
yield LLMThinkingEvent(text=buffer)
|
|
1177
1226
|
elif in_tool_block:
|
|
1178
1227
|
# Unterminated tool block
|
|
1179
|
-
yield
|
|
1228
|
+
yield RetryEvent(message=f"Stream ended with unterminated <{current_tool_tag}> block.")
|
|
1180
1229
|
if buffer:
|
|
1181
1230
|
yield LLMOutputEvent(text=buffer) # Yield remaining as text
|
|
1182
1231
|
elif buffer:
|
|
1183
1232
|
# Yield remaining plain text
|
|
1184
1233
|
yield LLMOutputEvent(text=buffer)
|
|
1185
1234
|
|
|
1235
|
+
# 性能日志
|
|
1236
|
+
duration = time.time() - start_time
|
|
1237
|
+
logger.info(
|
|
1238
|
+
f"Event stream processing completed: {event_count} events in {duration:.3f}s "
|
|
1239
|
+
f"({event_count/max(duration, 0.001):.1f} events/sec)")
|
|
1240
|
+
|
|
1186
1241
|
# 这个要放在最后,防止其他关联的多个事件的信息中断
|
|
1187
1242
|
yield TokenUsageEvent(usage=last_metadata)
|
|
1188
1243
|
|
|
@@ -1243,20 +1298,48 @@ class BaseAgent(ABC):
|
|
|
1243
1298
|
event_manager.write_result(
|
|
1244
1299
|
content=content.to_dict(), metadata=metadata.to_dict())
|
|
1245
1300
|
elif isinstance(agent_event, TokenUsageEvent):
|
|
1246
|
-
#
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1301
|
+
# 缓存模型价格信息
|
|
1302
|
+
if not hasattr(self, '_cached_model_info'):
|
|
1303
|
+
model_name = ",".join(llms_utils.get_llm_names(self.llm))
|
|
1304
|
+
self._cached_model_info = llms_utils.get_model_info(
|
|
1305
|
+
model_name, self.args.product_mode) or {}
|
|
1306
|
+
self._cached_model_name = model_name
|
|
1307
|
+
|
|
1308
|
+
# 获取价格
|
|
1309
|
+
input_price = self._cached_model_info.get("input_price", 0.0)
|
|
1310
|
+
output_price = self._cached_model_info.get("output_price", 0.0)
|
|
1252
1311
|
|
|
1253
1312
|
# 计算成本
|
|
1254
1313
|
last_meta = agent_event.usage
|
|
1255
|
-
|
|
1256
|
-
|
|
1314
|
+
input_tokens = max(last_meta.input_tokens_count, 0)
|
|
1315
|
+
output_tokens = max(last_meta.generated_tokens_count, 0)
|
|
1316
|
+
|
|
1317
|
+
input_cost = (input_tokens * input_price) / 1000000 # 转换为百万
|
|
1318
|
+
output_cost = (output_tokens * output_price) / 1000000
|
|
1319
|
+
|
|
1320
|
+
# 预测总成本
|
|
1321
|
+
if not hasattr(self, '_total_input_tokens'):
|
|
1322
|
+
self._total_input_tokens = 0
|
|
1323
|
+
self._total_output_tokens = 0
|
|
1324
|
+
self._total_input_cost = 0.0
|
|
1325
|
+
self._total_output_cost = 0.0
|
|
1326
|
+
|
|
1327
|
+
self._total_input_tokens += input_tokens
|
|
1328
|
+
self._total_output_tokens += output_tokens
|
|
1329
|
+
self._total_input_cost += input_cost
|
|
1330
|
+
self._total_output_cost += output_cost
|
|
1257
1331
|
|
|
1258
|
-
#
|
|
1259
|
-
logger.info(
|
|
1332
|
+
# 记录详细Token使用情况
|
|
1333
|
+
logger.info(
|
|
1334
|
+
f"Token Usage Details:\n"
|
|
1335
|
+
f"- Model: {self._cached_model_name}\n"
|
|
1336
|
+
f"- Input: {input_tokens} tokens (${input_cost:.6f})\n"
|
|
1337
|
+
f"- Output: {output_tokens} tokens (${output_cost:.6f})\n"
|
|
1338
|
+
f"- Running Totals:\n"
|
|
1339
|
+
f" - Input: {self._total_input_tokens} tokens (${self._total_input_cost:.6f})\n"
|
|
1340
|
+
f" - Output: {self._total_output_tokens} tokens (${self._total_output_cost:.6f})\n"
|
|
1341
|
+
f"- Estimated Final Cost: ${(self._total_input_cost + self._total_output_cost) * 1.2:.6f} (with 20% buffer)"
|
|
1342
|
+
)
|
|
1260
1343
|
|
|
1261
1344
|
# 写入Token统计事件
|
|
1262
1345
|
get_event_manager(self.args.event_file).write_result(
|
|
@@ -1439,6 +1522,8 @@ class BaseAgent(ABC):
|
|
|
1439
1522
|
yield ("result",event.completion.result)
|
|
1440
1523
|
if event.completion.command:
|
|
1441
1524
|
yield ("result", agentic_lang.get_message_with_format("suggested_command", command=event.completion.command))
|
|
1525
|
+
elif isinstance(event, RetryEvent):
|
|
1526
|
+
yield ("thinking", agentic_lang.get_message_with_format("retry_message", message=event.message))
|
|
1442
1527
|
elif isinstance(event, ErrorEvent):
|
|
1443
1528
|
yield ("result", agentic_lang.get_message("error_title"))
|
|
1444
1529
|
yield ("result", agentic_lang.get_message_with_format("error_content", message=event.message))
|
|
@@ -1453,16 +1538,15 @@ class BaseAgent(ABC):
|
|
|
1453
1538
|
finally:
|
|
1454
1539
|
# 在结束时打印累计的token使用情况
|
|
1455
1540
|
duration = time.time() - start_time
|
|
1456
|
-
yield ("result","\n" + self.printer.get_message_from_key_with_format("code_generation_complete",
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
yield ("result", "\n" + agentic_lang.get_message("agent_execution_complete"))
|
|
1541
|
+
# yield ("result","\n" + self.printer.get_message_from_key_with_format("code_generation_complete",
|
|
1542
|
+
# duration=duration,
|
|
1543
|
+
# input_tokens=total_input_tokens,
|
|
1544
|
+
# output_tokens=total_output_tokens,
|
|
1545
|
+
# input_cost=total_input_cost,
|
|
1546
|
+
# output_cost=total_output_cost,
|
|
1547
|
+
# speed=0.0,
|
|
1548
|
+
# model_names=model_name,
|
|
1549
|
+
# sampling_count=1))
|
|
1466
1550
|
|
|
1467
1551
|
def run_in_terminal(self, request: AgentRequest):
|
|
1468
1552
|
"""
|
|
@@ -1746,4 +1830,19 @@ class BaseAgent(ABC):
|
|
|
1746
1830
|
)
|
|
1747
1831
|
else:
|
|
1748
1832
|
self.printer.print_in_terminal("no_changes_made")
|
|
1749
|
-
|
|
1833
|
+
|
|
1834
|
+
@byzerllm.prompt(render="jinja2")
|
|
1835
|
+
def git_require_msg(self, source_dir: str, error: str) -> str:
|
|
1836
|
+
'''
|
|
1837
|
+
auto_merge only works for git repositories.
|
|
1838
|
+
|
|
1839
|
+
Try to use git init in the source directory.
|
|
1840
|
+
|
|
1841
|
+
```shell
|
|
1842
|
+
cd {{ source_dir }}
|
|
1843
|
+
git init .
|
|
1844
|
+
```
|
|
1845
|
+
|
|
1846
|
+
Then try to run auto-coder again.
|
|
1847
|
+
Error: {{ error }}
|
|
1848
|
+
'''
|