auto-coder 1.0.0__py3-none-any.whl → 2.0.1__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.1.dist-info/LICENSE +158 -0
- auto_coder-2.0.1.dist-info/METADATA +558 -0
- auto_coder-2.0.1.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.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 +77 -73
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +962 -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 +409 -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 +316 -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 +356 -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 +1094 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +400 -129
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- 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 +923 -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 +665 -0
- autocoder/workflow_agents/loader.py +749 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +173 -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.1.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import pytest
|
|
3
|
+
from collections import OrderedDict
|
|
3
4
|
from typing import Dict, List, Any
|
|
4
5
|
|
|
5
6
|
# 导入被测模块
|
|
@@ -8,7 +9,8 @@ from .parser import (
|
|
|
8
9
|
parse_query,
|
|
9
10
|
has_command,
|
|
10
11
|
get_command_args,
|
|
11
|
-
get_command_kwargs
|
|
12
|
+
get_command_kwargs,
|
|
13
|
+
get_query_command
|
|
12
14
|
)
|
|
13
15
|
|
|
14
16
|
|
|
@@ -82,6 +84,28 @@ class TestCommandParser:
|
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
assert result == expected
|
|
87
|
+
|
|
88
|
+
def test_single_command_new_params(self, parser):
|
|
89
|
+
"""测试单个命令混合参数"""
|
|
90
|
+
result = parser.parse('/new "把 /Users/williamzhu/.auto-coder/async_agent/tasks/stdin_20250815101939_e9042b6c 中未commit变更合并回来"')
|
|
91
|
+
expected = {
|
|
92
|
+
"new": {
|
|
93
|
+
"args": ['把 /Users/williamzhu/.auto-coder/async_agent/tasks/stdin_20250815101939_e9042b6c 中未commit变更合并回来'],
|
|
94
|
+
"kwargs": {}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
assert result == expected
|
|
98
|
+
|
|
99
|
+
def test_single_command_async_params(self, parser):
|
|
100
|
+
"""测试单个命令混合参数"""
|
|
101
|
+
result = parser.parse("/async \"/list @./src/agent.ts 中,while 循环里有loop call limit 限制,当前会发出一个 emitEvent 事件,同时也需要发出一个渲染事件(opts.render方法)\"")
|
|
102
|
+
expected = {
|
|
103
|
+
"async": {
|
|
104
|
+
"args": ['/list @./src/agent.ts 中,while 循环里有loop call limit 限制,当前会发出一个 emitEvent 事件,同时也需要发出一个渲染事件(opts.render方法)'],
|
|
105
|
+
"kwargs": {}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
assert result == expected
|
|
85
109
|
|
|
86
110
|
def test_quoted_args_double_quotes(self, parser):
|
|
87
111
|
"""测试双引号参数"""
|
|
@@ -153,6 +177,24 @@ class TestCommandParser:
|
|
|
153
177
|
}
|
|
154
178
|
assert result == expected
|
|
155
179
|
|
|
180
|
+
def test_command_order_preservation(self, parser):
|
|
181
|
+
"""测试命令顺序保持"""
|
|
182
|
+
result = parser.parse("/third /first /second arg1 /fourth key=value")
|
|
183
|
+
|
|
184
|
+
# 验证返回的是OrderedDict
|
|
185
|
+
assert isinstance(result, OrderedDict)
|
|
186
|
+
|
|
187
|
+
# 验证命令顺序
|
|
188
|
+
command_order = list(result.keys())
|
|
189
|
+
expected_order = ["third", "first", "second", "fourth"]
|
|
190
|
+
assert command_order == expected_order
|
|
191
|
+
|
|
192
|
+
# 验证内容正确性
|
|
193
|
+
assert result["third"]["args"] == []
|
|
194
|
+
assert result["first"]["args"] == []
|
|
195
|
+
assert result["second"]["args"] == ["arg1"]
|
|
196
|
+
assert result["fourth"]["kwargs"] == {"key": "value"}
|
|
197
|
+
|
|
156
198
|
def test_path_not_recognized_as_command(self, parser):
|
|
157
199
|
"""测试路径不被识别为命令"""
|
|
158
200
|
result = parser.parse("/add /path/to/file.txt /config model=gpt-4")
|
|
@@ -243,6 +285,46 @@ class TestCommandParser:
|
|
|
243
285
|
}
|
|
244
286
|
}
|
|
245
287
|
assert result == expected
|
|
288
|
+
|
|
289
|
+
def test_auto_new_complex_scenario(self, parser):
|
|
290
|
+
"""测试复杂的自动化场景:/auto /new 运行使用交互式方式运行 auto-coder.chat 然后在里面运行 /rules /list"""
|
|
291
|
+
query = "/auto /new 运行使用交互式方式运行 auto-coder.chat 然后在里面运行 /rules /list"
|
|
292
|
+
result = parser.parse(query)
|
|
293
|
+
expected = {
|
|
294
|
+
"auto": {
|
|
295
|
+
"args": [],
|
|
296
|
+
"kwargs": {}
|
|
297
|
+
},
|
|
298
|
+
"new": {
|
|
299
|
+
"args": ["运行使用交互式方式运行", "auto-coder.chat", "然后在里面运行"],
|
|
300
|
+
"kwargs": {}
|
|
301
|
+
},
|
|
302
|
+
"rules": {
|
|
303
|
+
"args": [],
|
|
304
|
+
"kwargs": {}
|
|
305
|
+
},
|
|
306
|
+
"list": {
|
|
307
|
+
"args": [],
|
|
308
|
+
"kwargs": {}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
assert result == expected
|
|
312
|
+
|
|
313
|
+
def test_auto_new_complex_scenario2(self, parser):
|
|
314
|
+
"""测试复杂的自动化场景:/auto /new 运行使用交互式方式运行 auto-coder.chat 然后在里面运行 /rules /list"""
|
|
315
|
+
query = '/auto /new "运行使用交互式方式运行 auto-coder.chat 然后在里面运行 /rules /list"'
|
|
316
|
+
result = parser.parse(query)
|
|
317
|
+
expected = {
|
|
318
|
+
"auto": {
|
|
319
|
+
"args": [],
|
|
320
|
+
"kwargs": {}
|
|
321
|
+
},
|
|
322
|
+
"new": {
|
|
323
|
+
"args": ["运行使用交互式方式运行 auto-coder.chat 然后在里面运行 /rules /list"],
|
|
324
|
+
"kwargs": {}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
assert result == expected
|
|
246
328
|
|
|
247
329
|
|
|
248
330
|
class TestConvenienceFunctions:
|
|
@@ -251,6 +333,10 @@ class TestConvenienceFunctions:
|
|
|
251
333
|
def test_parse_query_function(self):
|
|
252
334
|
"""测试parse_query函数"""
|
|
253
335
|
result = parse_query("/add file1.txt mode=fast")
|
|
336
|
+
|
|
337
|
+
# 验证返回的是OrderedDict
|
|
338
|
+
assert isinstance(result, OrderedDict)
|
|
339
|
+
|
|
254
340
|
expected = {
|
|
255
341
|
"add": {
|
|
256
342
|
"args": ["file1.txt"],
|
|
@@ -426,9 +512,12 @@ class TestErrorHandling:
|
|
|
426
512
|
"""测试命令中的特殊字符"""
|
|
427
513
|
parser = CommandParser()
|
|
428
514
|
|
|
429
|
-
#
|
|
515
|
+
# 命令名可以包含单词字符和连字符,但不能包含点号
|
|
430
516
|
result = parser.parse("/test-command /test.command")
|
|
431
|
-
|
|
517
|
+
expected = OrderedDict({
|
|
518
|
+
'test-command': {'args': ['/test.command'], 'kwargs': {}}
|
|
519
|
+
})
|
|
520
|
+
assert result == expected
|
|
432
521
|
|
|
433
522
|
def test_whitespace_handling(self):
|
|
434
523
|
"""测试空白字符处理"""
|
|
@@ -460,19 +549,6 @@ class TestErrorHandling:
|
|
|
460
549
|
}
|
|
461
550
|
assert result == expected
|
|
462
551
|
|
|
463
|
-
def test__command_with_path(self, parser):
|
|
464
|
-
"""测试单个命令混合参数"""
|
|
465
|
-
result = parser.parse('/command "tdd/hello.md" name="威廉"')
|
|
466
|
-
expected = {
|
|
467
|
-
"command": {
|
|
468
|
-
"args": ["tdd/hello.md"],
|
|
469
|
-
"kwargs": {
|
|
470
|
-
"name": "威廉"
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
assert result == expected
|
|
475
|
-
|
|
476
552
|
|
|
477
553
|
# 参数化测试用例
|
|
478
554
|
@pytest.mark.parametrize("query,expected_commands", [
|
|
@@ -511,6 +587,155 @@ def test_get_kwargs_parametrized(query, command, expected_kwargs):
|
|
|
511
587
|
assert get_command_kwargs(query, command) == expected_kwargs
|
|
512
588
|
|
|
513
589
|
|
|
590
|
+
class TestQueryCommand:
|
|
591
|
+
"""测试 QueryCommand 类和 get_query_command 函数"""
|
|
592
|
+
|
|
593
|
+
def test_basic_query_command(self):
|
|
594
|
+
"""测试基本的 QueryCommand 功能"""
|
|
595
|
+
query = "/model gpt-4 /temperature 0.7"
|
|
596
|
+
v = get_query_command(query)
|
|
597
|
+
|
|
598
|
+
assert v.model == "gpt-4"
|
|
599
|
+
assert v.temperature == "0.7"
|
|
600
|
+
assert v.query == ""
|
|
601
|
+
|
|
602
|
+
def test_query_command_with_sub_commands(self):
|
|
603
|
+
"""测试带子命令的 QueryCommand"""
|
|
604
|
+
query = "/async /model gpt-4 /task-prefix mytask hello world"
|
|
605
|
+
v = get_query_command(query, sub_commands=["model", "task-prefix"])
|
|
606
|
+
|
|
607
|
+
assert v.model == "gpt-4"
|
|
608
|
+
assert v.task_prefix == "mytask"
|
|
609
|
+
assert v.query == "hello world"
|
|
610
|
+
|
|
611
|
+
def test_query_command_hyphen_to_underscore(self):
|
|
612
|
+
"""测试连字符自动转换为下划线"""
|
|
613
|
+
query = "/task-prefix mytask /api-key secret123"
|
|
614
|
+
v = get_query_command(query)
|
|
615
|
+
|
|
616
|
+
# 可以用下划线访问
|
|
617
|
+
assert v.task_prefix == "mytask"
|
|
618
|
+
assert v.api_key == "secret123"
|
|
619
|
+
|
|
620
|
+
def test_query_command_multiple_args(self):
|
|
621
|
+
"""测试多个参数的处理"""
|
|
622
|
+
query = "/async /model gpt-4 /task-prefix mytask arg1 arg2 arg3"
|
|
623
|
+
v = get_query_command(query, sub_commands=["model", "task-prefix"])
|
|
624
|
+
|
|
625
|
+
assert v.model == "gpt-4"
|
|
626
|
+
assert v.task_prefix == "mytask"
|
|
627
|
+
assert v.query == "arg1 arg2 arg3"
|
|
628
|
+
|
|
629
|
+
def test_query_command_no_special_handling(self):
|
|
630
|
+
"""测试不进行特殊处理的情况"""
|
|
631
|
+
query = "/model gpt-4 extra /task-prefix mytask arg1 arg2"
|
|
632
|
+
v = get_query_command(query, sub_commands=None)
|
|
633
|
+
|
|
634
|
+
# 没有指定sub_commands,所以不会特殊处理
|
|
635
|
+
assert v.model == ["gpt-4", "extra"]
|
|
636
|
+
assert v.task_prefix == ["mytask", "arg1", "arg2"]
|
|
637
|
+
assert v.query == ""
|
|
638
|
+
|
|
639
|
+
def test_query_command_with_kwargs(self):
|
|
640
|
+
"""测试带键值对参数的命令"""
|
|
641
|
+
query = "/config model=gpt-4 temperature=0.7"
|
|
642
|
+
v = get_query_command(query)
|
|
643
|
+
|
|
644
|
+
config = v.config
|
|
645
|
+
assert isinstance(config, dict)
|
|
646
|
+
assert config["model"] == "gpt-4"
|
|
647
|
+
assert config["temperature"] == "0.7"
|
|
648
|
+
|
|
649
|
+
def test_query_command_mixed_args_kwargs(self):
|
|
650
|
+
"""测试混合参数的命令"""
|
|
651
|
+
query = "/deploy myapp env=prod version=1.0"
|
|
652
|
+
v = get_query_command(query)
|
|
653
|
+
|
|
654
|
+
# deploy 命令有位置参数和键值对参数
|
|
655
|
+
# 当有kwargs时,返回kwargs
|
|
656
|
+
deploy_info = v.get_command_info("deploy")
|
|
657
|
+
assert deploy_info["args"] == ["myapp"]
|
|
658
|
+
assert deploy_info["kwargs"] == {"env": "prod", "version": "1.0"}
|
|
659
|
+
|
|
660
|
+
def test_query_command_has_command(self):
|
|
661
|
+
"""测试 has_command 方法"""
|
|
662
|
+
query = "/model gpt-4 /task-prefix mytask"
|
|
663
|
+
v = get_query_command(query)
|
|
664
|
+
|
|
665
|
+
assert v.has_command("model") == True
|
|
666
|
+
assert v.has_command("task-prefix") == True
|
|
667
|
+
assert v.has_command("task_prefix") == True # 也可以用下划线形式
|
|
668
|
+
assert v.has_command("nonexistent") == False
|
|
669
|
+
|
|
670
|
+
def test_query_command_get_all_commands(self):
|
|
671
|
+
"""测试 get_all_commands 方法"""
|
|
672
|
+
query = "/first /second /third"
|
|
673
|
+
v = get_query_command(query)
|
|
674
|
+
|
|
675
|
+
commands = v.get_all_commands()
|
|
676
|
+
assert commands == ["first", "second", "third"]
|
|
677
|
+
|
|
678
|
+
def test_query_command_nonexistent_attribute(self):
|
|
679
|
+
"""测试访问不存在的属性"""
|
|
680
|
+
query = "/model gpt-4"
|
|
681
|
+
v = get_query_command(query)
|
|
682
|
+
|
|
683
|
+
assert v.model == "gpt-4"
|
|
684
|
+
assert v.nonexistent is None
|
|
685
|
+
|
|
686
|
+
def test_query_command_empty_command(self):
|
|
687
|
+
"""测试空参数的命令"""
|
|
688
|
+
query = "/start /stop /restart"
|
|
689
|
+
v = get_query_command(query)
|
|
690
|
+
|
|
691
|
+
assert v.start == ""
|
|
692
|
+
assert v.stop == ""
|
|
693
|
+
assert v.restart == ""
|
|
694
|
+
|
|
695
|
+
def test_query_command_complex_scenario(self):
|
|
696
|
+
"""测试复杂场景"""
|
|
697
|
+
query = '/async /model gpt-4-turbo /task-prefix analysis "Process the following data" with multiple words'
|
|
698
|
+
v = get_query_command(query, sub_commands=["model", "task-prefix"])
|
|
699
|
+
|
|
700
|
+
assert v.model == "gpt-4-turbo"
|
|
701
|
+
assert v.task_prefix == "analysis" # 第一个参数
|
|
702
|
+
assert v.query == 'Process the following data with multiple words' # 剩余参数
|
|
703
|
+
|
|
704
|
+
def test_query_command_last_command_not_in_list(self):
|
|
705
|
+
"""测试最后一个命令不在子命令列表中"""
|
|
706
|
+
query = "/model gpt-4 /other command /final arg1 arg2 arg3"
|
|
707
|
+
v = get_query_command(query, sub_commands=["model"])
|
|
708
|
+
|
|
709
|
+
# model 是子命令但不是最后一个,所以保持原样
|
|
710
|
+
assert v.model == "gpt-4"
|
|
711
|
+
# other 和 final 不在子命令列表中,保持原样
|
|
712
|
+
assert v.other == "command"
|
|
713
|
+
assert v.final == ["arg1", "arg2", "arg3"]
|
|
714
|
+
assert v.query == ""
|
|
715
|
+
|
|
716
|
+
def test_query_command_disable_last_takes_rest(self):
|
|
717
|
+
"""测试禁用 last_command_takes_rest"""
|
|
718
|
+
query = "/model gpt-4 /task-prefix mytask arg1 arg2"
|
|
719
|
+
v = get_query_command(query,
|
|
720
|
+
sub_commands=["model", "task-prefix"],
|
|
721
|
+
last_command_takes_rest=False)
|
|
722
|
+
|
|
723
|
+
# 禁用了特殊处理,所以所有参数都保留
|
|
724
|
+
assert v.model == "gpt-4"
|
|
725
|
+
assert v.task_prefix == ["mytask", "arg1", "arg2"]
|
|
726
|
+
assert v.query == ""
|
|
727
|
+
|
|
728
|
+
def test_query_command_repr(self):
|
|
729
|
+
"""测试 __repr__ 方法"""
|
|
730
|
+
query = "/model gpt-4 /task-prefix mytask hello"
|
|
731
|
+
v = get_query_command(query, sub_commands=["task-prefix"])
|
|
732
|
+
|
|
733
|
+
repr_str = repr(v)
|
|
734
|
+
assert "QueryCommand" in repr_str
|
|
735
|
+
assert "model" in repr_str
|
|
736
|
+
assert "task-prefix" in repr_str
|
|
737
|
+
|
|
738
|
+
|
|
514
739
|
if __name__ == "__main__":
|
|
515
740
|
# 可以直接运行此文件进行测试
|
|
516
741
|
pytest.main([__file__, "-v"])
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from typing import List, Dict, Any
|
|
3
|
+
|
|
4
|
+
from .config import (
|
|
5
|
+
ConfigBuilder,
|
|
6
|
+
create_config
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from .typed_parser import (
|
|
10
|
+
ParsedCommand,
|
|
11
|
+
TypedCommandParser,
|
|
12
|
+
parse_typed_query
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestTypedCommandParser:
|
|
17
|
+
"""测试 TypedCommandParser 类"""
|
|
18
|
+
|
|
19
|
+
def test_basic_typed_parsing(self):
|
|
20
|
+
"""测试基本的类型化解析"""
|
|
21
|
+
config = (create_config()
|
|
22
|
+
.command("model")
|
|
23
|
+
.positional("name", required=True)
|
|
24
|
+
.command("config")
|
|
25
|
+
.keyword("temperature", type=float)
|
|
26
|
+
.keyword("max_tokens", type=int)
|
|
27
|
+
.build()
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
parser = TypedCommandParser(config)
|
|
31
|
+
result = parser.parse_typed(
|
|
32
|
+
"/model gpt-4 /config temperature=0.8 max_tokens=100")
|
|
33
|
+
|
|
34
|
+
assert "model" in result
|
|
35
|
+
assert result["model"].args == ["gpt-4"]
|
|
36
|
+
assert result["model"].is_valid
|
|
37
|
+
|
|
38
|
+
assert "config" in result
|
|
39
|
+
assert result["config"].kwargs["temperature"] == 0.8 # 转换为float
|
|
40
|
+
assert result["config"].kwargs["max_tokens"] == 100 # 转换为int
|
|
41
|
+
assert result["config"].is_valid
|
|
42
|
+
|
|
43
|
+
def test_typed_parsing_with_validation_errors(self):
|
|
44
|
+
"""测试带验证错误的类型化解析"""
|
|
45
|
+
config = (create_config()
|
|
46
|
+
.command("model")
|
|
47
|
+
.positional("name", required=True, choices=["gpt-3.5", "gpt-4"])
|
|
48
|
+
.build()
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
parser = TypedCommandParser(config)
|
|
52
|
+
result = parser.parse_typed("/model gpt-5")
|
|
53
|
+
|
|
54
|
+
assert "model" in result
|
|
55
|
+
assert not result["model"].is_valid
|
|
56
|
+
assert len(result["model"].errors) > 0
|
|
57
|
+
|
|
58
|
+
def test_typed_parsing_with_defaults(self):
|
|
59
|
+
"""测试带默认值的类型化解析"""
|
|
60
|
+
config = (create_config()
|
|
61
|
+
.command("config")
|
|
62
|
+
.keyword("temperature", type=float, default=0.7)
|
|
63
|
+
.keyword("max_tokens", type=int, default=100)
|
|
64
|
+
.build()
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
parser = TypedCommandParser(config)
|
|
68
|
+
result = parser.parse_typed("/config temperature=0.9")
|
|
69
|
+
|
|
70
|
+
assert result["config"].kwargs["temperature"] == 0.9
|
|
71
|
+
assert result["config"].kwargs["max_tokens"] == 100 # 使用默认值
|
|
72
|
+
|
|
73
|
+
def test_typed_parsing_with_remainder(self):
|
|
74
|
+
"""测试收集剩余参数的类型化解析"""
|
|
75
|
+
config = (create_config()
|
|
76
|
+
.command("task")
|
|
77
|
+
.positional("prefix", required=True)
|
|
78
|
+
.collect_remainder("query")
|
|
79
|
+
.build()
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
parser = TypedCommandParser(config)
|
|
83
|
+
result = parser.parse_typed("/task mytask this is the query")
|
|
84
|
+
|
|
85
|
+
assert result["task"].args == ["mytask"]
|
|
86
|
+
assert result["task"].remainder == "this is the query"
|
|
87
|
+
|
|
88
|
+
def test_typed_parsing_strict_mode(self):
|
|
89
|
+
"""测试严格模式"""
|
|
90
|
+
config = (create_config()
|
|
91
|
+
.strict(True)
|
|
92
|
+
.command("known")
|
|
93
|
+
.build()
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
parser = TypedCommandParser(config)
|
|
97
|
+
result = parser.parse_typed("/known /unknown")
|
|
98
|
+
|
|
99
|
+
assert result["known"].is_valid
|
|
100
|
+
assert not result["unknown"].is_valid
|
|
101
|
+
assert "Unknown command" in result["unknown"].errors[0]
|
|
102
|
+
|
|
103
|
+
def test_bool_type_conversion(self):
|
|
104
|
+
"""测试布尔类型转换"""
|
|
105
|
+
config = (create_config()
|
|
106
|
+
.command("flags")
|
|
107
|
+
.keyword("verbose", type=bool)
|
|
108
|
+
.keyword("debug", type=bool)
|
|
109
|
+
.build()
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
parser = TypedCommandParser(config)
|
|
113
|
+
|
|
114
|
+
# 测试各种布尔值表示
|
|
115
|
+
result = parser.parse_typed("/flags verbose=true debug=false")
|
|
116
|
+
assert result["flags"].kwargs["verbose"] is True
|
|
117
|
+
assert result["flags"].kwargs["debug"] is False
|
|
118
|
+
|
|
119
|
+
result = parser.parse_typed("/flags verbose=1 debug=0")
|
|
120
|
+
assert result["flags"].kwargs["verbose"] is True
|
|
121
|
+
assert result["flags"].kwargs["debug"] is False
|
|
122
|
+
|
|
123
|
+
result = parser.parse_typed("/flags verbose=yes debug=no")
|
|
124
|
+
assert result["flags"].kwargs["verbose"] is True
|
|
125
|
+
assert result["flags"].kwargs["debug"] is False
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class TestTypedQueryCommand:
|
|
129
|
+
"""测试 TypedQueryCommand 类"""
|
|
130
|
+
|
|
131
|
+
def test_basic_typed_query_command(self):
|
|
132
|
+
"""测试基本的类型化查询命令"""
|
|
133
|
+
config = (create_config()
|
|
134
|
+
.command("model")
|
|
135
|
+
.positional("name", required=True)
|
|
136
|
+
.command("temperature")
|
|
137
|
+
# value 名字比较特殊,作为位置参数,可以直接通过 result.temperature 访问
|
|
138
|
+
.positional("value", type=float)
|
|
139
|
+
.build()
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
result = parse_typed_query("/model gpt-4 /temperature 0.8", config)
|
|
143
|
+
|
|
144
|
+
assert result.model.name == "gpt-4"
|
|
145
|
+
assert result.temperature == 0.8
|
|
146
|
+
assert isinstance(result.temperature, float)
|
|
147
|
+
|
|
148
|
+
def test_typed_query_command_with_remainder(self):
|
|
149
|
+
"""测试带剩余参数的类型化查询命令"""
|
|
150
|
+
config = (create_config()
|
|
151
|
+
.command("task")
|
|
152
|
+
.positional("prefix", required=True)
|
|
153
|
+
.collect_remainder("query")
|
|
154
|
+
.build()
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
result = parse_typed_query("/task mytask this is the query", config)
|
|
158
|
+
|
|
159
|
+
assert result.task.prefix == "mytask"
|
|
160
|
+
assert result.task.query == "this is the query"
|
|
161
|
+
|
|
162
|
+
def test_typed_query_command_validation(self):
|
|
163
|
+
"""测试类型化查询命令的验证"""
|
|
164
|
+
config = (create_config()
|
|
165
|
+
.command("model")
|
|
166
|
+
.positional("name", required=True, choices=["gpt-3.5", "gpt-4"])
|
|
167
|
+
.build()
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
result = parse_typed_query("/model gpt-5", config)
|
|
171
|
+
|
|
172
|
+
assert not result.is_valid()
|
|
173
|
+
errors = result.get_errors()
|
|
174
|
+
assert "model" in errors
|
|
175
|
+
|
|
176
|
+
def test_typed_query_command_get_command(self):
|
|
177
|
+
"""测试获取解析后的命令对象"""
|
|
178
|
+
config = (create_config()
|
|
179
|
+
.command("config")
|
|
180
|
+
.keyword("temperature", type=float)
|
|
181
|
+
.build()
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
result = parse_typed_query("/config temperature=0.8", config)
|
|
185
|
+
|
|
186
|
+
parsed_cmd = result.get_command("config")
|
|
187
|
+
assert isinstance(parsed_cmd, ParsedCommand)
|
|
188
|
+
assert parsed_cmd.name == "config"
|
|
189
|
+
assert parsed_cmd.kwargs["temperature"] == 0.8
|
|
190
|
+
|
|
191
|
+
def test_typed_query_command_hyphen_conversion(self):
|
|
192
|
+
"""测试连字符转换"""
|
|
193
|
+
config = (create_config()
|
|
194
|
+
.command("task-prefix")
|
|
195
|
+
# value 名字比较特殊,作为位置参数,可以直接通过 result.task_prefix 访问
|
|
196
|
+
.positional("value")
|
|
197
|
+
.build()
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
result = parse_typed_query("/task-prefix mytask", config)
|
|
201
|
+
|
|
202
|
+
# 可以用下划线访问
|
|
203
|
+
assert result.task_prefix == "mytask"
|
|
204
|
+
assert result.has_command("task-prefix")
|
|
205
|
+
assert result.has_command("task_prefix")
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class TestIntegrationScenarios:
|
|
209
|
+
"""集成测试场景"""
|
|
210
|
+
def test_validation_and_error_reporting(self):
|
|
211
|
+
"""测试验证和错误报告"""
|
|
212
|
+
config = (create_config()
|
|
213
|
+
.strict(True) # 严格模式
|
|
214
|
+
.command("deploy")
|
|
215
|
+
.positional("app", required=True)
|
|
216
|
+
.keyword("env", required=True, choices=["dev", "staging", "prod"])
|
|
217
|
+
.keyword("version", required=True)
|
|
218
|
+
.build()
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# 缺少必需参数
|
|
222
|
+
result = parse_typed_query("/deploy myapp", config)
|
|
223
|
+
assert not result.is_valid()
|
|
224
|
+
errors = result.get_errors()
|
|
225
|
+
assert "deploy" in errors
|
|
226
|
+
assert any("env" in e for e in errors["deploy"])
|
|
227
|
+
|
|
228
|
+
# 无效的选项值
|
|
229
|
+
result = parse_typed_query(
|
|
230
|
+
"/deploy myapp env=test version=1.0", config)
|
|
231
|
+
assert not result.is_valid()
|
|
232
|
+
errors = result.get_errors()
|
|
233
|
+
assert any("must be one of" in e for e in errors["deploy"])
|
|
234
|
+
|
|
235
|
+
# 未知命令(严格模式)
|
|
236
|
+
result = parse_typed_query("/unknown", config)
|
|
237
|
+
assert not result.is_valid()
|
|
238
|
+
errors = result.get_errors()
|
|
239
|
+
assert "unknown" in errors
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class TestCommandLevelRemainder:
|
|
243
|
+
"""测试命令级别的剩余参数收集"""
|
|
244
|
+
def test_async_command_scenario(self):
|
|
245
|
+
global_config = (create_config()
|
|
246
|
+
.collect_remainder("query")
|
|
247
|
+
.command("async")
|
|
248
|
+
.max_args(0)
|
|
249
|
+
.command("model")
|
|
250
|
+
# 用 name 也可以;用 "value" 可直接 result.model 返回值
|
|
251
|
+
.positional("value", required=True)
|
|
252
|
+
.max_args(1)
|
|
253
|
+
.command("loop")
|
|
254
|
+
.positional("value", type=int)
|
|
255
|
+
.command("name")
|
|
256
|
+
.max_args(1)
|
|
257
|
+
.build()
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
result = parse_typed_query(
|
|
261
|
+
"/async /model gpt-4 /loop 3 /name task-01 analysis Process the data", global_config)
|
|
262
|
+
assert result.model == "gpt-4"
|
|
263
|
+
assert result.loop == 3
|
|
264
|
+
assert result.name == "task-01"
|
|
265
|
+
assert result.query == "analysis Process the data"
|
|
266
|
+
|
|
267
|
+
result = parse_typed_query(
|
|
268
|
+
"/async /model gpt-4 /name task-01 /loop 3 analysis Process the data", global_config)
|
|
269
|
+
assert result.model == "gpt-4"
|
|
270
|
+
assert result.loop == 3
|
|
271
|
+
assert result.name == "task-01"
|
|
272
|
+
assert result.query == "analysis Process the data"
|
|
273
|
+
|
|
274
|
+
result = parse_typed_query(
|
|
275
|
+
"/async /name task-01 /model gpt-4 /loop 3 analysis Process the data", global_config)
|
|
276
|
+
assert result.model == "gpt-4"
|
|
277
|
+
assert result.loop == 3
|
|
278
|
+
assert result.name == "task-01"
|
|
279
|
+
assert result.query == "analysis Process the data"
|
|
280
|
+
|
|
281
|
+
def test_quoted_string_scenario(self):
|
|
282
|
+
global_config = (create_config()
|
|
283
|
+
.collect_remainder("query")
|
|
284
|
+
.command("async")
|
|
285
|
+
.max_args(0)
|
|
286
|
+
.command("model")
|
|
287
|
+
# 用 name 也可以;用 "value" 可直接 result.model 返回值
|
|
288
|
+
.positional("value", required=True)
|
|
289
|
+
.max_args(1)
|
|
290
|
+
.command("loop")
|
|
291
|
+
.positional("value", type=int)
|
|
292
|
+
.command("name")
|
|
293
|
+
.max_args(1)
|
|
294
|
+
.command("wow")
|
|
295
|
+
.keyword("name", type=str)
|
|
296
|
+
.keyword("x", type=str)
|
|
297
|
+
.build()
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
result = parse_typed_query(
|
|
301
|
+
"/async /model gpt-4 /loop 3 /name task-01 \"analysis Process the data\"", global_config)
|
|
302
|
+
assert result.model == "gpt-4"
|
|
303
|
+
assert result.loop == 3
|
|
304
|
+
assert result.name == "task-01"
|
|
305
|
+
assert result.query == "analysis Process the data"
|
|
306
|
+
|
|
307
|
+
result = parse_typed_query(
|
|
308
|
+
"/async /model gpt-4 /name task-01 /loop 3 \"analysis Process the data\"", global_config)
|
|
309
|
+
assert result.model == "gpt-4"
|
|
310
|
+
assert result.loop == 3
|
|
311
|
+
assert result.name == "task-01"
|
|
312
|
+
assert result.query == "analysis Process the data"
|
|
313
|
+
|
|
314
|
+
result = parse_typed_query(
|
|
315
|
+
"/async /name task-01 /model gpt-4 /loop 3 \"\"\"analysis Process the data\"\"\"", global_config)
|
|
316
|
+
assert result.model == "gpt-4"
|
|
317
|
+
assert result.loop == 3
|
|
318
|
+
assert result.name == "task-01"
|
|
319
|
+
assert result.query == "analysis Process the data"
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
result = parse_typed_query(
|
|
323
|
+
"/async /name task-01 /model gpt-4 /wow name=test x=\"analysis2 Process the data\" /loop 3 \"\"\"analysis Process the data\"\"\"", global_config)
|
|
324
|
+
assert result.model == "gpt-4"
|
|
325
|
+
assert result.loop == 3
|
|
326
|
+
assert result.name == "task-01"
|
|
327
|
+
assert result.query == "analysis Process the data"
|
|
328
|
+
assert result.wow.name == "test"
|
|
329
|
+
assert result.wow.x == "analysis2 Process the data"
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
result = parse_typed_query(
|
|
333
|
+
"/async /name task-01 /model gpt-4 /wow name=test x=\"\"\"analysis2 \Process the data\"\"\" /loop 3 \"\"\"analysis Process the data\"\"\"", global_config)
|
|
334
|
+
assert result.model == "gpt-4"
|
|
335
|
+
assert result.loop == 3
|
|
336
|
+
assert result.name == "task-01"
|
|
337
|
+
assert result.query == "analysis Process the data"
|
|
338
|
+
assert result.wow.name == "test"
|
|
339
|
+
assert result.wow.x == "analysis2 \Process the data"
|
|
340
|
+
|
|
341
|
+
if __name__ == "__main__":
|
|
342
|
+
pytest.main([__file__, "-v"])
|