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
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Auto-Coder AutoCoderArgs 参数解析模块
|
|
3
|
+
|
|
4
|
+
提供 AutoCoderArgs 参数的高级解析功能,包括:
|
|
5
|
+
- 支持多种数据类型的统一解析
|
|
6
|
+
- Token 数量单位解析(k, m, g 等)
|
|
7
|
+
- 数学表达式计算
|
|
8
|
+
- 基于模型配置的动态解析
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from .parser import AutoCoderArgsParser
|
|
12
|
+
from .token_parser import TokenParser
|
|
13
|
+
|
|
14
|
+
__all__ = ["AutoCoderArgsParser", "TokenParser"]
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
from typing import Union, Optional, Dict, Any, Type
|
|
2
|
+
from pydantic import Field
|
|
3
|
+
from ..llms import LLMManager
|
|
4
|
+
from .token_parser import TokenParser
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AutoCoderArgsParser:
|
|
8
|
+
"""AutoCoderArgs 参数解析器,提供高级参数解析功能"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, llm_manager: Optional[LLMManager] = None):
|
|
11
|
+
"""
|
|
12
|
+
初始化参数解析器
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
llm_manager: LLM 管理器实例
|
|
16
|
+
"""
|
|
17
|
+
self.llm_manager = llm_manager or LLMManager()
|
|
18
|
+
self.token_parser = TokenParser(self.llm_manager)
|
|
19
|
+
|
|
20
|
+
def parse_conversation_prune_safe_zone_tokens(self,
|
|
21
|
+
value: Union[str, int, float],
|
|
22
|
+
code_model: Optional[str] = None) -> int:
|
|
23
|
+
"""
|
|
24
|
+
解析 conversation_prune_safe_zone_tokens 参数
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
value: 参数值,支持字符串、整数、浮点数
|
|
28
|
+
code_model: 代码模型名称,用于浮点数解析
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
解析后的 token 数量
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
>>> parser = AutoCoderArgsParser()
|
|
35
|
+
>>> parser.parse_conversation_prune_safe_zone_tokens(51200)
|
|
36
|
+
51200
|
|
37
|
+
>>> parser.parse_conversation_prune_safe_zone_tokens("50k")
|
|
38
|
+
51200
|
|
39
|
+
>>> parser.parse_conversation_prune_safe_zone_tokens("50*1024")
|
|
40
|
+
51200
|
|
41
|
+
>>> parser.parse_conversation_prune_safe_zone_tokens(0.1, "deepseek/v3")
|
|
42
|
+
# 返回 deepseek/v3 context_window 的 10%
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
return self.token_parser.parse_token_value(value, code_model)
|
|
46
|
+
except ValueError as e:
|
|
47
|
+
# 如果解析失败,返回默认值并记录警告
|
|
48
|
+
default_value = 50 * 1024
|
|
49
|
+
print(f"Warning: Failed to parse conversation_prune_safe_zone_tokens '{value}': {e}. Using default value: {default_value}")
|
|
50
|
+
return default_value
|
|
51
|
+
|
|
52
|
+
def parse_context_prune_safe_zone_tokens(self,
|
|
53
|
+
value: Union[str, int, float],
|
|
54
|
+
code_model: Optional[str] = None) -> int:
|
|
55
|
+
"""
|
|
56
|
+
解析 context_prune_safe_zone_tokens 参数
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
value: 参数值
|
|
60
|
+
code_model: 代码模型名称
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
解析后的 token 数量
|
|
64
|
+
"""
|
|
65
|
+
try:
|
|
66
|
+
return self.token_parser.parse_token_value(value, code_model)
|
|
67
|
+
except ValueError as e:
|
|
68
|
+
default_value = 24 * 1024
|
|
69
|
+
print(f"Warning: Failed to parse context_prune_safe_zone_tokens '{value}': {e}. Using default value: {default_value}")
|
|
70
|
+
return default_value
|
|
71
|
+
|
|
72
|
+
def parse_token_field(self,
|
|
73
|
+
field_name: str,
|
|
74
|
+
value: Union[str, int, float],
|
|
75
|
+
code_model: Optional[str] = None,
|
|
76
|
+
default_value: Optional[int] = None) -> int:
|
|
77
|
+
"""
|
|
78
|
+
通用的 token 字段解析方法
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
field_name: 字段名称
|
|
82
|
+
value: 字段值
|
|
83
|
+
code_model: 代码模型名称
|
|
84
|
+
default_value: 默认值,如果为 None 则使用 50*1024
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
解析后的 token 数量
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
return self.token_parser.parse_token_value(value, code_model)
|
|
91
|
+
except ValueError as e:
|
|
92
|
+
fallback_value = default_value or 50 * 1024
|
|
93
|
+
print(f"Warning: Failed to parse {field_name} '{value}': {e}. Using default value: {fallback_value}")
|
|
94
|
+
return fallback_value
|
|
95
|
+
|
|
96
|
+
def validate_parsed_args(self, args_dict: Dict[str, Any],
|
|
97
|
+
code_model: Optional[str] = None) -> Dict[str, Any]:
|
|
98
|
+
"""
|
|
99
|
+
验证和解析整个参数字典
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
args_dict: 参数字典
|
|
103
|
+
code_model: 代码模型名称
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
验证和解析后的参数字典
|
|
107
|
+
"""
|
|
108
|
+
# 定义需要解析的 token 字段及其默认值
|
|
109
|
+
token_fields = {
|
|
110
|
+
'conversation_prune_safe_zone_tokens': 50 * 1024,
|
|
111
|
+
'context_prune_safe_zone_tokens': 24 * 1024,
|
|
112
|
+
'context_prune_sliding_window_size': 1000,
|
|
113
|
+
'context_prune_sliding_window_overlap': 100,
|
|
114
|
+
'rag_params_max_tokens': 500000,
|
|
115
|
+
'rag_context_window_limit': 120000,
|
|
116
|
+
'rag_duckdb_vector_dim': 1024,
|
|
117
|
+
'rag_duckdb_query_top_k': 10000,
|
|
118
|
+
'rag_emb_dim': 1024,
|
|
119
|
+
'rag_emb_text_size': 1024,
|
|
120
|
+
'hybrid_index_max_output_tokens': 1000000,
|
|
121
|
+
'data_cells_max_num': 2000,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
parsed_dict = args_dict.copy()
|
|
125
|
+
|
|
126
|
+
for field_name, default_value in token_fields.items():
|
|
127
|
+
if field_name in parsed_dict:
|
|
128
|
+
original_value = parsed_dict[field_name]
|
|
129
|
+
# 如果值不是简单的 int,则进行解析
|
|
130
|
+
if not isinstance(original_value, int):
|
|
131
|
+
parsed_dict[field_name] = self.parse_token_field(
|
|
132
|
+
field_name, original_value, code_model, default_value
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
return parsed_dict
|
|
136
|
+
|
|
137
|
+
def get_parsing_info(self) -> Dict[str, Any]:
|
|
138
|
+
"""
|
|
139
|
+
获取解析器信息和使用示例
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
包含解析器信息的字典
|
|
143
|
+
"""
|
|
144
|
+
return {
|
|
145
|
+
"supported_types": ["int", "float", "str"],
|
|
146
|
+
"string_formats": self.token_parser.get_examples(),
|
|
147
|
+
"supported_units": self.token_parser.get_supported_units(),
|
|
148
|
+
"float_behavior": "Float values (0-1) are treated as percentages of the code_model's context_window",
|
|
149
|
+
"fallback_context_window": 50 * 1024,
|
|
150
|
+
"safety_notes": [
|
|
151
|
+
"Invalid expressions fall back to default values",
|
|
152
|
+
"Negative results are clamped to 0",
|
|
153
|
+
"Division by zero is handled gracefully"
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
def create_flexible_field(self,
|
|
158
|
+
default_value: Union[str, int, float],
|
|
159
|
+
description: str,
|
|
160
|
+
min_value: Optional[int] = None,
|
|
161
|
+
max_value: Optional[int] = None) -> Field:
|
|
162
|
+
"""
|
|
163
|
+
创建支持灵活解析的 Pydantic 字段
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
default_value: 默认值
|
|
167
|
+
description: 字段描述
|
|
168
|
+
min_value: 最小值
|
|
169
|
+
max_value: 最大值
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
Pydantic Field 对象
|
|
173
|
+
"""
|
|
174
|
+
field_kwargs = {
|
|
175
|
+
"default": default_value,
|
|
176
|
+
"description": description
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if min_value is not None:
|
|
180
|
+
field_kwargs["ge"] = min_value
|
|
181
|
+
if max_value is not None:
|
|
182
|
+
field_kwargs["le"] = max_value
|
|
183
|
+
|
|
184
|
+
return Field(**field_kwargs)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# 测试模块初始化文件
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from unittest.mock import Mock
|
|
5
|
+
|
|
6
|
+
from autocoder.common.autocoderargs_parser import AutoCoderArgsParser, TokenParser
|
|
7
|
+
from autocoder.common.llms import LLMManager, LLMModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def mock_llm_manager():
|
|
12
|
+
"""创建 mock LLM manager fixture"""
|
|
13
|
+
mock_manager = Mock(spec=LLMManager)
|
|
14
|
+
|
|
15
|
+
# 设置默认的模型信息
|
|
16
|
+
mock_model = Mock(spec=LLMModel)
|
|
17
|
+
mock_model.context_window = 32768 # deepseek/v3 的默认值
|
|
18
|
+
mock_manager.get_model.return_value = mock_model
|
|
19
|
+
|
|
20
|
+
return mock_manager
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def args_parser(mock_llm_manager):
|
|
25
|
+
"""创建 AutoCoderArgsParser 实例 fixture"""
|
|
26
|
+
return AutoCoderArgsParser(mock_llm_manager)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TestAutoCoderArgsParser:
|
|
30
|
+
"""AutoCoderArgsParser 测试类"""
|
|
31
|
+
|
|
32
|
+
@pytest.mark.parametrize("value,expected", [
|
|
33
|
+
(51200, 51200), # 整数
|
|
34
|
+
("50k", 51200), # 带单位字符串
|
|
35
|
+
("50*1024", 51200), # 数学表达式
|
|
36
|
+
(0.1, 3276), # 浮点数比例 (32768 * 0.1)
|
|
37
|
+
])
|
|
38
|
+
def test_parse_conversation_prune_safe_zone_tokens(self, args_parser, value, expected):
|
|
39
|
+
"""测试 conversation_prune_safe_zone_tokens 解析"""
|
|
40
|
+
result = args_parser.parse_conversation_prune_safe_zone_tokens(value, "deepseek/v3")
|
|
41
|
+
assert result == expected
|
|
42
|
+
|
|
43
|
+
def test_parse_conversation_prune_safe_zone_tokens_invalid(self, args_parser, capsys):
|
|
44
|
+
"""测试无效值的处理"""
|
|
45
|
+
result = args_parser.parse_conversation_prune_safe_zone_tokens("invalid", "deepseek/v3")
|
|
46
|
+
|
|
47
|
+
# 应该返回默认值
|
|
48
|
+
assert result == 50 * 1024
|
|
49
|
+
|
|
50
|
+
# 应该有警告信息
|
|
51
|
+
captured = capsys.readouterr()
|
|
52
|
+
assert "Warning: Failed to parse conversation_prune_safe_zone_tokens" in captured.out
|
|
53
|
+
|
|
54
|
+
@pytest.mark.parametrize("value,expected", [
|
|
55
|
+
(24576, 24576), # 整数
|
|
56
|
+
("24k", 24576), # 带单位字符串
|
|
57
|
+
("24*1024", 24576), # 数学表达式
|
|
58
|
+
(0.05, 1638), # 浮点数比例 (32768 * 0.05)
|
|
59
|
+
])
|
|
60
|
+
def test_parse_context_prune_safe_zone_tokens(self, args_parser, value, expected):
|
|
61
|
+
"""测试 context_prune_safe_zone_tokens 解析"""
|
|
62
|
+
result = args_parser.parse_context_prune_safe_zone_tokens(value, "deepseek/v3")
|
|
63
|
+
assert result == expected
|
|
64
|
+
|
|
65
|
+
def test_parse_context_prune_safe_zone_tokens_invalid(self, args_parser, capsys):
|
|
66
|
+
"""测试 context_prune_safe_zone_tokens 无效值处理"""
|
|
67
|
+
result = args_parser.parse_context_prune_safe_zone_tokens("invalid", "deepseek/v3")
|
|
68
|
+
|
|
69
|
+
# 应该返回默认值
|
|
70
|
+
assert result == 24 * 1024
|
|
71
|
+
|
|
72
|
+
# 应该有警告信息
|
|
73
|
+
captured = capsys.readouterr()
|
|
74
|
+
assert "Warning: Failed to parse context_prune_safe_zone_tokens" in captured.out
|
|
75
|
+
|
|
76
|
+
@pytest.mark.parametrize("field_name,value,default_value,expected", [
|
|
77
|
+
("rag_params_max_tokens", "500k", 500000, 512000),
|
|
78
|
+
("data_cells_max_num", "2k", 2000, 2048),
|
|
79
|
+
("context_prune_sliding_window_size", 1000, 1000, 1000),
|
|
80
|
+
("hybrid_index_max_output_tokens", "1m", 1000000, 1048576),
|
|
81
|
+
])
|
|
82
|
+
def test_parse_token_field(self, args_parser, field_name, value, default_value, expected):
|
|
83
|
+
"""测试通用 token 字段解析"""
|
|
84
|
+
result = args_parser.parse_token_field(field_name, value, "deepseek/v3", default_value)
|
|
85
|
+
assert result == expected
|
|
86
|
+
|
|
87
|
+
def test_parse_token_field_invalid(self, args_parser, capsys):
|
|
88
|
+
"""测试通用 token 字段无效值处理"""
|
|
89
|
+
field_name = "test_field"
|
|
90
|
+
result = args_parser.parse_token_field(field_name, "invalid", "deepseek/v3", 1000)
|
|
91
|
+
|
|
92
|
+
# 应该返回提供的默认值
|
|
93
|
+
assert result == 1000
|
|
94
|
+
|
|
95
|
+
# 应该有警告信息
|
|
96
|
+
captured = capsys.readouterr()
|
|
97
|
+
assert f"Warning: Failed to parse {field_name}" in captured.out
|
|
98
|
+
|
|
99
|
+
def test_validate_parsed_args(self, args_parser):
|
|
100
|
+
"""测试批量参数验证和解析"""
|
|
101
|
+
args_dict = {
|
|
102
|
+
"conversation_prune_safe_zone_tokens": "50k",
|
|
103
|
+
"context_prune_safe_zone_tokens": "24*1024",
|
|
104
|
+
"rag_params_max_tokens": 0.5, # 比例值
|
|
105
|
+
"data_cells_max_num": "2k",
|
|
106
|
+
"other_field": "not_a_token_field", # 非 token 字段
|
|
107
|
+
"regular_int_field": 12345 # 已经是 int 的字段
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
parsed_dict = args_parser.validate_parsed_args(args_dict, "deepseek/v3")
|
|
111
|
+
|
|
112
|
+
# 检查 token 字段被正确解析
|
|
113
|
+
assert parsed_dict["conversation_prune_safe_zone_tokens"] == 51200
|
|
114
|
+
assert parsed_dict["context_prune_safe_zone_tokens"] == 24576
|
|
115
|
+
assert parsed_dict["rag_params_max_tokens"] == 16384 # 32768 * 0.5
|
|
116
|
+
assert parsed_dict["data_cells_max_num"] == 2048
|
|
117
|
+
|
|
118
|
+
# 检查非 token 字段保持不变
|
|
119
|
+
assert parsed_dict["other_field"] == "not_a_token_field"
|
|
120
|
+
assert parsed_dict["regular_int_field"] == 12345
|
|
121
|
+
|
|
122
|
+
def test_validate_parsed_args_with_non_token_fields_only(self, args_parser):
|
|
123
|
+
"""测试只包含非 token 字段的参数字典"""
|
|
124
|
+
args_dict = {
|
|
125
|
+
"model": "deepseek/v3",
|
|
126
|
+
"query": "test query",
|
|
127
|
+
"output": "result.txt",
|
|
128
|
+
"skip_confirm": True
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
parsed_dict = args_parser.validate_parsed_args(args_dict, "deepseek/v3")
|
|
132
|
+
|
|
133
|
+
# 所有字段应该保持不变
|
|
134
|
+
assert parsed_dict == args_dict
|
|
135
|
+
|
|
136
|
+
def test_get_parsing_info(self, args_parser):
|
|
137
|
+
"""测试获取解析器信息"""
|
|
138
|
+
info = args_parser.get_parsing_info()
|
|
139
|
+
|
|
140
|
+
# 检查必要的信息字段
|
|
141
|
+
assert "supported_types" in info
|
|
142
|
+
assert "string_formats" in info
|
|
143
|
+
assert "supported_units" in info
|
|
144
|
+
assert "float_behavior" in info
|
|
145
|
+
assert "fallback_context_window" in info
|
|
146
|
+
assert "safety_notes" in info
|
|
147
|
+
|
|
148
|
+
# 检查支持的类型
|
|
149
|
+
assert "int" in info["supported_types"]
|
|
150
|
+
assert "float" in info["supported_types"]
|
|
151
|
+
assert "str" in info["supported_types"]
|
|
152
|
+
|
|
153
|
+
# 检查字符串格式示例
|
|
154
|
+
assert isinstance(info["string_formats"], dict)
|
|
155
|
+
assert "整数" in info["string_formats"]
|
|
156
|
+
|
|
157
|
+
# 检查支持的单位
|
|
158
|
+
assert isinstance(info["supported_units"], dict)
|
|
159
|
+
assert "k" in info["supported_units"]
|
|
160
|
+
assert info["supported_units"]["k"] == 1024
|
|
161
|
+
|
|
162
|
+
def test_float_value_with_zero_context_window(self, args_parser, mock_llm_manager):
|
|
163
|
+
"""测试当模型 context_window 为 0 时的回退机制"""
|
|
164
|
+
# Mock 模型的 context_window 为 0
|
|
165
|
+
mock_model = Mock(spec=LLMModel)
|
|
166
|
+
mock_model.context_window = 0
|
|
167
|
+
mock_llm_manager.get_model.return_value = mock_model
|
|
168
|
+
|
|
169
|
+
result = args_parser.parse_conversation_prune_safe_zone_tokens(0.1, "test/model")
|
|
170
|
+
# 应该使用默认值 120*1000
|
|
171
|
+
expected = int((120 * 1000) * 0.1)
|
|
172
|
+
assert result == expected
|
|
173
|
+
|
|
174
|
+
def test_float_value_with_missing_model(self, args_parser, mock_llm_manager):
|
|
175
|
+
"""测试当模型不存在时的回退机制"""
|
|
176
|
+
# Mock 获取模型返回 None
|
|
177
|
+
mock_llm_manager.get_model.return_value = None
|
|
178
|
+
|
|
179
|
+
result = args_parser.parse_conversation_prune_safe_zone_tokens(0.1, "nonexistent/model")
|
|
180
|
+
# 应该使用默认值 120*1000
|
|
181
|
+
expected = int((120 * 1000) * 0.1)
|
|
182
|
+
assert result == expected
|
|
183
|
+
|
|
184
|
+
def test_args_parser_uses_token_parser(self, args_parser):
|
|
185
|
+
"""测试 AutoCoderArgsParser 正确使用 TokenParser"""
|
|
186
|
+
# 确保 AutoCoderArgsParser 内部使用 TokenParser
|
|
187
|
+
assert hasattr(args_parser, 'token_parser')
|
|
188
|
+
assert isinstance(args_parser.token_parser, TokenParser)
|
|
189
|
+
assert args_parser.token_parser.llm_manager == args_parser.llm_manager
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class TestAutoCoderArgsParserIntegration:
|
|
193
|
+
"""AutoCoderArgsParser 集成测试"""
|
|
194
|
+
|
|
195
|
+
def test_integration_with_real_llm_manager(self):
|
|
196
|
+
"""测试与真实 LLM Manager 的集成"""
|
|
197
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
198
|
+
models_json = Path(temp_dir) / "models.json"
|
|
199
|
+
|
|
200
|
+
# 创建真实的 LLM Manager(使用临时目录)
|
|
201
|
+
from autocoder.common.llms import LLMManager
|
|
202
|
+
llm_manager = LLMManager(str(models_json))
|
|
203
|
+
|
|
204
|
+
# 创建 AutoCoderArgsParser
|
|
205
|
+
parser = AutoCoderArgsParser(llm_manager)
|
|
206
|
+
|
|
207
|
+
# 测试基本功能
|
|
208
|
+
result = parser.parse_conversation_prune_safe_zone_tokens("50k")
|
|
209
|
+
assert result == 51200
|
|
210
|
+
|
|
211
|
+
# 测试浮点数(由于使用默认模型,会使用回退值)
|
|
212
|
+
result = parser.parse_conversation_prune_safe_zone_tokens(0.1)
|
|
213
|
+
expected = int((120 * 1000) * 0.1)
|
|
214
|
+
assert result == expected
|
|
215
|
+
|
|
216
|
+
@pytest.mark.parametrize("field_value", [
|
|
217
|
+
"50k",
|
|
218
|
+
"50*1024",
|
|
219
|
+
0.1,
|
|
220
|
+
51200
|
|
221
|
+
])
|
|
222
|
+
def test_all_supported_formats(self, field_value):
|
|
223
|
+
"""测试所有支持的格式都能正常工作"""
|
|
224
|
+
# 使用临时 LLM Manager
|
|
225
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
226
|
+
models_json = Path(temp_dir) / "models.json"
|
|
227
|
+
|
|
228
|
+
from autocoder.common.llms import LLMManager
|
|
229
|
+
llm_manager = LLMManager(str(models_json))
|
|
230
|
+
parser = AutoCoderArgsParser(llm_manager)
|
|
231
|
+
|
|
232
|
+
# 所有格式都应该成功解析,不抛出异常
|
|
233
|
+
result = parser.parse_conversation_prune_safe_zone_tokens(field_value)
|
|
234
|
+
assert isinstance(result, int)
|
|
235
|
+
assert result >= 0
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from unittest.mock import Mock
|
|
5
|
+
|
|
6
|
+
from autocoder.common.autocoderargs_parser.token_parser import TokenParser
|
|
7
|
+
from autocoder.common.llms import LLMManager, LLMModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def mock_llm_manager():
|
|
12
|
+
"""创建 mock LLM manager fixture"""
|
|
13
|
+
return Mock(spec=LLMManager)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.fixture
|
|
17
|
+
def token_parser(mock_llm_manager):
|
|
18
|
+
"""创建 TokenParser 实例 fixture"""
|
|
19
|
+
return TokenParser(mock_llm_manager)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.fixture
|
|
23
|
+
def temp_dir():
|
|
24
|
+
"""创建临时目录 fixture"""
|
|
25
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
26
|
+
yield temp_dir
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TestTokenParser:
|
|
30
|
+
"""TokenParser 测试类"""
|
|
31
|
+
|
|
32
|
+
def test_parse_int_value(self, token_parser):
|
|
33
|
+
"""测试整数值解析"""
|
|
34
|
+
result = token_parser.parse_token_value(51200)
|
|
35
|
+
assert result == 51200
|
|
36
|
+
|
|
37
|
+
# 测试负数会被转为 0
|
|
38
|
+
result = token_parser.parse_token_value(-100)
|
|
39
|
+
assert result == 0
|
|
40
|
+
|
|
41
|
+
def test_parse_float_value(self, token_parser, mock_llm_manager):
|
|
42
|
+
"""测试浮点数值解析"""
|
|
43
|
+
# Mock 模型信息
|
|
44
|
+
mock_model = Mock(spec=LLMModel)
|
|
45
|
+
mock_model.context_window = 100000
|
|
46
|
+
mock_llm_manager.get_model.return_value = mock_model
|
|
47
|
+
|
|
48
|
+
result = token_parser.parse_token_value(0.1, "test/model")
|
|
49
|
+
assert result == 10000 # 100000 * 0.1
|
|
50
|
+
|
|
51
|
+
# 测试无效的浮点数范围
|
|
52
|
+
with pytest.raises(ValueError):
|
|
53
|
+
token_parser.parse_token_value(1.5, "test/model")
|
|
54
|
+
|
|
55
|
+
with pytest.raises(ValueError):
|
|
56
|
+
token_parser.parse_token_value(-0.1, "test/model")
|
|
57
|
+
|
|
58
|
+
def test_parse_float_value_fallback(self, token_parser, mock_llm_manager):
|
|
59
|
+
"""测试浮点数解析的回退机制"""
|
|
60
|
+
# Mock 获取模型失败
|
|
61
|
+
mock_llm_manager.get_model.return_value = None
|
|
62
|
+
|
|
63
|
+
result = token_parser.parse_token_value(0.1)
|
|
64
|
+
expected = int((120 * 1000) * 0.1) # 默认 context_window
|
|
65
|
+
assert result == expected
|
|
66
|
+
|
|
67
|
+
@pytest.mark.parametrize("input_str,expected", [
|
|
68
|
+
("100k", 100 * 1024),
|
|
69
|
+
("1m", 1024 * 1024),
|
|
70
|
+
("2.5k", int(2.5 * 1024)),
|
|
71
|
+
("1g", 1024 * 1024 * 1024),
|
|
72
|
+
("50K", 50 * 1024), # 大写
|
|
73
|
+
("1M", 1024 * 1024), # 大写
|
|
74
|
+
("100kb", 100 * 1024), # 带 b
|
|
75
|
+
("2MB", 2 * 1024 * 1024), # 大写带 b
|
|
76
|
+
])
|
|
77
|
+
def test_parse_unit_strings(self, token_parser, input_str, expected):
|
|
78
|
+
"""测试带单位的字符串解析"""
|
|
79
|
+
result = token_parser.parse_token_value(input_str)
|
|
80
|
+
assert result == expected
|
|
81
|
+
|
|
82
|
+
@pytest.mark.parametrize("input_str,expected", [
|
|
83
|
+
("1024", 1024), # 纯整数字符串
|
|
84
|
+
("0", 0), # 零
|
|
85
|
+
("8", 8), # 单个数字
|
|
86
|
+
("123456", 123456), # 大数字
|
|
87
|
+
("1024.0", 1024), # 浮点数字符串(整数值)
|
|
88
|
+
("1024.5", 1024), # 浮点数字符串(小数会被截断)
|
|
89
|
+
("1024.", 1024), # 末尾有小数点
|
|
90
|
+
(".5", 0), # 纯小数(< 1 的会被转为 0)
|
|
91
|
+
("0.8", 0), # 小数(< 1 的会被转为 0)
|
|
92
|
+
("100.99", 100), # 小数截断
|
|
93
|
+
("-10", 0), # 负数会被转为 0
|
|
94
|
+
("-100.5", 0), # 负浮点数会被转为 0
|
|
95
|
+
])
|
|
96
|
+
def test_parse_numeric_strings(self, token_parser, input_str, expected):
|
|
97
|
+
"""测试纯数字字符串解析"""
|
|
98
|
+
result = token_parser.parse_token_value(input_str)
|
|
99
|
+
assert result == expected
|
|
100
|
+
|
|
101
|
+
@pytest.mark.parametrize("input_str,expected", [
|
|
102
|
+
("00123", 123), # 前导零
|
|
103
|
+
("123.000", 123), # 后续零
|
|
104
|
+
("0000", 0), # 多个零
|
|
105
|
+
("1.0000", 1), # 浮点数后续零
|
|
106
|
+
("0001.5", 1), # 前导零加浮点数
|
|
107
|
+
])
|
|
108
|
+
def test_parse_numeric_strings_edge_cases(self, token_parser, input_str, expected):
|
|
109
|
+
"""测试纯数字字符串解析的边界情况"""
|
|
110
|
+
result = token_parser.parse_token_value(input_str)
|
|
111
|
+
assert result == expected
|
|
112
|
+
|
|
113
|
+
def test_parse_priority_order(self, token_parser):
|
|
114
|
+
"""测试解析优先级:纯数字 > 带单位 > 数学表达式"""
|
|
115
|
+
# 确保纯数字不会被误认为是数学表达式
|
|
116
|
+
assert token_parser.parse_token_value("1024") == 1024
|
|
117
|
+
assert token_parser.parse_token_value("1024.0") == 1024
|
|
118
|
+
|
|
119
|
+
# 确保带单位的解析优先于数学表达式(虽然这种情况不太可能发生冲突)
|
|
120
|
+
assert token_parser.parse_token_value("1k") == 1024
|
|
121
|
+
assert token_parser.parse_token_value("1m") == 1024 * 1024
|
|
122
|
+
|
|
123
|
+
# 确保数学表达式正常工作
|
|
124
|
+
assert token_parser.parse_token_value("1+1") == 2
|
|
125
|
+
assert token_parser.parse_token_value("2*2") == 4
|
|
126
|
+
|
|
127
|
+
@pytest.mark.parametrize("expr,expected", [
|
|
128
|
+
("50*1024", 50 * 1024),
|
|
129
|
+
("100*1000", 100 * 1000),
|
|
130
|
+
("2**16", 2**16),
|
|
131
|
+
("1024+512", 1024 + 512),
|
|
132
|
+
("2048-512", 2048 - 512),
|
|
133
|
+
("100*10+50", 100 * 10 + 50),
|
|
134
|
+
("(100+50)*10", (100 + 50) * 10),
|
|
135
|
+
("1024//2", 1024 // 2),
|
|
136
|
+
("1024%100", 1024 % 100),
|
|
137
|
+
])
|
|
138
|
+
def test_parse_math_expressions(self, token_parser, expr, expected):
|
|
139
|
+
"""测试数学表达式解析"""
|
|
140
|
+
result = token_parser.parse_token_value(expr)
|
|
141
|
+
assert result == expected
|
|
142
|
+
|
|
143
|
+
@pytest.mark.parametrize("invalid_expr", [
|
|
144
|
+
"invalid_string",
|
|
145
|
+
"100x", # 无效单位
|
|
146
|
+
"1024 + undefined_var", # 未定义变量
|
|
147
|
+
"1024 / 0", # 除零
|
|
148
|
+
"", # 空字符串
|
|
149
|
+
" ", # 只有空格
|
|
150
|
+
])
|
|
151
|
+
def test_parse_invalid_expressions(self, token_parser, invalid_expr):
|
|
152
|
+
"""测试无效表达式处理"""
|
|
153
|
+
with pytest.raises(ValueError):
|
|
154
|
+
token_parser.parse_token_value(invalid_expr)
|
|
155
|
+
|
|
156
|
+
def test_validate_token_value(self, token_parser):
|
|
157
|
+
"""测试值验证功能"""
|
|
158
|
+
# 有效值
|
|
159
|
+
assert token_parser.validate_token_value(1024) is True
|
|
160
|
+
assert token_parser.validate_token_value("50k") is True
|
|
161
|
+
assert token_parser.validate_token_value("50*1024") is True
|
|
162
|
+
|
|
163
|
+
# 范围验证
|
|
164
|
+
assert token_parser.validate_token_value(1024, min_tokens=500, max_tokens=2000) is True
|
|
165
|
+
assert token_parser.validate_token_value(100, min_tokens=500, max_tokens=2000) is False
|
|
166
|
+
assert token_parser.validate_token_value(3000, min_tokens=500, max_tokens=2000) is False
|
|
167
|
+
|
|
168
|
+
# 无效值
|
|
169
|
+
assert token_parser.validate_token_value("invalid") is False
|
|
170
|
+
|
|
171
|
+
def test_get_supported_units(self, token_parser):
|
|
172
|
+
"""测试获取支持的单位"""
|
|
173
|
+
units = token_parser.get_supported_units()
|
|
174
|
+
assert 'k' in units
|
|
175
|
+
assert 'm' in units
|
|
176
|
+
assert 'g' in units
|
|
177
|
+
assert units['k'] == 1024
|
|
178
|
+
assert units['m'] == 1024 * 1024
|
|
179
|
+
|
|
180
|
+
def test_get_examples(self, token_parser):
|
|
181
|
+
"""测试获取使用示例"""
|
|
182
|
+
examples = token_parser.get_examples()
|
|
183
|
+
assert isinstance(examples, dict)
|
|
184
|
+
assert "整数" in examples
|
|
185
|
+
assert "带单位" in examples
|
|
186
|
+
assert "数学表达式" in examples
|
|
187
|
+
|
|
188
|
+
@pytest.mark.parametrize("invalid_value", [
|
|
189
|
+
[1, 2, 3], # 列表类型不支持
|
|
190
|
+
{"value": 1024}, # 字典类型不支持
|
|
191
|
+
])
|
|
192
|
+
def test_unsupported_type(self, token_parser, invalid_value):
|
|
193
|
+
"""测试不支持的类型"""
|
|
194
|
+
with pytest.raises(ValueError):
|
|
195
|
+
token_parser.parse_token_value(invalid_value)
|