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,1067 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Wrap LLM Hint 模块测试套件
|
|
3
|
+
|
|
4
|
+
完整测试 WrapLLMHint 核心类、工具函数和集成功能。
|
|
5
|
+
使用 pytest 框架进行测试。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
import unittest
|
|
10
|
+
from typing import List, Dict, Any
|
|
11
|
+
|
|
12
|
+
from .wrap_llm_hint import WrapLLMHint, HintConfig
|
|
13
|
+
from .utils import (
|
|
14
|
+
add_hint_to_text,
|
|
15
|
+
create_hint_wrapper,
|
|
16
|
+
extract_hint_from_text,
|
|
17
|
+
extract_content_from_text,
|
|
18
|
+
has_hint_in_text,
|
|
19
|
+
replace_hint_in_text,
|
|
20
|
+
add_multiple_hints_to_text,
|
|
21
|
+
get_text_statistics,
|
|
22
|
+
batch_add_hints,
|
|
23
|
+
safe_add_hint,
|
|
24
|
+
create_conversation_hint,
|
|
25
|
+
merge_with_last_user_message,
|
|
26
|
+
append_hint_to_text,
|
|
27
|
+
safe_append_hint
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TestWrapLLMHint(unittest.TestCase):
|
|
32
|
+
"""测试核心 WrapLLMHint 类"""
|
|
33
|
+
|
|
34
|
+
def setUp(self):
|
|
35
|
+
"""测试前置设置"""
|
|
36
|
+
self.wrapper = WrapLLMHint()
|
|
37
|
+
self.custom_config = HintConfig(
|
|
38
|
+
separator="\n===\n",
|
|
39
|
+
prefix="[HINT] ",
|
|
40
|
+
suffix=" [/HINT]",
|
|
41
|
+
allow_empty_hint=True,
|
|
42
|
+
strip_whitespace=False
|
|
43
|
+
)
|
|
44
|
+
self.custom_wrapper = WrapLLMHint(self.custom_config)
|
|
45
|
+
|
|
46
|
+
def test_init_default_config(self):
|
|
47
|
+
"""测试默认配置初始化"""
|
|
48
|
+
wrapper = WrapLLMHint()
|
|
49
|
+
self.assertEqual(wrapper.config.separator, "\n---\n")
|
|
50
|
+
self.assertEqual(wrapper.config.prefix, "[[")
|
|
51
|
+
self.assertEqual(wrapper.config.suffix, "]]")
|
|
52
|
+
self.assertFalse(wrapper.config.allow_empty_hint)
|
|
53
|
+
self.assertTrue(wrapper.config.strip_whitespace)
|
|
54
|
+
|
|
55
|
+
def test_init_custom_config(self):
|
|
56
|
+
"""测试自定义配置初始化"""
|
|
57
|
+
self.assertEqual(self.custom_wrapper.config.separator, "\n===\n")
|
|
58
|
+
self.assertEqual(self.custom_wrapper.config.prefix, "[HINT] ")
|
|
59
|
+
self.assertEqual(self.custom_wrapper.config.suffix, " [/HINT]")
|
|
60
|
+
self.assertTrue(self.custom_wrapper.config.allow_empty_hint)
|
|
61
|
+
self.assertFalse(self.custom_wrapper.config.strip_whitespace)
|
|
62
|
+
|
|
63
|
+
def test_add_hint_basic(self):
|
|
64
|
+
"""测试基本提示添加功能"""
|
|
65
|
+
content = "这是原始内容"
|
|
66
|
+
hint = "这是提示信息"
|
|
67
|
+
expected = "这是原始内容\n---\n[[这是提示信息]]"
|
|
68
|
+
|
|
69
|
+
result = self.wrapper.add_hint(content, hint)
|
|
70
|
+
self.assertEqual(result, expected)
|
|
71
|
+
|
|
72
|
+
def test_add_hint_with_custom_config(self):
|
|
73
|
+
"""测试自定义配置的提示添加"""
|
|
74
|
+
content = "测试内容"
|
|
75
|
+
hint = "测试提示"
|
|
76
|
+
expected = "测试内容\n===\n[HINT] 测试提示 [/HINT]"
|
|
77
|
+
|
|
78
|
+
result = self.custom_wrapper.add_hint(content, hint)
|
|
79
|
+
self.assertEqual(result, expected)
|
|
80
|
+
|
|
81
|
+
def test_add_hint_empty_content(self):
|
|
82
|
+
"""测试空内容的提示添加"""
|
|
83
|
+
content = ""
|
|
84
|
+
hint = "提示信息"
|
|
85
|
+
expected = "\n---\n[[提示信息]]"
|
|
86
|
+
|
|
87
|
+
result = self.wrapper.add_hint(content, hint)
|
|
88
|
+
self.assertEqual(result, expected)
|
|
89
|
+
|
|
90
|
+
def test_add_hint_whitespace_content(self):
|
|
91
|
+
"""测试只有空白字符的内容"""
|
|
92
|
+
content = " \n \t "
|
|
93
|
+
hint = "提示信息"
|
|
94
|
+
expected = "\n---\n[[提示信息]]"
|
|
95
|
+
|
|
96
|
+
result = self.wrapper.add_hint(content, hint)
|
|
97
|
+
self.assertEqual(result, expected)
|
|
98
|
+
|
|
99
|
+
def test_add_hint_strip_whitespace(self):
|
|
100
|
+
"""测试去除提示空白字符"""
|
|
101
|
+
content = "内容"
|
|
102
|
+
hint = " 提示信息 "
|
|
103
|
+
expected = "内容\n---\n[[提示信息]]"
|
|
104
|
+
|
|
105
|
+
result = self.wrapper.add_hint(content, hint)
|
|
106
|
+
self.assertEqual(result, expected)
|
|
107
|
+
|
|
108
|
+
def test_add_hint_no_strip_whitespace(self):
|
|
109
|
+
"""测试不去除提示空白字符"""
|
|
110
|
+
content = "内容"
|
|
111
|
+
hint = " 提示信息 "
|
|
112
|
+
expected = "内容\n===\n[HINT] 提示信息 [/HINT]"
|
|
113
|
+
|
|
114
|
+
result = self.custom_wrapper.add_hint(content, hint)
|
|
115
|
+
self.assertEqual(result, expected)
|
|
116
|
+
|
|
117
|
+
def test_add_hint_empty_hint_not_allowed(self):
|
|
118
|
+
"""测试不允许空提示时的错误处理"""
|
|
119
|
+
content = "内容"
|
|
120
|
+
hint = ""
|
|
121
|
+
|
|
122
|
+
with self.assertRaises(ValueError):
|
|
123
|
+
self.wrapper.add_hint(content, hint)
|
|
124
|
+
|
|
125
|
+
def test_add_hint_empty_hint_allowed(self):
|
|
126
|
+
"""测试允许空提示时的处理"""
|
|
127
|
+
content = "内容"
|
|
128
|
+
hint = ""
|
|
129
|
+
expected = "内容\n===\n[HINT] [/HINT]" # 空提示时仍然添加前缀后缀
|
|
130
|
+
|
|
131
|
+
result = self.custom_wrapper.add_hint(content, hint)
|
|
132
|
+
self.assertEqual(result, expected)
|
|
133
|
+
|
|
134
|
+
def test_add_hint_type_validation(self):
|
|
135
|
+
"""测试输入类型验证"""
|
|
136
|
+
with self.assertRaises(TypeError):
|
|
137
|
+
self.wrapper.add_hint(123, "hint") # type: ignore
|
|
138
|
+
|
|
139
|
+
with self.assertRaises(TypeError):
|
|
140
|
+
self.wrapper.add_hint("content", 123) # type: ignore
|
|
141
|
+
|
|
142
|
+
def test_add_hint_safe_success(self):
|
|
143
|
+
"""测试安全添加提示成功的情况"""
|
|
144
|
+
content = "内容"
|
|
145
|
+
hint = "提示"
|
|
146
|
+
fallback = "备用提示"
|
|
147
|
+
expected = "内容\n---\n[[提示]]"
|
|
148
|
+
|
|
149
|
+
result = self.wrapper.add_hint_safe(content, hint, fallback)
|
|
150
|
+
self.assertEqual(result, expected)
|
|
151
|
+
|
|
152
|
+
def test_add_hint_safe_fallback(self):
|
|
153
|
+
"""测试安全添加提示使用备用提示"""
|
|
154
|
+
content = "内容"
|
|
155
|
+
hint = "" # 空提示会出错
|
|
156
|
+
fallback = "备用提示"
|
|
157
|
+
expected = "内容\n---\n[[备用提示]]"
|
|
158
|
+
|
|
159
|
+
result = self.wrapper.add_hint_safe(content, hint, fallback)
|
|
160
|
+
self.assertEqual(result, expected)
|
|
161
|
+
|
|
162
|
+
def test_add_hint_safe_no_fallback(self):
|
|
163
|
+
"""测试安全添加提示无备用提示"""
|
|
164
|
+
content = "内容"
|
|
165
|
+
hint = ""
|
|
166
|
+
fallback = ""
|
|
167
|
+
|
|
168
|
+
result = self.wrapper.add_hint_safe(content, hint, fallback)
|
|
169
|
+
self.assertEqual(result, content) # 返回原内容
|
|
170
|
+
|
|
171
|
+
def test_add_multiple_hints_basic(self):
|
|
172
|
+
"""测试添加多个提示"""
|
|
173
|
+
content = "内容"
|
|
174
|
+
hints = ["提示1", "提示2", "提示3"]
|
|
175
|
+
|
|
176
|
+
result = self.wrapper.add_multiple_hints(content, hints)
|
|
177
|
+
|
|
178
|
+
self.assertIn("提示1", result)
|
|
179
|
+
self.assertIn("提示2", result)
|
|
180
|
+
self.assertIn("提示3", result)
|
|
181
|
+
# 验证分隔符数量
|
|
182
|
+
self.assertEqual(result.count("\n---\n"), 3)
|
|
183
|
+
|
|
184
|
+
def test_add_multiple_hints_empty_list(self):
|
|
185
|
+
"""测试添加空提示列表"""
|
|
186
|
+
content = "内容"
|
|
187
|
+
hints = []
|
|
188
|
+
|
|
189
|
+
result = self.wrapper.add_multiple_hints(content, hints)
|
|
190
|
+
self.assertEqual(result, content)
|
|
191
|
+
|
|
192
|
+
def test_add_multiple_hints_with_empty_hints(self):
|
|
193
|
+
"""测试添加包含空提示的列表"""
|
|
194
|
+
content = "内容"
|
|
195
|
+
hints = ["提示1", "", "提示3"]
|
|
196
|
+
|
|
197
|
+
result = self.wrapper.add_multiple_hints(content, hints)
|
|
198
|
+
|
|
199
|
+
# 只应添加非空提示
|
|
200
|
+
self.assertIn("提示1", result)
|
|
201
|
+
self.assertIn("提示3", result)
|
|
202
|
+
self.assertEqual(result.count("\n---\n"), 2)
|
|
203
|
+
|
|
204
|
+
def test_extract_hint_basic(self):
|
|
205
|
+
"""测试基本提示提取"""
|
|
206
|
+
wrapped_content = "内容\n---\n[[提示信息]]"
|
|
207
|
+
|
|
208
|
+
result = self.wrapper.extract_hint(wrapped_content)
|
|
209
|
+
self.assertEqual(result, "提示信息")
|
|
210
|
+
|
|
211
|
+
def test_extract_hint_no_hint(self):
|
|
212
|
+
"""测试无提示内容的提取"""
|
|
213
|
+
content = "只有内容,没有提示"
|
|
214
|
+
|
|
215
|
+
result = self.wrapper.extract_hint(content)
|
|
216
|
+
self.assertIsNone(result)
|
|
217
|
+
|
|
218
|
+
def test_extract_hint_multiple_separators(self):
|
|
219
|
+
"""测试多个分隔符时提取最后一个提示"""
|
|
220
|
+
wrapped_content = "内容\n---\n[[提示1]]\n---\n[[提示2]]"
|
|
221
|
+
|
|
222
|
+
result = self.wrapper.extract_hint(wrapped_content)
|
|
223
|
+
self.assertEqual(result, "提示2")
|
|
224
|
+
|
|
225
|
+
def test_extract_hint_custom_config(self):
|
|
226
|
+
"""测试自定义配置的提示提取"""
|
|
227
|
+
wrapped_content = "内容\n===\n[HINT] 提示信息 [/HINT]"
|
|
228
|
+
|
|
229
|
+
result = self.custom_wrapper.extract_hint(wrapped_content)
|
|
230
|
+
self.assertEqual(result, "提示信息") # 实际实现仍然去除了空白字符
|
|
231
|
+
|
|
232
|
+
def test_extract_hint_invalid_input(self):
|
|
233
|
+
"""测试无效输入的提示提取"""
|
|
234
|
+
result = self.wrapper.extract_hint(123) # type: ignore
|
|
235
|
+
self.assertIsNone(result)
|
|
236
|
+
|
|
237
|
+
def test_extract_content_basic(self):
|
|
238
|
+
"""测试基本内容提取"""
|
|
239
|
+
wrapped_content = "原始内容\n---\n[[提示信息]]"
|
|
240
|
+
|
|
241
|
+
result = self.wrapper.extract_content(wrapped_content)
|
|
242
|
+
self.assertEqual(result, "原始内容")
|
|
243
|
+
|
|
244
|
+
def test_extract_content_no_hint(self):
|
|
245
|
+
"""测试无提示内容的内容提取"""
|
|
246
|
+
content = "只有内容"
|
|
247
|
+
|
|
248
|
+
result = self.wrapper.extract_content(content)
|
|
249
|
+
self.assertEqual(result, content)
|
|
250
|
+
|
|
251
|
+
def test_extract_content_multiple_separators(self):
|
|
252
|
+
"""测试多个分隔符时提取内容"""
|
|
253
|
+
wrapped_content = "第一部分\n---\n[[提示1]]\n---\n[[提示2]]"
|
|
254
|
+
|
|
255
|
+
result = self.wrapper.extract_content(wrapped_content)
|
|
256
|
+
self.assertEqual(result, "第一部分\n---\n[[提示1]]")
|
|
257
|
+
|
|
258
|
+
def test_extract_content_invalid_input(self):
|
|
259
|
+
"""测试无效输入的内容提取"""
|
|
260
|
+
result = self.wrapper.extract_content(123) # type: ignore
|
|
261
|
+
self.assertEqual(result, "")
|
|
262
|
+
|
|
263
|
+
def test_has_hint_true(self):
|
|
264
|
+
"""测试包含提示的内容检查"""
|
|
265
|
+
content = "内容\n---\n[[提示]]"
|
|
266
|
+
|
|
267
|
+
result = self.wrapper.has_hint(content)
|
|
268
|
+
self.assertTrue(result)
|
|
269
|
+
|
|
270
|
+
def test_has_hint_false(self):
|
|
271
|
+
"""测试不包含提示的内容检查"""
|
|
272
|
+
content = "只有内容"
|
|
273
|
+
|
|
274
|
+
result = self.wrapper.has_hint(content)
|
|
275
|
+
self.assertFalse(result)
|
|
276
|
+
|
|
277
|
+
def test_has_hint_invalid_input(self):
|
|
278
|
+
"""测试无效输入的检查"""
|
|
279
|
+
result = self.wrapper.has_hint(123) # type: ignore
|
|
280
|
+
self.assertFalse(result)
|
|
281
|
+
|
|
282
|
+
def test_replace_hint_basic(self):
|
|
283
|
+
"""测试基本提示替换"""
|
|
284
|
+
wrapped_content = "内容\n---\n[[旧提示]]"
|
|
285
|
+
new_hint = "新提示"
|
|
286
|
+
expected = "内容\n---\n[[新提示]]"
|
|
287
|
+
|
|
288
|
+
result = self.wrapper.replace_hint(wrapped_content, new_hint)
|
|
289
|
+
self.assertEqual(result, expected)
|
|
290
|
+
|
|
291
|
+
def test_replace_hint_no_existing_hint(self):
|
|
292
|
+
"""测试替换不存在的提示"""
|
|
293
|
+
content = "只有内容"
|
|
294
|
+
new_hint = "新提示"
|
|
295
|
+
expected = "只有内容\n---\n[[新提示]]"
|
|
296
|
+
|
|
297
|
+
result = self.wrapper.replace_hint(content, new_hint)
|
|
298
|
+
self.assertEqual(result, expected)
|
|
299
|
+
|
|
300
|
+
def test_get_statistics_basic(self):
|
|
301
|
+
"""测试基本统计信息获取"""
|
|
302
|
+
wrapped_content = "内容\n---\n[[提示]]"
|
|
303
|
+
|
|
304
|
+
stats = self.wrapper.get_statistics(wrapped_content)
|
|
305
|
+
|
|
306
|
+
self.assertEqual(stats["total_length"], len(wrapped_content))
|
|
307
|
+
self.assertEqual(stats["content_length"], 2) # "内容"
|
|
308
|
+
self.assertEqual(stats["hint_length"], 2) # "提示"
|
|
309
|
+
self.assertTrue(stats["has_hint"])
|
|
310
|
+
self.assertEqual(stats["separator_count"], 1)
|
|
311
|
+
self.assertEqual(stats["separator"], "\n---\n")
|
|
312
|
+
|
|
313
|
+
def test_get_statistics_no_hint(self):
|
|
314
|
+
"""测试无提示内容的统计信息"""
|
|
315
|
+
content = "只有内容"
|
|
316
|
+
|
|
317
|
+
stats = self.wrapper.get_statistics(content)
|
|
318
|
+
|
|
319
|
+
self.assertEqual(stats["total_length"], len(content))
|
|
320
|
+
self.assertEqual(stats["content_length"], len(content))
|
|
321
|
+
self.assertEqual(stats["hint_length"], 0)
|
|
322
|
+
self.assertFalse(stats["has_hint"])
|
|
323
|
+
self.assertEqual(stats["separator_count"], 0)
|
|
324
|
+
|
|
325
|
+
def test_get_statistics_invalid_input(self):
|
|
326
|
+
"""测试无效输入的统计信息"""
|
|
327
|
+
stats = self.wrapper.get_statistics(123) # type: ignore
|
|
328
|
+
|
|
329
|
+
expected = {
|
|
330
|
+
"total_length": 0,
|
|
331
|
+
"content_length": 0,
|
|
332
|
+
"hint_length": 0,
|
|
333
|
+
"has_hint": False,
|
|
334
|
+
"separator_count": 0
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
for key, value in expected.items():
|
|
338
|
+
self.assertEqual(stats[key], value)
|
|
339
|
+
|
|
340
|
+
# 新增:append_hint 功能测试
|
|
341
|
+
def test_append_hint_no_existing_hint(self):
|
|
342
|
+
"""测试追加提示到没有现有提示的内容"""
|
|
343
|
+
content = "原始内容"
|
|
344
|
+
hint = "新提示"
|
|
345
|
+
expected = "原始内容\n---\n[[新提示]]"
|
|
346
|
+
|
|
347
|
+
result = self.wrapper.append_hint(content, hint)
|
|
348
|
+
self.assertEqual(result, expected)
|
|
349
|
+
|
|
350
|
+
def test_append_hint_with_existing_hint(self):
|
|
351
|
+
"""测试追加提示到已有提示的内容"""
|
|
352
|
+
content = "原始内容\n---\n[[现有提示]]"
|
|
353
|
+
hint = "追加提示"
|
|
354
|
+
expected = "原始内容\n---\n[[现有提示\n追加提示]]"
|
|
355
|
+
|
|
356
|
+
result = self.wrapper.append_hint(content, hint)
|
|
357
|
+
self.assertEqual(result, expected)
|
|
358
|
+
|
|
359
|
+
def test_append_hint_multiple_times(self):
|
|
360
|
+
"""测试多次追加提示"""
|
|
361
|
+
content = "原始内容"
|
|
362
|
+
|
|
363
|
+
# 第一次追加
|
|
364
|
+
result1 = self.wrapper.append_hint(content, "提示1")
|
|
365
|
+
expected1 = "原始内容\n---\n[[提示1]]"
|
|
366
|
+
self.assertEqual(result1, expected1)
|
|
367
|
+
|
|
368
|
+
# 第二次追加
|
|
369
|
+
result2 = self.wrapper.append_hint(result1, "提示2")
|
|
370
|
+
expected2 = "原始内容\n---\n[[提示1\n提示2]]"
|
|
371
|
+
self.assertEqual(result2, expected2)
|
|
372
|
+
|
|
373
|
+
# 第三次追加
|
|
374
|
+
result3 = self.wrapper.append_hint(result2, "提示3")
|
|
375
|
+
expected3 = "原始内容\n---\n[[提示1\n提示2\n提示3]]"
|
|
376
|
+
self.assertEqual(result3, expected3)
|
|
377
|
+
|
|
378
|
+
def test_append_hint_with_custom_config(self):
|
|
379
|
+
"""测试自定义配置的追加提示"""
|
|
380
|
+
content = "内容\n===\n[HINT] 现有提示 [/HINT]"
|
|
381
|
+
hint = "追加提示"
|
|
382
|
+
expected = "内容\n===\n[HINT] 现有提示\n追加提示 [/HINT]"
|
|
383
|
+
|
|
384
|
+
result = self.custom_wrapper.append_hint(content, hint)
|
|
385
|
+
self.assertEqual(result, expected)
|
|
386
|
+
|
|
387
|
+
def test_append_hint_empty_hint_not_allowed(self):
|
|
388
|
+
"""测试追加空提示时的错误处理"""
|
|
389
|
+
content = "内容\n---\n[[现有提示]]"
|
|
390
|
+
hint = ""
|
|
391
|
+
|
|
392
|
+
with self.assertRaises(ValueError):
|
|
393
|
+
self.wrapper.append_hint(content, hint)
|
|
394
|
+
|
|
395
|
+
def test_append_hint_empty_hint_allowed(self):
|
|
396
|
+
"""测试允许空提示时的追加"""
|
|
397
|
+
content = "内容\n===\n[HINT] 现有提示 [/HINT]"
|
|
398
|
+
hint = ""
|
|
399
|
+
|
|
400
|
+
# 空提示被允许但实际不会追加
|
|
401
|
+
result = self.custom_wrapper.append_hint(content, hint)
|
|
402
|
+
self.assertEqual(result, content) # 返回原内容
|
|
403
|
+
|
|
404
|
+
def test_append_hint_type_validation(self):
|
|
405
|
+
"""测试追加提示的输入类型验证"""
|
|
406
|
+
content = "内容\n---\n[[提示]]"
|
|
407
|
+
|
|
408
|
+
with self.assertRaises(TypeError):
|
|
409
|
+
self.wrapper.append_hint(123, "hint") # type: ignore
|
|
410
|
+
|
|
411
|
+
with self.assertRaises(TypeError):
|
|
412
|
+
self.wrapper.append_hint(content, 123) # type: ignore
|
|
413
|
+
|
|
414
|
+
def test_append_hint_strip_whitespace(self):
|
|
415
|
+
"""测试追加提示时去除空白字符"""
|
|
416
|
+
content = "内容\n---\n[[现有提示]]"
|
|
417
|
+
hint = " 追加提示 "
|
|
418
|
+
expected = "内容\n---\n[[现有提示\n追加提示]]"
|
|
419
|
+
|
|
420
|
+
result = self.wrapper.append_hint(content, hint)
|
|
421
|
+
self.assertEqual(result, expected)
|
|
422
|
+
|
|
423
|
+
def test_append_hint_no_strip_whitespace(self):
|
|
424
|
+
"""测试追加提示时不去除空白字符"""
|
|
425
|
+
content = "内容\n===\n[HINT] 现有提示 [/HINT]"
|
|
426
|
+
hint = " 追加提示 "
|
|
427
|
+
expected = "内容\n===\n[HINT] 现有提示\n 追加提示 [/HINT]"
|
|
428
|
+
|
|
429
|
+
result = self.custom_wrapper.append_hint(content, hint)
|
|
430
|
+
self.assertEqual(result, expected)
|
|
431
|
+
|
|
432
|
+
def test_append_hint_extract_verification(self):
|
|
433
|
+
"""测试追加提示后的提取验证"""
|
|
434
|
+
content = "原始内容\n---\n[[第一个提示]]"
|
|
435
|
+
hint = "第二个提示"
|
|
436
|
+
|
|
437
|
+
result = self.wrapper.append_hint(content, hint)
|
|
438
|
+
|
|
439
|
+
# 验证可以正确提取内容
|
|
440
|
+
extracted_content = self.wrapper.extract_content(result)
|
|
441
|
+
self.assertEqual(extracted_content, "原始内容")
|
|
442
|
+
|
|
443
|
+
# 验证可以正确提取合并后的提示
|
|
444
|
+
extracted_hint = self.wrapper.extract_hint(result)
|
|
445
|
+
self.assertEqual(extracted_hint, "第一个提示\n第二个提示")
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
class TestUtils(unittest.TestCase):
|
|
449
|
+
"""测试工具函数模块"""
|
|
450
|
+
|
|
451
|
+
def test_add_hint_to_text_basic(self):
|
|
452
|
+
"""测试基本文本提示添加"""
|
|
453
|
+
content = "测试内容"
|
|
454
|
+
hint = "测试提示"
|
|
455
|
+
expected = "测试内容\n---\n[[测试提示]]"
|
|
456
|
+
|
|
457
|
+
result = add_hint_to_text(content, hint)
|
|
458
|
+
self.assertEqual(result, expected)
|
|
459
|
+
|
|
460
|
+
def test_add_hint_to_text_custom_separator(self):
|
|
461
|
+
"""测试自定义分隔符的提示添加"""
|
|
462
|
+
content = "测试内容"
|
|
463
|
+
hint = "测试提示"
|
|
464
|
+
separator = "\n===\n"
|
|
465
|
+
expected = "测试内容\n===\n[[测试提示]]"
|
|
466
|
+
|
|
467
|
+
result = add_hint_to_text(content, hint, separator)
|
|
468
|
+
self.assertEqual(result, expected)
|
|
469
|
+
|
|
470
|
+
def test_create_hint_wrapper_default(self):
|
|
471
|
+
"""测试创建默认配置的包装器"""
|
|
472
|
+
wrapper = create_hint_wrapper()
|
|
473
|
+
|
|
474
|
+
self.assertEqual(wrapper.config.separator, "\n---\n")
|
|
475
|
+
self.assertEqual(wrapper.config.prefix, "[[")
|
|
476
|
+
self.assertEqual(wrapper.config.suffix, "]]")
|
|
477
|
+
|
|
478
|
+
def test_create_hint_wrapper_custom(self):
|
|
479
|
+
"""测试创建自定义配置的包装器"""
|
|
480
|
+
wrapper = create_hint_wrapper(
|
|
481
|
+
separator="\n***\n",
|
|
482
|
+
prefix="[NOTE] ",
|
|
483
|
+
suffix=" [/NOTE]",
|
|
484
|
+
allow_empty_hint=True,
|
|
485
|
+
strip_whitespace=False
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
self.assertEqual(wrapper.config.separator, "\n***\n")
|
|
489
|
+
self.assertEqual(wrapper.config.prefix, "[NOTE] ")
|
|
490
|
+
self.assertEqual(wrapper.config.suffix, " [/NOTE]")
|
|
491
|
+
self.assertTrue(wrapper.config.allow_empty_hint)
|
|
492
|
+
self.assertFalse(wrapper.config.strip_whitespace)
|
|
493
|
+
|
|
494
|
+
def test_extract_hint_from_text_basic(self):
|
|
495
|
+
"""测试从文本提取提示"""
|
|
496
|
+
wrapped_content = "内容\n---\n[[提示信息]]"
|
|
497
|
+
|
|
498
|
+
result = extract_hint_from_text(wrapped_content)
|
|
499
|
+
self.assertEqual(result, "提示信息")
|
|
500
|
+
|
|
501
|
+
def test_extract_hint_from_text_custom_separator(self):
|
|
502
|
+
"""测试使用自定义分隔符提取提示"""
|
|
503
|
+
wrapped_content = "内容\n***\n[[提示信息]]"
|
|
504
|
+
separator = "\n***\n"
|
|
505
|
+
|
|
506
|
+
result = extract_hint_from_text(wrapped_content, separator)
|
|
507
|
+
self.assertEqual(result, "提示信息")
|
|
508
|
+
|
|
509
|
+
def test_extract_hint_from_text_no_hint(self):
|
|
510
|
+
"""测试从无提示文本提取"""
|
|
511
|
+
content = "只有内容"
|
|
512
|
+
|
|
513
|
+
result = extract_hint_from_text(content)
|
|
514
|
+
self.assertIsNone(result)
|
|
515
|
+
|
|
516
|
+
def test_extract_content_from_text_basic(self):
|
|
517
|
+
"""测试从文本提取内容"""
|
|
518
|
+
wrapped_content = "原始内容\n---\n[[提示]]"
|
|
519
|
+
|
|
520
|
+
result = extract_content_from_text(wrapped_content)
|
|
521
|
+
self.assertEqual(result, "原始内容")
|
|
522
|
+
|
|
523
|
+
def test_extract_content_from_text_custom_separator(self):
|
|
524
|
+
"""测试使用自定义分隔符提取内容"""
|
|
525
|
+
wrapped_content = "原始内容\n***\n[[提示]]"
|
|
526
|
+
separator = "\n***\n"
|
|
527
|
+
|
|
528
|
+
result = extract_content_from_text(wrapped_content, separator)
|
|
529
|
+
self.assertEqual(result, "原始内容")
|
|
530
|
+
|
|
531
|
+
def test_has_hint_in_text_true(self):
|
|
532
|
+
"""测试检查包含提示的文本"""
|
|
533
|
+
content = "内容\n---\n提示"
|
|
534
|
+
|
|
535
|
+
result = has_hint_in_text(content)
|
|
536
|
+
self.assertTrue(result)
|
|
537
|
+
|
|
538
|
+
def test_has_hint_in_text_false(self):
|
|
539
|
+
"""测试检查不包含提示的文本"""
|
|
540
|
+
content = "只有内容"
|
|
541
|
+
|
|
542
|
+
result = has_hint_in_text(content)
|
|
543
|
+
self.assertFalse(result)
|
|
544
|
+
|
|
545
|
+
def test_replace_hint_in_text_basic(self):
|
|
546
|
+
"""测试替换文本中的提示"""
|
|
547
|
+
wrapped_content = "内容\n---\n[[旧提示]]"
|
|
548
|
+
new_hint = "新提示"
|
|
549
|
+
expected = "内容\n---\n[[新提示]]"
|
|
550
|
+
|
|
551
|
+
result = replace_hint_in_text(wrapped_content, new_hint)
|
|
552
|
+
self.assertEqual(result, expected)
|
|
553
|
+
|
|
554
|
+
def test_add_multiple_hints_to_text_basic(self):
|
|
555
|
+
"""测试给文本添加多个提示"""
|
|
556
|
+
content = "内容"
|
|
557
|
+
hints = ["提示1", "提示2"]
|
|
558
|
+
|
|
559
|
+
result = add_multiple_hints_to_text(content, hints)
|
|
560
|
+
|
|
561
|
+
self.assertIn("提示1", result)
|
|
562
|
+
self.assertIn("提示2", result)
|
|
563
|
+
self.assertEqual(result.count("\n---\n"), 2)
|
|
564
|
+
|
|
565
|
+
def test_get_text_statistics_basic(self):
|
|
566
|
+
"""测试获取文本统计信息"""
|
|
567
|
+
wrapped_content = "内容\n---\n[[提示]]"
|
|
568
|
+
|
|
569
|
+
stats = get_text_statistics(wrapped_content)
|
|
570
|
+
|
|
571
|
+
self.assertIn("total_length", stats)
|
|
572
|
+
self.assertIn("content_length", stats)
|
|
573
|
+
self.assertIn("hint_length", stats)
|
|
574
|
+
self.assertIn("has_hint", stats)
|
|
575
|
+
self.assertIn("separator_count", stats)
|
|
576
|
+
self.assertTrue(stats["has_hint"])
|
|
577
|
+
|
|
578
|
+
def test_batch_add_hints_basic(self):
|
|
579
|
+
"""测试批量添加提示"""
|
|
580
|
+
contents = ["内容1", "内容2", "内容3"]
|
|
581
|
+
hints = ["提示1", "提示2", "提示3"]
|
|
582
|
+
|
|
583
|
+
results = batch_add_hints(contents, hints)
|
|
584
|
+
|
|
585
|
+
self.assertEqual(len(results), 3)
|
|
586
|
+
for i, result in enumerate(results):
|
|
587
|
+
self.assertIn(contents[i], result)
|
|
588
|
+
self.assertIn(hints[i], result)
|
|
589
|
+
|
|
590
|
+
def test_batch_add_hints_length_mismatch(self):
|
|
591
|
+
"""测试批量添加提示时长度不匹配"""
|
|
592
|
+
contents = ["内容1", "内容2"]
|
|
593
|
+
hints = ["提示1"]
|
|
594
|
+
|
|
595
|
+
with self.assertRaises(ValueError):
|
|
596
|
+
batch_add_hints(contents, hints)
|
|
597
|
+
|
|
598
|
+
def test_batch_add_hints_with_errors(self):
|
|
599
|
+
"""测试批量添加提示时有错误的情况"""
|
|
600
|
+
contents = ["内容1", "内容2"]
|
|
601
|
+
hints = ["提示1", ""] # 空提示会出错
|
|
602
|
+
|
|
603
|
+
# 应该不抛出异常,错误时保留原内容
|
|
604
|
+
results = batch_add_hints(contents, hints)
|
|
605
|
+
|
|
606
|
+
self.assertEqual(len(results), 2)
|
|
607
|
+
self.assertIn("提示1", results[0])
|
|
608
|
+
self.assertEqual(results[1], "内容2") # 保留原内容
|
|
609
|
+
|
|
610
|
+
def test_safe_add_hint_success(self):
|
|
611
|
+
"""测试安全添加提示成功"""
|
|
612
|
+
content = "内容"
|
|
613
|
+
hint = "提示"
|
|
614
|
+
|
|
615
|
+
result = safe_add_hint(content, hint)
|
|
616
|
+
expected = "内容\n---\n[[提示]]"
|
|
617
|
+
self.assertEqual(result, expected)
|
|
618
|
+
|
|
619
|
+
def test_safe_add_hint_fallback(self):
|
|
620
|
+
"""测试安全添加提示使用备用提示"""
|
|
621
|
+
content = "内容"
|
|
622
|
+
hint = "" # 空提示
|
|
623
|
+
fallback = "备用提示"
|
|
624
|
+
|
|
625
|
+
result = safe_add_hint(content, hint, fallback)
|
|
626
|
+
expected = "内容\n---\n[[备用提示]]"
|
|
627
|
+
self.assertEqual(result, expected)
|
|
628
|
+
|
|
629
|
+
def test_create_conversation_hint(self):
|
|
630
|
+
"""测试创建对话提示"""
|
|
631
|
+
cleanup_message = "对话过长需要清理"
|
|
632
|
+
|
|
633
|
+
result = create_conversation_hint(cleanup_message)
|
|
634
|
+
self.assertEqual(result, cleanup_message)
|
|
635
|
+
|
|
636
|
+
def test_merge_with_last_user_message_user_last(self):
|
|
637
|
+
"""测试合并到最后一个用户消息"""
|
|
638
|
+
conversations = [
|
|
639
|
+
{"role": "user", "content": "用户消息1"},
|
|
640
|
+
{"role": "assistant", "content": "助手消息"},
|
|
641
|
+
{"role": "user", "content": "用户消息2"}
|
|
642
|
+
]
|
|
643
|
+
cleanup_message = "清理提示"
|
|
644
|
+
|
|
645
|
+
result = merge_with_last_user_message(conversations, cleanup_message)
|
|
646
|
+
|
|
647
|
+
self.assertEqual(len(result), 3)
|
|
648
|
+
self.assertIn("用户消息2", result[-1]["content"])
|
|
649
|
+
self.assertIn("清理提示", result[-1]["content"])
|
|
650
|
+
self.assertIn("\n---\n", result[-1]["content"])
|
|
651
|
+
|
|
652
|
+
def test_merge_with_last_user_message_assistant_last(self):
|
|
653
|
+
"""测试最后一个消息不是用户消息时的合并"""
|
|
654
|
+
conversations = [
|
|
655
|
+
{"role": "user", "content": "用户消息"},
|
|
656
|
+
{"role": "assistant", "content": "助手消息"}
|
|
657
|
+
]
|
|
658
|
+
cleanup_message = "清理提示"
|
|
659
|
+
|
|
660
|
+
result = merge_with_last_user_message(conversations, cleanup_message)
|
|
661
|
+
|
|
662
|
+
self.assertEqual(len(result), 3)
|
|
663
|
+
self.assertEqual(result[-1]["role"], "user")
|
|
664
|
+
self.assertEqual(result[-1]["content"], cleanup_message)
|
|
665
|
+
|
|
666
|
+
def test_merge_with_last_user_message_empty_list(self):
|
|
667
|
+
"""测试空对话列表的合并"""
|
|
668
|
+
conversations = []
|
|
669
|
+
cleanup_message = "清理提示"
|
|
670
|
+
|
|
671
|
+
result = merge_with_last_user_message(conversations, cleanup_message)
|
|
672
|
+
self.assertEqual(result, [])
|
|
673
|
+
|
|
674
|
+
# 新增:append_hint_to_text 功能测试
|
|
675
|
+
def test_append_hint_to_text_no_existing_hint(self):
|
|
676
|
+
"""测试追加提示到没有现有提示的文本"""
|
|
677
|
+
content = "原始内容"
|
|
678
|
+
hint = "新提示"
|
|
679
|
+
expected = "原始内容\n---\n[[新提示]]"
|
|
680
|
+
|
|
681
|
+
result = append_hint_to_text(content, hint)
|
|
682
|
+
self.assertEqual(result, expected)
|
|
683
|
+
|
|
684
|
+
def test_append_hint_to_text_with_existing_hint(self):
|
|
685
|
+
"""测试追加提示到已有提示的文本"""
|
|
686
|
+
content = "原始内容\n---\n[[现有提示]]"
|
|
687
|
+
hint = "追加提示"
|
|
688
|
+
expected = "原始内容\n---\n[[现有提示\n追加提示]]"
|
|
689
|
+
|
|
690
|
+
result = append_hint_to_text(content, hint)
|
|
691
|
+
self.assertEqual(result, expected)
|
|
692
|
+
|
|
693
|
+
def test_append_hint_to_text_custom_separator(self):
|
|
694
|
+
"""测试使用自定义分隔符追加提示"""
|
|
695
|
+
content = "内容\n***\n[[现有提示]]"
|
|
696
|
+
hint = "追加提示"
|
|
697
|
+
separator = "\n***\n"
|
|
698
|
+
expected = "内容\n***\n[[现有提示\n追加提示]]"
|
|
699
|
+
|
|
700
|
+
result = append_hint_to_text(content, hint, separator)
|
|
701
|
+
self.assertEqual(result, expected)
|
|
702
|
+
|
|
703
|
+
def test_append_hint_to_text_multiple_times(self):
|
|
704
|
+
"""测试多次追加提示到文本"""
|
|
705
|
+
content = "原始内容"
|
|
706
|
+
|
|
707
|
+
# 第一次追加
|
|
708
|
+
result1 = append_hint_to_text(content, "提示1")
|
|
709
|
+
expected1 = "原始内容\n---\n[[提示1]]"
|
|
710
|
+
self.assertEqual(result1, expected1)
|
|
711
|
+
|
|
712
|
+
# 第二次追加
|
|
713
|
+
result2 = append_hint_to_text(result1, "提示2")
|
|
714
|
+
expected2 = "原始内容\n---\n[[提示1\n提示2]]"
|
|
715
|
+
self.assertEqual(result2, expected2)
|
|
716
|
+
|
|
717
|
+
# 第三次追加
|
|
718
|
+
result3 = append_hint_to_text(result2, "提示3")
|
|
719
|
+
expected3 = "原始内容\n---\n[[提示1\n提示2\n提示3]]"
|
|
720
|
+
self.assertEqual(result3, expected3)
|
|
721
|
+
|
|
722
|
+
def test_safe_append_hint_success(self):
|
|
723
|
+
"""测试安全追加提示成功"""
|
|
724
|
+
content = "内容\n---\n[[现有提示]]"
|
|
725
|
+
hint = "追加提示"
|
|
726
|
+
expected = "内容\n---\n[[现有提示\n追加提示]]"
|
|
727
|
+
|
|
728
|
+
result = safe_append_hint(content, hint)
|
|
729
|
+
self.assertEqual(result, expected)
|
|
730
|
+
|
|
731
|
+
def test_safe_append_hint_fallback(self):
|
|
732
|
+
"""测试安全追加提示使用备用提示"""
|
|
733
|
+
content = "内容\n---\n[[现有提示]]"
|
|
734
|
+
hint = "" # 空提示会出错
|
|
735
|
+
fallback = "备用提示"
|
|
736
|
+
expected = "内容\n---\n[[现有提示\n备用提示]]"
|
|
737
|
+
|
|
738
|
+
result = safe_append_hint(content, hint, fallback)
|
|
739
|
+
self.assertEqual(result, expected)
|
|
740
|
+
|
|
741
|
+
def test_safe_append_hint_no_fallback(self):
|
|
742
|
+
"""测试安全追加提示无备用提示"""
|
|
743
|
+
content = "内容\n---\n[[现有提示]]"
|
|
744
|
+
hint = ""
|
|
745
|
+
fallback = ""
|
|
746
|
+
|
|
747
|
+
result = safe_append_hint(content, hint, fallback)
|
|
748
|
+
self.assertEqual(result, content) # 返回原内容
|
|
749
|
+
|
|
750
|
+
def test_merge_with_last_user_message_append_mode(self):
|
|
751
|
+
"""测试使用追加模式合并到最后一个用户消息"""
|
|
752
|
+
conversations = [
|
|
753
|
+
{"role": "user", "content": "用户消息\n---\n[[现有提示]]"},
|
|
754
|
+
{"role": "assistant", "content": "助手消息"}
|
|
755
|
+
]
|
|
756
|
+
cleanup_message = "追加提示"
|
|
757
|
+
|
|
758
|
+
# 使用追加模式
|
|
759
|
+
result = merge_with_last_user_message(conversations, cleanup_message, append_mode=True)
|
|
760
|
+
|
|
761
|
+
self.assertEqual(len(result), 3)
|
|
762
|
+
self.assertEqual(result[-1]["role"], "user")
|
|
763
|
+
self.assertEqual(result[-1]["content"], cleanup_message)
|
|
764
|
+
|
|
765
|
+
# 测试最后一个是用户消息的情况
|
|
766
|
+
conversations2 = [
|
|
767
|
+
{"role": "user", "content": "用户消息\n---\n[[现有提示]]"}
|
|
768
|
+
]
|
|
769
|
+
|
|
770
|
+
result2 = merge_with_last_user_message(conversations2, cleanup_message, append_mode=True)
|
|
771
|
+
|
|
772
|
+
self.assertEqual(len(result2), 1)
|
|
773
|
+
self.assertIn("用户消息", result2[0]["content"])
|
|
774
|
+
self.assertIn("现有提示", result2[0]["content"])
|
|
775
|
+
self.assertIn("追加提示", result2[0]["content"])
|
|
776
|
+
|
|
777
|
+
# 验证格式正确
|
|
778
|
+
expected_pattern = "用户消息\n---\n[[现有提示\n追加提示]]"
|
|
779
|
+
self.assertEqual(result2[0]["content"], expected_pattern)
|
|
780
|
+
|
|
781
|
+
def test_merge_with_last_user_message_replace_mode(self):
|
|
782
|
+
"""测试使用替换模式合并到最后一个用户消息(默认行为)"""
|
|
783
|
+
conversations = [
|
|
784
|
+
{"role": "user", "content": "用户消息\n---\n[[现有提示]]"}
|
|
785
|
+
]
|
|
786
|
+
cleanup_message = "新提示"
|
|
787
|
+
|
|
788
|
+
# 使用替换模式(默认)
|
|
789
|
+
result = merge_with_last_user_message(conversations, cleanup_message, append_mode=False)
|
|
790
|
+
|
|
791
|
+
self.assertEqual(len(result), 1)
|
|
792
|
+
self.assertIn("用户消息", result[0]["content"])
|
|
793
|
+
self.assertIn("新提示", result[0]["content"])
|
|
794
|
+
# 应该不包含原有提示(被替换了)
|
|
795
|
+
self.assertNotIn("现有提示", result[0]["content"])
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
class TestIntegration(unittest.TestCase):
|
|
799
|
+
"""集成测试"""
|
|
800
|
+
|
|
801
|
+
def test_end_to_end_workflow(self):
|
|
802
|
+
"""测试端到端工作流程"""
|
|
803
|
+
# 1. 创建原始内容
|
|
804
|
+
content = "这是一个重要的用户消息"
|
|
805
|
+
hint = "请注意:这条消息需要特别关注"
|
|
806
|
+
|
|
807
|
+
# 2. 添加提示
|
|
808
|
+
wrapped_content = add_hint_to_text(content, hint)
|
|
809
|
+
|
|
810
|
+
# 3. 验证包含提示
|
|
811
|
+
self.assertTrue(has_hint_in_text(wrapped_content))
|
|
812
|
+
|
|
813
|
+
# 4. 提取内容和提示
|
|
814
|
+
extracted_content = extract_content_from_text(wrapped_content)
|
|
815
|
+
extracted_hint = extract_hint_from_text(wrapped_content)
|
|
816
|
+
|
|
817
|
+
# 5. 验证提取结果
|
|
818
|
+
self.assertEqual(extracted_content, content)
|
|
819
|
+
self.assertEqual(extracted_hint, hint)
|
|
820
|
+
|
|
821
|
+
# 6. 替换提示
|
|
822
|
+
new_hint = "更新的提示信息"
|
|
823
|
+
updated_content = replace_hint_in_text(wrapped_content, new_hint)
|
|
824
|
+
|
|
825
|
+
# 7. 验证替换结果
|
|
826
|
+
updated_hint = extract_hint_from_text(updated_content)
|
|
827
|
+
self.assertEqual(updated_hint, new_hint)
|
|
828
|
+
|
|
829
|
+
def test_conversation_integration(self):
|
|
830
|
+
"""测试对话系统集成"""
|
|
831
|
+
# 模拟 agentic_conversation_pruner.py 的使用场景
|
|
832
|
+
conversations = [
|
|
833
|
+
{"role": "user", "content": "请帮我分析这段代码"},
|
|
834
|
+
{"role": "assistant", "content": "好的,我来为您分析"},
|
|
835
|
+
{"role": "user", "content": "还有其他建议吗?"}
|
|
836
|
+
]
|
|
837
|
+
|
|
838
|
+
cleanup_message = "[[对话内容过长,请使用 conversation_message_ids_write 工具保存要删除的消息ID。]]"
|
|
839
|
+
|
|
840
|
+
# 合并清理消息到最后一个用户消息
|
|
841
|
+
updated_conversations = merge_with_last_user_message(conversations, cleanup_message)
|
|
842
|
+
|
|
843
|
+
# 验证结果
|
|
844
|
+
self.assertEqual(len(updated_conversations), 3)
|
|
845
|
+
last_message = updated_conversations[-1]
|
|
846
|
+
self.assertEqual(last_message["role"], "user")
|
|
847
|
+
self.assertIn("还有其他建议吗?", last_message["content"])
|
|
848
|
+
self.assertIn(cleanup_message, last_message["content"])
|
|
849
|
+
|
|
850
|
+
# 验证可以提取原始消息
|
|
851
|
+
original_content = extract_content_from_text(last_message["content"])
|
|
852
|
+
self.assertEqual(original_content, "还有其他建议吗?")
|
|
853
|
+
|
|
854
|
+
# 验证可以提取清理消息
|
|
855
|
+
extracted_cleanup = extract_hint_from_text(last_message["content"])
|
|
856
|
+
self.assertEqual(extracted_cleanup, cleanup_message)
|
|
857
|
+
|
|
858
|
+
def test_batch_processing_integration(self):
|
|
859
|
+
"""测试批量处理集成"""
|
|
860
|
+
# 准备批量数据
|
|
861
|
+
contents = [
|
|
862
|
+
"第一个文档内容",
|
|
863
|
+
"第二个文档内容",
|
|
864
|
+
"第三个文档内容"
|
|
865
|
+
]
|
|
866
|
+
hints = [
|
|
867
|
+
"第一个文档的处理提示",
|
|
868
|
+
"第二个文档的处理提示",
|
|
869
|
+
"第三个文档的处理提示"
|
|
870
|
+
]
|
|
871
|
+
|
|
872
|
+
# 批量添加提示
|
|
873
|
+
results = batch_add_hints(contents, hints)
|
|
874
|
+
|
|
875
|
+
# 验证批量处理结果
|
|
876
|
+
self.assertEqual(len(results), 3)
|
|
877
|
+
|
|
878
|
+
for i, result in enumerate(results):
|
|
879
|
+
# 验证每个结果都包含原内容和提示
|
|
880
|
+
self.assertIn(contents[i], result)
|
|
881
|
+
self.assertIn(hints[i], result)
|
|
882
|
+
|
|
883
|
+
# 验证可以单独提取内容和提示
|
|
884
|
+
extracted_content = extract_content_from_text(result)
|
|
885
|
+
extracted_hint = extract_hint_from_text(result)
|
|
886
|
+
|
|
887
|
+
self.assertEqual(extracted_content, contents[i])
|
|
888
|
+
self.assertEqual(extracted_hint, hints[i])
|
|
889
|
+
|
|
890
|
+
def test_custom_configuration_integration(self):
|
|
891
|
+
"""测试自定义配置集成"""
|
|
892
|
+
# 创建自定义配置
|
|
893
|
+
wrapper = create_hint_wrapper(
|
|
894
|
+
separator="\n+++\n",
|
|
895
|
+
prefix="[SYSTEM] ",
|
|
896
|
+
suffix=" [/SYSTEM]",
|
|
897
|
+
allow_empty_hint=True
|
|
898
|
+
)
|
|
899
|
+
|
|
900
|
+
content = "系统消息内容"
|
|
901
|
+
hint = "重要的系统提示"
|
|
902
|
+
|
|
903
|
+
# 使用自定义配置添加提示
|
|
904
|
+
result = wrapper.add_hint(content, hint)
|
|
905
|
+
|
|
906
|
+
# 验证自定义格式
|
|
907
|
+
self.assertIn("\n+++\n", result)
|
|
908
|
+
self.assertIn("[SYSTEM]", result)
|
|
909
|
+
self.assertIn("[/SYSTEM]", result)
|
|
910
|
+
|
|
911
|
+
# 验证可以正确提取(需要使用相同配置)
|
|
912
|
+
extracted_content = wrapper.extract_content(result)
|
|
913
|
+
extracted_hint = wrapper.extract_hint(result)
|
|
914
|
+
|
|
915
|
+
self.assertEqual(extracted_content, content)
|
|
916
|
+
self.assertEqual(extracted_hint, hint)
|
|
917
|
+
|
|
918
|
+
def test_error_handling_integration(self):
|
|
919
|
+
"""测试错误处理集成"""
|
|
920
|
+
# 测试各种错误情况的处理
|
|
921
|
+
|
|
922
|
+
# 1. 空提示处理
|
|
923
|
+
content = "测试内容"
|
|
924
|
+
empty_hint = ""
|
|
925
|
+
fallback_hint = "备用提示"
|
|
926
|
+
|
|
927
|
+
result = safe_add_hint(content, empty_hint, fallback_hint)
|
|
928
|
+
self.assertIn(fallback_hint, result)
|
|
929
|
+
|
|
930
|
+
# 2. 批量处理中的错误处理
|
|
931
|
+
contents = ["内容1", "内容2"]
|
|
932
|
+
hints = ["正常提示", ""] # 一个正常,一个空提示
|
|
933
|
+
|
|
934
|
+
results = batch_add_hints(contents, hints)
|
|
935
|
+
self.assertEqual(len(results), 2)
|
|
936
|
+
# 第一个应该成功添加提示
|
|
937
|
+
self.assertIn("正常提示", results[0])
|
|
938
|
+
# 第二个应该保留原内容(因为空提示出错)
|
|
939
|
+
self.assertEqual(results[1], "内容2")
|
|
940
|
+
|
|
941
|
+
def test_statistics_integration(self):
|
|
942
|
+
"""测试统计功能集成"""
|
|
943
|
+
content = "这是一段测试内容"
|
|
944
|
+
hint = "这是测试提示信息"
|
|
945
|
+
|
|
946
|
+
# 添加提示
|
|
947
|
+
wrapped_content = add_hint_to_text(content, hint)
|
|
948
|
+
|
|
949
|
+
# 获取统计信息
|
|
950
|
+
stats = get_text_statistics(wrapped_content)
|
|
951
|
+
|
|
952
|
+
# 验证统计信息
|
|
953
|
+
self.assertEqual(stats["content_length"], len(content))
|
|
954
|
+
self.assertEqual(stats["hint_length"], len(hint))
|
|
955
|
+
self.assertTrue(stats["has_hint"])
|
|
956
|
+
self.assertEqual(stats["separator_count"], 1)
|
|
957
|
+
self.assertEqual(stats["total_length"], len(wrapped_content))
|
|
958
|
+
|
|
959
|
+
# 添加多个提示并验证统计
|
|
960
|
+
multiple_hints = ["提示1", "提示2", "提示3"]
|
|
961
|
+
multi_wrapped = add_multiple_hints_to_text(content, multiple_hints)
|
|
962
|
+
multi_stats = get_text_statistics(multi_wrapped)
|
|
963
|
+
|
|
964
|
+
self.assertEqual(multi_stats["separator_count"], 3)
|
|
965
|
+
self.assertTrue(multi_stats["has_hint"])
|
|
966
|
+
|
|
967
|
+
def test_append_hint_integration(self):
|
|
968
|
+
"""测试追加hint功能的集成测试"""
|
|
969
|
+
# 测试用户需求:从 ---\n[[hint1]] 追加后为 ---\n[[hint1\nhint2]]
|
|
970
|
+
|
|
971
|
+
# 1. 创建带有初始hint的内容
|
|
972
|
+
content = "这是原始文本内容"
|
|
973
|
+
initial_hint = "hint1"
|
|
974
|
+
|
|
975
|
+
wrapped_content = add_hint_to_text(content, initial_hint)
|
|
976
|
+
expected_initial = "这是原始文本内容\n---\n[[hint1]]"
|
|
977
|
+
self.assertEqual(wrapped_content, expected_initial)
|
|
978
|
+
|
|
979
|
+
# 2. 追加新的hint
|
|
980
|
+
additional_hint = "hint2"
|
|
981
|
+
appended_content = append_hint_to_text(wrapped_content, additional_hint)
|
|
982
|
+
expected_appended = "这是原始文本内容\n---\n[[hint1\nhint2]]"
|
|
983
|
+
self.assertEqual(appended_content, expected_appended)
|
|
984
|
+
|
|
985
|
+
# 3. 验证可以正确提取内容和组合后的hint
|
|
986
|
+
extracted_content = extract_content_from_text(appended_content)
|
|
987
|
+
extracted_hint = extract_hint_from_text(appended_content)
|
|
988
|
+
|
|
989
|
+
self.assertEqual(extracted_content, content)
|
|
990
|
+
self.assertEqual(extracted_hint, "hint1\nhint2")
|
|
991
|
+
|
|
992
|
+
# 4. 继续追加第三个hint
|
|
993
|
+
third_hint = "hint3"
|
|
994
|
+
final_content = append_hint_to_text(appended_content, third_hint)
|
|
995
|
+
expected_final = "这是原始文本内容\n---\n[[hint1\nhint2\nhint3]]"
|
|
996
|
+
self.assertEqual(final_content, expected_final)
|
|
997
|
+
|
|
998
|
+
# 5. 验证最终的提取结果
|
|
999
|
+
final_extracted_content = extract_content_from_text(final_content)
|
|
1000
|
+
final_extracted_hint = extract_hint_from_text(final_content)
|
|
1001
|
+
|
|
1002
|
+
self.assertEqual(final_extracted_content, content)
|
|
1003
|
+
self.assertEqual(final_extracted_hint, "hint1\nhint2\nhint3")
|
|
1004
|
+
|
|
1005
|
+
def test_append_vs_add_behavior_difference(self):
|
|
1006
|
+
"""测试追加和添加功能的行为差异"""
|
|
1007
|
+
content = "测试内容\n---\n[[现有提示]]"
|
|
1008
|
+
new_hint = "新提示"
|
|
1009
|
+
|
|
1010
|
+
# 使用 add_hint_to_text(会创建新的分隔符)
|
|
1011
|
+
add_result = add_hint_to_text(content, new_hint)
|
|
1012
|
+
# 这会导致: "测试内容\n---\n[[现有提示]]\n---\n[[新提示]]"
|
|
1013
|
+
self.assertEqual(add_result.count("\n---\n"), 2)
|
|
1014
|
+
|
|
1015
|
+
# 使用 append_hint_to_text(会追加到现有hint中)
|
|
1016
|
+
append_result = append_hint_to_text(content, new_hint)
|
|
1017
|
+
expected_append = "测试内容\n---\n[[现有提示\n新提示]]"
|
|
1018
|
+
self.assertEqual(append_result, expected_append)
|
|
1019
|
+
self.assertEqual(append_result.count("\n---\n"), 1)
|
|
1020
|
+
|
|
1021
|
+
# 验证提取的hint内容不同
|
|
1022
|
+
add_hint_extracted = extract_hint_from_text(add_result)
|
|
1023
|
+
append_hint_extracted = extract_hint_from_text(append_result)
|
|
1024
|
+
|
|
1025
|
+
self.assertEqual(add_hint_extracted, new_hint) # add 只提取最后一个
|
|
1026
|
+
self.assertEqual(append_hint_extracted, "现有提示\n新提示") # append 提取组合的
|
|
1027
|
+
|
|
1028
|
+
def test_conversation_append_integration(self):
|
|
1029
|
+
"""测试对话系统中的追加功能集成"""
|
|
1030
|
+
# 模拟已经有hint的对话消息
|
|
1031
|
+
conversations = [
|
|
1032
|
+
{"role": "user", "content": "请帮我分析代码\n---\n[[重要:这是复杂的代码]]"},
|
|
1033
|
+
{"role": "assistant", "content": "好的,我来分析"},
|
|
1034
|
+
{"role": "user", "content": "还有其他问题吗?\n---\n[[请仔细检查]]"}
|
|
1035
|
+
]
|
|
1036
|
+
|
|
1037
|
+
cleanup_message = "对话内容过长,请使用 conversation_message_ids_write 工具"
|
|
1038
|
+
|
|
1039
|
+
# 使用追加模式合并
|
|
1040
|
+
result = merge_with_last_user_message(conversations, cleanup_message, append_mode=True)
|
|
1041
|
+
|
|
1042
|
+
# 验证结果
|
|
1043
|
+
self.assertEqual(len(result), 3)
|
|
1044
|
+
last_message = result[-1]
|
|
1045
|
+
|
|
1046
|
+
# 验证内容包含原始消息
|
|
1047
|
+
self.assertIn("还有其他问题吗?", last_message["content"])
|
|
1048
|
+
|
|
1049
|
+
# 验证包含原有hint和新hint
|
|
1050
|
+
self.assertIn("请仔细检查", last_message["content"])
|
|
1051
|
+
self.assertIn(cleanup_message, last_message["content"])
|
|
1052
|
+
|
|
1053
|
+
# 验证格式正确(应该是追加模式的格式)
|
|
1054
|
+
expected_content = "还有其他问题吗?\n---\n[[请仔细检查\n对话内容过长,请使用 conversation_message_ids_write 工具]]"
|
|
1055
|
+
self.assertEqual(last_message["content"], expected_content)
|
|
1056
|
+
|
|
1057
|
+
# 验证提取功能
|
|
1058
|
+
extracted_content = extract_content_from_text(last_message["content"])
|
|
1059
|
+
extracted_hint = extract_hint_from_text(last_message["content"])
|
|
1060
|
+
|
|
1061
|
+
self.assertEqual(extracted_content, "还有其他问题吗?")
|
|
1062
|
+
self.assertEqual(extracted_hint, "请仔细检查\n对话内容过长,请使用 conversation_message_ids_write 工具")
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
if __name__ == "__main__":
|
|
1066
|
+
# 支持直接运行测试文件
|
|
1067
|
+
unittest.main(verbosity=2)
|